@arbor-education/design-system.components 0.21.1 → 0.23.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 +22 -0
- package/component-library.md +77 -14
- package/dist/components/articleCard/ArticleCard.d.ts +2 -2
- package/dist/components/articleCard/ArticleCard.d.ts.map +1 -1
- package/dist/components/articleCard/ArticleCard.js +3 -3
- package/dist/components/articleCard/ArticleCard.js.map +1 -1
- package/dist/components/articleCard/ArticleCard.stories.d.ts +11 -3
- package/dist/components/articleCard/ArticleCard.stories.d.ts.map +1 -1
- package/dist/components/articleCard/ArticleCard.stories.js +16 -11
- package/dist/components/articleCard/ArticleCard.stories.js.map +1 -1
- package/dist/components/combobox/Combobox.js +1 -1
- package/dist/components/combobox/Combobox.js.map +1 -1
- package/dist/components/combobox/Combobox.stories.d.ts +4 -0
- package/dist/components/combobox/Combobox.stories.d.ts.map +1 -1
- package/dist/components/combobox/Combobox.stories.js +144 -12
- package/dist/components/combobox/Combobox.stories.js.map +1 -1
- package/dist/components/combobox/Combobox.test.js +22 -0
- package/dist/components/combobox/Combobox.test.js.map +1 -1
- package/dist/components/combobox/ComboboxButtonTrigger.d.ts +4 -4
- package/dist/components/combobox/ComboboxButtonTrigger.d.ts.map +1 -1
- package/dist/components/combobox/ComboboxButtonTrigger.js +35 -40
- package/dist/components/combobox/ComboboxButtonTrigger.js.map +1 -1
- package/dist/components/combobox/ComboboxTrigger.d.ts.map +1 -1
- package/dist/components/combobox/ComboboxTrigger.js +11 -4
- package/dist/components/combobox/ComboboxTrigger.js.map +1 -1
- package/dist/components/combobox/useVisibleTriggerTags.d.ts +21 -0
- package/dist/components/combobox/useVisibleTriggerTags.d.ts.map +1 -0
- package/dist/components/combobox/useVisibleTriggerTags.js +46 -0
- package/dist/components/combobox/useVisibleTriggerTags.js.map +1 -0
- package/dist/components/combobox/useVisibleTriggerTags.test.d.ts +2 -0
- package/dist/components/combobox/useVisibleTriggerTags.test.d.ts.map +1 -0
- package/dist/components/combobox/useVisibleTriggerTags.test.js +81 -0
- package/dist/components/combobox/useVisibleTriggerTags.test.js.map +1 -0
- package/dist/components/filterBar/FilterBar.d.ts +71 -0
- package/dist/components/filterBar/FilterBar.d.ts.map +1 -0
- package/dist/components/filterBar/FilterBar.js +89 -0
- package/dist/components/filterBar/FilterBar.js.map +1 -0
- package/dist/components/filterBar/FilterBar.stories.d.ts +170 -0
- package/dist/components/filterBar/FilterBar.stories.d.ts.map +1 -0
- package/dist/components/filterBar/FilterBar.stories.js +894 -0
- package/dist/components/filterBar/FilterBar.stories.js.map +1 -0
- package/dist/components/filterBar/FilterBar.test.d.ts +2 -0
- package/dist/components/filterBar/FilterBar.test.d.ts.map +1 -0
- package/dist/components/filterBar/FilterBar.test.js +164 -0
- package/dist/components/filterBar/FilterBar.test.js.map +1 -0
- 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/iconText/IconText.d.ts +43 -0
- package/dist/components/iconText/IconText.d.ts.map +1 -0
- package/dist/components/iconText/IconText.js +29 -0
- package/dist/components/iconText/IconText.js.map +1 -0
- package/dist/components/{icoText/IcoText.stories.d.ts → iconText/IconText.stories.d.ts} +8 -9
- package/dist/components/iconText/IconText.stories.d.ts.map +1 -0
- package/dist/components/{icoText/IcoText.stories.js → iconText/IconText.stories.js} +81 -81
- package/dist/components/iconText/IconText.stories.js.map +1 -0
- package/dist/components/iconText/IconText.test.d.ts +2 -0
- package/dist/components/iconText/IconText.test.d.ts.map +1 -0
- package/dist/components/{icoText/IcoText.test.js → iconText/IconText.test.js} +6 -6
- package/dist/components/iconText/IconText.test.js.map +1 -0
- package/dist/components/modal/Modal.d.ts +1 -0
- package/dist/components/modal/Modal.d.ts.map +1 -1
- package/dist/components/modal/Modal.js +2 -2
- package/dist/components/modal/Modal.js.map +1 -1
- package/dist/components/table/cellRenderers/ComboboxCellRenderer.test.d.ts.map +1 -1
- package/dist/components/table/cellRenderers/ComboboxCellRenderer.test.js +13 -2
- package/dist/components/table/cellRenderers/ComboboxCellRenderer.test.js.map +1 -1
- package/dist/components/tag/Tag.d.ts +14 -1
- package/dist/components/tag/Tag.d.ts.map +1 -1
- package/dist/components/tag/Tag.js +9 -3
- package/dist/components/tag/Tag.js.map +1 -1
- package/dist/components/tag/Tag.stories.d.ts +1 -1
- package/dist/components/tag/Tag.stories.d.ts.map +1 -1
- package/dist/components/tag/Tag.stories.js +3 -3
- package/dist/components/tag/Tag.stories.js.map +1 -1
- package/dist/components/tag/Tag.test.js +36 -5
- package/dist/components/tag/Tag.test.js.map +1 -1
- package/dist/components/tagList/TagList.d.ts +49 -0
- package/dist/components/tagList/TagList.d.ts.map +1 -0
- package/dist/components/tagList/TagList.js +114 -0
- package/dist/components/tagList/TagList.js.map +1 -0
- package/dist/components/tagList/TagList.stories.d.ts +130 -0
- package/dist/components/tagList/TagList.stories.d.ts.map +1 -0
- package/dist/components/tagList/TagList.stories.js +443 -0
- package/dist/components/tagList/TagList.stories.js.map +1 -0
- package/dist/components/{icoText/IcoText.test.d.ts → tagList/TagList.test.d.ts} +1 -1
- package/dist/components/tagList/TagList.test.d.ts.map +1 -0
- package/dist/components/tagList/TagList.test.js +246 -0
- package/dist/components/tagList/TagList.test.js.map +1 -0
- package/dist/components/tagList/useTagListCollapsedLayout.d.ts +19 -0
- package/dist/components/tagList/useTagListCollapsedLayout.d.ts.map +1 -0
- package/dist/components/tagList/useTagListCollapsedLayout.js +48 -0
- package/dist/components/tagList/useTagListCollapsedLayout.js.map +1 -0
- package/dist/components/tagList/useVisibleTags.d.ts +18 -0
- package/dist/components/tagList/useVisibleTags.d.ts.map +1 -0
- package/dist/components/tagList/useVisibleTags.js +41 -0
- package/dist/components/tagList/useVisibleTags.js.map +1 -0
- package/dist/index.css +272 -13
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/hooks/useElementWidth.d.ts.map +1 -0
- package/dist/{components/combobox → utils/hooks}/useElementWidth.js +0 -1
- package/dist/utils/hooks/useElementWidth.js.map +1 -0
- package/dist/utils/hooks/useMeasuredChildWidths.d.ts +8 -0
- package/dist/utils/hooks/useMeasuredChildWidths.d.ts.map +1 -0
- package/dist/utils/hooks/useMeasuredChildWidths.js +26 -0
- package/dist/utils/hooks/useMeasuredChildWidths.js.map +1 -0
- package/dist/utils/hooks/useRovingFocus.d.ts +18 -0
- package/dist/utils/hooks/useRovingFocus.d.ts.map +1 -0
- package/dist/utils/hooks/useRovingFocus.js +130 -0
- package/dist/utils/hooks/useRovingFocus.js.map +1 -0
- package/dist/utils/hooks/useRovingFocus.test.d.ts +2 -0
- package/dist/utils/hooks/useRovingFocus.test.d.ts.map +1 -0
- package/dist/utils/hooks/useRovingFocus.test.js +59 -0
- package/dist/utils/hooks/useRovingFocus.test.js.map +1 -0
- package/dist/utils/spacedWidths.d.ts +3 -0
- package/dist/utils/spacedWidths.d.ts.map +1 -0
- package/dist/utils/spacedWidths.js +28 -0
- package/dist/utils/spacedWidths.js.map +1 -0
- package/dist/utils/spacedWidths.test.d.ts +2 -0
- package/dist/utils/spacedWidths.test.d.ts.map +1 -0
- package/dist/utils/spacedWidths.test.js +17 -0
- package/dist/utils/spacedWidths.test.js.map +1 -0
- package/package.json +1 -1
- package/src/components/articleCard/ArticleCard.stories.tsx +17 -12
- package/src/components/articleCard/ArticleCard.tsx +9 -9
- package/src/components/combobox/Combobox.stories.tsx +186 -12
- package/src/components/combobox/Combobox.test.tsx +53 -0
- package/src/components/combobox/Combobox.tsx +3 -3
- package/src/components/combobox/ComboboxButtonTrigger.tsx +52 -56
- package/src/components/combobox/ComboboxTrigger.tsx +19 -16
- package/src/components/combobox/combobox.scss +8 -3
- package/src/components/combobox/useVisibleTriggerTags.test.tsx +91 -0
- package/src/components/combobox/useVisibleTriggerTags.ts +83 -0
- package/src/components/filterBar/FilterBar.stories.tsx +1199 -0
- package/src/components/filterBar/FilterBar.test.tsx +248 -0
- package/src/components/filterBar/FilterBar.tsx +298 -0
- package/src/components/filterBar/filterBar.scss +143 -0
- package/src/components/icon/allowedIcons.tsx +3 -1
- package/src/components/{icoText/IcoText.stories.tsx → iconText/IconText.stories.tsx} +112 -112
- package/src/components/{icoText/IcoText.test.tsx → iconText/IconText.test.tsx} +10 -10
- package/src/components/{icoText/IcoText.tsx → iconText/IconText.tsx} +27 -20
- package/src/components/modal/Modal.tsx +5 -1
- package/src/components/table/cellRenderers/ComboboxCellRenderer.test.tsx +20 -3
- package/src/components/tag/Tag.stories.tsx +4 -4
- package/src/components/tag/Tag.test.tsx +62 -5
- package/src/components/tag/Tag.tsx +61 -3
- package/src/components/tag/tag.scss +80 -9
- package/src/components/tagList/TagList.stories.tsx +564 -0
- package/src/components/tagList/TagList.test.tsx +342 -0
- package/src/components/tagList/TagList.tsx +296 -0
- package/src/components/tagList/tagList.scss +56 -0
- package/src/components/tagList/useTagListCollapsedLayout.ts +83 -0
- package/src/components/tagList/useVisibleTags.ts +74 -0
- package/src/index.scss +3 -1
- package/src/index.ts +13 -1
- package/src/tokens.scss +3 -1
- package/src/{components/combobox → utils/hooks}/useElementWidth.ts +0 -1
- package/src/utils/hooks/useMeasuredChildWidths.ts +39 -0
- package/src/utils/hooks/useRovingFocus.test.tsx +105 -0
- package/src/utils/hooks/useRovingFocus.ts +163 -0
- package/src/utils/spacedWidths.test.ts +20 -0
- package/src/utils/spacedWidths.ts +37 -0
- package/dist/components/combobox/useElementWidth.d.ts.map +0 -1
- package/dist/components/combobox/useElementWidth.js.map +0 -1
- package/dist/components/combobox/useVisibleChips.d.ts +0 -21
- package/dist/components/combobox/useVisibleChips.d.ts.map +0 -1
- package/dist/components/combobox/useVisibleChips.js +0 -59
- package/dist/components/combobox/useVisibleChips.js.map +0 -1
- package/dist/components/combobox/useVisibleChips.test.d.ts +0 -2
- package/dist/components/combobox/useVisibleChips.test.d.ts.map +0 -1
- package/dist/components/combobox/useVisibleChips.test.js +0 -81
- package/dist/components/combobox/useVisibleChips.test.js.map +0 -1
- package/dist/components/icoText/IcoText.d.ts +0 -37
- package/dist/components/icoText/IcoText.d.ts.map +0 -1
- package/dist/components/icoText/IcoText.js +0 -29
- package/dist/components/icoText/IcoText.js.map +0 -1
- package/dist/components/icoText/IcoText.stories.d.ts.map +0 -1
- package/dist/components/icoText/IcoText.stories.js.map +0 -1
- package/dist/components/icoText/IcoText.test.d.ts.map +0 -1
- package/dist/components/icoText/IcoText.test.js.map +0 -1
- package/src/components/combobox/useVisibleChips.test.tsx +0 -91
- package/src/components/combobox/useVisibleChips.ts +0 -100
- /package/dist/{components/combobox → utils/hooks}/useElementWidth.d.ts +0 -0
- /package/src/components/{icoText/icoText.scss → iconText/iconText.scss} +0 -0
|
@@ -114,6 +114,17 @@ The component does NOT debounce; add your own debounce inside \`onSearch\`.
|
|
|
114
114
|
|
|
115
115
|
---
|
|
116
116
|
|
|
117
|
+
### Tag focus recovery
|
|
118
|
+
|
|
119
|
+
When \`selectedValueDisplay="tags"\`, selected chips are rendered through the shared
|
|
120
|
+
\`TagList\` interaction model. Removing the final chip returns focus to the natural
|
|
121
|
+
home control for that trigger:
|
|
122
|
+
|
|
123
|
+
- inline trigger: back to the combobox input
|
|
124
|
+
- button trigger: back to the trigger button
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
117
128
|
### Grouped options
|
|
118
129
|
|
|
119
130
|
Options with the same \`group\` string are rendered under a shared group heading.
|
|
@@ -394,7 +405,7 @@ export const SingleSelect = withDescription(
|
|
|
394
405
|
|
|
395
406
|
// 4. MultiSelect
|
|
396
407
|
export const MultiSelect = withDescription(
|
|
397
|
-
'Set `multiple` to allow multiple selections — each selected value is shown as a removable tag chip. Press Backspace to remove the last tag.',
|
|
408
|
+
'Set `multiple` to allow multiple selections — each selected value is shown as a removable tag chip. Press Backspace to remove the last tag. When the final chip is removed, focus returns to the inline combobox input.',
|
|
398
409
|
{
|
|
399
410
|
args: {
|
|
400
411
|
options: comboboxPeopleOptions,
|
|
@@ -591,7 +602,7 @@ export const ButtonTriggerSingleSelect = withDescription(
|
|
|
591
602
|
|
|
592
603
|
// 13. ButtonTriggerMultiSelect
|
|
593
604
|
export const ButtonTriggerMultiSelect = withDescription(
|
|
594
|
-
'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.',
|
|
605
|
+
'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. When the trigger is showing tag chips, removing the final chip returns focus to the button trigger.',
|
|
595
606
|
{
|
|
596
607
|
args: {
|
|
597
608
|
options: comboboxPeopleOptions,
|
|
@@ -610,7 +621,59 @@ export const ButtonTriggerMultiSelect = withDescription(
|
|
|
610
621
|
},
|
|
611
622
|
);
|
|
612
623
|
|
|
613
|
-
// 14.
|
|
624
|
+
// 14. FocusRecovery
|
|
625
|
+
export const FocusRecovery = withDescription(
|
|
626
|
+
'A focused verification story for chip removal. Each example starts with one selected value so you can remove the final chip and confirm focus returns to the natural home control: the input for the inline trigger and the button for the button trigger.',
|
|
627
|
+
{
|
|
628
|
+
parameters: {
|
|
629
|
+
controls: { disable: true },
|
|
630
|
+
docs: {
|
|
631
|
+
source: {
|
|
632
|
+
code: `
|
|
633
|
+
<div style={{ display: 'grid', gap: 16 }}>
|
|
634
|
+
<Combobox
|
|
635
|
+
options={teacherOptions}
|
|
636
|
+
multiple
|
|
637
|
+
defaultValue={['alice-johnson']}
|
|
638
|
+
placeholder="Select teachers..."
|
|
639
|
+
/>
|
|
640
|
+
|
|
641
|
+
<Combobox
|
|
642
|
+
options={teacherOptions}
|
|
643
|
+
triggerVariant="button"
|
|
644
|
+
multiple
|
|
645
|
+
defaultValue={['alice-johnson']}
|
|
646
|
+
placeholder="Filter by teacher"
|
|
647
|
+
showSelectionCountBadge
|
|
648
|
+
/>
|
|
649
|
+
</div>
|
|
650
|
+
`.trim(),
|
|
651
|
+
},
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
render: () => (
|
|
655
|
+
<div style={{ display: 'grid', gap: 16 }}>
|
|
656
|
+
<Combobox
|
|
657
|
+
options={comboboxPeopleOptions}
|
|
658
|
+
multiple
|
|
659
|
+
defaultValue={['alice-johnson']}
|
|
660
|
+
placeholder="Select teachers..."
|
|
661
|
+
/>
|
|
662
|
+
|
|
663
|
+
<Combobox
|
|
664
|
+
options={comboboxPeopleOptions}
|
|
665
|
+
triggerVariant="button"
|
|
666
|
+
multiple
|
|
667
|
+
defaultValue={['alice-johnson']}
|
|
668
|
+
placeholder="Filter by teacher"
|
|
669
|
+
showSelectionCountBadge
|
|
670
|
+
/>
|
|
671
|
+
</div>
|
|
672
|
+
),
|
|
673
|
+
},
|
|
674
|
+
);
|
|
675
|
+
|
|
676
|
+
// 15. ButtonTriggerPlainTextValue
|
|
614
677
|
export const ButtonTriggerPlainTextValue = withDescription(
|
|
615
678
|
'`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.',
|
|
616
679
|
{
|
|
@@ -631,7 +694,118 @@ export const ButtonTriggerPlainTextValue = withDescription(
|
|
|
631
694
|
},
|
|
632
695
|
);
|
|
633
696
|
|
|
634
|
-
//
|
|
697
|
+
// 16. ButtonTriggerOverflow
|
|
698
|
+
export const ButtonTriggerOverflow = withDescription(
|
|
699
|
+
'A dedicated single-line tag overflow example for the button trigger. The trigger width is constrained and multiple default selections are provided so the compact tag display stays on one line, shows the built-in ellipsis, and keeps the selected-count badge visible.',
|
|
700
|
+
{
|
|
701
|
+
args: {
|
|
702
|
+
options: comboboxPeopleOptions,
|
|
703
|
+
triggerVariant: 'button',
|
|
704
|
+
multiple: true,
|
|
705
|
+
defaultValue: ['alice-johnson', 'bob-smith', 'carol-white', 'daniel-clark'],
|
|
706
|
+
placeholder: 'Filter by teacher',
|
|
707
|
+
showSelectionCountBadge: true,
|
|
708
|
+
},
|
|
709
|
+
decorators: [
|
|
710
|
+
Story => (
|
|
711
|
+
<div style={{ width: 260 }}>
|
|
712
|
+
<Story />
|
|
713
|
+
</div>
|
|
714
|
+
),
|
|
715
|
+
],
|
|
716
|
+
parameters: {
|
|
717
|
+
docs: {
|
|
718
|
+
source: {
|
|
719
|
+
code: `
|
|
720
|
+
<div style={{ width: 260 }}>
|
|
721
|
+
<Combobox
|
|
722
|
+
options={teacherOptions}
|
|
723
|
+
triggerVariant="button"
|
|
724
|
+
multiple
|
|
725
|
+
defaultValue={['alice-johnson', 'bob-smith', 'carol-white', 'daniel-clark']}
|
|
726
|
+
placeholder="Filter by teacher"
|
|
727
|
+
showSelectionCountBadge
|
|
728
|
+
/>
|
|
729
|
+
</div>
|
|
730
|
+
`.trim(),
|
|
731
|
+
},
|
|
732
|
+
},
|
|
733
|
+
},
|
|
734
|
+
},
|
|
735
|
+
);
|
|
736
|
+
|
|
737
|
+
// 17. ButtonTriggerSingleLineTagsWithCountBadge
|
|
738
|
+
export const ButtonTriggerSingleLineTagsWithCountBadge = withDescription(
|
|
739
|
+
'A focused badge-in-trigger example for button-trigger multi-select. The trigger width is constrained so selected tags remain on a single line while the selected-count badge stays visible alongside the ellipsis.',
|
|
740
|
+
{
|
|
741
|
+
args: {
|
|
742
|
+
options: comboboxPeopleOptions,
|
|
743
|
+
triggerVariant: 'button',
|
|
744
|
+
multiple: true,
|
|
745
|
+
defaultValue: ['alice-johnson', 'bob-smith', 'carol-white', 'daniel-clark'],
|
|
746
|
+
placeholder: 'Filter by teacher',
|
|
747
|
+
showSelectionCountBadge: true,
|
|
748
|
+
},
|
|
749
|
+
decorators: [
|
|
750
|
+
Story => (
|
|
751
|
+
<div style={{ width: 260 }}>
|
|
752
|
+
<Story />
|
|
753
|
+
</div>
|
|
754
|
+
),
|
|
755
|
+
],
|
|
756
|
+
parameters: {
|
|
757
|
+
docs: {
|
|
758
|
+
source: {
|
|
759
|
+
code: `
|
|
760
|
+
<div style={{ width: 260 }}>
|
|
761
|
+
<Combobox
|
|
762
|
+
options={teacherOptions}
|
|
763
|
+
triggerVariant="button"
|
|
764
|
+
multiple
|
|
765
|
+
defaultValue={['alice-johnson', 'bob-smith', 'carol-white', 'daniel-clark']}
|
|
766
|
+
placeholder="Filter by teacher"
|
|
767
|
+
showSelectionCountBadge
|
|
768
|
+
/>
|
|
769
|
+
</div>
|
|
770
|
+
`.trim(),
|
|
771
|
+
},
|
|
772
|
+
},
|
|
773
|
+
},
|
|
774
|
+
},
|
|
775
|
+
);
|
|
776
|
+
|
|
777
|
+
// 18. WithClearAll
|
|
778
|
+
export const WithClearAll = withDescription(
|
|
779
|
+
'Shows the existing clear-all affordance below the combobox. This is useful when users need a single action to reset multiple selected values without removing chips one by one. Removing chips individually still follows the shared `TagList` focus recovery behavior.',
|
|
780
|
+
{
|
|
781
|
+
args: {
|
|
782
|
+
options: comboboxPeopleOptions,
|
|
783
|
+
multiple: true,
|
|
784
|
+
defaultValue: ['alice-johnson', 'bob-smith', 'carol-white'],
|
|
785
|
+
placeholder: 'Select teachers...',
|
|
786
|
+
showClearAll: true,
|
|
787
|
+
clearAllLabel: 'Clear all',
|
|
788
|
+
},
|
|
789
|
+
parameters: {
|
|
790
|
+
docs: {
|
|
791
|
+
source: {
|
|
792
|
+
code: `
|
|
793
|
+
<Combobox
|
|
794
|
+
options={teacherOptions}
|
|
795
|
+
multiple
|
|
796
|
+
defaultValue={['alice-johnson', 'bob-smith', 'carol-white']}
|
|
797
|
+
placeholder="Select teachers..."
|
|
798
|
+
showClearAll
|
|
799
|
+
clearAllLabel="Clear all"
|
|
800
|
+
/>
|
|
801
|
+
`.trim(),
|
|
802
|
+
},
|
|
803
|
+
},
|
|
804
|
+
},
|
|
805
|
+
},
|
|
806
|
+
);
|
|
807
|
+
|
|
808
|
+
// 18. HiddenTrigger
|
|
635
809
|
export const HiddenTrigger = withDescription(
|
|
636
810
|
'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.',
|
|
637
811
|
{
|
|
@@ -650,7 +824,7 @@ export const HiddenTrigger = withDescription(
|
|
|
650
824
|
},
|
|
651
825
|
);
|
|
652
826
|
|
|
653
|
-
//
|
|
827
|
+
// 18. ManualOpenOnFocus
|
|
654
828
|
export const ManualOpenOnFocus = withDescription(
|
|
655
829
|
'Set `dropdownOnFocus={false}` to prevent the dropdown from opening automatically on focus — the user must start typing or click the chevron to open it.',
|
|
656
830
|
{
|
|
@@ -689,7 +863,7 @@ function AsyncSearchTemplate() {
|
|
|
689
863
|
return <Combobox options={options} onSearch={handleSearch} placeholder="Search staff..." />;
|
|
690
864
|
}
|
|
691
865
|
|
|
692
|
-
//
|
|
866
|
+
// 19. AsyncSearch
|
|
693
867
|
export const AsyncSearch = withDescription(
|
|
694
868
|
'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.',
|
|
695
869
|
{
|
|
@@ -747,7 +921,7 @@ function CreateNewTemplate() {
|
|
|
747
921
|
);
|
|
748
922
|
}
|
|
749
923
|
|
|
750
|
-
//
|
|
924
|
+
// 20. CreateNew
|
|
751
925
|
export const CreateNew = withDescription(
|
|
752
926
|
'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`.',
|
|
753
927
|
{
|
|
@@ -806,7 +980,7 @@ function SingleSelectCreateTemplate() {
|
|
|
806
980
|
);
|
|
807
981
|
}
|
|
808
982
|
|
|
809
|
-
//
|
|
983
|
+
// 21. SingleSelectCreate
|
|
810
984
|
export const SingleSelectCreate = withDescription(
|
|
811
985
|
'`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.',
|
|
812
986
|
{
|
|
@@ -843,7 +1017,7 @@ function SingleSelectCreateExample() {
|
|
|
843
1017
|
},
|
|
844
1018
|
);
|
|
845
1019
|
|
|
846
|
-
//
|
|
1020
|
+
// 22. CustomOptionLayout
|
|
847
1021
|
export const CustomOptionLayout = withDescription(
|
|
848
1022
|
'Use `renderOption` to fully customise how each option is rendered inside the dropdown — useful for adding avatars, icons, or additional metadata alongside the label.',
|
|
849
1023
|
{
|
|
@@ -880,7 +1054,7 @@ export const CustomOptionLayout = withDescription(
|
|
|
880
1054
|
},
|
|
881
1055
|
);
|
|
882
1056
|
|
|
883
|
-
//
|
|
1057
|
+
// 23. CustomTagLabel
|
|
884
1058
|
export const CustomTagLabel = withDescription(
|
|
885
1059
|
'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.',
|
|
886
1060
|
{
|
|
@@ -907,7 +1081,7 @@ export const CustomTagLabel = withDescription(
|
|
|
907
1081
|
},
|
|
908
1082
|
);
|
|
909
1083
|
|
|
910
|
-
//
|
|
1084
|
+
// 24. WithDisabledOptions
|
|
911
1085
|
export const WithDisabledOptions = withDescription(
|
|
912
1086
|
'Individual options can be disabled by setting `disabled: true` on the option object. Disabled options are visible but cannot be selected.',
|
|
913
1087
|
{
|
|
@@ -935,7 +1109,7 @@ const options = [
|
|
|
935
1109
|
},
|
|
936
1110
|
);
|
|
937
1111
|
|
|
938
|
-
//
|
|
1112
|
+
// 25. ScrollableLongList
|
|
939
1113
|
export const ScrollableLongList = withDescription(
|
|
940
1114
|
'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.',
|
|
941
1115
|
{
|
|
@@ -223,6 +223,19 @@ describe('Combobox', () => {
|
|
|
223
223
|
expect(badge).toHaveTextContent('2');
|
|
224
224
|
});
|
|
225
225
|
|
|
226
|
+
test('button trigger renders selected chips through TagList', () => {
|
|
227
|
+
const { container } = render(
|
|
228
|
+
<Combobox
|
|
229
|
+
options={people}
|
|
230
|
+
triggerVariant="button"
|
|
231
|
+
multiple
|
|
232
|
+
defaultValue={['alice', 'bob']}
|
|
233
|
+
/>,
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
expect(container.querySelector('.ds-combobox__button-tags-viewport .ds-tag-list')).toBeInTheDocument();
|
|
237
|
+
});
|
|
238
|
+
|
|
226
239
|
test('button trigger does not show ellipsis when all selected chips fit', () => {
|
|
227
240
|
const rectSpy = vi.spyOn(HTMLElement.prototype, 'getBoundingClientRect').mockImplementation(function mockRect(this: HTMLElement) {
|
|
228
241
|
let width = 0;
|
|
@@ -376,6 +389,14 @@ describe('Combobox', () => {
|
|
|
376
389
|
expect(onValueChange).toHaveBeenLastCalledWith(['alice', 'bob']);
|
|
377
390
|
});
|
|
378
391
|
|
|
392
|
+
test('input trigger renders selected chips through TagList', () => {
|
|
393
|
+
const { container } = render(
|
|
394
|
+
<Combobox options={people} multiple defaultValue={['alice', 'bob']} />,
|
|
395
|
+
);
|
|
396
|
+
|
|
397
|
+
expect(container.querySelector('.ds-combobox__chips-and-input .ds-tag-list')).toBeInTheDocument();
|
|
398
|
+
});
|
|
399
|
+
|
|
379
400
|
test('Ctrl+A selects all chips when input is focused', async () => {
|
|
380
401
|
const user = userEvent.setup();
|
|
381
402
|
render(<Combobox options={people} multiple defaultValue={['alice', 'bob']} />);
|
|
@@ -470,6 +491,38 @@ describe('Combobox', () => {
|
|
|
470
491
|
expect(onValueChange).toHaveBeenCalledWith(['bob']);
|
|
471
492
|
});
|
|
472
493
|
|
|
494
|
+
test('removing the last chip in the input trigger returns focus to the combobox input', async () => {
|
|
495
|
+
render(
|
|
496
|
+
<Combobox options={people} multiple defaultValue={['alice']} placeholder="Search people..." />,
|
|
497
|
+
);
|
|
498
|
+
|
|
499
|
+
const aliceTag = screen.getByText('Alice Johnson').closest('.ds-tag') as HTMLElement;
|
|
500
|
+
const removeBtn = within(aliceTag).getByRole('button', { name: 'Remove Alice Johnson' });
|
|
501
|
+
|
|
502
|
+
await userEvent.click(removeBtn);
|
|
503
|
+
|
|
504
|
+
expect(screen.getByRole('combobox')).toHaveFocus();
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
test('removing the last chip in the button trigger returns focus to the parent trigger', async () => {
|
|
508
|
+
const { container } = render(
|
|
509
|
+
<Combobox
|
|
510
|
+
options={people}
|
|
511
|
+
triggerVariant="button"
|
|
512
|
+
multiple
|
|
513
|
+
defaultValue={['alice']}
|
|
514
|
+
placeholder="Filter by teacher"
|
|
515
|
+
/>,
|
|
516
|
+
);
|
|
517
|
+
|
|
518
|
+
const visibleTagViewport = container.querySelector('.ds-combobox__button-tags-viewport') as HTMLElement;
|
|
519
|
+
const removeBtn = within(visibleTagViewport).getByRole('button', { name: 'Remove Alice Johnson' });
|
|
520
|
+
|
|
521
|
+
await userEvent.click(removeBtn);
|
|
522
|
+
|
|
523
|
+
expect(container.querySelector('.ds-combobox__trigger--button')).toHaveFocus();
|
|
524
|
+
});
|
|
525
|
+
|
|
473
526
|
test('uses resolved tag labels in button trigger remove button labels', () => {
|
|
474
527
|
render(
|
|
475
528
|
<Combobox
|
|
@@ -346,9 +346,9 @@ const ComboboxRoot = (props: ComboboxProps): React.JSX.Element => {
|
|
|
346
346
|
showDropdownTrigger={showDropdownTrigger}
|
|
347
347
|
selectedValueDisplay={selectedValueDisplay}
|
|
348
348
|
triggerEndContent={triggerEndContent}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
349
|
+
selectedTags={selectedChips}
|
|
350
|
+
selectedTagValuesSet={selectedChipValuesSet}
|
|
351
|
+
focusedTagIndex={focusedChipIndex}
|
|
352
352
|
resolveTagLabel={resolveTagLabel}
|
|
353
353
|
removeValue={removeValue}
|
|
354
354
|
handleTriggerClick={handleTriggerClick}
|
|
@@ -2,11 +2,13 @@ import classNames from 'classnames';
|
|
|
2
2
|
import { Badge } from 'Components/badge/Badge';
|
|
3
3
|
import { Icon } from 'Components/icon/Icon';
|
|
4
4
|
import { Tag } from 'Components/tag/Tag';
|
|
5
|
+
import { TagList } from 'Components/tagList/TagList';
|
|
6
|
+
import { useMeasuredChildWidths } from 'Utils/hooks/useMeasuredChildWidths';
|
|
7
|
+
import { useElementWidth } from 'Utils/hooks/useElementWidth';
|
|
5
8
|
import { Popover } from 'radix-ui';
|
|
6
9
|
import { useMemo, useRef } from 'react';
|
|
7
10
|
import type { ComboboxAriaInvalid, ComboboxOption, ComboboxSelectedValueDisplay } from './types.js';
|
|
8
|
-
import {
|
|
9
|
-
import { useVisibleChips } from './useVisibleChips.js';
|
|
11
|
+
import { useVisibleTriggerTags } from './useVisibleTriggerTags.js';
|
|
10
12
|
|
|
11
13
|
export type ComboboxButtonTriggerProps = {
|
|
12
14
|
triggerRef: React.RefObject<HTMLDivElement | null>;
|
|
@@ -21,9 +23,9 @@ export type ComboboxButtonTriggerProps = {
|
|
|
21
23
|
showDropdownTrigger: boolean;
|
|
22
24
|
selectedValueDisplay: ComboboxSelectedValueDisplay;
|
|
23
25
|
triggerEndContent?: React.ReactNode;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
selectedTags: ComboboxOption[];
|
|
27
|
+
selectedTagValuesSet: Set<string>;
|
|
28
|
+
focusedTagIndex: number | null;
|
|
27
29
|
resolveTagLabel: (opt: ComboboxOption) => string;
|
|
28
30
|
removeValue: (value: string) => void;
|
|
29
31
|
handleTriggerClick: () => void;
|
|
@@ -46,9 +48,9 @@ export const ComboboxButtonTrigger = ({
|
|
|
46
48
|
showDropdownTrigger,
|
|
47
49
|
selectedValueDisplay,
|
|
48
50
|
triggerEndContent,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
selectedTags,
|
|
52
|
+
selectedTagValuesSet,
|
|
53
|
+
focusedTagIndex,
|
|
52
54
|
resolveTagLabel,
|
|
53
55
|
removeValue,
|
|
54
56
|
handleTriggerClick,
|
|
@@ -62,65 +64,47 @@ export const ComboboxButtonTrigger = ({
|
|
|
62
64
|
const ellipsisProbeRef = useRef<HTMLSpanElement>(null);
|
|
63
65
|
const badgeProbeRef = useRef<HTMLSpanElement>(null);
|
|
64
66
|
|
|
65
|
-
const
|
|
67
|
+
const tagWatchKey = useMemo(
|
|
66
68
|
() =>
|
|
67
|
-
|
|
69
|
+
selectedTags
|
|
68
70
|
.map(opt => `${opt.value}:${resolveTagLabel(opt)}:${opt.iconName ?? ''}`)
|
|
69
71
|
.join('|'),
|
|
70
|
-
[resolveTagLabel,
|
|
72
|
+
[resolveTagLabel, selectedTags],
|
|
71
73
|
);
|
|
72
74
|
|
|
73
75
|
const selectedValueText = useMemo(
|
|
74
|
-
() =>
|
|
75
|
-
[resolveTagLabel,
|
|
76
|
+
() => selectedTags.map(resolveTagLabel).join(', '),
|
|
77
|
+
[resolveTagLabel, selectedTags],
|
|
76
78
|
);
|
|
77
79
|
const usesTagDisplay = selectedValueDisplay === 'tags';
|
|
78
|
-
const shouldShowBadge = showSelectionCountBadge &&
|
|
80
|
+
const shouldShowBadge = showSelectionCountBadge && selectedTags.length > 0;
|
|
79
81
|
|
|
80
|
-
const contentWidth = useElementWidth(contentRef, `${
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
const
|
|
84
|
-
const measurementTrackElement = measureTrackRef.current;
|
|
82
|
+
const contentWidth = useElementWidth(contentRef, `${tagWatchKey}-${isOpen}-${shouldShowBadge}`);
|
|
83
|
+
const ellipsisWidth = useElementWidth(ellipsisProbeRef, `${tagWatchKey}-${isOpen}`);
|
|
84
|
+
const badgeWidth = useElementWidth(badgeProbeRef, `${tagWatchKey}-${isOpen}-${shouldShowBadge}`);
|
|
85
|
+
const { childGap: tagGap, childWidths: tagWidths } = useMeasuredChildWidths(measureTrackRef, `${tagWatchKey}-${isOpen}`);
|
|
85
86
|
|
|
86
|
-
const
|
|
87
|
-
const el = measureTrackRef.current;
|
|
88
|
-
if (!el) return 0;
|
|
89
|
-
const styles = getComputedStyle(el);
|
|
90
|
-
const parsed = Number.parseFloat(styles.columnGap || styles.gap || '0');
|
|
91
|
-
return Number.isFinite(parsed) ? parsed : 0;
|
|
92
|
-
}, [measurementTrackElement, measurementTrackWidth]);
|
|
93
|
-
|
|
94
|
-
const chipWidths = useMemo(() => {
|
|
95
|
-
const el = measureTrackRef.current;
|
|
96
|
-
if (!el) return [];
|
|
97
|
-
return Array.from(el.children).map((child) => {
|
|
98
|
-
const width = (child as HTMLElement).getBoundingClientRect().width;
|
|
99
|
-
return Number.isFinite(width) ? width : 0;
|
|
100
|
-
});
|
|
101
|
-
}, [chipWatchKey, measurementTrackElement, measurementTrackWidth]);
|
|
102
|
-
|
|
103
|
-
const layout = useVisibleChips({
|
|
87
|
+
const layout = useVisibleTriggerTags({
|
|
104
88
|
containerWidth: contentWidth,
|
|
105
|
-
|
|
106
|
-
|
|
89
|
+
tagWidths,
|
|
90
|
+
tagGap,
|
|
107
91
|
badgeWidth,
|
|
108
92
|
ellipsisWidth,
|
|
109
93
|
showBadge: shouldShowBadge,
|
|
110
94
|
});
|
|
111
95
|
|
|
112
|
-
const canMeasure = contentWidth > 0 &&
|
|
113
|
-
const
|
|
114
|
-
? layout.
|
|
115
|
-
:
|
|
96
|
+
const canMeasure = contentWidth > 0 && tagWidths.length === selectedTags.length;
|
|
97
|
+
const visibleTags = canMeasure
|
|
98
|
+
? layout.visibleTagIndices.map(index => selectedTags[index]!).filter(Boolean)
|
|
99
|
+
: selectedTags;
|
|
116
100
|
const showEllipsis = usesTagDisplay && (canMeasure ? layout.showEllipsis : false);
|
|
117
101
|
const showBadge = usesTagDisplay && (canMeasure ? layout.showBadge : shouldShowBadge);
|
|
118
102
|
|
|
119
|
-
const renderSelectionTag = (opt: ComboboxOption,
|
|
103
|
+
const renderSelectionTag = (opt: ComboboxOption, tagIdx: number, onRemove?: () => void) => (
|
|
120
104
|
<Tag
|
|
121
105
|
key={opt.value}
|
|
122
106
|
color="neutral"
|
|
123
|
-
selected={
|
|
107
|
+
selected={selectedTagValuesSet.has(opt.value) || focusedTagIndex === tagIdx}
|
|
124
108
|
slotStart={opt.iconName ? <Icon name={opt.iconName} size={12} /> : undefined}
|
|
125
109
|
onRemove={onRemove}
|
|
126
110
|
removeLabel={`Remove ${resolveTagLabel(opt)}`}
|
|
@@ -132,10 +116,20 @@ export const ComboboxButtonTrigger = ({
|
|
|
132
116
|
|
|
133
117
|
const renderSelectionCountBadge = (withA11yLabel: boolean) => (
|
|
134
118
|
<Badge colour="salmon" a11yLabel={withA11yLabel ? selectionCountA11yLabel : undefined}>
|
|
135
|
-
{
|
|
119
|
+
{selectedTags.length}
|
|
136
120
|
</Badge>
|
|
137
121
|
);
|
|
138
122
|
|
|
123
|
+
const visibleTagItems = visibleTags.map((opt, tagIdx) => ({
|
|
124
|
+
id: opt.value,
|
|
125
|
+
children: resolveTagLabel(opt),
|
|
126
|
+
color: 'neutral' as const,
|
|
127
|
+
selected: selectedTagValuesSet.has(opt.value) || focusedTagIndex === tagIdx,
|
|
128
|
+
slotStart: opt.iconName ? <Icon name={opt.iconName} size={12} /> : undefined,
|
|
129
|
+
onRemove: disabled ? undefined : () => removeValue(opt.value),
|
|
130
|
+
removeLabel: `Remove ${resolveTagLabel(opt)}`,
|
|
131
|
+
}));
|
|
132
|
+
|
|
139
133
|
return (
|
|
140
134
|
<Popover.Anchor asChild>
|
|
141
135
|
<div
|
|
@@ -160,13 +154,15 @@ export const ComboboxButtonTrigger = ({
|
|
|
160
154
|
{usesTagDisplay
|
|
161
155
|
? (
|
|
162
156
|
<div className="ds-combobox__button-tags-viewport">
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
157
|
+
{selectedTags.length === 0
|
|
158
|
+
? <span className="ds-combobox__button-placeholder">{placeholder}</span>
|
|
159
|
+
: (
|
|
160
|
+
<TagList
|
|
161
|
+
items={visibleTagItems}
|
|
162
|
+
returnFocusRef={triggerRef}
|
|
163
|
+
className="ds-combobox__tag-list"
|
|
164
|
+
/>
|
|
165
|
+
)}
|
|
170
166
|
{showEllipsis && <span className="ds-combobox__button-ellipsis" aria-hidden="true">…</span>}
|
|
171
167
|
</div>
|
|
172
168
|
)
|
|
@@ -202,11 +198,11 @@ export const ComboboxButtonTrigger = ({
|
|
|
202
198
|
|
|
203
199
|
{usesTagDisplay && (
|
|
204
200
|
<div className="ds-combobox__measure" aria-hidden="true">
|
|
205
|
-
{/* Mirror the rendered
|
|
201
|
+
{/* Mirror the rendered tags off-screen so width calculations use the real Tag layout. */}
|
|
206
202
|
<div className="ds-combobox__button-tags-track" ref={measureTrackRef}>
|
|
207
|
-
{
|
|
203
|
+
{selectedTags.map((opt, tagIdx) => (
|
|
208
204
|
<span key={`measure-${opt.value}`} className="ds-combobox__measure-chip">
|
|
209
|
-
{renderSelectionTag(opt,
|
|
205
|
+
{renderSelectionTag(opt, tagIdx, disabled ? undefined : () => {})}
|
|
210
206
|
</span>
|
|
211
207
|
))}
|
|
212
208
|
</div>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import classNames from 'classnames';
|
|
2
2
|
import { Icon } from 'Components/icon/Icon';
|
|
3
|
-
import {
|
|
3
|
+
import { TagList } from 'Components/tagList/TagList';
|
|
4
4
|
import { Popover } from 'radix-ui';
|
|
5
5
|
import type { ComboboxAriaInvalid, ComboboxOption, ComboboxSelectedValueDisplay } from './types.js';
|
|
6
6
|
|
|
@@ -74,6 +74,15 @@ export const ComboboxTrigger = (props: ComboboxTriggerProps): React.JSX.Element
|
|
|
74
74
|
= selectedValueDisplay === 'text'
|
|
75
75
|
&& query.length === 0
|
|
76
76
|
&& selectedValueText.length > 0;
|
|
77
|
+
const selectedTagItems = selectedChips.map(opt => ({
|
|
78
|
+
id: opt.value,
|
|
79
|
+
children: resolveTagLabel(opt),
|
|
80
|
+
color: 'neutral' as const,
|
|
81
|
+
selected: selectedChipValuesSet.has(opt.value),
|
|
82
|
+
slotStart: opt.iconName ? <Icon name={opt.iconName} size={12} /> : undefined,
|
|
83
|
+
onRemove: disabled ? undefined : () => removeValue(opt.value),
|
|
84
|
+
removeLabel: `Remove ${resolveTagLabel(opt)}`,
|
|
85
|
+
}));
|
|
77
86
|
|
|
78
87
|
return (
|
|
79
88
|
<Popover.Anchor asChild>
|
|
@@ -87,21 +96,15 @@ export const ComboboxTrigger = (props: ComboboxTriggerProps): React.JSX.Element
|
|
|
87
96
|
onClick={handleTriggerClick}
|
|
88
97
|
>
|
|
89
98
|
<div className="ds-combobox__chips-and-input">
|
|
90
|
-
{selectedValueDisplay === 'tags'
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
removeButtonTabIndex={-1}
|
|
100
|
-
>
|
|
101
|
-
{resolveTagLabel(opt)}
|
|
102
|
-
</Tag>
|
|
103
|
-
))
|
|
104
|
-
: null}
|
|
99
|
+
{selectedValueDisplay === 'tags' && (
|
|
100
|
+
<TagList
|
|
101
|
+
items={selectedTagItems}
|
|
102
|
+
wrap
|
|
103
|
+
highlightedItemIndex={focusedChipIndex}
|
|
104
|
+
returnFocusRef={inputRef}
|
|
105
|
+
className="ds-combobox__tag-list"
|
|
106
|
+
/>
|
|
107
|
+
)}
|
|
105
108
|
{showSelectedValueText && (
|
|
106
109
|
<span className="ds-combobox__selected-value">
|
|
107
110
|
{selectedValueText}
|
|
@@ -9,16 +9,14 @@
|
|
|
9
9
|
align-items: center;
|
|
10
10
|
gap: var(--spacing-small);
|
|
11
11
|
min-height: var(--form-field-text-medium-height);
|
|
12
|
-
padding: var(--spacing-xsmall) var(--spacing-small);
|
|
12
|
+
padding: calc(var(--spacing-xsmall) - (var(--border-weight))) var(--spacing-small);
|
|
13
13
|
border: var(--border-weight) solid var(--form-field-combobox-default-color-border);
|
|
14
14
|
border-radius: var(--form-field-radius);
|
|
15
15
|
background-color: var(--form-field-combobox-default-color-background);
|
|
16
16
|
color: var(--form-field-combobox-default-color-text);
|
|
17
17
|
cursor: text;
|
|
18
18
|
transition: border-color 0.2s, box-shadow 0.2s, background-color 0.2s;
|
|
19
|
-
box-sizing: border-box;
|
|
20
19
|
font-style: normal;
|
|
21
|
-
line-height: 150%;
|
|
22
20
|
|
|
23
21
|
&:hover:not(.ds-combobox__trigger--disabled) {
|
|
24
22
|
border-color: var(--form-field-combobox-hover-color-border);
|
|
@@ -70,11 +68,18 @@
|
|
|
70
68
|
}
|
|
71
69
|
|
|
72
70
|
.ds-combobox__button-tags-viewport {
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: center;
|
|
73
73
|
flex: 1;
|
|
74
74
|
min-width: 0;
|
|
75
75
|
overflow: hidden;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
.ds-combobox__tag-list {
|
|
79
|
+
flex: 1;
|
|
80
|
+
min-width: 0;
|
|
81
|
+
}
|
|
82
|
+
|
|
78
83
|
.ds-combobox__button-tags-track {
|
|
79
84
|
display: inline-flex;
|
|
80
85
|
width: auto;
|