Skip to content

Commit 3584821

Browse files
authored
Merge pull request #20 from marklearst/pr/20-listbox
feat(listbox): add multiple support
2 parents 9ef3e0f + 17825d2 commit 3584821

2 files changed

Lines changed: 64 additions & 1 deletion

File tree

src/components/form-field/listbox/listbox.stories.tsx

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,55 @@ const ListboxBadgeWithHooks: FC<{
123123
)
124124
}
125125

126+
const ListboxMultiWithHooks = ({
127+
label,
128+
description,
129+
placeholder,
130+
}: {
131+
label: string
132+
description: string
133+
placeholder: string
134+
}) => {
135+
const [selectedPeople, setSelectedPeople] = useState<Person[]>([])
136+
const selectedLabels = selectedPeople.map((person) => person.name).join(', ')
137+
138+
return (
139+
<FormField>
140+
<FormField.LabelGroup>
141+
<FormField.Label htmlFor='value'>{label}</FormField.Label>
142+
<FormField.Description id='value-description'>
143+
{description}
144+
</FormField.Description>
145+
</FormField.LabelGroup>
146+
<FormField.Listbox
147+
value={selectedPeople}
148+
onChange={setSelectedPeople}
149+
multiple
150+
>
151+
<FormField.Listbox.Button>
152+
<FormField.Listbox.Button.TextValue
153+
value={selectedLabels || null}
154+
placeholder={placeholder}
155+
/>
156+
</FormField.Listbox.Button>
157+
<FormField.Listbox.Options>
158+
{people.map((person) => (
159+
<FormField.Listbox.Option
160+
value={person}
161+
key={person.id}
162+
disabled={person.isDead}
163+
>
164+
<FormField.Listbox.Option.TextOption>
165+
{person.name}
166+
</FormField.Listbox.Option.TextOption>
167+
</FormField.Listbox.Option>
168+
))}
169+
</FormField.Listbox.Options>
170+
</FormField.Listbox>
171+
</FormField>
172+
)
173+
}
174+
126175
export const Default: Story = {
127176
render: ({ label, description, placeholder, width }) => (
128177
<div style={{ width }}>
@@ -160,3 +209,15 @@ export const Disabled: Story = {
160209
</div>
161210
),
162211
}
212+
213+
export const Multiple: Story = {
214+
render: ({ label, description, placeholder, width }) => (
215+
<div style={{ width }}>
216+
<ListboxMultiWithHooks
217+
label={label}
218+
description={description}
219+
placeholder={placeholder}
220+
/>
221+
</div>
222+
),
223+
}

src/components/form-field/listbox/listbox.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,19 @@ export interface ListboxProps<TValue> {
1818
children: ReactNode
1919
value: TValue
2020
onChange: (value: TValue) => void
21+
multiple?: boolean
2122
className?: string
2223
}
2324

2425
const Listbox = <TValue,>({
2526
children,
2627
value,
2728
onChange,
29+
multiple,
2830
className,
2931
}: ListboxProps<TValue>) => {
3032
return (
31-
<HeadlessListbox value={value} onChange={onChange}>
33+
<HeadlessListbox value={value} onChange={onChange} multiple={multiple}>
3234
<div
3335
className={classNames(
3436
'relative w-full',

0 commit comments

Comments
 (0)