import type { Meta, StoryObj } from '@storybook/react-vite' import { useState } from 'react' import { IconSquareRounded } from '@tabler/icons-react' import { Avatar } from './Avatar' import { ChipInput, InputChip, type ChipInputOption } from './ChipInput' const PEOPLE: ChipInputOption[] = [ { id: '1', name: 'Ana Duarte', description: 'Design' }, { id: '2', name: 'Ravi Mehta', description: 'Engineering' }, { id: '3', name: 'Marta Silva', description: 'Product' }, { id: '4', name: 'Jonas Weber', description: 'Engineering' }, { id: '5', name: 'Lea Novak', description: 'Research' }, ].map(({ id, name, description }) => ({ id, label: name, description })) const LABELS: ChipInputOption[] = [ { id: 'a', label: 'Amber' }, { id: 'b', label: 'Cobalt' }, { id: 'c', label: 'Moss' }, { id: 'd', label: 'Slate' }, ] /** The person flavour: faces in the chips and the rows, from the two leading * slots — the Avatar at its own corners, never forced into a circle. */ const personLeading = { chipLeading: (o: ChipInputOption) => , rowLeading: (o: ChipInputOption) => , } const meta = { title: 'Inputs/ChipInput', component: ChipInput, parameters: { // The suggestion list portals to document.body at fixed coordinates — // render docs usage in an iframe so it lands where the field is. docs: { story: { inline: false, height: '320px' } }, }, args: { value: [], onChange: () => {}, options: PEOPLE }, argTypes: { value: { control: false }, onChange: { control: false }, options: { control: false }, chipLeading: { control: false }, rowLeading: { control: false }, }, decorators: [(Story) =>
{Story()}
], } satisfies Meta export default meta type Story = StoryObj /** Type a name — suggestions appear only once there is a query. */ export const TypeToSearch: Story = { parameters: { controls: { disable: true } }, render: (args) => { const [value, setValue] = useState([]) return }, } /** Chosen people are chips. Backspace on an empty query removes the last one. */ export const WithChips: Story = { parameters: { controls: { disable: true } }, render: (args) => { const [value, setValue] = useState([PEOPLE[0], PEOPLE[1]]) return }, } /** `excludeIds` keeps someone out of the suggestions — the current user, say. */ export const ExcludingSomeone: Story = { parameters: { controls: { disable: true } }, render: (args) => { const [value, setValue] = useState([]) return }, } /** * Nothing about people: no leading slots, and the chips are plain labels. * The same input picks anything multi-select. */ export const PlainLabels: Story = { parameters: { controls: { disable: true } }, render: (args) => { const [value, setValue] = useState([LABELS[0]]) return }, } /** The chip on its own: with a face, with nothing, and display-only (no ✕). */ export const TheChipItself: Story = { parameters: { controls: { disable: true } }, render: () => (
} onRemove={() => {}} /> {}} />
), } /** A chip capped in width, its long label cut, and a ✕ named for what it does. */ export const ALongLabelCut: Story = { parameters: { controls: { disable: true } }, render: () => (
} onRemove={() => {}} removeLabel="Leave the label" truncate className="max-w-44" />
), }