@entur/dropdown 7.3.8 → 8.0.0-beta.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/dist/Dropdown.d.ts +1 -7
- package/dist/MultiSelect.d.ts +4 -4
- package/dist/SearchableDropdown.d.ts +4 -4
- package/dist/components/DropdownList.d.ts +4 -5
- package/dist/components/FieldComponents.d.ts +1 -1
- package/dist/dropdown.cjs.js +314 -333
- package/dist/dropdown.cjs.js.map +1 -1
- package/dist/dropdown.esm.js +315 -334
- package/dist/dropdown.esm.js.map +1 -1
- package/dist/styles.css +4 -1
- package/dist/utils.d.ts +7 -1
- package/package.json +7 -7
package/dist/dropdown.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useDebounce, mergeRefs, useRandomId, warnAboutMissingStyles } from "@entur/utils";
|
|
2
2
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
3
|
-
import React, { forwardRef, createElement, useState, useRef, useEffect, useCallback } from "react";
|
|
3
|
+
import React, { forwardRef, createElement, useMemo, useState, useRef, useEffect, useCallback, useLayoutEffect } from "react";
|
|
4
4
|
import { useCombobox, useMultipleSelection, useSelect } from "downshift";
|
|
5
5
|
import classNames from "classnames";
|
|
6
6
|
import { useFloating, offset, shift, size, flip, autoUpdate } from "@floating-ui/react-dom";
|
|
@@ -14,21 +14,21 @@ import { LoadingDots } from "@entur/loader";
|
|
|
14
14
|
import { Tooltip } from "@entur/tooltip";
|
|
15
15
|
const DropdownList = ({
|
|
16
16
|
ariaLabelChosenSingular = "valgt",
|
|
17
|
-
ariaLabelSelectedItem = ", valgt element
|
|
17
|
+
ariaLabelSelectedItem = ", valgt element",
|
|
18
18
|
getItemProps,
|
|
19
|
-
getMenuProps,
|
|
20
19
|
isOpen,
|
|
21
20
|
highlightedIndex,
|
|
22
21
|
listItems,
|
|
23
22
|
floatingStyles,
|
|
24
|
-
|
|
23
|
+
innerRef,
|
|
25
24
|
loading = false,
|
|
26
25
|
loadingText = "Laster inn …",
|
|
27
26
|
noMatchesText = "Ingen treff for søket",
|
|
27
|
+
readOnly = false,
|
|
28
28
|
selectAllCheckboxState,
|
|
29
29
|
selectAllItem,
|
|
30
30
|
selectedItems,
|
|
31
|
-
|
|
31
|
+
style,
|
|
32
32
|
...rest
|
|
33
33
|
}) => {
|
|
34
34
|
const isMultiselect = selectAllItem !== void 0;
|
|
@@ -41,7 +41,7 @@ const DropdownList = ({
|
|
|
41
41
|
return true;
|
|
42
42
|
});
|
|
43
43
|
const ariaValuesSelectAll = () => {
|
|
44
|
-
switch (selectAllCheckboxState
|
|
44
|
+
switch (selectAllCheckboxState) {
|
|
45
45
|
case "indeterminate": {
|
|
46
46
|
return {
|
|
47
47
|
label: `${selectAllItem?.label}, delvis valgt`,
|
|
@@ -64,7 +64,7 @@ const DropdownList = ({
|
|
|
64
64
|
Checkbox,
|
|
65
65
|
{
|
|
66
66
|
"aria-hidden": "true",
|
|
67
|
-
checked: selectAllCheckboxState
|
|
67
|
+
checked: selectAllCheckboxState,
|
|
68
68
|
className: "eds-dropdown__list__item__checkbox",
|
|
69
69
|
tabIndex: -1,
|
|
70
70
|
onChange: () => void 0
|
|
@@ -111,75 +111,68 @@ const DropdownList = ({
|
|
|
111
111
|
}) : null
|
|
112
112
|
] });
|
|
113
113
|
};
|
|
114
|
-
return (
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
"
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
{
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
},
|
|
177
|
-
key
|
|
178
|
-
);
|
|
179
|
-
});
|
|
180
|
-
})()
|
|
181
|
-
}
|
|
182
|
-
)
|
|
114
|
+
return /* @__PURE__ */ jsx(
|
|
115
|
+
"ul",
|
|
116
|
+
{
|
|
117
|
+
className: "eds-dropdown__list",
|
|
118
|
+
ref: innerRef,
|
|
119
|
+
style: {
|
|
120
|
+
display: isOpen && !readOnly ? void 0 : "none",
|
|
121
|
+
...floatingStyles,
|
|
122
|
+
...style
|
|
123
|
+
},
|
|
124
|
+
...rest,
|
|
125
|
+
children: (() => {
|
|
126
|
+
if (!isOpen || readOnly) return null;
|
|
127
|
+
if (loading) {
|
|
128
|
+
return /* @__PURE__ */ jsx(
|
|
129
|
+
"li",
|
|
130
|
+
{
|
|
131
|
+
className: "eds-dropdown__list__item",
|
|
132
|
+
children: loadingText
|
|
133
|
+
},
|
|
134
|
+
"dropdown-list-loading"
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
if (isNoMatches) {
|
|
138
|
+
return /* @__PURE__ */ jsx(
|
|
139
|
+
"li",
|
|
140
|
+
{
|
|
141
|
+
className: "eds-dropdown__list__item",
|
|
142
|
+
children: noMatchesText
|
|
143
|
+
},
|
|
144
|
+
"dropdown-list-no-match"
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
return listItems.map((item, index) => {
|
|
148
|
+
const key = item.itemKey ?? `${item.label ?? ""}-${item.value ?? ""}-${(item.icons ?? []).map((icon) => icon?.displayName ?? icon?.name ?? "unknown").join("-")}`;
|
|
149
|
+
const itemIsSelectAll = item.value === selectAllItem?.value;
|
|
150
|
+
if (itemIsSelectAll && listItems.length <= 2) return null;
|
|
151
|
+
return /* @__PURE__ */ jsx(
|
|
152
|
+
"li",
|
|
153
|
+
{
|
|
154
|
+
className: classNames("eds-dropdown__list__item", {
|
|
155
|
+
"eds-dropdown__list__item--select-all": itemIsSelectAll,
|
|
156
|
+
"eds-dropdown__list__item--highlighted": highlightedIndex === index,
|
|
157
|
+
"eds-dropdown__list__item--selected": !isMultiselect && isItemSelected(item)
|
|
158
|
+
}),
|
|
159
|
+
...getItemProps({
|
|
160
|
+
// @ts-expect-error Since getItemProps expects the same item type
|
|
161
|
+
// here as items, it throws error when selectAllItem is a string.
|
|
162
|
+
// This does, however, not cause any functional issues.
|
|
163
|
+
item,
|
|
164
|
+
index,
|
|
165
|
+
"aria-selected": itemIsSelectAll ? ariaValuesSelectAll().selected : isItemSelected(item)
|
|
166
|
+
}),
|
|
167
|
+
children: itemIsSelectAll ? selectAllListItemContent() : listItemContent(
|
|
168
|
+
item
|
|
169
|
+
)
|
|
170
|
+
},
|
|
171
|
+
key
|
|
172
|
+
);
|
|
173
|
+
});
|
|
174
|
+
})()
|
|
175
|
+
}
|
|
183
176
|
);
|
|
184
177
|
};
|
|
185
178
|
const SelectedItemTag = ({
|
|
@@ -192,6 +185,7 @@ const SelectedItemTag = ({
|
|
|
192
185
|
removeSelectedItem,
|
|
193
186
|
selectedItem
|
|
194
187
|
}) => {
|
|
188
|
+
if (!selectedItem) return null;
|
|
195
189
|
const { tabIndex: _, ...selectedItemProps } = getSelectedItemProps?.({
|
|
196
190
|
selectedItem,
|
|
197
191
|
index
|
|
@@ -408,6 +402,10 @@ const itemToString = (item) => item ? item.label : "";
|
|
|
408
402
|
const itemToKey = (item) => item?.label + item?.value;
|
|
409
403
|
const isFunctionWithQueryArgument = (object) => typeof object === "function" && object.length > 0;
|
|
410
404
|
const clamp = (val, min = 1, max = 10) => Math.min(Math.max(val, min), max);
|
|
405
|
+
const resetInputState = (changes) => ({
|
|
406
|
+
...changes,
|
|
407
|
+
inputValue: EMPTY_INPUT
|
|
408
|
+
});
|
|
411
409
|
const useMultiselectUtils = ({
|
|
412
410
|
listItems,
|
|
413
411
|
selectedItems,
|
|
@@ -455,11 +453,11 @@ const useMultiselectUtils = ({
|
|
|
455
453
|
(selectedItem) => selectedItem.value !== clickedItem.value
|
|
456
454
|
)
|
|
457
455
|
);
|
|
458
|
-
const selectAllCheckboxState = () => {
|
|
456
|
+
const selectAllCheckboxState = useMemo(() => {
|
|
459
457
|
if (allListItemsAreSelected) return true;
|
|
460
458
|
if (someListItemsAreSelected) return "indeterminate";
|
|
461
459
|
return false;
|
|
462
|
-
};
|
|
460
|
+
}, [allListItemsAreSelected, someListItemsAreSelected]);
|
|
463
461
|
const selectAllUnselectedItemsInListItems = (onChange) => {
|
|
464
462
|
onChange([...selectedItems, ...unselectedItemsInListItems]);
|
|
465
463
|
};
|
|
@@ -523,7 +521,6 @@ const SearchableDropdown = React.forwardRef(
|
|
|
523
521
|
prepend,
|
|
524
522
|
readOnly = false,
|
|
525
523
|
selectedItem: value,
|
|
526
|
-
selectOnBlur = false,
|
|
527
524
|
selectOnTab = false,
|
|
528
525
|
style,
|
|
529
526
|
variant = "info",
|
|
@@ -550,77 +547,56 @@ const SearchableDropdown = React.forwardRef(
|
|
|
550
547
|
if (shouldRefetchItems) fetchItems(inputValue2 ?? EMPTY_INPUT);
|
|
551
548
|
filterListItems({ inputValue: inputValue2 ?? EMPTY_INPUT });
|
|
552
549
|
};
|
|
553
|
-
const resetInputState = ({
|
|
554
|
-
changes
|
|
555
|
-
}) => {
|
|
556
|
-
updateListItems({ inputValue: EMPTY_INPUT });
|
|
557
|
-
return {
|
|
558
|
-
...changes,
|
|
559
|
-
inputValue: EMPTY_INPUT
|
|
560
|
-
};
|
|
561
|
-
};
|
|
562
550
|
const inputHasFocus = typeof document !== "undefined" ? inputRef?.current === document?.activeElement : false;
|
|
563
551
|
useEffect(() => {
|
|
564
552
|
filterListItems({ inputValue });
|
|
565
553
|
}, [normalizedItems]);
|
|
566
|
-
useEffect(() => {
|
|
567
|
-
if (selectedItem !== null && !inputHasFocus) {
|
|
568
|
-
setShowSelectedItem(true);
|
|
569
|
-
updateListItems({ inputValue: EMPTY_INPUT });
|
|
570
|
-
setInputValue(EMPTY_INPUT);
|
|
571
|
-
}
|
|
572
|
-
}, []);
|
|
573
554
|
const stateReducer = useCallback(
|
|
574
555
|
(state, {
|
|
575
556
|
type,
|
|
576
557
|
changes
|
|
577
558
|
}) => {
|
|
578
|
-
if (changes.highlightedIndex !== void 0 && changes?.highlightedIndex >= 0) {
|
|
579
|
-
setLastHighlightedIndex(changes?.highlightedIndex);
|
|
580
|
-
}
|
|
581
559
|
switch (type) {
|
|
582
560
|
// empty input to show selected item and reset dropdown list on item selection
|
|
583
561
|
case useCombobox.stateChangeTypes.ItemClick:
|
|
584
562
|
case useCombobox.stateChangeTypes.InputKeyDownEnter:
|
|
563
|
+
return resetInputState(changes);
|
|
585
564
|
case useCombobox.stateChangeTypes.InputBlur:
|
|
586
|
-
return resetInputState({
|
|
565
|
+
return resetInputState({
|
|
566
|
+
...changes,
|
|
567
|
+
selectedItem: state.selectedItem
|
|
568
|
+
});
|
|
587
569
|
case useCombobox.stateChangeTypes.ControlledPropUpdatedSelectedItem:
|
|
588
|
-
|
|
589
|
-
setShowSelectedItem(true);
|
|
590
|
-
return resetInputState({ changes });
|
|
570
|
+
return { ...changes, inputValue: state.inputValue };
|
|
591
571
|
// remove leading whitespace, select element with spacebar on empty input
|
|
592
572
|
case useCombobox.stateChangeTypes.InputChange: {
|
|
593
|
-
const leadingWhitespaceTest = /^\s+/g;
|
|
594
573
|
const isSpacePressedOnEmptyInput = changes.inputValue === " ";
|
|
595
|
-
if (!isSpacePressedOnEmptyInput)
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
return { ...changes, highlightedIndex: 0 };
|
|
574
|
+
if (!isSpacePressedOnEmptyInput)
|
|
575
|
+
return { ...changes, highlightedIndex: 0 };
|
|
576
|
+
const sanitizedInputValue = (changes.inputValue ?? "").replace(
|
|
577
|
+
/^\s+/,
|
|
578
|
+
EMPTY_INPUT
|
|
579
|
+
);
|
|
580
|
+
if (!state.isOpen)
|
|
581
|
+
return {
|
|
582
|
+
...changes,
|
|
583
|
+
inputValue: sanitizedInputValue,
|
|
584
|
+
isOpen: true
|
|
585
|
+
};
|
|
586
|
+
const i = changes.highlightedIndex ?? -1;
|
|
587
|
+
if (i >= 0 && i < listItems.length)
|
|
588
|
+
return {
|
|
589
|
+
...changes,
|
|
590
|
+
inputValue: sanitizedInputValue,
|
|
591
|
+
selectedItem: listItems[i]
|
|
592
|
+
};
|
|
593
|
+
return { ...changes, inputValue: sanitizedInputValue };
|
|
618
594
|
}
|
|
619
595
|
default:
|
|
620
596
|
return changes;
|
|
621
597
|
}
|
|
622
598
|
},
|
|
623
|
-
[
|
|
599
|
+
[listItems, EMPTY_INPUT]
|
|
624
600
|
);
|
|
625
601
|
const {
|
|
626
602
|
isOpen,
|
|
@@ -647,9 +623,23 @@ const SearchableDropdown = React.forwardRef(
|
|
|
647
623
|
onSelectedItemChange({ selectedItem: newSelectedItem }) {
|
|
648
624
|
onChange(newSelectedItem);
|
|
649
625
|
},
|
|
626
|
+
onHighlightedIndexChange: ({ highlightedIndex: highlightedIndex2 }) => {
|
|
627
|
+
if (highlightedIndex2 >= 0) setLastHighlightedIndex(highlightedIndex2);
|
|
628
|
+
},
|
|
650
629
|
// Accessibility
|
|
651
630
|
getA11yStatusMessage: (options) => getA11yStatusMessage({ ...options, resultCount: listItems.length })
|
|
652
631
|
});
|
|
632
|
+
useEffect(() => {
|
|
633
|
+
if (value !== null && !inputHasFocus) {
|
|
634
|
+
setShowSelectedItem(true);
|
|
635
|
+
updateListItems({ inputValue: EMPTY_INPUT });
|
|
636
|
+
setInputValue(EMPTY_INPUT);
|
|
637
|
+
}
|
|
638
|
+
}, [value]);
|
|
639
|
+
const handleOnClear = () => {
|
|
640
|
+
inputRef.current?.focus();
|
|
641
|
+
reset();
|
|
642
|
+
};
|
|
653
643
|
const { refs, floatingStyles, update } = useFloating({
|
|
654
644
|
open: isOpen,
|
|
655
645
|
placement: "bottom-start",
|
|
@@ -657,19 +647,17 @@ const SearchableDropdown = React.forwardRef(
|
|
|
657
647
|
offset(space.extraSmall2),
|
|
658
648
|
shift({ padding: space.extraSmall }),
|
|
659
649
|
size({
|
|
660
|
-
apply({
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
maxHeight: `${clamp(10 * 16, availableHeight, 20 * 16)}px`
|
|
666
|
-
});
|
|
650
|
+
apply({ elements, availableHeight }) {
|
|
651
|
+
elements.floating.style.setProperty(
|
|
652
|
+
"--list-max-height",
|
|
653
|
+
`${clamp(10 * 16, availableHeight, 20 * 16)}px`
|
|
654
|
+
);
|
|
667
655
|
}
|
|
668
656
|
}),
|
|
669
657
|
flip({ fallbackStrategy: "initialPlacement" })
|
|
670
658
|
]
|
|
671
659
|
});
|
|
672
|
-
|
|
660
|
+
useLayoutEffect(() => {
|
|
673
661
|
if (isOpen && refs.reference.current && refs.floating.current) {
|
|
674
662
|
return autoUpdate(
|
|
675
663
|
refs.reference.current,
|
|
@@ -678,10 +666,39 @@ const SearchableDropdown = React.forwardRef(
|
|
|
678
666
|
);
|
|
679
667
|
}
|
|
680
668
|
}, [isOpen, refs.reference, refs.floating, update]);
|
|
681
|
-
const
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
};
|
|
669
|
+
const labelProps = getLabelProps();
|
|
670
|
+
const toggleButtonProps = getToggleButtonProps({
|
|
671
|
+
"aria-busy": !(loading ?? resolvedItemsLoading) ? void 0 : "true"
|
|
672
|
+
});
|
|
673
|
+
const menuProps = getMenuProps({
|
|
674
|
+
refKey: "innerRef",
|
|
675
|
+
ref: refs.setFloating,
|
|
676
|
+
style: listStyle
|
|
677
|
+
});
|
|
678
|
+
const inputProps = getInputProps({
|
|
679
|
+
onKeyDown(e) {
|
|
680
|
+
if (isOpen && e.key === "Tab") {
|
|
681
|
+
const highlitedItem = listItems[highlightedIndex];
|
|
682
|
+
if (selectOnTab && highlitedItem) {
|
|
683
|
+
selectItem(highlitedItem);
|
|
684
|
+
setShowSelectedItem(true);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
},
|
|
688
|
+
onBlur(e) {
|
|
689
|
+
if (selectedItem !== null) setShowSelectedItem(true);
|
|
690
|
+
onBlur?.(e);
|
|
691
|
+
},
|
|
692
|
+
onFocus(e) {
|
|
693
|
+
if (!readOnly) setShowSelectedItem(false);
|
|
694
|
+
onFocus?.(e);
|
|
695
|
+
},
|
|
696
|
+
disabled,
|
|
697
|
+
readOnly,
|
|
698
|
+
placeholder: selectedItem?.label ?? placeholder,
|
|
699
|
+
tabIndex: disabled || readOnly ? -1 : void 0,
|
|
700
|
+
ref: mergeRefs(inputRef, ref)
|
|
701
|
+
});
|
|
685
702
|
return /* @__PURE__ */ jsxs(
|
|
686
703
|
BaseFormControl,
|
|
687
704
|
{
|
|
@@ -696,17 +713,14 @@ const SearchableDropdown = React.forwardRef(
|
|
|
696
713
|
feedback,
|
|
697
714
|
isFilled: selectedItem !== null || inputValue !== EMPTY_INPUT,
|
|
698
715
|
label,
|
|
699
|
-
labelId:
|
|
700
|
-
labelProps
|
|
716
|
+
labelId: labelProps.id,
|
|
717
|
+
labelProps,
|
|
701
718
|
labelTooltip,
|
|
702
719
|
onClick: (e) => {
|
|
703
|
-
if (e.target === e.currentTarget)
|
|
704
|
-
getInputProps()?.onClick?.(e);
|
|
705
|
-
}
|
|
720
|
+
if (e.target === e.currentTarget) inputProps?.onClick?.(e);
|
|
706
721
|
onClick?.(e);
|
|
707
722
|
},
|
|
708
723
|
onKeyDown,
|
|
709
|
-
onFocus,
|
|
710
724
|
prepend,
|
|
711
725
|
readOnly,
|
|
712
726
|
ref: refs.setReference,
|
|
@@ -720,17 +734,15 @@ const SearchableDropdown = React.forwardRef(
|
|
|
720
734
|
ariaLabelSelectedItem,
|
|
721
735
|
floatingStyles,
|
|
722
736
|
getItemProps,
|
|
723
|
-
getMenuProps,
|
|
724
737
|
highlightedIndex,
|
|
725
738
|
isOpen,
|
|
726
739
|
listItems,
|
|
727
|
-
style: listStyle,
|
|
728
|
-
setListRef: refs.setFloating,
|
|
729
740
|
loading: loading ?? resolvedItemsLoading,
|
|
730
741
|
loadingText,
|
|
731
742
|
noMatchesText,
|
|
732
743
|
selectedItems: selectedItem !== null ? [selectedItem] : [],
|
|
733
|
-
readOnly
|
|
744
|
+
readOnly,
|
|
745
|
+
...menuProps
|
|
734
746
|
}
|
|
735
747
|
),
|
|
736
748
|
...rest,
|
|
@@ -745,7 +757,7 @@ const SearchableDropdown = React.forwardRef(
|
|
|
745
757
|
onClick: (event) => {
|
|
746
758
|
if (!disabled && !readOnly) {
|
|
747
759
|
inputRef.current?.focus();
|
|
748
|
-
|
|
760
|
+
inputProps?.onClick?.(event);
|
|
749
761
|
}
|
|
750
762
|
},
|
|
751
763
|
tabIndex: readOnly ? 0 : -1,
|
|
@@ -758,38 +770,13 @@ const SearchableDropdown = React.forwardRef(
|
|
|
758
770
|
className: classNames("eds-dropdown__input eds-form-control", {
|
|
759
771
|
"eds-dropdown__input--hidden": showSelectedItem
|
|
760
772
|
}),
|
|
761
|
-
...
|
|
762
|
-
onKeyDown(e) {
|
|
763
|
-
if (isOpen && e.key === "Tab") {
|
|
764
|
-
const highlitedItem = listItems[highlightedIndex];
|
|
765
|
-
if ((selectOnTab || selectOnBlur) && highlitedItem && highlitedItem !== selectedItem) {
|
|
766
|
-
selectItem(highlitedItem);
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
},
|
|
770
|
-
onBlur(e) {
|
|
771
|
-
if (selectedItem !== null) setShowSelectedItem(true);
|
|
772
|
-
onBlur?.(e);
|
|
773
|
-
},
|
|
774
|
-
onFocus() {
|
|
775
|
-
if (!readOnly) {
|
|
776
|
-
setShowSelectedItem(false);
|
|
777
|
-
}
|
|
778
|
-
},
|
|
779
|
-
disabled,
|
|
780
|
-
readOnly,
|
|
781
|
-
placeholder: selectedItem?.label ?? placeholder,
|
|
782
|
-
tabIndex: disabled || readOnly ? -1 : void 0,
|
|
783
|
-
ref: mergeRefs(inputRef, ref)
|
|
784
|
-
})
|
|
773
|
+
...inputProps
|
|
785
774
|
}
|
|
786
775
|
),
|
|
787
776
|
/* @__PURE__ */ jsx(
|
|
788
777
|
DropdownFieldAppendix,
|
|
789
778
|
{
|
|
790
|
-
...
|
|
791
|
-
"aria-busy": !(loading ?? resolvedItemsLoading) ? void 0 : "true"
|
|
792
|
-
}),
|
|
779
|
+
...toggleButtonProps,
|
|
793
780
|
ariaLabelCloseList,
|
|
794
781
|
ariaLabelOpenList,
|
|
795
782
|
clearable,
|
|
@@ -834,7 +821,6 @@ const MultiSelect = React.forwardRef(
|
|
|
834
821
|
placeholder,
|
|
835
822
|
readOnly = false,
|
|
836
823
|
selectedItems = [],
|
|
837
|
-
selectOnBlur = false,
|
|
838
824
|
selectOnTab = false,
|
|
839
825
|
style,
|
|
840
826
|
variant = "information",
|
|
@@ -865,10 +851,14 @@ const MultiSelect = React.forwardRef(
|
|
|
865
851
|
fetchItems
|
|
866
852
|
} = useResolvedItems(initialItems, debounceTimeout);
|
|
867
853
|
const isAllNonAsyncItemsSelected = typeof initialItems !== "function" && selectedItems.length === normalizedItems.length;
|
|
868
|
-
const
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
854
|
+
const selectAllUniqueId = useRandomId("select-all");
|
|
855
|
+
const selectAll = React.useMemo(
|
|
856
|
+
() => ({
|
|
857
|
+
value: selectAllUniqueId,
|
|
858
|
+
label: labelSelectAll
|
|
859
|
+
}),
|
|
860
|
+
[labelSelectAll]
|
|
861
|
+
);
|
|
872
862
|
const summarySelectedItems = React.useMemo(
|
|
873
863
|
() => ({
|
|
874
864
|
value: EMPTY_INPUT,
|
|
@@ -885,15 +875,21 @@ const MultiSelect = React.forwardRef(
|
|
|
885
875
|
...!hideSelectAll ? [selectAll] : [],
|
|
886
876
|
...normalizedItems
|
|
887
877
|
]);
|
|
888
|
-
const filterListItems = (
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
878
|
+
const filterListItems = React.useCallback(
|
|
879
|
+
({ inputValue: inputValue2 }) => setListItems([
|
|
880
|
+
...!hideSelectAll ? [selectAll] : [],
|
|
881
|
+
...normalizedItems.filter((item) => itemFilter(item, inputValue2))
|
|
882
|
+
]),
|
|
883
|
+
[hideSelectAll, selectAll, normalizedItems, itemFilter]
|
|
884
|
+
);
|
|
885
|
+
const updateListItems = React.useCallback(
|
|
886
|
+
({ inputValue: inputValue2 }) => {
|
|
887
|
+
const shouldRefetchItems = isFunctionWithQueryArgument(initialItems);
|
|
888
|
+
if (shouldRefetchItems) fetchItems(inputValue2 ?? EMPTY_INPUT);
|
|
889
|
+
filterListItems({ inputValue: inputValue2 ?? EMPTY_INPUT });
|
|
890
|
+
},
|
|
891
|
+
[filterListItems, initialItems, fetchItems]
|
|
892
|
+
);
|
|
897
893
|
React.useEffect(() => {
|
|
898
894
|
filterListItems({ inputValue });
|
|
899
895
|
}, [normalizedItems]);
|
|
@@ -925,67 +921,57 @@ const MultiSelect = React.forwardRef(
|
|
|
925
921
|
});
|
|
926
922
|
const stateReducer = React.useCallback(
|
|
927
923
|
(state, {
|
|
928
|
-
|
|
929
|
-
|
|
924
|
+
type,
|
|
925
|
+
changes
|
|
930
926
|
}) => {
|
|
931
|
-
if (changes.highlightedIndex !== void 0 && changes?.highlightedIndex >= 0) {
|
|
932
|
-
setLastHighlightedIndex(changes?.highlightedIndex);
|
|
933
|
-
}
|
|
934
927
|
switch (type) {
|
|
935
|
-
// reset input value when leaving input field
|
|
936
|
-
case useCombobox.stateChangeTypes.InputBlur:
|
|
937
|
-
return {
|
|
938
|
-
...changes,
|
|
939
|
-
inputValue: EMPTY_INPUT
|
|
940
|
-
};
|
|
941
928
|
// keep menu open and edit input value on item selection
|
|
942
929
|
case useCombobox.stateChangeTypes.InputKeyDownEnter:
|
|
943
930
|
case useCombobox.stateChangeTypes.ItemClick: {
|
|
944
931
|
return {
|
|
945
932
|
...changes,
|
|
946
933
|
isOpen: true,
|
|
947
|
-
inputValue: clearInputOnSelect ? EMPTY_INPUT :
|
|
934
|
+
inputValue: clearInputOnSelect ? EMPTY_INPUT : state.inputValue
|
|
948
935
|
};
|
|
949
936
|
}
|
|
937
|
+
// reset input value when leaving input field
|
|
938
|
+
case useCombobox.stateChangeTypes.InputBlur: {
|
|
939
|
+
const { selectedItem: _, ...otherChanges } = changes;
|
|
940
|
+
return resetInputState(otherChanges);
|
|
941
|
+
}
|
|
950
942
|
// edit input value when selected items is updated outside component
|
|
951
943
|
case useCombobox.stateChangeTypes.ControlledPropUpdatedSelectedItem: {
|
|
952
|
-
return {
|
|
953
|
-
...changes,
|
|
954
|
-
inputValue: inputRef?.current?.value ?? EMPTY_INPUT
|
|
955
|
-
};
|
|
944
|
+
return { ...changes, inputValue: state.inputValue };
|
|
956
945
|
}
|
|
957
946
|
// remove leading whitespace, select item with spacebar if input is empty and filter list items
|
|
958
947
|
case useCombobox.stateChangeTypes.InputChange: {
|
|
959
|
-
const leadingWhitespaceTest = /^\s+/g;
|
|
960
948
|
const isSpacePressedOnEmptyInput = changes.inputValue === " ";
|
|
961
|
-
if (
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
}
|
|
982
|
-
return changes;
|
|
949
|
+
if (!isSpacePressedOnEmptyInput)
|
|
950
|
+
return { ...changes, highlightedIndex: hideSelectAll ? 0 : 1 };
|
|
951
|
+
const sanitizedInputValue = (changes.inputValue ?? "").replace(
|
|
952
|
+
/^\s+/,
|
|
953
|
+
EMPTY_INPUT
|
|
954
|
+
);
|
|
955
|
+
if (!state.isOpen)
|
|
956
|
+
return {
|
|
957
|
+
...changes,
|
|
958
|
+
inputValue: sanitizedInputValue,
|
|
959
|
+
isOpen: true
|
|
960
|
+
};
|
|
961
|
+
const i = changes.highlightedIndex ?? -1;
|
|
962
|
+
if (i >= 0 && i < listItems.length)
|
|
963
|
+
return {
|
|
964
|
+
...changes,
|
|
965
|
+
inputValue: sanitizedInputValue,
|
|
966
|
+
selectedItem: listItems[i]
|
|
967
|
+
};
|
|
968
|
+
return { ...changes, inputValue: sanitizedInputValue };
|
|
983
969
|
}
|
|
984
970
|
default:
|
|
985
971
|
return changes;
|
|
986
972
|
}
|
|
987
973
|
},
|
|
988
|
-
[hideSelectAll,
|
|
974
|
+
[hideSelectAll, listItems, clearInputOnSelect]
|
|
989
975
|
);
|
|
990
976
|
const {
|
|
991
977
|
getInputProps,
|
|
@@ -994,10 +980,8 @@ const MultiSelect = React.forwardRef(
|
|
|
994
980
|
getMenuProps,
|
|
995
981
|
getToggleButtonProps,
|
|
996
982
|
highlightedIndex,
|
|
997
|
-
setHighlightedIndex,
|
|
998
983
|
inputValue,
|
|
999
|
-
isOpen
|
|
1000
|
-
setInputValue
|
|
984
|
+
isOpen
|
|
1001
985
|
} = useCombobox({
|
|
1002
986
|
defaultHighlightedIndex: lastHighlightedIndex,
|
|
1003
987
|
// after selection, highlight previously selected item.
|
|
@@ -1007,8 +991,6 @@ const MultiSelect = React.forwardRef(
|
|
|
1007
991
|
stateReducer,
|
|
1008
992
|
onInputValueChange(changes) {
|
|
1009
993
|
updateListItems({ inputValue: changes.inputValue });
|
|
1010
|
-
setHighlightedIndex(hideSelectAll ? 0 : 1);
|
|
1011
|
-
setLastHighlightedIndex(hideSelectAll ? 0 : 1);
|
|
1012
994
|
},
|
|
1013
995
|
onSelectedItemChange({ selectedItem: clickedItem }) {
|
|
1014
996
|
if (!clickedItem) return;
|
|
@@ -1017,6 +999,9 @@ const MultiSelect = React.forwardRef(
|
|
|
1017
999
|
onChange: setSelectedItems
|
|
1018
1000
|
});
|
|
1019
1001
|
},
|
|
1002
|
+
onHighlightedIndexChange: ({ highlightedIndex: highlightedIndex2 }) => {
|
|
1003
|
+
if (highlightedIndex2 >= 0) setLastHighlightedIndex(highlightedIndex2);
|
|
1004
|
+
},
|
|
1020
1005
|
// Accessibility
|
|
1021
1006
|
getA11yStatusMessage: (options) => getA11yStatusMessage({
|
|
1022
1007
|
...options,
|
|
@@ -1032,19 +1017,17 @@ const MultiSelect = React.forwardRef(
|
|
|
1032
1017
|
offset(space.extraSmall2),
|
|
1033
1018
|
shift({ padding: space.extraSmall }),
|
|
1034
1019
|
size({
|
|
1035
|
-
apply({
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
maxHeight: `${clamp(10 * 16, availableHeight, 20 * 16)}px`
|
|
1041
|
-
});
|
|
1020
|
+
apply({ elements, availableHeight }) {
|
|
1021
|
+
elements.floating.style.setProperty(
|
|
1022
|
+
"--list-max-height",
|
|
1023
|
+
`${clamp(10 * 16, availableHeight, 20 * 16)}px`
|
|
1024
|
+
);
|
|
1042
1025
|
}
|
|
1043
1026
|
}),
|
|
1044
1027
|
flip({ fallbackStrategy: "initialPlacement" })
|
|
1045
1028
|
]
|
|
1046
1029
|
});
|
|
1047
|
-
|
|
1030
|
+
useLayoutEffect(() => {
|
|
1048
1031
|
if (isOpen && refs.reference.current && refs.floating.current) {
|
|
1049
1032
|
return autoUpdate(
|
|
1050
1033
|
refs.reference.current,
|
|
@@ -1057,6 +1040,42 @@ const MultiSelect = React.forwardRef(
|
|
|
1057
1040
|
inputRef.current?.focus();
|
|
1058
1041
|
reset();
|
|
1059
1042
|
};
|
|
1043
|
+
const dropdownProps = getDropdownProps({
|
|
1044
|
+
preventKeyAction: isOpen,
|
|
1045
|
+
value: inputValue ?? EMPTY_INPUT,
|
|
1046
|
+
ref: mergeRefs(inputRef, ref)
|
|
1047
|
+
});
|
|
1048
|
+
const inputProps = getInputProps({
|
|
1049
|
+
onKeyDown: (e) => {
|
|
1050
|
+
if (selectOnTab && isOpen && e.key === "Tab") {
|
|
1051
|
+
const highlitedItem = listItems[highlightedIndex];
|
|
1052
|
+
if (!highlitedItem) return;
|
|
1053
|
+
const shouldSkipTabSelection = clickedItemIsSelectAll(highlitedItem) || !clickedItemIsSelectAll(highlitedItem) && clickedItemIsInSelectedItems(highlitedItem);
|
|
1054
|
+
if (shouldSkipTabSelection) return;
|
|
1055
|
+
handleListItemClicked({
|
|
1056
|
+
clickedItem: highlitedItem,
|
|
1057
|
+
onChange: setSelectedItems
|
|
1058
|
+
});
|
|
1059
|
+
}
|
|
1060
|
+
},
|
|
1061
|
+
onBlur,
|
|
1062
|
+
onFocus,
|
|
1063
|
+
...dropdownProps,
|
|
1064
|
+
className: "eds-dropdown__input eds-form-control",
|
|
1065
|
+
disabled: readOnly || disabled,
|
|
1066
|
+
placeholder,
|
|
1067
|
+
tabIndex: disabled || readOnly ? -1 : void 0
|
|
1068
|
+
});
|
|
1069
|
+
const labelProps = getLabelProps();
|
|
1070
|
+
const menuProps = getMenuProps({
|
|
1071
|
+
"aria-multiselectable": true,
|
|
1072
|
+
refKey: "innerRef",
|
|
1073
|
+
ref: refs.setFloating,
|
|
1074
|
+
style: listStyle
|
|
1075
|
+
});
|
|
1076
|
+
const toggleButtonProps = getToggleButtonProps({
|
|
1077
|
+
"aria-busy": !(loading ?? resolvedItemsLoading) ? void 0 : "true"
|
|
1078
|
+
});
|
|
1060
1079
|
return /* @__PURE__ */ jsxs(
|
|
1061
1080
|
BaseFormControl,
|
|
1062
1081
|
{
|
|
@@ -1071,21 +1090,14 @@ const MultiSelect = React.forwardRef(
|
|
|
1071
1090
|
feedback,
|
|
1072
1091
|
isFilled: hasSelectedItems || inputValue !== EMPTY_INPUT,
|
|
1073
1092
|
label,
|
|
1074
|
-
labelId:
|
|
1075
|
-
labelProps
|
|
1093
|
+
labelId: labelProps.id,
|
|
1094
|
+
labelProps,
|
|
1076
1095
|
labelTooltip,
|
|
1077
|
-
onBlur: (e) => {
|
|
1078
|
-
setInputValue("");
|
|
1079
|
-
onBlur?.(e);
|
|
1080
|
-
},
|
|
1081
1096
|
onClick: (e) => {
|
|
1082
|
-
if (e.target === e.currentTarget)
|
|
1083
|
-
getInputProps()?.onClick?.(e);
|
|
1084
|
-
}
|
|
1097
|
+
if (e.target === e.currentTarget) inputProps?.onClick?.(e);
|
|
1085
1098
|
onClick?.(e);
|
|
1086
1099
|
},
|
|
1087
1100
|
onKeyDown,
|
|
1088
|
-
onFocus,
|
|
1089
1101
|
readOnly,
|
|
1090
1102
|
ref: refs.setReference,
|
|
1091
1103
|
style,
|
|
@@ -1097,19 +1109,17 @@ const MultiSelect = React.forwardRef(
|
|
|
1097
1109
|
ariaLabelSelectedItem,
|
|
1098
1110
|
floatingStyles,
|
|
1099
1111
|
getItemProps,
|
|
1100
|
-
getMenuProps,
|
|
1101
1112
|
highlightedIndex,
|
|
1102
1113
|
isOpen,
|
|
1103
1114
|
listItems,
|
|
1104
|
-
style: listStyle,
|
|
1105
|
-
setListRef: refs.setFloating,
|
|
1106
1115
|
loading: loading ?? resolvedItemsLoading,
|
|
1107
1116
|
loadingText,
|
|
1108
1117
|
noMatchesText,
|
|
1109
1118
|
selectAllCheckboxState,
|
|
1110
1119
|
selectAllItem: selectAll,
|
|
1111
1120
|
selectedItems,
|
|
1112
|
-
readOnly
|
|
1121
|
+
readOnly,
|
|
1122
|
+
...menuProps
|
|
1113
1123
|
}
|
|
1114
1124
|
),
|
|
1115
1125
|
...rest,
|
|
@@ -1124,7 +1134,7 @@ const MultiSelect = React.forwardRef(
|
|
|
1124
1134
|
}
|
|
1125
1135
|
),
|
|
1126
1136
|
children: [
|
|
1127
|
-
selectedItems.length > 1 ? /* @__PURE__ */ jsx(VisuallyHidden, { onClick: inputRef.current?.focus, children: ariaLabelJumpToInput }) : null,
|
|
1137
|
+
selectedItems.length > 1 ? /* @__PURE__ */ jsx(VisuallyHidden, { onClick: () => inputRef.current?.focus(), children: ariaLabelJumpToInput }) : null,
|
|
1128
1138
|
selectedItems.length <= maxChips ? selectedItems.map((selectedItem, index) => /* @__PURE__ */ jsx(
|
|
1129
1139
|
SelectedItemTag,
|
|
1130
1140
|
{
|
|
@@ -1152,43 +1162,14 @@ const MultiSelect = React.forwardRef(
|
|
|
1152
1162
|
selectedItem: summarySelectedItems
|
|
1153
1163
|
}
|
|
1154
1164
|
),
|
|
1155
|
-
/* @__PURE__ */ jsx(
|
|
1156
|
-
"input",
|
|
1157
|
-
{
|
|
1158
|
-
...getInputProps({
|
|
1159
|
-
onKeyDown: (e) => {
|
|
1160
|
-
if (selectOnTab && isOpen && e.key === "Tab") {
|
|
1161
|
-
const highlitedItem = listItems[highlightedIndex];
|
|
1162
|
-
if (!highlitedItem) return;
|
|
1163
|
-
const shouldSkipTabSelection = clickedItemIsSelectAll(highlitedItem) || !clickedItemIsSelectAll(highlitedItem) && clickedItemIsInSelectedItems(highlitedItem);
|
|
1164
|
-
if (shouldSkipTabSelection) return;
|
|
1165
|
-
handleListItemClicked({
|
|
1166
|
-
clickedItem: highlitedItem,
|
|
1167
|
-
onChange: setSelectedItems
|
|
1168
|
-
});
|
|
1169
|
-
}
|
|
1170
|
-
},
|
|
1171
|
-
...getDropdownProps({
|
|
1172
|
-
preventKeyAction: isOpen,
|
|
1173
|
-
value: inputValue ?? EMPTY_INPUT,
|
|
1174
|
-
ref: mergeRefs(inputRef, ref)
|
|
1175
|
-
}),
|
|
1176
|
-
className: "eds-dropdown__input eds-form-control",
|
|
1177
|
-
disabled: readOnly || disabled,
|
|
1178
|
-
placeholder,
|
|
1179
|
-
tabIndex: disabled || readOnly ? -1 : void 0
|
|
1180
|
-
})
|
|
1181
|
-
}
|
|
1182
|
-
)
|
|
1165
|
+
/* @__PURE__ */ jsx("input", { ...inputProps })
|
|
1183
1166
|
]
|
|
1184
1167
|
}
|
|
1185
1168
|
),
|
|
1186
1169
|
/* @__PURE__ */ jsx(
|
|
1187
1170
|
DropdownFieldAppendix,
|
|
1188
1171
|
{
|
|
1189
|
-
...
|
|
1190
|
-
"aria-busy": !(loading ?? resolvedItemsLoading) ? void 0 : "true"
|
|
1191
|
-
}),
|
|
1172
|
+
...toggleButtonProps,
|
|
1192
1173
|
ariaLabelCloseList,
|
|
1193
1174
|
ariaLabelOpenList,
|
|
1194
1175
|
clearable,
|
|
@@ -1231,7 +1212,6 @@ const Dropdown = React.forwardRef(
|
|
|
1231
1212
|
prepend,
|
|
1232
1213
|
readOnly = false,
|
|
1233
1214
|
selectedItem,
|
|
1234
|
-
selectOnBlur = false,
|
|
1235
1215
|
selectOnTab = false,
|
|
1236
1216
|
style,
|
|
1237
1217
|
variant = "information",
|
|
@@ -1252,22 +1232,20 @@ const Dropdown = React.forwardRef(
|
|
|
1252
1232
|
items: normalizedItems,
|
|
1253
1233
|
defaultHighlightedIndex: selectedItem ? void 0 : 0,
|
|
1254
1234
|
selectedItem,
|
|
1255
|
-
stateReducer(
|
|
1235
|
+
stateReducer(state, { changes, type }) {
|
|
1256
1236
|
const toggleButtonIsFocused = typeof document !== "undefined" && document.activeElement === refs.reference.current;
|
|
1257
1237
|
switch (type) {
|
|
1258
1238
|
case useSelect.stateChangeTypes.ToggleButtonKeyDownArrowDown:
|
|
1259
1239
|
case useSelect.stateChangeTypes.ToggleButtonKeyDownArrowUp:
|
|
1260
1240
|
if (!toggleButtonIsFocused) return { ...changes, isOpen: false };
|
|
1241
|
+
break;
|
|
1242
|
+
case useSelect.stateChangeTypes.ToggleButtonBlur:
|
|
1243
|
+
return { ...changes, selectedItem: state.selectedItem };
|
|
1261
1244
|
}
|
|
1262
1245
|
return changes;
|
|
1263
1246
|
},
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
case useSelect.stateChangeTypes.ToggleButtonBlur:
|
|
1267
|
-
if (!selectOnBlur) return;
|
|
1268
|
-
}
|
|
1269
|
-
if (newSelectedItem === void 0) return;
|
|
1270
|
-
onChange?.(newSelectedItem ?? null);
|
|
1247
|
+
onSelectedItemChange({ selectedItem: newSelectedItem }) {
|
|
1248
|
+
onChange?.(newSelectedItem);
|
|
1271
1249
|
},
|
|
1272
1250
|
itemToString
|
|
1273
1251
|
});
|
|
@@ -1278,19 +1256,17 @@ const Dropdown = React.forwardRef(
|
|
|
1278
1256
|
offset(space.extraSmall2),
|
|
1279
1257
|
shift({ padding: space.extraSmall }),
|
|
1280
1258
|
size({
|
|
1281
|
-
apply({
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
maxHeight: `${clamp(10 * 16, availableHeight, 20 * 16)}px`
|
|
1287
|
-
});
|
|
1259
|
+
apply({ elements, availableHeight }) {
|
|
1260
|
+
elements.floating.style.setProperty(
|
|
1261
|
+
"--list-max-height",
|
|
1262
|
+
`${clamp(10 * 16, availableHeight, 20 * 16)}px`
|
|
1263
|
+
);
|
|
1288
1264
|
}
|
|
1289
1265
|
}),
|
|
1290
1266
|
flip({ fallbackStrategy: "initialPlacement" })
|
|
1291
1267
|
]
|
|
1292
1268
|
});
|
|
1293
|
-
|
|
1269
|
+
useLayoutEffect(() => {
|
|
1294
1270
|
if (isOpen && refs.reference.current && refs.floating.current) {
|
|
1295
1271
|
return autoUpdate(
|
|
1296
1272
|
refs.reference.current,
|
|
@@ -1300,9 +1276,35 @@ const Dropdown = React.forwardRef(
|
|
|
1300
1276
|
}
|
|
1301
1277
|
}, [isOpen, refs.reference, refs.floating, update]);
|
|
1302
1278
|
const handleOnClear = () => {
|
|
1303
|
-
reset();
|
|
1304
1279
|
refs.reference.current?.focus();
|
|
1280
|
+
reset();
|
|
1305
1281
|
};
|
|
1282
|
+
const labelProps = getLabelProps({
|
|
1283
|
+
isFilled
|
|
1284
|
+
});
|
|
1285
|
+
const toggleButtonProps = getToggleButtonProps({
|
|
1286
|
+
ref: mergeRefs(ref, refs.setReference),
|
|
1287
|
+
"aria-disabled": disabled,
|
|
1288
|
+
"aria-label": disabled ? "Disabled dropdown" : "",
|
|
1289
|
+
disabled,
|
|
1290
|
+
readOnly,
|
|
1291
|
+
label,
|
|
1292
|
+
labelId: labelProps?.id,
|
|
1293
|
+
tabIndex: disabled || readOnly ? -1 : 0,
|
|
1294
|
+
onKeyDown(e) {
|
|
1295
|
+
if (isOpen && e.key === "Tab") {
|
|
1296
|
+
const highlitedItem = normalizedItems[highlightedIndex];
|
|
1297
|
+
if (selectOnTab && highlitedItem && highlitedItem !== selectedItem) {
|
|
1298
|
+
selectItem(highlitedItem);
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
});
|
|
1303
|
+
const menuProps = getMenuProps({
|
|
1304
|
+
refKey: "innerRef",
|
|
1305
|
+
ref: refs.setFloating,
|
|
1306
|
+
style: listStyle
|
|
1307
|
+
});
|
|
1306
1308
|
return /* @__PURE__ */ jsxs(
|
|
1307
1309
|
BaseFormControl,
|
|
1308
1310
|
{
|
|
@@ -1311,31 +1313,12 @@ const Dropdown = React.forwardRef(
|
|
|
1311
1313
|
}),
|
|
1312
1314
|
disableLabelAnimation,
|
|
1313
1315
|
feedback,
|
|
1314
|
-
|
|
1315
|
-
labelProps: getLabelProps(),
|
|
1316
|
+
labelProps,
|
|
1316
1317
|
labelTooltip,
|
|
1317
1318
|
prepend,
|
|
1318
1319
|
style,
|
|
1319
1320
|
variant,
|
|
1320
|
-
...
|
|
1321
|
-
ref: mergeRefs(ref, refs.setReference),
|
|
1322
|
-
"aria-disabled": disabled,
|
|
1323
|
-
"aria-label": disabled ? "Disabled dropdown" : "",
|
|
1324
|
-
disabled,
|
|
1325
|
-
readOnly,
|
|
1326
|
-
label,
|
|
1327
|
-
labelId: getLabelProps()?.id,
|
|
1328
|
-
children: void 0,
|
|
1329
|
-
tabIndex: disabled || readOnly ? -1 : 0,
|
|
1330
|
-
onKeyDown(e) {
|
|
1331
|
-
if (isOpen && e.key === "Tab") {
|
|
1332
|
-
const highlitedItem = normalizedItems[highlightedIndex];
|
|
1333
|
-
if ((selectOnTab || selectOnBlur) && highlitedItem && highlitedItem !== selectedItem) {
|
|
1334
|
-
selectItem(highlitedItem);
|
|
1335
|
-
}
|
|
1336
|
-
}
|
|
1337
|
-
}
|
|
1338
|
-
}),
|
|
1321
|
+
...toggleButtonProps,
|
|
1339
1322
|
after: /* @__PURE__ */ jsx(
|
|
1340
1323
|
DropdownList,
|
|
1341
1324
|
{
|
|
@@ -1343,17 +1326,15 @@ const Dropdown = React.forwardRef(
|
|
|
1343
1326
|
ariaLabelSelectedItem,
|
|
1344
1327
|
floatingStyles,
|
|
1345
1328
|
getItemProps,
|
|
1346
|
-
getMenuProps,
|
|
1347
1329
|
highlightedIndex,
|
|
1348
1330
|
isOpen,
|
|
1349
1331
|
listItems: normalizedItems,
|
|
1350
|
-
noMatchesText,
|
|
1351
|
-
style: listStyle,
|
|
1352
|
-
setListRef: refs.setFloating,
|
|
1353
1332
|
loading: loading ?? resolvedItemsLoading,
|
|
1354
1333
|
loadingText,
|
|
1334
|
+
noMatchesText,
|
|
1355
1335
|
selectedItems: selectedItem !== null ? [selectedItem] : [],
|
|
1356
|
-
readOnly
|
|
1336
|
+
readOnly,
|
|
1337
|
+
...menuProps
|
|
1357
1338
|
}
|
|
1358
1339
|
),
|
|
1359
1340
|
...rest,
|