@arbor-education/design-system.components 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gather/skills/write-stories/SKILL.md +207 -271
- package/.storybook/preview.ts +5 -0
- package/CHANGELOG.md +17 -0
- package/README.md +8 -0
- package/component-library.md +144 -13
- package/dist/components/articleCard/ArticleCard.stories.d.ts +137 -11
- package/dist/components/articleCard/ArticleCard.stories.d.ts.map +1 -1
- package/dist/components/articleCard/ArticleCard.stories.js +358 -91
- package/dist/components/articleCard/ArticleCard.stories.js.map +1 -1
- package/dist/components/avatar/Avatar.stories.d.ts +6 -6
- package/dist/components/avatar/Avatar.stories.d.ts.map +1 -1
- package/dist/components/avatar/Avatar.stories.js +393 -49
- package/dist/components/avatar/Avatar.stories.js.map +1 -1
- package/dist/components/avatarGroup/AvatarGroup.stories.d.ts +9 -7
- package/dist/components/avatarGroup/AvatarGroup.stories.d.ts.map +1 -1
- package/dist/components/avatarGroup/AvatarGroup.stories.js +688 -65
- package/dist/components/avatarGroup/AvatarGroup.stories.js.map +1 -1
- package/dist/components/banner/Banner.stories.d.ts.map +1 -1
- package/dist/components/banner/Banner.stories.js +7 -3
- package/dist/components/banner/Banner.stories.js.map +1 -1
- package/dist/components/card/Card.stories.d.ts +105 -4
- package/dist/components/card/Card.stories.d.ts.map +1 -1
- package/dist/components/card/Card.stories.js +336 -18
- package/dist/components/card/Card.stories.js.map +1 -1
- package/dist/components/combobox/Combobox.stories.d.ts +134 -21
- package/dist/components/combobox/Combobox.stories.d.ts.map +1 -1
- package/dist/components/combobox/Combobox.stories.js +676 -175
- package/dist/components/combobox/Combobox.stories.js.map +1 -1
- package/dist/components/datePicker/DatePicker.stories.d.ts +119 -27
- package/dist/components/datePicker/DatePicker.stories.d.ts.map +1 -1
- package/dist/components/datePicker/DatePicker.stories.js +575 -47
- package/dist/components/datePicker/DatePicker.stories.js.map +1 -1
- package/dist/components/dateTimePicker/DateTimePicker.stories.d.ts +155 -39
- package/dist/components/dateTimePicker/DateTimePicker.stories.d.ts.map +1 -1
- package/dist/components/dateTimePicker/DateTimePicker.stories.js +674 -103
- package/dist/components/dateTimePicker/DateTimePicker.stories.js.map +1 -1
- package/dist/components/editableText/EditableText.stories.d.ts +53 -12
- package/dist/components/editableText/EditableText.stories.d.ts.map +1 -1
- package/dist/components/editableText/EditableText.stories.js +401 -64
- package/dist/components/editableText/EditableText.stories.js.map +1 -1
- package/dist/components/formField/FormField.d.ts +4 -0
- package/dist/components/formField/FormField.d.ts.map +1 -1
- package/dist/components/formField/FormField.js +2 -1
- package/dist/components/formField/FormField.js.map +1 -1
- package/dist/components/formField/FormField.test.js +5 -0
- package/dist/components/formField/FormField.test.js.map +1 -1
- package/dist/components/formField/fieldset/Fieldset.stories.d.ts +56 -4
- package/dist/components/formField/fieldset/Fieldset.stories.d.ts.map +1 -1
- package/dist/components/formField/fieldset/Fieldset.stories.js +534 -28
- package/dist/components/formField/fieldset/Fieldset.stories.js.map +1 -1
- package/dist/components/formField/inputs/checkbox/CheckboxGroup.d.ts +3 -1
- package/dist/components/formField/inputs/checkbox/CheckboxGroup.d.ts.map +1 -1
- package/dist/components/formField/inputs/checkbox/CheckboxInput.js +1 -1
- package/dist/components/formField/inputs/checkbox/CheckboxInput.js.map +1 -1
- package/dist/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.d.ts +95 -1
- package/dist/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.d.ts.map +1 -1
- package/dist/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.js +386 -9
- package/dist/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.js.map +1 -1
- package/dist/components/formField/inputs/radio/RadioButtonGroup.d.ts +6 -2
- package/dist/components/formField/inputs/radio/RadioButtonGroup.d.ts.map +1 -1
- package/dist/components/formField/inputs/radio/RadioButtonGroup.js.map +1 -1
- package/dist/components/formField/inputs/radio/RadioButtonInput.stories.d.ts.map +1 -1
- package/dist/components/formField/inputs/radio/RadioButtonInput.stories.js +61 -49
- package/dist/components/formField/inputs/radio/RadioButtonInput.stories.js.map +1 -1
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.d.ts +188 -166
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.d.ts.map +1 -1
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.js +821 -160
- package/dist/components/formField/inputs/selectDropdown/SelectDropdown.stories.js.map +1 -1
- package/dist/components/formField/inputs/time/TimeInput.stories.d.ts +176 -22
- package/dist/components/formField/inputs/time/TimeInput.stories.d.ts.map +1 -1
- package/dist/components/formField/inputs/time/TimeInput.stories.js +851 -92
- package/dist/components/formField/inputs/time/TimeInput.stories.js.map +1 -1
- package/dist/components/formField/label/Label.stories.d.ts +54 -5
- package/dist/components/formField/label/Label.stories.d.ts.map +1 -1
- package/dist/components/formField/label/Label.stories.js +238 -4
- package/dist/components/formField/label/Label.stories.js.map +1 -1
- package/dist/components/icoText/IcoText.stories.d.ts +32 -6
- package/dist/components/icoText/IcoText.stories.d.ts.map +1 -1
- package/dist/components/icoText/IcoText.stories.js +309 -14
- package/dist/components/icoText/IcoText.stories.js.map +1 -1
- package/dist/components/kpiCard/KPICard.stories.d.ts +100 -2
- package/dist/components/kpiCard/KPICard.stories.d.ts.map +1 -1
- package/dist/components/kpiCard/KPICard.stories.js +354 -10
- package/dist/components/kpiCard/KPICard.stories.js.map +1 -1
- package/dist/components/kvpList/KVPList.stories.d.ts +57 -4
- package/dist/components/kvpList/KVPList.stories.d.ts.map +1 -1
- package/dist/components/kvpList/KVPList.stories.js +403 -10
- package/dist/components/kvpList/KVPList.stories.js.map +1 -1
- package/dist/components/modal/Modal.stories.d.ts +113 -9
- package/dist/components/modal/Modal.stories.d.ts.map +1 -1
- package/dist/components/modal/Modal.stories.js +633 -13
- package/dist/components/modal/Modal.stories.js.map +1 -1
- package/dist/components/modal/modalManager/ModalManager.stories.d.ts +34 -10
- package/dist/components/modal/modalManager/ModalManager.stories.d.ts.map +1 -1
- package/dist/components/modal/modalManager/ModalManager.stories.js +463 -85
- package/dist/components/modal/modalManager/ModalManager.stories.js.map +1 -1
- package/dist/components/pill/Pill.d.ts.map +1 -1
- package/dist/components/pill/Pill.js +1 -1
- package/dist/components/pill/Pill.js.map +1 -1
- package/dist/components/pill/Pill.stories.d.ts.map +1 -1
- package/dist/components/pill/Pill.stories.js +11 -13
- package/dist/components/pill/Pill.stories.js.map +1 -1
- package/dist/components/row/Row.stories.d.ts +1 -2
- package/dist/components/row/Row.stories.d.ts.map +1 -1
- package/dist/components/row/Row.stories.js +360 -50
- package/dist/components/row/Row.stories.js.map +1 -1
- package/dist/components/searchBar/SearchBar.stories.d.ts +52 -4
- package/dist/components/searchBar/SearchBar.stories.d.ts.map +1 -1
- package/dist/components/searchBar/SearchBar.stories.js +428 -36
- package/dist/components/searchBar/SearchBar.stories.js.map +1 -1
- package/dist/components/section/Section.stories.d.ts +11 -41
- package/dist/components/section/Section.stories.d.ts.map +1 -1
- package/dist/components/section/Section.stories.js +494 -56
- package/dist/components/section/Section.stories.js.map +1 -1
- package/dist/components/singleUser/SingleUser.stories.d.ts +5 -4
- package/dist/components/singleUser/SingleUser.stories.d.ts.map +1 -1
- package/dist/components/singleUser/SingleUser.stories.js +303 -31
- package/dist/components/singleUser/SingleUser.stories.js.map +1 -1
- package/dist/components/slideoverManager/SlideoverManager.stories.d.ts +32 -11
- package/dist/components/slideoverManager/SlideoverManager.stories.d.ts.map +1 -1
- package/dist/components/slideoverManager/SlideoverManager.stories.js +380 -84
- package/dist/components/slideoverManager/SlideoverManager.stories.js.map +1 -1
- package/dist/components/table/DSDefaultColDef.d.ts.map +1 -1
- package/dist/components/table/DSDefaultColDef.js +4 -3
- package/dist/components/table/DSDefaultColDef.js.map +1 -1
- package/dist/components/table/Table.d.ts +6 -1
- package/dist/components/table/Table.d.ts.map +1 -1
- package/dist/components/table/Table.js +8 -3
- package/dist/components/table/Table.js.map +1 -1
- package/dist/components/table/Table.stories.d.ts +2 -0
- package/dist/components/table/Table.stories.d.ts.map +1 -1
- package/dist/components/table/Table.stories.js +357 -3
- package/dist/components/table/Table.stories.js.map +1 -1
- package/dist/components/table/TableFooter.stories.d.ts +49 -0
- package/dist/components/table/TableFooter.stories.d.ts.map +1 -0
- package/dist/components/table/TableFooter.stories.js +137 -0
- package/dist/components/table/TableFooter.stories.js.map +1 -0
- package/dist/components/table/TableHeader.stories.d.ts +93 -0
- package/dist/components/table/TableHeader.stories.d.ts.map +1 -0
- package/dist/components/table/TableHeader.stories.js +176 -0
- package/dist/components/table/TableHeader.stories.js.map +1 -0
- package/dist/components/table/cellEditors/DateCellEditor.stories.d.ts +44 -0
- package/dist/components/table/cellEditors/DateCellEditor.stories.d.ts.map +1 -0
- package/dist/components/table/cellEditors/DateCellEditor.stories.js +186 -0
- package/dist/components/table/cellEditors/DateCellEditor.stories.js.map +1 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.d.ts +40 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.js +209 -0
- package/dist/components/table/cellRenderers/BooleanCellRenderer.stories.js.map +1 -0
- package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.d.ts +48 -0
- package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.js +244 -0
- package/dist/components/table/cellRenderers/ButtonCellRenderer.stories.js.map +1 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.d.ts.map +1 -1
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.js +3 -1
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.js.map +1 -1
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.d.ts +64 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.js +241 -0
- package/dist/components/table/cellRenderers/CheckboxCellRenderer.stories.js.map +1 -0
- package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.d.ts +55 -0
- package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.js +245 -0
- package/dist/components/table/cellRenderers/DefaultCellRenderer.stories.js.map +1 -0
- package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.d.ts +67 -0
- package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.js +221 -0
- package/dist/components/table/cellRenderers/InlineTextCellRenderer.stories.js.map +1 -0
- package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.d.ts +75 -0
- package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.d.ts.map +1 -0
- package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.js +270 -0
- package/dist/components/table/cellRenderers/SelectDropdownCellRenderer.stories.js.map +1 -0
- package/dist/components/table/columnFilters/BooleanFilter.stories.d.ts +57 -0
- package/dist/components/table/columnFilters/BooleanFilter.stories.d.ts.map +1 -0
- package/dist/components/table/columnFilters/BooleanFilter.stories.js +198 -0
- package/dist/components/table/columnFilters/BooleanFilter.stories.js.map +1 -0
- package/dist/components/table/columnFilters/TimeFilter.stories.d.ts +58 -0
- package/dist/components/table/columnFilters/TimeFilter.stories.d.ts.map +1 -0
- package/dist/components/table/columnFilters/TimeFilter.stories.js +207 -0
- package/dist/components/table/columnFilters/TimeFilter.stories.js.map +1 -0
- package/dist/components/table/pagination/PaginationPanel.stories.d.ts +113 -0
- package/dist/components/table/pagination/PaginationPanel.stories.d.ts.map +1 -0
- package/dist/components/table/pagination/PaginationPanel.stories.js +272 -0
- package/dist/components/table/pagination/PaginationPanel.stories.js.map +1 -0
- package/dist/components/table/tableControls/TableControls.stories.d.ts +151 -0
- package/dist/components/table/tableControls/TableControls.stories.d.ts.map +1 -0
- package/dist/components/table/tableControls/TableControls.stories.js +356 -0
- package/dist/components/table/tableControls/TableControls.stories.js.map +1 -0
- package/dist/components/table/tableControls/TableSettingsDropdown.d.ts +27 -1
- package/dist/components/table/tableControls/TableSettingsDropdown.d.ts.map +1 -1
- package/dist/components/table/tableControls/TableSettingsDropdown.js +53 -26
- package/dist/components/table/tableControls/TableSettingsDropdown.js.map +1 -1
- package/dist/components/table/tableControls/TableSettingsDropdown.test.d.ts +2 -0
- package/dist/components/table/tableControls/TableSettingsDropdown.test.d.ts.map +1 -0
- package/dist/components/table/tableControls/TableSettingsDropdown.test.js +178 -0
- package/dist/components/table/tableControls/TableSettingsDropdown.test.js.map +1 -0
- package/dist/components/tabs/Tabs.stories.d.ts +22 -4
- package/dist/components/tabs/Tabs.stories.d.ts.map +1 -1
- package/dist/components/tabs/Tabs.stories.js +398 -22
- package/dist/components/tabs/Tabs.stories.js.map +1 -1
- package/dist/components/tabs/TabsItem.stories.d.ts +54 -1
- package/dist/components/tabs/TabsItem.stories.d.ts.map +1 -1
- package/dist/components/tabs/TabsItem.stories.js +61 -9
- package/dist/components/tabs/TabsItem.stories.js.map +1 -1
- package/dist/components/toast/Toast.stories.d.ts +103 -10
- package/dist/components/toast/Toast.stories.d.ts.map +1 -1
- package/dist/components/toast/Toast.stories.js +409 -47
- package/dist/components/toast/Toast.stories.js.map +1 -1
- package/dist/components/toggle/Toggle.stories.d.ts +61 -46
- package/dist/components/toggle/Toggle.stories.d.ts.map +1 -1
- package/dist/components/toggle/Toggle.stories.js +311 -122
- package/dist/components/toggle/Toggle.stories.js.map +1 -1
- package/dist/components/tooltip/Tooltip.stories.d.ts +78 -6
- package/dist/components/tooltip/Tooltip.stories.d.ts.map +1 -1
- package/dist/components/tooltip/Tooltip.stories.js +413 -7
- package/dist/components/tooltip/Tooltip.stories.js.map +1 -1
- package/dist/components/tooltip/TooltipWrapper.stories.d.ts +71 -7
- package/dist/components/tooltip/TooltipWrapper.stories.d.ts.map +1 -1
- package/dist/components/tooltip/TooltipWrapper.stories.js +238 -10
- package/dist/components/tooltip/TooltipWrapper.stories.js.map +1 -1
- package/dist/index.css +8 -0
- package/dist/index.css.map +1 -1
- package/dist/utils/PopupParentContext.stories.d.ts +17 -0
- package/dist/utils/PopupParentContext.stories.d.ts.map +1 -0
- package/dist/utils/PopupParentContext.stories.js +266 -0
- package/dist/utils/PopupParentContext.stories.js.map +1 -0
- package/dist/utils/getDefaultPopupParent.d.ts.map +1 -1
- package/dist/utils/getDefaultPopupParent.js +6 -0
- package/dist/utils/getDefaultPopupParent.js.map +1 -1
- package/package.json +1 -1
- package/src/components/articleCard/ArticleCard.stories.tsx +524 -111
- package/src/components/avatar/Avatar.stories.tsx +504 -59
- package/src/components/avatarGroup/AvatarGroup.stories.tsx +977 -175
- package/src/components/banner/Banner.stories.tsx +7 -3
- package/src/components/card/Card.stories.tsx +466 -36
- package/src/components/combobox/Combobox.stories.tsx +867 -260
- package/src/components/datePicker/DatePicker.stories.tsx +777 -60
- package/src/components/dateTimePicker/DateTimePicker.stories.tsx +910 -132
- package/src/components/editableText/EditableText.stories.tsx +567 -91
- package/src/components/formField/FormField.test.tsx +6 -0
- package/src/components/formField/FormField.tsx +5 -0
- package/src/components/formField/fieldset/Fieldset.stories.tsx +761 -51
- package/src/components/formField/inputs/checkbox/CheckboxGroup.tsx +1 -1
- package/src/components/formField/inputs/checkbox/CheckboxInput.tsx +1 -1
- package/src/components/formField/inputs/colourPickerDropdown/ColourPickerDropdown.stories.tsx +504 -11
- package/src/components/formField/inputs/radio/RadioButtonGroup.tsx +17 -4
- package/src/components/formField/inputs/radio/RadioButtonInput.stories.tsx +71 -59
- package/src/components/formField/inputs/selectDropdown/SelectDropdown.stories.tsx +1079 -168
- package/src/components/formField/inputs/time/TimeInput.stories.tsx +1140 -104
- package/src/components/formField/label/Label.stories.tsx +317 -8
- package/src/components/icoText/IcoText.stories.tsx +442 -31
- package/src/components/kpiCard/KPICard.stories.tsx +475 -30
- package/src/components/kvpList/KVPList.stories.tsx +593 -26
- package/src/components/modal/Modal.stories.tsx +963 -26
- package/src/components/modal/modalManager/ModalManager.stories.tsx +612 -454
- package/src/components/pill/Pill.stories.tsx +11 -13
- package/src/components/pill/Pill.tsx +1 -0
- package/src/components/row/Row.stories.tsx +474 -58
- package/src/components/searchBar/SearchBar.stories.tsx +570 -38
- package/src/components/section/Section.stories.tsx +723 -70
- package/src/components/singleUser/SingleUser.stories.tsx +393 -34
- package/src/components/slideoverManager/SlideoverManager.stories.tsx +572 -342
- package/src/components/table/DSDefaultColDef.ts +25 -5
- package/src/components/table/Table.stories.tsx +411 -3
- package/src/components/table/Table.tsx +9 -2
- package/src/components/table/TableFooter.stories.tsx +196 -0
- package/src/components/table/TableHeader.stories.tsx +251 -0
- package/src/components/table/cellEditors/DateCellEditor.stories.tsx +245 -0
- package/src/components/table/cellRenderers/BooleanCellRenderer.stories.tsx +278 -0
- package/src/components/table/cellRenderers/ButtonCellRenderer.stories.tsx +333 -0
- package/src/components/table/cellRenderers/CheckboxCellRenderer.stories.tsx +337 -0
- package/src/components/table/cellRenderers/CheckboxCellRenderer.tsx +5 -1
- package/src/components/table/cellRenderers/DefaultCellRenderer.stories.tsx +342 -0
- package/src/components/table/cellRenderers/InlineTextCellRenderer.stories.tsx +292 -0
- package/src/components/table/cellRenderers/SelectDropdownCellRenderer.stories.tsx +369 -0
- package/src/components/table/columnFilters/BooleanFilter.stories.tsx +268 -0
- package/src/components/table/columnFilters/TimeFilter.stories.tsx +281 -0
- package/src/components/table/pagination/PaginationPanel.stories.tsx +327 -0
- package/src/components/table/tableControls/TableControls.stories.tsx +415 -0
- package/src/components/table/tableControls/TableSettingsDropdown.test.tsx +207 -0
- package/src/components/table/tableControls/TableSettingsDropdown.tsx +103 -39
- package/src/components/tabs/Tabs.stories.tsx +540 -60
- package/src/components/tabs/TabsItem.stories.tsx +82 -8
- package/src/components/toast/Toast.stories.tsx +539 -77
- package/src/components/toggle/Toggle.stories.tsx +371 -135
- package/src/components/tooltip/Tooltip.stories.tsx +606 -15
- package/src/components/tooltip/TooltipWrapper.stories.tsx +348 -12
- package/src/docs/Contributing.mdx +241 -0
- package/src/docs/UsingComponents.mdx +93 -0
- package/src/docs/Welcome.mdx +68 -0
- package/src/global.scss +7 -0
- package/src/utils/PopupParentContext.stories.tsx +367 -0
- package/src/utils/getDefaultPopupParent.ts +6 -0
- package/.ralph/storybook-upgrade/knowledge.md +0 -308
- package/.ralph/storybook-upgrade/prd.json +0 -777
- package/.ralph/storybook-upgrade/progress.md +0 -342
- package/src/components/table/TableWIP.mdx +0 -3
|
@@ -1,262 +1,763 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Controls, Heading as DocHeading, Markdown, Primary as DocPrimary, Stories, Subtitle, Title, } from '@storybook/addon-docs/blocks';
|
|
2
3
|
import { useRef, useState } from 'react';
|
|
3
4
|
import { Icon } from '../icon/Icon';
|
|
4
5
|
import { comboboxAsyncSearchOptions, comboboxGroupedPeopleOptions, comboboxPeopleOptions, } from '../../mocks/comboboxStoryOptions';
|
|
5
6
|
import { Combobox } from './Combobox';
|
|
7
|
+
// ─── Docs-page content ────────────────────────────────────────────────────────
|
|
8
|
+
const DESCRIPTION_INTRO = `
|
|
9
|
+
The \`Combobox\` component is a searchable, accessible select field that supports
|
|
10
|
+
single-select, multi-select, grouped options, async search, and item creation —
|
|
11
|
+
built on Radix UI Popover for reliable portal-based positioning.
|
|
12
|
+
`.trim();
|
|
13
|
+
const USAGE_GUIDANCE = `
|
|
14
|
+
### When to use
|
|
15
|
+
|
|
16
|
+
- Selecting one or more items from a searchable list (teachers, pupils, subjects, year groups).
|
|
17
|
+
- Filtering a dataset where the user needs to type to narrow down many options.
|
|
18
|
+
- Allowing users to create new values on the fly (e.g. adding a new tag or subject name).
|
|
19
|
+
- Async-loaded lists where options are fetched from an API as the user types.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
### When NOT to use
|
|
24
|
+
|
|
25
|
+
| Situation | Use instead |
|
|
26
|
+
|-----------|-------------|
|
|
27
|
+
| A short list (≤ 6 items) with no need to search | \`SelectDropdown\` |
|
|
28
|
+
| Free-text search that triggers a navigation or query action | \`SearchBar\` |
|
|
29
|
+
| A simple true/false toggle | \`Checkbox\` or \`Toggle\` |
|
|
30
|
+
| Picking a date or time | \`DatePicker\` / \`TimePicker\` |
|
|
31
|
+
`.trim();
|
|
32
|
+
const DEVELOPER_NOTES = `
|
|
33
|
+
> **Built on Radix UI Popover.** The dropdown renders into a portal — do NOT place
|
|
34
|
+
> the Combobox inside a container with \`overflow: hidden\` or \`position: relative\`
|
|
35
|
+
> that clips its stacking context. This will cause the dropdown to be cut off.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
### \`value\` is always \`string[]\`
|
|
40
|
+
|
|
41
|
+
> **Critical:** Even in single-select mode, \`value\` and \`defaultValue\` are
|
|
42
|
+
> **always arrays**. This is the most common integration bug.
|
|
43
|
+
|
|
44
|
+
\`\`\`tsx
|
|
45
|
+
// ✅ Correct — value is string[]
|
|
46
|
+
<Combobox value={['alice-johnson']} onValueChange={(vals) => setVal(vals)} />
|
|
47
|
+
|
|
48
|
+
// ❌ Wrong — value must not be a plain string
|
|
49
|
+
<Combobox value="alice-johnson" />
|
|
50
|
+
\`\`\`
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
### Controlled vs uncontrolled
|
|
55
|
+
|
|
56
|
+
Use \`value\` + \`onValueChange\` for controlled mode. Use \`defaultValue\` for
|
|
57
|
+
uncontrolled initial selection. Do not mix both.
|
|
58
|
+
|
|
59
|
+
\`\`\`tsx
|
|
60
|
+
// Controlled
|
|
61
|
+
const [selected, setSelected] = useState<string[]>([]);
|
|
62
|
+
<Combobox value={selected} onValueChange={setSelected} options={options} />
|
|
63
|
+
|
|
64
|
+
// Uncontrolled with initial value
|
|
65
|
+
<Combobox defaultValue={['alice-johnson']} options={options} />
|
|
66
|
+
\`\`\`
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
### Async search
|
|
71
|
+
|
|
72
|
+
When you pass \`onSearch\`, **all client-side filtering is disabled** — you are
|
|
73
|
+
responsible for updating the \`options\` array yourself (e.g. from an API response).
|
|
74
|
+
The component does NOT debounce; add your own debounce inside \`onSearch\`.
|
|
75
|
+
|
|
76
|
+
\`\`\`tsx
|
|
77
|
+
<Combobox
|
|
78
|
+
options={results}
|
|
79
|
+
onSearch={async (query) => {
|
|
80
|
+
const data = await fetchStaff(query);
|
|
81
|
+
setResults(data);
|
|
82
|
+
}}
|
|
83
|
+
/>
|
|
84
|
+
\`\`\`
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
### Keyboard navigation
|
|
89
|
+
|
|
90
|
+
| Key | Action |
|
|
91
|
+
|-----|--------|
|
|
92
|
+
| \`↓\` / \`↑\` | Move focus through options |
|
|
93
|
+
| \`Enter\` | Select the focused option |
|
|
94
|
+
| \`Escape\` | Close the dropdown |
|
|
95
|
+
| \`Backspace\` | Remove the last selected tag (multi-select) |
|
|
96
|
+
| \`Tab\` | Close the dropdown and advance focus |
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
### Grouped options
|
|
101
|
+
|
|
102
|
+
Options with the same \`group\` string are rendered under a shared group heading.
|
|
103
|
+
The \`group\` string is **case-sensitive** and must match exactly across all options
|
|
104
|
+
in the same group.
|
|
105
|
+
|
|
106
|
+
\`\`\`tsx
|
|
107
|
+
const options = [
|
|
108
|
+
{ value: 'alice', label: 'Alice Johnson', group: 'Teachers' },
|
|
109
|
+
{ value: 'bob', label: 'Bob Smith', group: 'Teachers' }, // same group ✅
|
|
110
|
+
{ value: 'carol', label: 'Carol White', group: 'teachers' }, // different group ❌
|
|
111
|
+
];
|
|
112
|
+
\`\`\`
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
### Accessibility
|
|
117
|
+
|
|
118
|
+
- The trigger renders a combobox role with \`aria-expanded\`, \`aria-haspopup\`, and
|
|
119
|
+
\`aria-controls\` wired to the listbox.
|
|
120
|
+
- Options use \`aria-selected\` and \`aria-disabled\` where appropriate.
|
|
121
|
+
- Pass \`aria-label\` when there is no visible \`<label>\` element nearby.
|
|
122
|
+
- Pass \`aria-describedby\` to link to a \`<FormField>\` hint or error message.
|
|
123
|
+
- Pass \`aria-invalid\` alongside \`hasError\` to signal validation failure to
|
|
124
|
+
assistive technology.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
### Sub-components (escape hatches)
|
|
129
|
+
|
|
130
|
+
The compound sub-components (\`Combobox.Trigger\`, \`Combobox.ButtonTrigger\`,
|
|
131
|
+
\`Combobox.Listbox\`) exist for advanced layout needs where the trigger and listbox
|
|
132
|
+
must be separated in the DOM. For 99% of use cases, use \`<Combobox />\` directly.
|
|
133
|
+
`.trim();
|
|
134
|
+
const RELATED_COMPONENTS = [
|
|
135
|
+
'## Related components',
|
|
136
|
+
'',
|
|
137
|
+
'[SelectDropdown](?path=/docs/components-formfield-inputs-selectdropdown--docs) · [SearchBar](?path=/docs/components-searchbar--docs) · [FormField](?path=/docs/components-formfield--docs) · [CheckboxInput](?path=/docs/components-formfield-inputs-checkbox--docs)',
|
|
138
|
+
].join('\n');
|
|
139
|
+
const PROPS_INTRO = 'The preview below is wired to the **Controls** panel — tweak any prop to see the story update in real time.';
|
|
140
|
+
// ─── Docs page ────────────────────────────────────────────────────────────────
|
|
141
|
+
function ComboboxDocsPage() {
|
|
142
|
+
return (_jsxs(_Fragment, { children: [_jsx(Title, {}), _jsx(Subtitle, {}), _jsx(Markdown, { children: DESCRIPTION_INTRO }), _jsx(DocHeading, { children: "Interactive example" }), _jsx(Markdown, { children: PROPS_INTRO }), _jsx(DocPrimary, {}), _jsx(Controls, {}), _jsx(DocHeading, { children: "Usage guidance" }), _jsx(Markdown, { children: USAGE_GUIDANCE }), _jsx(DocHeading, { children: "Developer notes" }), _jsx(Markdown, { children: DEVELOPER_NOTES }), _jsx(DocHeading, { children: "Examples" }), _jsx(Stories, { title: "" }), _jsx(Markdown, { children: RELATED_COMPONENTS })] }));
|
|
143
|
+
}
|
|
144
|
+
// ─── Meta ─────────────────────────────────────────────────────────────────────
|
|
6
145
|
const meta = {
|
|
7
146
|
title: 'Components/Combobox',
|
|
8
147
|
component: Combobox,
|
|
9
148
|
tags: ['autodocs'],
|
|
10
149
|
parameters: {
|
|
150
|
+
layout: 'padded',
|
|
11
151
|
docs: {
|
|
12
|
-
|
|
13
|
-
component: 'Default usage is `<Combobox … />` with props such as `triggerVariant` and `multiple`. `Combobox.Trigger`, `Combobox.ButtonTrigger`, and `Combobox.Listbox` are composition escape hatches.',
|
|
14
|
-
},
|
|
152
|
+
page: ComboboxDocsPage,
|
|
15
153
|
},
|
|
16
154
|
},
|
|
155
|
+
decorators: [
|
|
156
|
+
(Story) => (_jsx("div", { "data-surface": "base", "data-colour-mode": "light", style: { padding: 'var(--size-space-400)', maxWidth: 480, minHeight: 300 }, children: _jsx(Story, {}) })),
|
|
157
|
+
],
|
|
17
158
|
argTypes: {
|
|
18
|
-
|
|
159
|
+
options: {
|
|
160
|
+
control: 'object',
|
|
161
|
+
description: 'Array of `ComboboxOption` objects `{ value: string; label: string; tagLabel?: string; iconName?: IconName; disabled?: boolean; group?: string }`.',
|
|
162
|
+
},
|
|
163
|
+
multiple: {
|
|
19
164
|
control: 'boolean',
|
|
20
|
-
description: '
|
|
165
|
+
description: 'Allow multiple selections. Each selected value is shown as a tag chip.',
|
|
21
166
|
},
|
|
22
|
-
|
|
167
|
+
placeholder: {
|
|
168
|
+
control: 'text',
|
|
169
|
+
description: 'Placeholder text shown in the trigger when no value is selected.',
|
|
170
|
+
},
|
|
171
|
+
disabled: {
|
|
172
|
+
control: 'boolean',
|
|
173
|
+
description: 'Disables the entire combobox — trigger and dropdown become non-interactive.',
|
|
174
|
+
},
|
|
175
|
+
loading: {
|
|
176
|
+
control: 'boolean',
|
|
177
|
+
description: 'Shows a loading indicator inside the dropdown while options are being fetched.',
|
|
178
|
+
},
|
|
179
|
+
hasError: {
|
|
180
|
+
control: 'boolean',
|
|
181
|
+
description: 'Applies error styling to the trigger. Pair with `aria-invalid` for full accessibility.',
|
|
182
|
+
},
|
|
183
|
+
searchType: {
|
|
184
|
+
control: 'inline-radio',
|
|
185
|
+
options: ['prefix', 'substring'],
|
|
186
|
+
description: '`prefix` (default) matches from the start of the label. `substring` matches anywhere. You can also pass a custom function `(query, options) => ComboboxOption[]`.',
|
|
187
|
+
},
|
|
188
|
+
highlightStringMatches: {
|
|
23
189
|
control: 'boolean',
|
|
24
|
-
description: '
|
|
190
|
+
description: 'Highlight the matching portion of each option label while the user is typing.',
|
|
191
|
+
},
|
|
192
|
+
selectedValueDisplay: {
|
|
193
|
+
control: 'inline-radio',
|
|
194
|
+
options: ['tags', 'text'],
|
|
195
|
+
description: '`tags` (default) renders each selected value as a chip. `text` shows a comma-separated string — useful in space-constrained button triggers.',
|
|
196
|
+
},
|
|
197
|
+
showClearAll: {
|
|
198
|
+
control: 'boolean',
|
|
199
|
+
description: 'Show a "Clear all" button inside the trigger when one or more values are selected.',
|
|
200
|
+
},
|
|
201
|
+
clearAllLabel: {
|
|
202
|
+
control: 'text',
|
|
203
|
+
description: 'Label for the clear-all button. Defaults to `"Clear all"`.',
|
|
25
204
|
},
|
|
26
205
|
triggerVariant: {
|
|
27
206
|
control: 'inline-radio',
|
|
28
207
|
options: ['input', 'button'],
|
|
29
|
-
description: '
|
|
208
|
+
description: '`input` (default) renders an inline text field. `button` renders a clickable button; the search field moves into the dropdown.',
|
|
209
|
+
},
|
|
210
|
+
allowCreate: {
|
|
211
|
+
control: 'boolean',
|
|
212
|
+
description: 'Show a "Create X" row when the typed query does not match any existing option.',
|
|
213
|
+
},
|
|
214
|
+
showDropdownTrigger: {
|
|
215
|
+
control: 'boolean',
|
|
216
|
+
description: 'Show or hide the chevron button at the end of the trigger. Defaults to `true`.',
|
|
217
|
+
},
|
|
218
|
+
dropdownOnFocus: {
|
|
219
|
+
control: 'boolean',
|
|
220
|
+
description: 'Open the dropdown automatically when the trigger receives focus. Defaults to `true`.',
|
|
221
|
+
},
|
|
222
|
+
showSelectionCountBadge: {
|
|
223
|
+
control: 'boolean',
|
|
224
|
+
description: 'Show a badge with the number of selected items (useful with `triggerVariant="button"`).',
|
|
30
225
|
},
|
|
226
|
+
// Callbacks — not controllable via the controls panel
|
|
227
|
+
onValueChange: { control: false },
|
|
228
|
+
onSearch: { control: false },
|
|
229
|
+
onCreateNew: { control: false },
|
|
230
|
+
onDeleteCreated: { control: false },
|
|
231
|
+
renderOption: { control: false },
|
|
232
|
+
getTagLabel: { control: false },
|
|
233
|
+
triggerEndContent: { control: false },
|
|
31
234
|
},
|
|
32
|
-
decorators: [
|
|
33
|
-
Story => (_jsx("div", { "data-surface": "base", "data-colour-mode": "light", className: "bg-surface text-on-surface-default", style: { padding: 32, maxWidth: 420 }, children: _jsx(Story, {}) })),
|
|
34
|
-
],
|
|
35
235
|
};
|
|
36
236
|
export default meta;
|
|
37
|
-
|
|
38
|
-
|
|
237
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
238
|
+
function withDescription(description, story) {
|
|
239
|
+
return {
|
|
240
|
+
...story,
|
|
241
|
+
parameters: {
|
|
242
|
+
...story.parameters,
|
|
243
|
+
docs: {
|
|
244
|
+
...story.parameters?.docs,
|
|
245
|
+
description: { story: description },
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
// ─── Stories ──────────────────────────────────────────────────────────────────
|
|
251
|
+
// 1. Default — wired to Controls
|
|
252
|
+
export const Default = {
|
|
253
|
+
args: {
|
|
254
|
+
options: comboboxPeopleOptions,
|
|
255
|
+
placeholder: 'Select a teacher...',
|
|
256
|
+
multiple: false,
|
|
257
|
+
disabled: false,
|
|
258
|
+
loading: false,
|
|
259
|
+
hasError: false,
|
|
260
|
+
searchType: 'prefix',
|
|
261
|
+
highlightStringMatches: false,
|
|
262
|
+
selectedValueDisplay: 'tags',
|
|
263
|
+
showClearAll: false,
|
|
264
|
+
},
|
|
265
|
+
render: args => _jsx(Combobox, { ...args }),
|
|
266
|
+
};
|
|
267
|
+
// 2. ControlledSingleSelect
|
|
268
|
+
function ControlledSingleSelectTemplate() {
|
|
269
|
+
const [value, setValue] = useState([]);
|
|
270
|
+
return (_jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 'var(--size-space-300)' }, children: [_jsx(Combobox, { id: "controlled-combobox", options: comboboxPeopleOptions, value: value, onValueChange: setValue, placeholder: "Select a teacher..." }), _jsxs("p", { className: "ds-text", style: { margin: 0 }, children: ["Selected:", ' ', value.length > 0 ? value.join(', ') : '(none)'] })] }));
|
|
271
|
+
}
|
|
272
|
+
export const ControlledSingleSelect = withDescription('Controlled mode: `value` and `onValueChange` are managed by the parent component. **`value` is always `string[]`** — even for single-select. This is the most common integration mistake.', {
|
|
273
|
+
render: () => _jsx(ControlledSingleSelectTemplate, {}),
|
|
39
274
|
parameters: {
|
|
40
|
-
...story.parameters,
|
|
41
275
|
docs: {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
276
|
+
source: {
|
|
277
|
+
code: `
|
|
278
|
+
function ControlledExample() {
|
|
279
|
+
// value is ALWAYS string[] — even for single-select
|
|
280
|
+
const [value, setValue] = useState<string[]>([]);
|
|
281
|
+
|
|
282
|
+
return (
|
|
283
|
+
<FormField label="Class teacher" htmlFor="teacher-select">
|
|
284
|
+
<Combobox
|
|
285
|
+
id="teacher-select"
|
|
286
|
+
options={teacherOptions}
|
|
287
|
+
value={value}
|
|
288
|
+
onValueChange={setValue}
|
|
289
|
+
placeholder="Select a teacher..."
|
|
290
|
+
/>
|
|
291
|
+
</FormField>
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
`.trim(),
|
|
45
295
|
},
|
|
46
296
|
},
|
|
47
297
|
},
|
|
48
298
|
});
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
value: `scroll-demo-${i + 1}`,
|
|
52
|
-
label: `Option ${i + 1}`,
|
|
53
|
-
iconName: 'user',
|
|
54
|
-
}));
|
|
55
|
-
const timeOptions = ['13:00', '13:30', '14:00', '14:30', '15:00'].map(time => ({
|
|
56
|
-
value: time,
|
|
57
|
-
label: time,
|
|
58
|
-
}));
|
|
59
|
-
export const ScrollableLongList = withDescription({
|
|
60
|
-
args: {
|
|
61
|
-
options: manyScrollableOptions,
|
|
62
|
-
placeholder: 'Open the list and move with arrow keys…',
|
|
63
|
-
},
|
|
64
|
-
}, 'Exercises a scrollable listbox with enough items to validate keyboard navigation and active-row scrolling.');
|
|
65
|
-
export const ButtonTriggerSingleSelect = withDescription({
|
|
299
|
+
// 3. SingleSelect
|
|
300
|
+
export const SingleSelect = withDescription('Single-select mode (default). Type to filter the list by prefix. Press Enter or click to select.', {
|
|
66
301
|
args: {
|
|
67
302
|
options: comboboxPeopleOptions,
|
|
68
|
-
placeholder: '
|
|
69
|
-
triggerVariant: 'button',
|
|
70
|
-
},
|
|
71
|
-
}, 'Shows the button-style trigger in single-select mode before the search input moves into the popover.');
|
|
72
|
-
export const ButtonTriggerPlainTextValue = withDescription({
|
|
73
|
-
args: {
|
|
74
|
-
options: timeOptions,
|
|
75
|
-
placeholder: 'Select time',
|
|
76
|
-
triggerVariant: 'button',
|
|
77
|
-
selectedValueDisplay: 'text',
|
|
78
|
-
showDropdownTrigger: false,
|
|
79
|
-
triggerEndContent: _jsx(Icon, { name: "clock-3", size: 16 }),
|
|
80
|
-
defaultValue: ['14:30'],
|
|
303
|
+
placeholder: 'Select a teacher...',
|
|
81
304
|
},
|
|
82
|
-
}
|
|
83
|
-
|
|
305
|
+
});
|
|
306
|
+
// 4. MultiSelect
|
|
307
|
+
export const MultiSelect = withDescription('Set `multiple` to allow multiple selections — each selected value is shown as a removable tag chip. Press Backspace to remove the last tag.', {
|
|
84
308
|
args: {
|
|
85
|
-
options:
|
|
86
|
-
defaultValue: ['scroll-demo-1', 'scroll-demo-2', 'scroll-demo-3'],
|
|
87
|
-
placeholder: 'Students',
|
|
309
|
+
options: comboboxPeopleOptions,
|
|
88
310
|
multiple: true,
|
|
89
|
-
|
|
311
|
+
placeholder: 'Select teachers...',
|
|
90
312
|
},
|
|
91
|
-
|
|
92
|
-
|
|
313
|
+
parameters: {
|
|
314
|
+
docs: {
|
|
315
|
+
source: {
|
|
316
|
+
code: '<Combobox options={teacherOptions} multiple placeholder="Select teachers..." />',
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
});
|
|
321
|
+
// 5. WithDefaultValue
|
|
322
|
+
export const WithDefaultValue = withDescription('`defaultValue` sets the initial selection in uncontrolled mode. Note that `defaultValue` must be a `string[]` even for single-select.', {
|
|
93
323
|
args: {
|
|
94
324
|
options: comboboxPeopleOptions,
|
|
95
|
-
|
|
325
|
+
defaultValue: ['alice-johnson'],
|
|
326
|
+
},
|
|
327
|
+
parameters: {
|
|
328
|
+
docs: {
|
|
329
|
+
source: {
|
|
330
|
+
code: '<Combobox options={teacherOptions} defaultValue={[\'alice-johnson\']} />',
|
|
331
|
+
},
|
|
332
|
+
},
|
|
96
333
|
},
|
|
97
|
-
}
|
|
98
|
-
|
|
334
|
+
});
|
|
335
|
+
// 6. SubstringSearch
|
|
336
|
+
export const SubstringSearch = withDescription('Pass `searchType="substring"` to match anywhere in the label — not just the start. Type "son" to see it match "Alice Johnson" and "Alice Williamson".', {
|
|
99
337
|
args: {
|
|
100
338
|
options: comboboxPeopleOptions,
|
|
101
|
-
placeholder: 'Search people...',
|
|
102
339
|
searchType: 'substring',
|
|
340
|
+
placeholder: 'Type part of a name...',
|
|
341
|
+
},
|
|
342
|
+
parameters: {
|
|
343
|
+
docs: {
|
|
344
|
+
source: {
|
|
345
|
+
code: '<Combobox options={teacherOptions} searchType="substring" placeholder="Type part of a name..." />',
|
|
346
|
+
},
|
|
347
|
+
},
|
|
103
348
|
},
|
|
104
|
-
}
|
|
105
|
-
|
|
349
|
+
});
|
|
350
|
+
// 7. HighlightedMatches
|
|
351
|
+
export const HighlightedMatches = withDescription('Add `highlightStringMatches` to highlight the matching portion of each option label as the user types. Works best with `searchType="substring"`.', {
|
|
106
352
|
args: {
|
|
107
353
|
options: comboboxPeopleOptions,
|
|
108
|
-
placeholder: 'Search people...',
|
|
109
354
|
searchType: 'substring',
|
|
110
355
|
highlightStringMatches: true,
|
|
356
|
+
placeholder: 'Type to highlight matches...',
|
|
357
|
+
},
|
|
358
|
+
parameters: {
|
|
359
|
+
docs: {
|
|
360
|
+
source: {
|
|
361
|
+
code: '<Combobox options={teacherOptions} searchType="substring" highlightStringMatches placeholder="Type to highlight matches..." />',
|
|
362
|
+
},
|
|
363
|
+
},
|
|
111
364
|
},
|
|
112
|
-
}
|
|
113
|
-
|
|
365
|
+
});
|
|
366
|
+
// 8. WithGroups
|
|
367
|
+
export const WithGroups = withDescription('Options with the same `group` string are visually grouped under a shared heading. The `group` value must match exactly (case-sensitive) across all options in the same group.', {
|
|
114
368
|
args: {
|
|
115
|
-
options:
|
|
369
|
+
options: comboboxGroupedPeopleOptions,
|
|
116
370
|
multiple: true,
|
|
117
|
-
placeholder: '
|
|
118
|
-
showClearAll: true,
|
|
371
|
+
placeholder: 'Select staff...',
|
|
119
372
|
},
|
|
120
|
-
|
|
121
|
-
|
|
373
|
+
parameters: {
|
|
374
|
+
docs: {
|
|
375
|
+
source: {
|
|
376
|
+
code: `
|
|
377
|
+
const options = [
|
|
378
|
+
{ value: 'alice', label: 'Alice Johnson', group: 'Teachers' },
|
|
379
|
+
{ value: 'bob', label: 'Bob Smith', group: 'Teachers' },
|
|
380
|
+
{ value: 'carol', label: 'Carol White', group: 'Support Staff' },
|
|
381
|
+
{ value: 'rachel', label: 'Rachel Green', group: 'Admin' },
|
|
382
|
+
];
|
|
383
|
+
|
|
384
|
+
<Combobox options={options} multiple placeholder="Select staff..." />
|
|
385
|
+
`.trim(),
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
},
|
|
389
|
+
});
|
|
390
|
+
// 9. Disabled
|
|
391
|
+
export const Disabled = withDescription('The entire combobox is non-interactive when `disabled` is set. The trigger becomes visually muted and cannot be clicked or focused.', {
|
|
122
392
|
args: {
|
|
123
393
|
options: comboboxPeopleOptions,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
394
|
+
disabled: true,
|
|
395
|
+
placeholder: 'Not available',
|
|
396
|
+
},
|
|
397
|
+
parameters: {
|
|
398
|
+
docs: {
|
|
399
|
+
source: {
|
|
400
|
+
code: '<Combobox options={teacherOptions} disabled placeholder="Not available" />',
|
|
401
|
+
},
|
|
402
|
+
},
|
|
128
403
|
},
|
|
129
|
-
}
|
|
130
|
-
|
|
404
|
+
});
|
|
405
|
+
// 10. ErrorState
|
|
406
|
+
export const ErrorState = withDescription('Set `hasError` to apply error styling to the trigger. Always pair with `aria-invalid` so assistive technology can identify the invalid field. Wrap in `FormField` to display the error message.', {
|
|
131
407
|
args: {
|
|
132
|
-
options:
|
|
408
|
+
'options': comboboxPeopleOptions,
|
|
409
|
+
'hasError': true,
|
|
410
|
+
'aria-invalid': true,
|
|
411
|
+
'placeholder': 'Select a teacher...',
|
|
412
|
+
},
|
|
413
|
+
render: args => _jsx(Combobox, { ...args }),
|
|
414
|
+
parameters: {
|
|
415
|
+
docs: {
|
|
416
|
+
source: {
|
|
417
|
+
code: `
|
|
418
|
+
<Combobox
|
|
419
|
+
options={teacherOptions}
|
|
420
|
+
hasError
|
|
421
|
+
aria-invalid
|
|
422
|
+
placeholder="Select a teacher..."
|
|
423
|
+
/>
|
|
424
|
+
`.trim(),
|
|
425
|
+
},
|
|
426
|
+
},
|
|
427
|
+
},
|
|
428
|
+
});
|
|
429
|
+
// 11. LoadingState
|
|
430
|
+
export const LoadingState = withDescription('Set `loading` to show a loading indicator inside the dropdown while options are being fetched. Use this during async search operations before the results arrive.', {
|
|
431
|
+
args: {
|
|
432
|
+
options: [],
|
|
433
|
+
loading: true,
|
|
434
|
+
placeholder: 'Searching...',
|
|
435
|
+
},
|
|
436
|
+
parameters: {
|
|
437
|
+
docs: {
|
|
438
|
+
source: {
|
|
439
|
+
code: `
|
|
440
|
+
// Typically used while an async fetch is in-flight:
|
|
441
|
+
<Combobox
|
|
442
|
+
options={results}
|
|
443
|
+
loading={isFetching}
|
|
444
|
+
onSearch={handleSearch}
|
|
445
|
+
placeholder="Search staff..."
|
|
446
|
+
/>
|
|
447
|
+
`.trim(),
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
},
|
|
451
|
+
});
|
|
452
|
+
// 12. ButtonTriggerSingleSelect
|
|
453
|
+
export const ButtonTriggerSingleSelect = withDescription('`triggerVariant="button"` renders a clickable button as the trigger instead of an inline input. The search field moves inside the dropdown. Ideal for toolbar filters and compact layouts.', {
|
|
454
|
+
args: {
|
|
455
|
+
options: comboboxPeopleOptions,
|
|
456
|
+
triggerVariant: 'button',
|
|
457
|
+
placeholder: 'Filter by teacher',
|
|
458
|
+
},
|
|
459
|
+
parameters: {
|
|
460
|
+
docs: {
|
|
461
|
+
source: {
|
|
462
|
+
code: '<Combobox options={teacherOptions} triggerVariant="button" placeholder="Filter by teacher" />',
|
|
463
|
+
},
|
|
464
|
+
},
|
|
465
|
+
},
|
|
466
|
+
});
|
|
467
|
+
// 13. ButtonTriggerMultiSelect
|
|
468
|
+
export const ButtonTriggerMultiSelect = withDescription('Button trigger with `multiple` enabled. Use `showSelectionCountBadge` to show a badge with the number of selected items — useful when the trigger label should not grow in size.', {
|
|
469
|
+
args: {
|
|
470
|
+
options: comboboxPeopleOptions,
|
|
471
|
+
triggerVariant: 'button',
|
|
133
472
|
multiple: true,
|
|
134
|
-
placeholder: '
|
|
473
|
+
placeholder: 'Filter by teachers',
|
|
474
|
+
showSelectionCountBadge: true,
|
|
135
475
|
},
|
|
136
|
-
|
|
137
|
-
|
|
476
|
+
parameters: {
|
|
477
|
+
docs: {
|
|
478
|
+
source: {
|
|
479
|
+
code: '<Combobox options={teacherOptions} triggerVariant="button" multiple placeholder="Filter by teachers" showSelectionCountBadge />',
|
|
480
|
+
},
|
|
481
|
+
},
|
|
482
|
+
},
|
|
483
|
+
});
|
|
484
|
+
// 14. ButtonTriggerPlainTextValue
|
|
485
|
+
export const ButtonTriggerPlainTextValue = withDescription('`selectedValueDisplay="text"` shows the selected value(s) as a comma-separated text string instead of tag chips — useful when space is limited inside a button trigger.', {
|
|
138
486
|
args: {
|
|
139
487
|
options: comboboxPeopleOptions,
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
488
|
+
triggerVariant: 'button',
|
|
489
|
+
selectedValueDisplay: 'text',
|
|
490
|
+
multiple: true,
|
|
491
|
+
placeholder: 'Filter by teacher',
|
|
492
|
+
},
|
|
493
|
+
parameters: {
|
|
494
|
+
docs: {
|
|
495
|
+
source: {
|
|
496
|
+
code: '<Combobox options={teacherOptions} triggerVariant="button" selectedValueDisplay="text" multiple placeholder="Filter by teacher" />',
|
|
497
|
+
},
|
|
498
|
+
},
|
|
143
499
|
},
|
|
144
|
-
}
|
|
145
|
-
|
|
500
|
+
});
|
|
501
|
+
// 15. HiddenTrigger
|
|
502
|
+
export const HiddenTrigger = withDescription('Set `showDropdownTrigger={false}` to hide the chevron button at the end of the input. The dropdown can still be opened by typing or focusing the field.', {
|
|
146
503
|
args: {
|
|
147
504
|
options: comboboxPeopleOptions,
|
|
148
|
-
placeholder: 'Search people...',
|
|
149
505
|
showDropdownTrigger: false,
|
|
506
|
+
placeholder: 'No chevron shown...',
|
|
507
|
+
},
|
|
508
|
+
parameters: {
|
|
509
|
+
docs: {
|
|
510
|
+
source: {
|
|
511
|
+
code: '<Combobox options={teacherOptions} showDropdownTrigger={false} placeholder="No chevron shown..." />',
|
|
512
|
+
},
|
|
513
|
+
},
|
|
150
514
|
},
|
|
151
|
-
}
|
|
152
|
-
|
|
515
|
+
});
|
|
516
|
+
// 16. ManualOpenOnFocus
|
|
517
|
+
export const ManualOpenOnFocus = withDescription('Set `dropdownOnFocus={false}` to prevent the dropdown from opening automatically on focus — the user must start typing or click the chevron to open it.', {
|
|
153
518
|
args: {
|
|
154
519
|
options: comboboxPeopleOptions,
|
|
155
|
-
placeholder: 'Search people...',
|
|
156
520
|
dropdownOnFocus: false,
|
|
521
|
+
placeholder: 'Focus me — dropdown stays closed',
|
|
157
522
|
},
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
renderOption: (option, selected) => (_jsxs(_Fragment, { children: [_jsx("span", { "aria-hidden": "true", children: _jsx("input", { type: "checkbox", checked: selected, readOnly: true, tabIndex: -1 }) }), _jsx("span", { className: "ds-combobox__option-label", children: option.label })] })),
|
|
523
|
+
parameters: {
|
|
524
|
+
docs: {
|
|
525
|
+
source: {
|
|
526
|
+
code: '<Combobox options={teacherOptions} dropdownOnFocus={false} placeholder="Focus me — dropdown stays closed" />',
|
|
527
|
+
},
|
|
528
|
+
},
|
|
165
529
|
},
|
|
166
|
-
}, 'Uses `renderOption` to swap the row content while the Combobox still owns selection and listbox behavior.');
|
|
167
|
-
const delay = (ms) => new Promise((resolve) => {
|
|
168
|
-
setTimeout(resolve, ms);
|
|
169
530
|
});
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
return comboboxAsyncSearchOptions;
|
|
175
|
-
return comboboxAsyncSearchOptions.filter(p => p.label.toLowerCase().includes(q));
|
|
176
|
-
}
|
|
177
|
-
const AsyncSearchTemplate = ({ allowCreate = false, searchType = 'substring', highlightStringMatches = true, }) => {
|
|
178
|
-
const [options, setOptions] = useState([]);
|
|
179
|
-
const [loading, setLoading] = useState(false);
|
|
180
|
-
const requestIdRef = useRef(0);
|
|
531
|
+
// ─── Async search template ─────────────────────────────────────────────────────
|
|
532
|
+
function AsyncSearchTemplate() {
|
|
533
|
+
const [options, setOptions] = useState(comboboxPeopleOptions);
|
|
534
|
+
const timerRef = useRef(null);
|
|
181
535
|
const handleSearch = (query) => {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
setOptions(next);
|
|
188
|
-
setLoading(false);
|
|
189
|
-
});
|
|
536
|
+
if (timerRef.current)
|
|
537
|
+
clearTimeout(timerRef.current);
|
|
538
|
+
timerRef.current = setTimeout(() => {
|
|
539
|
+
setOptions(comboboxAsyncSearchOptions.filter(o => o.label.toLowerCase().startsWith(query.toLowerCase())));
|
|
540
|
+
}, 300);
|
|
190
541
|
};
|
|
191
|
-
return
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
542
|
+
return _jsx(Combobox, { options: options, onSearch: handleSearch, placeholder: "Search staff..." });
|
|
543
|
+
}
|
|
544
|
+
// 17. AsyncSearch
|
|
545
|
+
export const AsyncSearch = withDescription('Pass `onSearch` to take control of filtering. The component disables all client-side matching — you update the `options` array yourself (e.g. via an API call). This example simulates a 300 ms network delay.', {
|
|
546
|
+
render: () => _jsx(AsyncSearchTemplate, {}),
|
|
547
|
+
parameters: {
|
|
548
|
+
docs: {
|
|
549
|
+
source: {
|
|
550
|
+
code: `
|
|
551
|
+
function AsyncSearchExample() {
|
|
552
|
+
const [options, setOptions] = useState<ComboboxOption[]>([]);
|
|
553
|
+
const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
554
|
+
|
|
555
|
+
const handleSearch = (query: string) => {
|
|
556
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
557
|
+
timerRef.current = setTimeout(async () => {
|
|
558
|
+
const results = await fetchStaff(query);
|
|
559
|
+
setOptions(results);
|
|
560
|
+
}, 300);
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
return (
|
|
564
|
+
<Combobox
|
|
565
|
+
options={options}
|
|
566
|
+
onSearch={handleSearch}
|
|
567
|
+
placeholder="Search staff..."
|
|
568
|
+
/>
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
`.trim(),
|
|
572
|
+
},
|
|
573
|
+
},
|
|
198
574
|
},
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
575
|
+
});
|
|
576
|
+
// ─── Create new template ───────────────────────────────────────────────────────
|
|
577
|
+
function CreateNewTemplate() {
|
|
202
578
|
const [options, setOptions] = useState(comboboxPeopleOptions);
|
|
203
|
-
const handleCreate = (
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
iconName: 'user',
|
|
208
|
-
};
|
|
209
|
-
setOptions(prev => [...prev, newOpt]);
|
|
210
|
-
return newOpt;
|
|
579
|
+
const handleCreate = (input) => {
|
|
580
|
+
const newOption = { value: input.toLowerCase().replace(/\s+/g, '-'), label: input };
|
|
581
|
+
setOptions(prev => [...prev, newOption]);
|
|
582
|
+
return newOption;
|
|
211
583
|
};
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
};
|
|
217
|
-
export const CreateNew = withDescription({
|
|
584
|
+
return (_jsx(Combobox, { options: options, multiple: true, allowCreate: true, onCreateNew: handleCreate, placeholder: "Select or add a teacher..." }));
|
|
585
|
+
}
|
|
586
|
+
// 18. CreateNew
|
|
587
|
+
export const CreateNew = withDescription('Set `allowCreate` to show a "Create X" option when the typed query does not match any existing option. The `onCreateNew` callback receives the typed string and must return a new `ComboboxOption`.', {
|
|
218
588
|
render: () => _jsx(CreateNewTemplate, {}),
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
589
|
+
parameters: {
|
|
590
|
+
docs: {
|
|
591
|
+
source: {
|
|
592
|
+
code: `
|
|
593
|
+
function CreateNewExample() {
|
|
594
|
+
const [options, setOptions] = useState(initialOptions);
|
|
595
|
+
|
|
596
|
+
const handleCreate = (input: string) => {
|
|
597
|
+
const newOption = {
|
|
598
|
+
value: input.toLowerCase().replace(/\\s+/g, '-'),
|
|
599
|
+
label: input,
|
|
230
600
|
};
|
|
231
|
-
|
|
232
|
-
|
|
601
|
+
setOptions((prev) => [...prev, newOption]);
|
|
602
|
+
return newOption;
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
return (
|
|
606
|
+
<Combobox
|
|
607
|
+
options={options}
|
|
608
|
+
multiple
|
|
609
|
+
allowCreate
|
|
610
|
+
onCreateNew={handleCreate}
|
|
611
|
+
placeholder="Select or add a teacher..."
|
|
612
|
+
/>
|
|
613
|
+
);
|
|
614
|
+
}
|
|
615
|
+
`.trim(),
|
|
616
|
+
},
|
|
617
|
+
},
|
|
618
|
+
},
|
|
619
|
+
});
|
|
620
|
+
// ─── Single select create template ────────────────────────────────────────────
|
|
621
|
+
function SingleSelectCreateTemplate() {
|
|
622
|
+
const [options, setOptions] = useState(comboboxPeopleOptions);
|
|
623
|
+
const handleCreate = (input) => {
|
|
624
|
+
const newOption = { value: input.toLowerCase().replace(/\s+/g, '-'), label: input };
|
|
625
|
+
setOptions(prev => [...prev, newOption]);
|
|
626
|
+
return newOption;
|
|
233
627
|
};
|
|
234
|
-
return (_jsx(Combobox, { options: options,
|
|
235
|
-
}
|
|
236
|
-
|
|
628
|
+
return (_jsx(Combobox, { options: options, allowCreate: true, onCreateNew: handleCreate, placeholder: "Select or add a teacher..." }));
|
|
629
|
+
}
|
|
630
|
+
// 19. SingleSelectCreate
|
|
631
|
+
export const SingleSelectCreate = withDescription('`allowCreate` works in single-select mode too — useful for fields like "Add a subject" where the user can either pick from existing values or type a new one.', {
|
|
237
632
|
render: () => _jsx(SingleSelectCreateTemplate, {}),
|
|
238
|
-
|
|
239
|
-
|
|
633
|
+
parameters: {
|
|
634
|
+
docs: {
|
|
635
|
+
source: {
|
|
636
|
+
code: `
|
|
637
|
+
function SingleSelectCreateExample() {
|
|
638
|
+
const [options, setOptions] = useState(initialOptions);
|
|
639
|
+
|
|
640
|
+
const handleCreate = (input: string) => {
|
|
641
|
+
const newOption = {
|
|
642
|
+
value: input.toLowerCase().replace(/\\s+/g, '-'),
|
|
643
|
+
label: input,
|
|
644
|
+
};
|
|
645
|
+
setOptions((prev) => [...prev, newOption]);
|
|
646
|
+
return newOption;
|
|
647
|
+
};
|
|
648
|
+
|
|
649
|
+
return (
|
|
650
|
+
<Combobox
|
|
651
|
+
options={options}
|
|
652
|
+
allowCreate
|
|
653
|
+
onCreateNew={handleCreate}
|
|
654
|
+
placeholder="Select or add a teacher..."
|
|
655
|
+
/>
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
`.trim(),
|
|
659
|
+
},
|
|
660
|
+
},
|
|
661
|
+
},
|
|
662
|
+
});
|
|
663
|
+
// 20. CustomOptionLayout
|
|
664
|
+
export const CustomOptionLayout = withDescription('Use `renderOption` to fully customise how each option is rendered inside the dropdown — useful for adding avatars, icons, or additional metadata alongside the label.', {
|
|
240
665
|
args: {
|
|
241
|
-
options:
|
|
242
|
-
{ value: 'u1', label: 'Alice Johnson (Year 10, Class A)', tagLabel: 'Alice J.', iconName: 'user' },
|
|
243
|
-
{ value: 'u2', label: 'Bob Smith (Year 11, Class B)', tagLabel: 'Bob S.', iconName: 'user' },
|
|
244
|
-
{ value: 'u3', label: 'Charlie Brown (Year 10, Class A)', tagLabel: 'Charlie B.', iconName: 'user' },
|
|
245
|
-
],
|
|
666
|
+
options: comboboxPeopleOptions,
|
|
246
667
|
multiple: true,
|
|
247
|
-
placeholder: '
|
|
248
|
-
|
|
668
|
+
placeholder: 'Select teachers...',
|
|
669
|
+
renderOption: (option) => (_jsxs("span", { style: { display: 'flex', alignItems: 'center', gap: 'var(--size-space-200)' }, children: [_jsx(Icon, { name: "user", size: 16 }), _jsx("span", { children: option.label })] })),
|
|
670
|
+
},
|
|
671
|
+
parameters: {
|
|
672
|
+
docs: {
|
|
673
|
+
source: {
|
|
674
|
+
code: `
|
|
675
|
+
<Combobox
|
|
676
|
+
options={teacherOptions}
|
|
677
|
+
multiple
|
|
678
|
+
placeholder="Select teachers..."
|
|
679
|
+
renderOption={(option) => (
|
|
680
|
+
<span style={{ display: 'flex', alignItems: 'center', gap: 'var(--size-space-200)' }}>
|
|
681
|
+
<Icon name="user" size={16} />
|
|
682
|
+
<span>{option.label}</span>
|
|
683
|
+
</span>
|
|
684
|
+
)}
|
|
685
|
+
/>
|
|
686
|
+
`.trim(),
|
|
687
|
+
},
|
|
688
|
+
},
|
|
249
689
|
},
|
|
250
|
-
}
|
|
251
|
-
|
|
690
|
+
});
|
|
691
|
+
// 21. CustomTagLabel
|
|
692
|
+
export const CustomTagLabel = withDescription('Use `getTagLabel` to customise the label shown inside a selected tag chip — useful when the full option label is too long to display comfortably in the trigger.', {
|
|
693
|
+
args: {
|
|
694
|
+
options: comboboxPeopleOptions,
|
|
695
|
+
multiple: true,
|
|
696
|
+
placeholder: 'Select teachers...',
|
|
697
|
+
getTagLabel: (option) => option.label.split(' ')[0] ?? option.label,
|
|
698
|
+
},
|
|
699
|
+
parameters: {
|
|
700
|
+
docs: {
|
|
701
|
+
source: {
|
|
702
|
+
code: `
|
|
703
|
+
<Combobox
|
|
704
|
+
options={teacherOptions}
|
|
705
|
+
multiple
|
|
706
|
+
placeholder="Select teachers..."
|
|
707
|
+
getTagLabel={(option) => option.label.split(' ')[0]}
|
|
708
|
+
/>
|
|
709
|
+
`.trim(),
|
|
710
|
+
},
|
|
711
|
+
},
|
|
712
|
+
},
|
|
713
|
+
});
|
|
714
|
+
// 22. WithDisabledOptions
|
|
715
|
+
export const WithDisabledOptions = withDescription('Individual options can be disabled by setting `disabled: true` on the option object. Disabled options are visible but cannot be selected.', {
|
|
252
716
|
args: {
|
|
253
|
-
options:
|
|
254
|
-
{ value: 'alice', label: 'Alice Johnson', iconName: 'user' },
|
|
255
|
-
{ value: 'bob', label: 'Bob Smith', iconName: 'user', disabled: true },
|
|
256
|
-
{ value: 'charlie', label: 'Charlie Brown', iconName: 'user' },
|
|
257
|
-
],
|
|
717
|
+
options: comboboxPeopleOptions.map((o, i) => ({ ...o, disabled: i % 3 === 1 })),
|
|
258
718
|
multiple: true,
|
|
259
|
-
placeholder: '
|
|
719
|
+
placeholder: 'Select teachers...',
|
|
260
720
|
},
|
|
261
|
-
|
|
721
|
+
parameters: {
|
|
722
|
+
docs: {
|
|
723
|
+
source: {
|
|
724
|
+
code: `
|
|
725
|
+
const options = [
|
|
726
|
+
{ value: 'alice', label: 'Alice Johnson' },
|
|
727
|
+
{ value: 'bob', label: 'Bob Smith', disabled: true },
|
|
728
|
+
{ value: 'carol', label: 'Carol White' },
|
|
729
|
+
{ value: 'dan', label: 'Dan Brown', disabled: true },
|
|
730
|
+
];
|
|
731
|
+
|
|
732
|
+
<Combobox options={options} multiple placeholder="Select teachers..." />
|
|
733
|
+
`.trim(),
|
|
734
|
+
},
|
|
735
|
+
},
|
|
736
|
+
},
|
|
737
|
+
});
|
|
738
|
+
// 23. ScrollableLongList
|
|
739
|
+
export const ScrollableLongList = withDescription('The dropdown scrolls automatically when there are many options. Here we render 50 generated options to demonstrate the scrollable list and confirm search still works at scale.', {
|
|
740
|
+
args: {
|
|
741
|
+
options: Array.from({ length: 50 }, (_, i) => ({
|
|
742
|
+
value: `option-${i}`,
|
|
743
|
+
label: `Option ${i + 1}`,
|
|
744
|
+
})),
|
|
745
|
+
multiple: true,
|
|
746
|
+
placeholder: 'Search 50 options...',
|
|
747
|
+
},
|
|
748
|
+
parameters: {
|
|
749
|
+
docs: {
|
|
750
|
+
source: {
|
|
751
|
+
code: `
|
|
752
|
+
const options = Array.from({ length: 50 }, (_, i) => ({
|
|
753
|
+
value: \`option-\${i}\`,
|
|
754
|
+
label: \`Option \${i + 1}\`,
|
|
755
|
+
}));
|
|
756
|
+
|
|
757
|
+
<Combobox options={options} multiple placeholder="Search 50 options..." />
|
|
758
|
+
`.trim(),
|
|
759
|
+
},
|
|
760
|
+
},
|
|
761
|
+
},
|
|
762
|
+
});
|
|
262
763
|
//# sourceMappingURL=Combobox.stories.js.map
|