import type { Meta, StoryObj } from '@storybook/react-vite' import { IconMessage2, IconMoodPlus } from '@tabler/icons-react' import { useState } from 'react' import { Popover } from './Popover' import { Reaction } from './Reaction' import { ReactionPicker, type ReactionOption } from './ReactionPicker' import { Toolbar, ToolbarButton } from './Toolbar' import { EmptyState } from './EmptyState' import { Card } from './Card' /** * The reactions on offer, to choose one from. **A `Reaction` is the answer; * this is the question.** * * Icon buttons holding emoji, on a `Toolbar` — so the strip carries the * elevated box a floating control needs, and the whole row is one Tab stop. * * The vocabulary is the app's: which emoji it offers and what each one means. * These canvases use a neutral set. */ const OPTIONS: ReactionOption[] = [ { emoji: '👍', label: 'Agree' }, { emoji: '🎉', label: 'Celebrate' }, { emoji: '🙏', label: 'Thank you' }, { emoji: '🚀', label: 'Ship it' }, { emoji: '👀', label: 'Looking' }, ] const meta = { title: 'Components/ReactionPicker', component: ReactionPicker, args: { options: OPTIONS, onSelect: () => {} }, argTypes: { options: { control: false }, onSelect: { control: false } }, } satisfies Meta export default meta type Story = StoryObj /** The picker, as it floats: the strip and its box. */ export const Default: Story = {} /** * **Where it comes from.** A card carries a `Toolbar` of actions; one of them * opens the picker, and it opens **above** that control — what is being * reacted to is underneath. * * The box here is the `Popover`'s, so the picker passes `surface={false}`: * two boxes inside each other is the tell. */ export const FromATrigger: Story = { parameters: { controls: { disable: true }, layout: 'centered' }, render: function FromTrigger() { const [chosen, setChosen] = useState(null) return (
A card. Its actions sit at the corner, and the picker opens above them.
} > {chosen ? `Chose ${chosen}` : 'Nothing chosen yet.'}
) }, } /** * **What it produces.** Picking puts a `Reaction` in the row on the card — * the pill with the count and, when it is yours, the accent fill. That state * belongs to `Reaction`; the picker only asks. */ export const AndWhatItProduces: Story = { parameters: { controls: { disable: true } }, render: function Produces() { const [mine, setMine] = useState(['👍']) return (
setMine((prev) => (prev.includes(emoji) ? prev.filter((e) => e !== emoji) : [...prev, emoji]))} />
{mine.length === 0 ? ( ) : ( mine.map((emoji) => { const option = OPTIONS.find((o) => o.emoji === emoji)! return ( setMine((prev) => prev.filter((e) => e !== emoji))} /> ) }) )}
) }, }