@arbor-education/design-system.components 0.6.0 → 0.7.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/CHANGELOG.md +25 -0
- package/dist/components/avatar/Avatar.d.ts +1 -1
- package/dist/components/avatar/Avatar.d.ts.map +1 -1
- package/dist/components/avatar/Avatar.js +1 -1
- package/dist/components/avatar/Avatar.js.map +1 -1
- package/dist/components/avatar/Avatar.stories.d.ts.map +1 -1
- package/dist/components/avatar/Avatar.stories.js +7 -0
- package/dist/components/avatar/Avatar.stories.js.map +1 -1
- package/dist/components/badge/Badge.d.ts +12 -0
- package/dist/components/badge/Badge.d.ts.map +1 -0
- package/dist/components/badge/Badge.js +6 -0
- package/dist/components/badge/Badge.js.map +1 -0
- package/dist/components/badge/Badge.stories.d.ts +10 -0
- package/dist/components/badge/Badge.stories.d.ts.map +1 -0
- package/dist/components/badge/Badge.stories.js +51 -0
- package/dist/components/badge/Badge.stories.js.map +1 -0
- package/dist/components/badge/Badge.test.d.ts +2 -0
- package/dist/components/badge/Badge.test.d.ts.map +1 -0
- package/dist/components/badge/Badge.test.js +23 -0
- package/dist/components/badge/Badge.test.js.map +1 -0
- package/dist/components/card/Card.js +1 -1
- package/dist/components/card/Card.js.map +1 -1
- package/dist/components/combobox/Combobox.d.ts +16 -0
- package/dist/components/combobox/Combobox.d.ts.map +1 -0
- package/dist/components/combobox/Combobox.js +195 -0
- package/dist/components/combobox/Combobox.js.map +1 -0
- package/dist/components/combobox/Combobox.stories.d.ts +24 -0
- package/dist/components/combobox/Combobox.stories.d.ts.map +1 -0
- package/dist/components/combobox/Combobox.stories.js +246 -0
- package/dist/components/combobox/Combobox.stories.js.map +1 -0
- package/dist/components/combobox/Combobox.test.d.ts +2 -0
- package/dist/components/combobox/Combobox.test.d.ts.map +1 -0
- package/dist/components/combobox/Combobox.test.js +798 -0
- package/dist/components/combobox/Combobox.test.js.map +1 -0
- package/dist/components/combobox/ComboboxButtonTrigger.d.ts +28 -0
- package/dist/components/combobox/ComboboxButtonTrigger.d.ts.map +1 -0
- package/dist/components/combobox/ComboboxButtonTrigger.js +64 -0
- package/dist/components/combobox/ComboboxButtonTrigger.js.map +1 -0
- package/dist/components/combobox/ComboboxListbox.d.ts +44 -0
- package/dist/components/combobox/ComboboxListbox.d.ts.map +1 -0
- package/dist/components/combobox/ComboboxListbox.js +37 -0
- package/dist/components/combobox/ComboboxListbox.js.map +1 -0
- package/dist/components/combobox/ComboboxOptionRow.d.ts +23 -0
- package/dist/components/combobox/ComboboxOptionRow.d.ts.map +1 -0
- package/dist/components/combobox/ComboboxOptionRow.js +27 -0
- package/dist/components/combobox/ComboboxOptionRow.js.map +1 -0
- package/dist/components/combobox/ComboboxTrigger.d.ts +35 -0
- package/dist/components/combobox/ComboboxTrigger.d.ts.map +1 -0
- package/dist/components/combobox/ComboboxTrigger.js +15 -0
- package/dist/components/combobox/ComboboxTrigger.js.map +1 -0
- package/dist/components/combobox/buildListboxDisplayOptions.d.ts +3 -0
- package/dist/components/combobox/buildListboxDisplayOptions.d.ts.map +1 -0
- package/dist/components/combobox/buildListboxDisplayOptions.js +13 -0
- package/dist/components/combobox/buildListboxDisplayOptions.js.map +1 -0
- package/dist/components/combobox/buildListboxDisplayOptions.test.d.ts +2 -0
- package/dist/components/combobox/buildListboxDisplayOptions.test.d.ts.map +1 -0
- package/dist/components/combobox/buildListboxDisplayOptions.test.js +22 -0
- package/dist/components/combobox/buildListboxDisplayOptions.test.js.map +1 -0
- package/dist/components/combobox/comboboxKeyboardTypes.d.ts +41 -0
- package/dist/components/combobox/comboboxKeyboardTypes.d.ts.map +1 -0
- package/dist/components/combobox/comboboxKeyboardTypes.js +2 -0
- package/dist/components/combobox/comboboxKeyboardTypes.js.map +1 -0
- package/dist/components/combobox/highlightLabel.d.ts +10 -0
- package/dist/components/combobox/highlightLabel.d.ts.map +1 -0
- package/dist/components/combobox/highlightLabel.js +18 -0
- package/dist/components/combobox/highlightLabel.js.map +1 -0
- package/dist/components/combobox/normaliseComboboxQuery.d.ts +2 -0
- package/dist/components/combobox/normaliseComboboxQuery.d.ts.map +1 -0
- package/dist/components/combobox/normaliseComboboxQuery.js +2 -0
- package/dist/components/combobox/normaliseComboboxQuery.js.map +1 -0
- package/dist/components/combobox/types.d.ts +46 -0
- package/dist/components/combobox/types.d.ts.map +1 -0
- package/dist/components/combobox/types.js +2 -0
- package/dist/components/combobox/types.js.map +1 -0
- package/dist/components/combobox/useChipSelection.d.ts +11 -0
- package/dist/components/combobox/useChipSelection.d.ts.map +1 -0
- package/dist/components/combobox/useChipSelection.js +35 -0
- package/dist/components/combobox/useChipSelection.js.map +1 -0
- package/dist/components/combobox/useComboboxChipKeyboard.d.ts +3 -0
- package/dist/components/combobox/useComboboxChipKeyboard.d.ts.map +1 -0
- package/dist/components/combobox/useComboboxChipKeyboard.js +103 -0
- package/dist/components/combobox/useComboboxChipKeyboard.js.map +1 -0
- package/dist/components/combobox/useComboboxChipKeyboard.test.d.ts +2 -0
- package/dist/components/combobox/useComboboxChipKeyboard.test.d.ts.map +1 -0
- package/dist/components/combobox/useComboboxChipKeyboard.test.js +116 -0
- package/dist/components/combobox/useComboboxChipKeyboard.test.js.map +1 -0
- package/dist/components/combobox/useComboboxKeyboard.d.ts +4 -0
- package/dist/components/combobox/useComboboxKeyboard.d.ts.map +1 -0
- package/dist/components/combobox/useComboboxKeyboard.js +68 -0
- package/dist/components/combobox/useComboboxKeyboard.js.map +1 -0
- package/dist/components/combobox/useComboboxListboxDom.d.ts +11 -0
- package/dist/components/combobox/useComboboxListboxDom.d.ts.map +1 -0
- package/dist/components/combobox/useComboboxListboxDom.js +15 -0
- package/dist/components/combobox/useComboboxListboxDom.js.map +1 -0
- package/dist/components/combobox/useComboboxListboxKeyboard.d.ts +3 -0
- package/dist/components/combobox/useComboboxListboxKeyboard.d.ts.map +1 -0
- package/dist/components/combobox/useComboboxListboxKeyboard.js +143 -0
- package/dist/components/combobox/useComboboxListboxKeyboard.js.map +1 -0
- package/dist/components/combobox/useComboboxListboxKeyboard.test.d.ts +2 -0
- package/dist/components/combobox/useComboboxListboxKeyboard.test.d.ts.map +1 -0
- package/dist/components/combobox/useComboboxListboxKeyboard.test.js +152 -0
- package/dist/components/combobox/useComboboxListboxKeyboard.test.js.map +1 -0
- package/dist/components/combobox/useComboboxPopoverBehavior.d.ts +38 -0
- package/dist/components/combobox/useComboboxPopoverBehavior.d.ts.map +1 -0
- package/dist/components/combobox/useComboboxPopoverBehavior.js +104 -0
- package/dist/components/combobox/useComboboxPopoverBehavior.js.map +1 -0
- package/dist/components/combobox/useComboboxState.d.ts +27 -0
- package/dist/components/combobox/useComboboxState.d.ts.map +1 -0
- package/dist/components/combobox/useComboboxState.js +122 -0
- package/dist/components/combobox/useComboboxState.js.map +1 -0
- package/dist/components/combobox/useElementWidth.d.ts +2 -0
- package/dist/components/combobox/useElementWidth.d.ts.map +1 -0
- package/dist/components/combobox/useElementWidth.js +31 -0
- package/dist/components/combobox/useElementWidth.js.map +1 -0
- package/dist/components/combobox/useVisibleChips.d.ts +21 -0
- package/dist/components/combobox/useVisibleChips.d.ts.map +1 -0
- package/dist/components/combobox/useVisibleChips.js +59 -0
- package/dist/components/combobox/useVisibleChips.js.map +1 -0
- package/dist/components/combobox/useVisibleChips.test.d.ts +2 -0
- package/dist/components/combobox/useVisibleChips.test.d.ts.map +1 -0
- package/dist/components/combobox/useVisibleChips.test.js +81 -0
- package/dist/components/combobox/useVisibleChips.test.js.map +1 -0
- package/dist/components/dot/Dot.d.ts +8 -0
- package/dist/components/dot/Dot.d.ts.map +1 -0
- package/dist/components/dot/Dot.js +6 -0
- package/dist/components/dot/Dot.js.map +1 -0
- package/dist/components/dot/Dot.stories.d.ts +15 -0
- package/dist/components/dot/Dot.stories.d.ts.map +1 -0
- package/dist/components/dot/Dot.stories.js +25 -0
- package/dist/components/dot/Dot.stories.js.map +1 -0
- package/dist/components/dot/Dot.test.d.ts +2 -0
- package/dist/components/dot/Dot.test.d.ts.map +1 -0
- package/dist/components/dot/Dot.test.js +19 -0
- package/dist/components/dot/Dot.test.js.map +1 -0
- package/dist/components/formField/FormField.d.ts +8 -4
- package/dist/components/formField/FormField.d.ts.map +1 -1
- package/dist/components/formField/FormField.js +7 -6
- package/dist/components/formField/FormField.js.map +1 -1
- package/dist/components/formField/FormField.stories.d.ts +1 -0
- package/dist/components/formField/FormField.stories.d.ts.map +1 -1
- package/dist/components/formField/FormField.stories.js +13 -1
- package/dist/components/formField/FormField.stories.js.map +1 -1
- package/dist/components/formField/FormField.test.js +10 -0
- package/dist/components/formField/FormField.test.js.map +1 -1
- package/dist/components/icon/allowedIcons.d.ts +1 -0
- package/dist/components/icon/allowedIcons.d.ts.map +1 -1
- package/dist/components/icon/allowedIcons.js +2 -1
- package/dist/components/icon/allowedIcons.js.map +1 -1
- package/dist/components/progress/Progress.stories.d.ts +49 -49
- package/dist/components/singleUser/SingleUser.d.ts +15 -0
- package/dist/components/singleUser/SingleUser.d.ts.map +1 -0
- package/dist/components/singleUser/SingleUser.js +9 -0
- package/dist/components/singleUser/SingleUser.js.map +1 -0
- package/dist/components/singleUser/SingleUser.stories.d.ts +11 -0
- package/dist/components/singleUser/SingleUser.stories.d.ts.map +1 -0
- package/dist/components/singleUser/SingleUser.stories.js +52 -0
- package/dist/components/singleUser/SingleUser.stories.js.map +1 -0
- package/dist/components/singleUser/SingleUser.test.d.ts +2 -0
- package/dist/components/singleUser/SingleUser.test.d.ts.map +1 -0
- package/dist/components/singleUser/SingleUser.test.js +30 -0
- package/dist/components/singleUser/SingleUser.test.js.map +1 -0
- package/dist/components/tabs/TabsItem.stories.d.ts +2 -2
- package/dist/components/tag/Tag.d.ts +9 -6
- package/dist/components/tag/Tag.d.ts.map +1 -1
- package/dist/components/tag/Tag.js +8 -2
- package/dist/components/tag/Tag.js.map +1 -1
- package/dist/components/tag/Tag.stories.d.ts +11 -6
- package/dist/components/tag/Tag.stories.d.ts.map +1 -1
- package/dist/components/tag/Tag.stories.js +68 -4
- package/dist/components/tag/Tag.stories.js.map +1 -1
- package/dist/components/tag/Tag.test.js +86 -50
- package/dist/components/tag/Tag.test.js.map +1 -1
- package/dist/components/toggle/Toggle.d.ts +3 -0
- package/dist/components/toggle/Toggle.d.ts.map +1 -0
- package/dist/components/toggle/Toggle.js +8 -0
- package/dist/components/toggle/Toggle.js.map +1 -0
- package/dist/components/toggle/Toggle.stories.d.ts +97 -0
- package/dist/components/toggle/Toggle.stories.d.ts.map +1 -0
- package/dist/components/toggle/Toggle.stories.js +186 -0
- package/dist/components/toggle/Toggle.stories.js.map +1 -0
- package/dist/components/toggle/Toggle.test.d.ts +2 -0
- package/dist/components/toggle/Toggle.test.d.ts.map +1 -0
- package/dist/components/toggle/Toggle.test.js +58 -0
- package/dist/components/toggle/Toggle.test.js.map +1 -0
- package/dist/index.css +656 -25
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +34 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -25
- package/dist/index.js.map +1 -1
- package/dist/mocks/comboboxStoryOptions.d.ts +5 -0
- package/dist/mocks/comboboxStoryOptions.d.ts.map +1 -0
- package/dist/mocks/comboboxStoryOptions.js +22 -0
- package/dist/mocks/comboboxStoryOptions.js.map +1 -0
- package/dist/utils/isSelectAllChord.d.ts +5 -0
- package/dist/utils/isSelectAllChord.d.ts.map +1 -0
- package/dist/utils/isSelectAllChord.js +7 -0
- package/dist/utils/isSelectAllChord.js.map +1 -0
- package/dist/utils/isSelectAllChord.test.d.ts +2 -0
- package/dist/utils/isSelectAllChord.test.d.ts.map +1 -0
- package/dist/utils/isSelectAllChord.test.js +19 -0
- package/dist/utils/isSelectAllChord.test.js.map +1 -0
- package/dist/utils/nextCircularIndex.d.ts +3 -0
- package/dist/utils/nextCircularIndex.d.ts.map +1 -0
- package/dist/utils/nextCircularIndex.js +10 -0
- package/dist/utils/nextCircularIndex.js.map +1 -0
- package/dist/utils/nextCircularIndex.test.d.ts +2 -0
- package/dist/utils/nextCircularIndex.test.d.ts.map +1 -0
- package/dist/utils/nextCircularIndex.test.js +23 -0
- package/dist/utils/nextCircularIndex.test.js.map +1 -0
- package/dist/utils/scrollElementIntoViewById.d.ts +2 -0
- package/dist/utils/scrollElementIntoViewById.d.ts.map +1 -0
- package/dist/utils/scrollElementIntoViewById.js +16 -0
- package/dist/utils/scrollElementIntoViewById.js.map +1 -0
- package/dist/utils/scrollElementIntoViewById.test.d.ts +2 -0
- package/dist/utils/scrollElementIntoViewById.test.d.ts.map +1 -0
- package/dist/utils/scrollElementIntoViewById.test.js +31 -0
- package/dist/utils/scrollElementIntoViewById.test.js.map +1 -0
- package/package.json +1 -1
- package/src/components/avatar/Avatar.stories.tsx +8 -0
- package/src/components/avatar/Avatar.tsx +3 -3
- package/src/components/badge/Badge.stories.tsx +74 -0
- package/src/components/badge/Badge.test.tsx +28 -0
- package/src/components/badge/Badge.tsx +35 -0
- package/src/components/badge/badge.scss +86 -0
- package/src/components/card/Card.tsx +1 -1
- package/src/components/combobox/Combobox.stories.tsx +340 -0
- package/src/components/combobox/Combobox.test.tsx +1160 -0
- package/src/components/combobox/Combobox.tsx +434 -0
- package/src/components/combobox/ComboboxButtonTrigger.tsx +195 -0
- package/src/components/combobox/ComboboxListbox.tsx +224 -0
- package/src/components/combobox/ComboboxOptionRow.tsx +128 -0
- package/src/components/combobox/ComboboxTrigger.tsx +134 -0
- package/src/components/combobox/buildListboxDisplayOptions.test.ts +24 -0
- package/src/components/combobox/buildListboxDisplayOptions.ts +12 -0
- package/src/components/combobox/combobox.scss +390 -0
- package/src/components/combobox/comboboxKeyboardTypes.ts +45 -0
- package/src/components/combobox/highlightLabel.tsx +42 -0
- package/src/components/combobox/normaliseComboboxQuery.ts +1 -0
- package/src/components/combobox/types.ts +53 -0
- package/src/components/combobox/useChipSelection.ts +53 -0
- package/src/components/combobox/useComboboxChipKeyboard.test.tsx +141 -0
- package/src/components/combobox/useComboboxChipKeyboard.ts +121 -0
- package/src/components/combobox/useComboboxKeyboard.ts +108 -0
- package/src/components/combobox/useComboboxListboxDom.ts +36 -0
- package/src/components/combobox/useComboboxListboxKeyboard.test.tsx +186 -0
- package/src/components/combobox/useComboboxListboxKeyboard.ts +172 -0
- package/src/components/combobox/useComboboxPopoverBehavior.ts +179 -0
- package/src/components/combobox/useComboboxState.ts +232 -0
- package/src/components/combobox/useElementWidth.ts +40 -0
- package/src/components/combobox/useVisibleChips.test.tsx +91 -0
- package/src/components/combobox/useVisibleChips.ts +100 -0
- package/src/components/dot/Dot.stories.tsx +41 -0
- package/src/components/dot/Dot.test.tsx +21 -0
- package/src/components/dot/Dot.tsx +18 -0
- package/src/components/dot/dot.scss +35 -0
- package/src/components/formField/FormField.stories.tsx +30 -1
- package/src/components/formField/FormField.test.tsx +20 -0
- package/src/components/formField/FormField.tsx +11 -5
- package/src/components/formField/inputs/number/numberInput.scss +12 -4
- package/src/components/icon/allowedIcons.tsx +2 -0
- package/src/components/pill/pill.scss +4 -6
- package/src/components/singleUser/SingleUser.stories.tsx +63 -0
- package/src/components/singleUser/SingleUser.test.tsx +61 -0
- package/src/components/singleUser/SingleUser.tsx +45 -0
- package/src/components/singleUser/singleUser.scss +14 -0
- package/src/components/tag/Tag.stories.tsx +88 -6
- package/src/components/tag/Tag.test.tsx +110 -44
- package/src/components/tag/Tag.tsx +38 -14
- package/src/components/tag/tag.scss +45 -30
- package/src/components/toggle/Toggle.stories.tsx +239 -0
- package/src/components/toggle/Toggle.test.tsx +66 -0
- package/src/components/toggle/Toggle.tsx +12 -0
- package/src/components/toggle/toggle.scss +126 -0
- package/src/index.scss +5 -0
- package/src/index.ts +47 -31
- package/src/mocks/comboboxStoryOptions.ts +25 -0
- package/src/tokens.scss +33 -4
- package/src/utils/isSelectAllChord.test.ts +24 -0
- package/src/utils/isSelectAllChord.ts +8 -0
- package/src/utils/nextCircularIndex.test.ts +26 -0
- package/src/utils/nextCircularIndex.ts +15 -0
- package/src/utils/scrollElementIntoViewById.test.ts +38 -0
- package/src/utils/scrollElementIntoViewById.ts +20 -0
- package/tokens/json/Arbor.json +3828 -3704
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { Badge, type BadgeColour } from './Badge';
|
|
3
|
+
|
|
4
|
+
const colours: BadgeColour[] = [
|
|
5
|
+
'purple',
|
|
6
|
+
'salmon',
|
|
7
|
+
'teal',
|
|
8
|
+
'yellow',
|
|
9
|
+
'green',
|
|
10
|
+
'orange',
|
|
11
|
+
'blue',
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
const meta: Meta<typeof Badge> = {
|
|
15
|
+
tags: ['autodocs'],
|
|
16
|
+
title: 'Components/Badge',
|
|
17
|
+
component: Badge,
|
|
18
|
+
argTypes: {
|
|
19
|
+
size: { control: 'select', options: ['sm', 'md', 'lg'] },
|
|
20
|
+
colour: { control: 'select', options: [undefined, ...colours] },
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default meta;
|
|
25
|
+
|
|
26
|
+
type Story = StoryObj<typeof Badge>;
|
|
27
|
+
|
|
28
|
+
const withDescription = (story: Story, description: string): Story => ({
|
|
29
|
+
...story,
|
|
30
|
+
parameters: {
|
|
31
|
+
...story.parameters,
|
|
32
|
+
docs: {
|
|
33
|
+
...story.parameters?.docs,
|
|
34
|
+
description: {
|
|
35
|
+
story: description,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export const Count: Story = withDescription({
|
|
42
|
+
args: {
|
|
43
|
+
children: '3',
|
|
44
|
+
},
|
|
45
|
+
}, 'Shows the default numeric Badge used for counts and status totals.');
|
|
46
|
+
|
|
47
|
+
export const WithA11yLabel: Story = withDescription({
|
|
48
|
+
args: {
|
|
49
|
+
children: '3',
|
|
50
|
+
a11yLabel: '3 selected items',
|
|
51
|
+
},
|
|
52
|
+
}, 'Adds an accessible label when the visual content alone is not descriptive enough.');
|
|
53
|
+
|
|
54
|
+
export const Sizes: Story = withDescription({
|
|
55
|
+
render: () => (
|
|
56
|
+
<div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
|
|
57
|
+
<Badge size="sm">1</Badge>
|
|
58
|
+
<Badge size="md">2</Badge>
|
|
59
|
+
<Badge size="lg">3</Badge>
|
|
60
|
+
</div>
|
|
61
|
+
),
|
|
62
|
+
}, 'Compares the small, medium, and large Badge size variants.');
|
|
63
|
+
|
|
64
|
+
export const Colours: Story = withDescription({
|
|
65
|
+
render: () => (
|
|
66
|
+
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem' }}>
|
|
67
|
+
{colours.map(c => (
|
|
68
|
+
<Badge key={c} colour={c} size="md">
|
|
69
|
+
{c.slice(0, 1).toUpperCase()}
|
|
70
|
+
</Badge>
|
|
71
|
+
))}
|
|
72
|
+
</div>
|
|
73
|
+
),
|
|
74
|
+
}, 'Displays each available Badge colour variant side by side.');
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import '@testing-library/jest-dom/vitest';
|
|
3
|
+
import { describe, expect, test } from 'vitest';
|
|
4
|
+
import { Badge } from './Badge';
|
|
5
|
+
|
|
6
|
+
describe('Badge', () => {
|
|
7
|
+
test('renders children text when no a11yLabel is provided', () => {
|
|
8
|
+
render(<Badge>3</Badge>);
|
|
9
|
+
expect(screen.getByText('3')).toBeInTheDocument();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test('uses aria-label and hides visible children from assistive tech when a11yLabel is provided', () => {
|
|
13
|
+
render(<Badge a11yLabel="3 selected items">3</Badge>);
|
|
14
|
+
const badge = screen.getByLabelText('3 selected items');
|
|
15
|
+
expect(badge).toBeInTheDocument();
|
|
16
|
+
expect(screen.getByText('3')).toHaveAttribute('aria-hidden', 'true');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('applies size and colour modifier classes', () => {
|
|
20
|
+
const { container } = render(
|
|
21
|
+
<Badge size="sm" colour="salmon">
|
|
22
|
+
2
|
|
23
|
+
</Badge>,
|
|
24
|
+
);
|
|
25
|
+
const el = container.firstChild as HTMLElement;
|
|
26
|
+
expect(el).toHaveClass('ds-badge--size-sm', 'ds-badge--salmon');
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import type { DotColour } from 'Components/dot/Dot';
|
|
3
|
+
|
|
4
|
+
export type BadgeSize = 'sm' | 'md' | 'lg';
|
|
5
|
+
export type BadgeColour = DotColour;
|
|
6
|
+
|
|
7
|
+
export type BadgeProps = {
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
a11yLabel?: string;
|
|
10
|
+
className?: string;
|
|
11
|
+
size?: BadgeSize;
|
|
12
|
+
colour?: BadgeColour;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const Badge = ({
|
|
16
|
+
children,
|
|
17
|
+
a11yLabel,
|
|
18
|
+
className,
|
|
19
|
+
size = 'md',
|
|
20
|
+
colour,
|
|
21
|
+
}: BadgeProps): React.JSX.Element => {
|
|
22
|
+
return (
|
|
23
|
+
<span
|
|
24
|
+
className={classNames(
|
|
25
|
+
'ds-badge',
|
|
26
|
+
`ds-badge--size-${size}`,
|
|
27
|
+
colour && `ds-badge--${colour}`,
|
|
28
|
+
className,
|
|
29
|
+
)}
|
|
30
|
+
aria-label={a11yLabel}
|
|
31
|
+
>
|
|
32
|
+
{a11yLabel ? <span aria-hidden="true">{children}</span> : children}
|
|
33
|
+
</span>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
.ds-badge {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
justify-content: center;
|
|
5
|
+
flex-shrink: 0;
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
|
|
8
|
+
--ds-badge-background: var(--color-grey-800);
|
|
9
|
+
--ds-badge-color: var(--color-mono-white);
|
|
10
|
+
--ds-badge-min-width: var(--badge-medium-size);
|
|
11
|
+
--ds-badge-height: var(--badge-medium-size);
|
|
12
|
+
--ds-badge-padding-inline: var(--badge-medium-spacing-horizontal);
|
|
13
|
+
--ds-badge-font-size: var(--badge-medium-font-size);
|
|
14
|
+
--ds-badge-font-weight: var(--badge-font-weight);
|
|
15
|
+
--ds-badge-line-height: 1;
|
|
16
|
+
--ds-badge-border-radius: var(--badge-medium-radius);
|
|
17
|
+
|
|
18
|
+
min-width: var(--ds-badge-min-width);
|
|
19
|
+
height: var(--ds-badge-height);
|
|
20
|
+
padding: 0 var(--ds-badge-padding-inline);
|
|
21
|
+
border-radius: var(--ds-badge-border-radius);
|
|
22
|
+
background: var(--ds-badge-background);
|
|
23
|
+
color: var(--ds-badge-color);
|
|
24
|
+
font-size: var(--ds-badge-font-size);
|
|
25
|
+
font-weight: var(--ds-badge-font-weight);
|
|
26
|
+
line-height: var(--ds-badge-line-height);
|
|
27
|
+
|
|
28
|
+
&--size-sm {
|
|
29
|
+
--ds-badge-min-width: var(--badge-small-size);
|
|
30
|
+
--ds-badge-height: var(--badge-small-size);
|
|
31
|
+
--ds-badge-padding-inline: var(--badge-small-spacing-horizontal);
|
|
32
|
+
--ds-badge-font-size: var(--badge-small-font-size);
|
|
33
|
+
--ds-badge-border-radius: var(--badge-small-radius);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&--size-md {
|
|
37
|
+
--ds-badge-min-width: var(--badge-medium-size);
|
|
38
|
+
--ds-badge-height: var(--badge-medium-size);
|
|
39
|
+
--ds-badge-padding-inline: var(--badge-medium-spacing-horizontal);
|
|
40
|
+
--ds-badge-font-size: var(--badge-medium-font-size);
|
|
41
|
+
--ds-badge-border-radius: var(--badge-medium-radius);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
&--size-lg {
|
|
45
|
+
--ds-badge-min-width: var(--badge-large-size);
|
|
46
|
+
--ds-badge-height: var(--badge-large-size);
|
|
47
|
+
--ds-badge-padding-inline: var(--badge-large-spacing-horizontal);
|
|
48
|
+
--ds-badge-font-size: var(--badge-large-font-size);
|
|
49
|
+
--ds-badge-border-radius: var(--badge-large-radius);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&--purple {
|
|
53
|
+
--ds-badge-background: var(--color-extended-colours-purple-500);
|
|
54
|
+
--ds-badge-color: var(--color-extended-colours-purple-800);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&--salmon {
|
|
58
|
+
--ds-badge-background: var(--color-extended-colours-salmon-500);
|
|
59
|
+
--ds-badge-color: var(--color-mono-white);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&--teal {
|
|
63
|
+
--ds-badge-background: var(--color-extended-colours-teal-500);
|
|
64
|
+
--ds-badge-color: var(--color-extended-colours-teal-800);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&--yellow {
|
|
68
|
+
--ds-badge-background: var(--color-extended-colours-yellow-500);
|
|
69
|
+
--ds-badge-color: var(--color-extended-colours-yellow-800);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
&--green {
|
|
73
|
+
--ds-badge-background: var(--color-extended-colours-green-500);
|
|
74
|
+
--ds-badge-color: var(--color-mono-white);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
&--orange {
|
|
78
|
+
--ds-badge-background: var(--color-extended-colours-orange-500);
|
|
79
|
+
--ds-badge-color: var(--color-extended-colours-orange-800);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
&--blue {
|
|
83
|
+
--ds-badge-background: var(--color-extended-colours-blue-500);
|
|
84
|
+
--ds-badge-color: var(--color-extended-colours-blue-800);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
|
+
import {
|
|
4
|
+
comboboxAsyncSearchOptions,
|
|
5
|
+
comboboxGroupedPeopleOptions,
|
|
6
|
+
comboboxPeopleOptions,
|
|
7
|
+
} from '../../mocks/comboboxStoryOptions';
|
|
8
|
+
import { Combobox } from './Combobox';
|
|
9
|
+
import type { ComboboxOption, ComboboxProps } from './types';
|
|
10
|
+
|
|
11
|
+
const meta: Meta<typeof Combobox> = {
|
|
12
|
+
title: 'Components/Combobox',
|
|
13
|
+
component: Combobox,
|
|
14
|
+
tags: ['autodocs'],
|
|
15
|
+
parameters: {
|
|
16
|
+
docs: {
|
|
17
|
+
description: {
|
|
18
|
+
component:
|
|
19
|
+
'Default usage is `<Combobox … />` with props such as `triggerVariant` and `multiple`. `Combobox.Trigger`, `Combobox.ButtonTrigger`, and `Combobox.Listbox` are composition escape hatches.',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
argTypes: {
|
|
24
|
+
dropdownOnFocus: {
|
|
25
|
+
control: 'boolean',
|
|
26
|
+
description: 'When true, focusing the input opens the dropdown if there are items to show.',
|
|
27
|
+
},
|
|
28
|
+
showDropdownTrigger: {
|
|
29
|
+
control: 'boolean',
|
|
30
|
+
description: 'When true, shows the chevron trigger button.',
|
|
31
|
+
},
|
|
32
|
+
triggerVariant: {
|
|
33
|
+
control: 'inline-radio',
|
|
34
|
+
options: ['input', 'button'],
|
|
35
|
+
description: 'Choose trigger style: input-in-trigger or button-style summary trigger.',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
decorators: [
|
|
39
|
+
Story => (
|
|
40
|
+
<div data-surface="base" data-colour-mode="light" className="bg-surface text-on-surface-default" style={{ padding: 32, maxWidth: 420 }}>
|
|
41
|
+
<Story />
|
|
42
|
+
</div>
|
|
43
|
+
),
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default meta;
|
|
48
|
+
|
|
49
|
+
type Story = StoryObj<typeof Combobox>;
|
|
50
|
+
|
|
51
|
+
const withDescription = (story: Story, description: string): Story => ({
|
|
52
|
+
...story,
|
|
53
|
+
parameters: {
|
|
54
|
+
...story.parameters,
|
|
55
|
+
docs: {
|
|
56
|
+
...story.parameters?.docs,
|
|
57
|
+
description: {
|
|
58
|
+
story: description,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
/** Enough rows to exceed `.ds-combobox__listbox` max-height so keyboard nav scrolls. */
|
|
65
|
+
const manyScrollableOptions: ComboboxOption[] = Array.from({ length: 45 }, (_, i) => ({
|
|
66
|
+
value: `scroll-demo-${i + 1}`,
|
|
67
|
+
label: `Option ${i + 1}`,
|
|
68
|
+
iconName: 'user',
|
|
69
|
+
}));
|
|
70
|
+
|
|
71
|
+
export const ScrollableLongList: Story = withDescription({
|
|
72
|
+
args: {
|
|
73
|
+
options: manyScrollableOptions,
|
|
74
|
+
placeholder: 'Open the list and move with arrow keys…',
|
|
75
|
+
},
|
|
76
|
+
}, 'Exercises a scrollable listbox with enough items to validate keyboard navigation and active-row scrolling.');
|
|
77
|
+
|
|
78
|
+
export const ButtonTriggerSingleSelect: Story = withDescription({
|
|
79
|
+
args: {
|
|
80
|
+
options: comboboxPeopleOptions,
|
|
81
|
+
placeholder: 'Students',
|
|
82
|
+
triggerVariant: 'button',
|
|
83
|
+
},
|
|
84
|
+
}, 'Shows the button-style trigger in single-select mode before the search input moves into the popover.');
|
|
85
|
+
|
|
86
|
+
export const ButtonTriggerMultiSelect: Story = withDescription({
|
|
87
|
+
args: {
|
|
88
|
+
options: manyScrollableOptions,
|
|
89
|
+
defaultValue: ['scroll-demo-1', 'scroll-demo-2', 'scroll-demo-3'],
|
|
90
|
+
placeholder: 'Students',
|
|
91
|
+
multiple: true,
|
|
92
|
+
triggerVariant: 'button',
|
|
93
|
+
},
|
|
94
|
+
}, 'Demonstrates the button trigger variant with multiple selected chips and the selection count badge.');
|
|
95
|
+
|
|
96
|
+
export const SingleSelect: Story = withDescription({
|
|
97
|
+
args: {
|
|
98
|
+
options: comboboxPeopleOptions,
|
|
99
|
+
placeholder: 'Search people...',
|
|
100
|
+
},
|
|
101
|
+
}, 'Basic single-select Combobox with built-in client-side prefix matching.');
|
|
102
|
+
|
|
103
|
+
export const SubstringSearch: Story = withDescription({
|
|
104
|
+
args: {
|
|
105
|
+
options: comboboxPeopleOptions,
|
|
106
|
+
placeholder: 'Search people...',
|
|
107
|
+
searchType: 'substring',
|
|
108
|
+
},
|
|
109
|
+
}, 'Switches the built-in matching mode from prefix search to substring search.');
|
|
110
|
+
|
|
111
|
+
export const HighlightedMatches: Story = withDescription({
|
|
112
|
+
args: {
|
|
113
|
+
options: comboboxPeopleOptions,
|
|
114
|
+
placeholder: 'Search people...',
|
|
115
|
+
searchType: 'substring',
|
|
116
|
+
highlightStringMatches: true,
|
|
117
|
+
},
|
|
118
|
+
}, 'Highlights the matched portions of each option while using substring filtering.');
|
|
119
|
+
|
|
120
|
+
export const MultiSelect: Story = withDescription({
|
|
121
|
+
args: {
|
|
122
|
+
options: comboboxPeopleOptions,
|
|
123
|
+
multiple: true,
|
|
124
|
+
placeholder: 'Search people...',
|
|
125
|
+
showClearAll: true,
|
|
126
|
+
},
|
|
127
|
+
}, 'Basic multi-select Combobox with removable chips and a clear-all action.');
|
|
128
|
+
|
|
129
|
+
export const WithDefaultValue: Story = withDescription({
|
|
130
|
+
args: {
|
|
131
|
+
options: comboboxPeopleOptions,
|
|
132
|
+
multiple: true,
|
|
133
|
+
defaultValue: ['alice', 'bob', 'charlie'],
|
|
134
|
+
placeholder: 'Search people...',
|
|
135
|
+
showClearAll: true,
|
|
136
|
+
},
|
|
137
|
+
}, 'Starts with preselected values so chip rendering and removal can be reviewed immediately.');
|
|
138
|
+
|
|
139
|
+
export const WithGroups: Story = withDescription({
|
|
140
|
+
args: {
|
|
141
|
+
options: comboboxGroupedPeopleOptions,
|
|
142
|
+
multiple: true,
|
|
143
|
+
placeholder: 'Search people...',
|
|
144
|
+
},
|
|
145
|
+
}, 'Shows grouped options in the dropdown while keeping the same multi-select interaction model.');
|
|
146
|
+
|
|
147
|
+
export const Disabled: Story = withDescription({
|
|
148
|
+
args: {
|
|
149
|
+
options: comboboxPeopleOptions,
|
|
150
|
+
disabled: true,
|
|
151
|
+
defaultValue: ['alice'],
|
|
152
|
+
placeholder: 'Search people...',
|
|
153
|
+
},
|
|
154
|
+
}, 'Displays the disabled state with an existing selected value.');
|
|
155
|
+
|
|
156
|
+
export const HiddenTrigger: Story = withDescription({
|
|
157
|
+
args: {
|
|
158
|
+
options: comboboxPeopleOptions,
|
|
159
|
+
placeholder: 'Search people...',
|
|
160
|
+
showDropdownTrigger: false,
|
|
161
|
+
},
|
|
162
|
+
}, 'Hides the chevron trigger while keeping focus, typing, and keyboard opening behavior.');
|
|
163
|
+
|
|
164
|
+
export const ManualOpenOnFocus: Story = withDescription({
|
|
165
|
+
args: {
|
|
166
|
+
options: comboboxPeopleOptions,
|
|
167
|
+
placeholder: 'Search people...',
|
|
168
|
+
dropdownOnFocus: false,
|
|
169
|
+
},
|
|
170
|
+
}, 'Disables focus-open so the list appears only after typing or explicit keyboard interaction.');
|
|
171
|
+
|
|
172
|
+
export const CustomOptionLayout: Story = withDescription({
|
|
173
|
+
args: {
|
|
174
|
+
options: comboboxPeopleOptions,
|
|
175
|
+
placeholder: 'Search people...',
|
|
176
|
+
multiple: true,
|
|
177
|
+
renderOption: (option, selected) => (
|
|
178
|
+
<>
|
|
179
|
+
<span aria-hidden="true">
|
|
180
|
+
<input type="checkbox" checked={selected} readOnly tabIndex={-1} />
|
|
181
|
+
</span>
|
|
182
|
+
<span className="ds-combobox__option-label">{option.label}</span>
|
|
183
|
+
</>
|
|
184
|
+
),
|
|
185
|
+
},
|
|
186
|
+
}, 'Uses `renderOption` to swap the row content while the Combobox still owns selection and listbox behavior.');
|
|
187
|
+
|
|
188
|
+
const delay = (ms: number) => new Promise<void>((resolve) => {
|
|
189
|
+
setTimeout(resolve, ms);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
async function searchPeople(query: string): Promise<ComboboxOption[]> {
|
|
193
|
+
await delay(700);
|
|
194
|
+
const q = query.trim().toLowerCase();
|
|
195
|
+
if (!q) return comboboxAsyncSearchOptions;
|
|
196
|
+
return comboboxAsyncSearchOptions.filter(p => p.label.toLowerCase().includes(q));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
type AsyncSearchTemplateProps = Pick<
|
|
200
|
+
ComboboxProps,
|
|
201
|
+
'allowCreate' | 'searchType' | 'highlightStringMatches'
|
|
202
|
+
>;
|
|
203
|
+
|
|
204
|
+
const AsyncSearchTemplate = ({
|
|
205
|
+
allowCreate = false,
|
|
206
|
+
searchType = 'substring',
|
|
207
|
+
highlightStringMatches = true,
|
|
208
|
+
}: AsyncSearchTemplateProps) => {
|
|
209
|
+
const [options, setOptions] = useState<ComboboxOption[]>([]);
|
|
210
|
+
const [loading, setLoading] = useState(false);
|
|
211
|
+
const requestIdRef = useRef(0);
|
|
212
|
+
|
|
213
|
+
const handleSearch = (query: string) => {
|
|
214
|
+
const id = ++requestIdRef.current;
|
|
215
|
+
setLoading(true);
|
|
216
|
+
void searchPeople(query).then((next) => {
|
|
217
|
+
if (id !== requestIdRef.current) return;
|
|
218
|
+
setOptions(next);
|
|
219
|
+
setLoading(false);
|
|
220
|
+
});
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
return (
|
|
224
|
+
<Combobox
|
|
225
|
+
options={options}
|
|
226
|
+
multiple
|
|
227
|
+
placeholder="Type to search..."
|
|
228
|
+
loading={loading}
|
|
229
|
+
allowCreate={allowCreate}
|
|
230
|
+
searchType={searchType}
|
|
231
|
+
highlightStringMatches={highlightStringMatches}
|
|
232
|
+
onSearch={handleSearch}
|
|
233
|
+
/>
|
|
234
|
+
);
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
export const AsyncSearch: Story = withDescription({
|
|
238
|
+
args: {
|
|
239
|
+
allowCreate: false,
|
|
240
|
+
searchType: 'substring',
|
|
241
|
+
highlightStringMatches: true,
|
|
242
|
+
},
|
|
243
|
+
render: args => (
|
|
244
|
+
<AsyncSearchTemplate
|
|
245
|
+
allowCreate={args.allowCreate}
|
|
246
|
+
searchType={args.searchType}
|
|
247
|
+
highlightStringMatches={args.highlightStringMatches}
|
|
248
|
+
/>
|
|
249
|
+
),
|
|
250
|
+
}, 'Simulates async search results with local data so loading, filtering, and optional create flows can be reviewed.');
|
|
251
|
+
|
|
252
|
+
const CreateNewTemplate = () => {
|
|
253
|
+
const [options, setOptions] = useState<ComboboxOption[]>(comboboxPeopleOptions);
|
|
254
|
+
|
|
255
|
+
const handleCreate = (name: string) => {
|
|
256
|
+
const newOpt: ComboboxOption = {
|
|
257
|
+
value: name.toLowerCase().replace(/\s/g, '-'),
|
|
258
|
+
label: name,
|
|
259
|
+
iconName: 'user',
|
|
260
|
+
};
|
|
261
|
+
setOptions(prev => [...prev, newOpt]);
|
|
262
|
+
return newOpt;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const handleDelete = (value: string) => {
|
|
266
|
+
setOptions(prev => prev.filter(opt => opt.value !== value));
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
return (
|
|
270
|
+
<Combobox
|
|
271
|
+
options={options}
|
|
272
|
+
multiple
|
|
273
|
+
placeholder="Search or create..."
|
|
274
|
+
allowCreate
|
|
275
|
+
onCreateNew={handleCreate}
|
|
276
|
+
onDeleteCreated={handleDelete}
|
|
277
|
+
/>
|
|
278
|
+
);
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
export const CreateNew: Story = withDescription({
|
|
282
|
+
render: () => <CreateNewTemplate />,
|
|
283
|
+
}, 'Demonstrates multi-select creation and deletion of user-added options.');
|
|
284
|
+
|
|
285
|
+
const SingleSelectCreateTemplate = () => {
|
|
286
|
+
const [options, setOptions] = useState<ComboboxOption[]>(comboboxPeopleOptions);
|
|
287
|
+
|
|
288
|
+
const handleCreate = (name: string) => {
|
|
289
|
+
const newOpt: ComboboxOption = {
|
|
290
|
+
value: name.toLowerCase().replace(/\s/g, '-'),
|
|
291
|
+
label: name,
|
|
292
|
+
iconName: 'user',
|
|
293
|
+
};
|
|
294
|
+
setOptions(prev => [...prev, newOpt]);
|
|
295
|
+
return newOpt;
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
const handleDelete = (value: string) => {
|
|
299
|
+
setOptions(prev => prev.filter(opt => opt.value !== value));
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
return (
|
|
303
|
+
<Combobox
|
|
304
|
+
options={options}
|
|
305
|
+
placeholder="Search or create..."
|
|
306
|
+
allowCreate
|
|
307
|
+
onCreateNew={handleCreate}
|
|
308
|
+
onDeleteCreated={handleDelete}
|
|
309
|
+
/>
|
|
310
|
+
);
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
export const SingleSelectCreate: Story = withDescription({
|
|
314
|
+
render: () => <SingleSelectCreateTemplate />,
|
|
315
|
+
}, 'Shows single-select creation where a newly created option becomes the current value immediately.');
|
|
316
|
+
|
|
317
|
+
export const CustomTagLabel: Story = withDescription({
|
|
318
|
+
args: {
|
|
319
|
+
options: [
|
|
320
|
+
{ value: 'u1', label: 'Alice Johnson (Year 10, Class A)', tagLabel: 'Alice J.', iconName: 'user' },
|
|
321
|
+
{ value: 'u2', label: 'Bob Smith (Year 11, Class B)', tagLabel: 'Bob S.', iconName: 'user' },
|
|
322
|
+
{ value: 'u3', label: 'Charlie Brown (Year 10, Class A)', tagLabel: 'Charlie B.', iconName: 'user' },
|
|
323
|
+
],
|
|
324
|
+
multiple: true,
|
|
325
|
+
placeholder: 'Search students...',
|
|
326
|
+
showClearAll: true,
|
|
327
|
+
},
|
|
328
|
+
}, 'Uses `tagLabel` to shorten selected chip text while preserving fuller option labels in the dropdown.');
|
|
329
|
+
|
|
330
|
+
export const WithDisabledOptions: Story = withDescription({
|
|
331
|
+
args: {
|
|
332
|
+
options: [
|
|
333
|
+
{ value: 'alice', label: 'Alice Johnson', iconName: 'user' },
|
|
334
|
+
{ value: 'bob', label: 'Bob Smith', iconName: 'user', disabled: true },
|
|
335
|
+
{ value: 'charlie', label: 'Charlie Brown', iconName: 'user' },
|
|
336
|
+
],
|
|
337
|
+
multiple: true,
|
|
338
|
+
placeholder: 'Search people...',
|
|
339
|
+
},
|
|
340
|
+
}, 'Includes a disabled option to show how unavailable rows appear and behave inside the listbox.');
|