@entur/dropdown 7.3.8 → 7.3.9-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.
@@ -55,7 +55,7 @@ export type MultiSelectProps<ValueType> = Omit<DropdownProps<ValueType>, 'select
55
55
  /** Callback som kalles når brukeren går ut av input-feltet */
56
56
  onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
57
57
  /** Callback når komponenten klikkes */
58
- onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
58
+ onClick?: (event: React.MouseEvent<HTMLElement>) => void;
59
59
  /** Callback når en tast trykkes */
60
60
  onKeyDown?: (event: React.KeyboardEvent<HTMLDivElement>) => void;
61
61
  /** Callback når komponenten får fokus */
@@ -115,7 +115,7 @@ export declare const MultiSelect: <ValueType extends unknown>(props: Omit<Dropdo
115
115
  /** Callback som kalles når brukeren går ut av input-feltet */
116
116
  onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
117
117
  /** Callback når komponenten klikkes */
118
- onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
118
+ onClick?: (event: React.MouseEvent<HTMLElement>) => void;
119
119
  /** Callback når en tast trykkes */
120
120
  onKeyDown?: (event: React.KeyboardEvent<HTMLDivElement>) => void;
121
121
  /** Callback når komponenten får fokus */
@@ -17,7 +17,7 @@ export type SearchableDropdownProps<ValueType> = DropdownProps<ValueType> & {
17
17
  /** Callback som kalles når brukeren går ut av input-feltet */
18
18
  onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
19
19
  /** Callback når komponenten klikkes */
20
- onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
20
+ onClick?: (event: React.MouseEvent<HTMLElement>) => void;
21
21
  /** Callback når en tast trykkes */
22
22
  onKeyDown?: (event: React.KeyboardEvent<HTMLDivElement>) => void;
23
23
  /** Callback når komponenten får fokus */
@@ -39,7 +39,7 @@ export declare const SearchableDropdown: <ValueType extends unknown>(props: Drop
39
39
  /** Callback som kalles når brukeren går ut av input-feltet */
40
40
  onBlur?: (event: React.FocusEvent<HTMLInputElement>) => void;
41
41
  /** Callback når komponenten klikkes */
42
- onClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
42
+ onClick?: (event: React.MouseEvent<HTMLElement>) => void;
43
43
  /** Callback når en tast trykkes */
44
44
  onKeyDown?: (event: React.KeyboardEvent<HTMLDivElement>) => void;
45
45
  /** Callback når komponenten får fokus */
@@ -1,10 +1,9 @@
1
- import { default as React } from 'react';
1
+ import { default as React, MutableRefObject } from 'react';
2
2
  import { UseComboboxPropGetters, UseSelectPropGetters } from 'downshift';
3
3
  import { NormalizedDropdownItemType } from '../types';
4
4
  type DropdownListProps<ValueType> = {
5
5
  ariaLabelChosenSingular?: string;
6
6
  ariaLabelSelectedItem?: string;
7
- getMenuProps: UseComboboxPropGetters<ValueType>['getMenuProps'] | UseSelectPropGetters<ValueType>['getMenuProps'];
8
7
  getItemProps: UseComboboxPropGetters<ValueType>['getItemProps'] | UseSelectPropGetters<ValueType>['getItemProps'];
9
8
  highlightedIndex: number;
10
9
  isOpen: boolean;
@@ -12,15 +11,15 @@ type DropdownListProps<ValueType> = {
12
11
  floatingStyles: {
13
12
  [key: string]: any;
14
13
  } | undefined;
15
- setListRef: (node: HTMLElement | null) => void;
14
+ innerRef?: MutableRefObject<HTMLUListElement> | ((node: HTMLElement | null) => void);
16
15
  loading?: boolean;
17
16
  loadingText?: string;
18
17
  noMatchesText?: string;
19
- selectAllCheckboxState?: () => boolean | 'indeterminate';
18
+ selectAllCheckboxState?: boolean | 'indeterminate';
20
19
  selectAllItem?: NormalizedDropdownItemType<string>;
21
20
  selectedItems: NormalizedDropdownItemType<ValueType>[];
22
21
  style?: React.CSSProperties;
23
22
  readOnly?: boolean;
24
23
  };
25
- export declare const DropdownList: <ValueType extends unknown>({ ariaLabelChosenSingular, ariaLabelSelectedItem, getItemProps, getMenuProps, isOpen, highlightedIndex, listItems, floatingStyles, setListRef, loading, loadingText, noMatchesText, selectAllCheckboxState, selectAllItem, selectedItems, readOnly, ...rest }: DropdownListProps<ValueType>) => React.JSX.Element;
24
+ export declare const DropdownList: <ValueType extends unknown>({ ariaLabelChosenSingular, ariaLabelSelectedItem, getItemProps, isOpen, highlightedIndex, listItems, floatingStyles, innerRef, loading, loadingText, noMatchesText, readOnly, selectAllCheckboxState, selectAllItem, selectedItems, style, ...rest }: DropdownListProps<ValueType>) => React.JSX.Element;
26
25
  export {};
@@ -18,19 +18,19 @@ const DropdownList = ({
18
18
  ariaLabelChosenSingular = "valgt",
19
19
  ariaLabelSelectedItem = ", valgt element, trykk for å fjerne",
20
20
  getItemProps,
21
- getMenuProps,
22
21
  isOpen,
23
22
  highlightedIndex,
24
23
  listItems,
25
24
  floatingStyles,
26
- setListRef,
25
+ innerRef,
27
26
  loading = false,
28
27
  loadingText = "Laster inn …",
29
28
  noMatchesText = "Ingen treff for søket",
29
+ readOnly = false,
30
30
  selectAllCheckboxState,
31
31
  selectAllItem,
32
32
  selectedItems,
33
- readOnly = false,
33
+ style,
34
34
  ...rest
35
35
  }) => {
36
36
  const isMultiselect = selectAllItem !== void 0;
@@ -43,7 +43,7 @@ const DropdownList = ({
43
43
  return true;
44
44
  });
45
45
  const ariaValuesSelectAll = () => {
46
- switch (selectAllCheckboxState?.()) {
46
+ switch (selectAllCheckboxState) {
47
47
  case "indeterminate": {
48
48
  return {
49
49
  label: `${selectAllItem?.label}, delvis valgt`,
@@ -66,7 +66,7 @@ const DropdownList = ({
66
66
  form.Checkbox,
67
67
  {
68
68
  "aria-hidden": "true",
69
- checked: selectAllCheckboxState?.(),
69
+ checked: selectAllCheckboxState,
70
70
  className: "eds-dropdown__list__item__checkbox",
71
71
  tabIndex: -1,
72
72
  onChange: () => void 0
@@ -113,75 +113,68 @@ const DropdownList = ({
113
113
  }) : null
114
114
  ] });
115
115
  };
116
- return (
117
- // use popover from @entur/tooltip when that package upgrades to floating-ui
118
- /* @__PURE__ */ jsxRuntime.jsx(
119
- "ul",
120
- {
121
- ...getMenuProps({
122
- "aria-multiselectable": isMultiselect,
123
- ref: setListRef,
124
- className: "eds-dropdown__list",
125
- style: {
126
- ...floatingStyles,
127
- display: isOpen && !readOnly ? void 0 : "none",
128
- ...rest.style
129
- }
130
- }),
131
- children: (() => {
132
- if (!isOpen || readOnly) {
133
- return null;
134
- }
135
- if (loading) {
136
- return /* @__PURE__ */ jsxRuntime.jsx(
137
- "li",
138
- {
139
- className: "eds-dropdown__list__item",
140
- children: loadingText
141
- },
142
- "dropdown-list-loading"
143
- );
144
- }
145
- if (isNoMatches) {
146
- return /* @__PURE__ */ jsxRuntime.jsx(
147
- "li",
148
- {
149
- className: "eds-dropdown__list__item",
150
- children: noMatchesText
151
- },
152
- "dropdown-list-no-match"
153
- );
154
- }
155
- return listItems.map((item, index) => {
156
- const key = item.itemKey ?? `${item.label ?? ""}-${item.value ?? ""}-${(item.icons ?? []).map((icon) => icon?.displayName ?? icon?.name ?? "unknown").join("-")}`;
157
- const itemIsSelectAll = item.value === selectAllItem?.value;
158
- if (itemIsSelectAll && listItems.length <= 2) return null;
159
- return /* @__PURE__ */ jsxRuntime.jsx(
160
- "li",
161
- {
162
- className: classNames("eds-dropdown__list__item", {
163
- "eds-dropdown__list__item--select-all": itemIsSelectAll,
164
- "eds-dropdown__list__item--highlighted": highlightedIndex === index,
165
- "eds-dropdown__list__item--selected": !isMultiselect && isItemSelected(item)
166
- }),
167
- ...getItemProps({
168
- // @ts-expect-error Since getItemProps expects the same item type
169
- // here as items, it throws error when selectAllItem is a string.
170
- // This does, however, not cause any functional issues.
171
- item,
172
- index,
173
- "aria-selected": itemIsSelectAll ? ariaValuesSelectAll().selected : isItemSelected(item)
174
- }),
175
- children: itemIsSelectAll ? selectAllListItemContent() : listItemContent(
176
- item
177
- )
178
- },
179
- key
180
- );
181
- });
182
- })()
183
- }
184
- )
116
+ return /* @__PURE__ */ jsxRuntime.jsx(
117
+ "ul",
118
+ {
119
+ className: "eds-dropdown__list",
120
+ ref: innerRef,
121
+ style: {
122
+ display: isOpen && !readOnly ? void 0 : "none",
123
+ ...floatingStyles,
124
+ ...style
125
+ },
126
+ ...rest,
127
+ children: (() => {
128
+ if (!isOpen || readOnly) return null;
129
+ if (loading) {
130
+ return /* @__PURE__ */ jsxRuntime.jsx(
131
+ "li",
132
+ {
133
+ className: "eds-dropdown__list__item",
134
+ children: loadingText
135
+ },
136
+ "dropdown-list-loading"
137
+ );
138
+ }
139
+ if (isNoMatches) {
140
+ return /* @__PURE__ */ jsxRuntime.jsx(
141
+ "li",
142
+ {
143
+ className: "eds-dropdown__list__item",
144
+ children: noMatchesText
145
+ },
146
+ "dropdown-list-no-match"
147
+ );
148
+ }
149
+ return listItems.map((item, index) => {
150
+ const key = item.itemKey ?? `${item.label ?? ""}-${item.value ?? ""}-${(item.icons ?? []).map((icon) => icon?.displayName ?? icon?.name ?? "unknown").join("-")}`;
151
+ const itemIsSelectAll = item.value === selectAllItem?.value;
152
+ if (itemIsSelectAll && listItems.length <= 2) return null;
153
+ return /* @__PURE__ */ jsxRuntime.jsx(
154
+ "li",
155
+ {
156
+ className: classNames("eds-dropdown__list__item", {
157
+ "eds-dropdown__list__item--select-all": itemIsSelectAll,
158
+ "eds-dropdown__list__item--highlighted": highlightedIndex === index,
159
+ "eds-dropdown__list__item--selected": !isMultiselect && isItemSelected(item)
160
+ }),
161
+ ...getItemProps({
162
+ // @ts-expect-error Since getItemProps expects the same item type
163
+ // here as items, it throws error when selectAllItem is a string.
164
+ // This does, however, not cause any functional issues.
165
+ item,
166
+ index,
167
+ "aria-selected": itemIsSelectAll ? ariaValuesSelectAll().selected : isItemSelected(item)
168
+ }),
169
+ children: itemIsSelectAll ? selectAllListItemContent() : listItemContent(
170
+ item
171
+ )
172
+ },
173
+ key
174
+ );
175
+ });
176
+ })()
177
+ }
185
178
  );
186
179
  };
187
180
  const SelectedItemTag = ({
@@ -457,11 +450,11 @@ const useMultiselectUtils = ({
457
450
  (selectedItem) => selectedItem.value !== clickedItem.value
458
451
  )
459
452
  );
460
- const selectAllCheckboxState = () => {
453
+ const selectAllCheckboxState = React.useMemo(() => {
461
454
  if (allListItemsAreSelected) return true;
462
455
  if (someListItemsAreSelected) return "indeterminate";
463
456
  return false;
464
- };
457
+ }, [allListItemsAreSelected, someListItemsAreSelected]);
465
458
  const selectAllUnselectedItemsInListItems = (onChange) => {
466
459
  onChange([...selectedItems, ...unselectedItemsInListItems]);
467
460
  };
@@ -555,7 +548,6 @@ const SearchableDropdown = React.forwardRef(
555
548
  const resetInputState = ({
556
549
  changes
557
550
  }) => {
558
- updateListItems({ inputValue: EMPTY_INPUT });
559
551
  return {
560
552
  ...changes,
561
553
  inputValue: EMPTY_INPUT
@@ -584,11 +576,12 @@ const SearchableDropdown = React.forwardRef(
584
576
  // empty input to show selected item and reset dropdown list on item selection
585
577
  case downshift.useCombobox.stateChangeTypes.ItemClick:
586
578
  case downshift.useCombobox.stateChangeTypes.InputKeyDownEnter:
587
- case downshift.useCombobox.stateChangeTypes.InputBlur:
588
579
  return resetInputState({ changes });
580
+ case downshift.useCombobox.stateChangeTypes.InputBlur:
581
+ return resetInputState({
582
+ changes: { ...changes, selectedItem: value }
583
+ });
589
584
  case downshift.useCombobox.stateChangeTypes.ControlledPropUpdatedSelectedItem:
590
- if (changes.selectedItem !== null && !inputHasFocus)
591
- setShowSelectedItem(true);
592
585
  return resetInputState({ changes });
593
586
  // remove leading whitespace, select element with spacebar on empty input
594
587
  case downshift.useCombobox.stateChangeTypes.InputChange: {
@@ -659,19 +652,17 @@ const SearchableDropdown = React.forwardRef(
659
652
  reactDom.offset(tokens.space.extraSmall2),
660
653
  reactDom.shift({ padding: tokens.space.extraSmall }),
661
654
  reactDom.size({
662
- apply({ rects, elements, availableHeight }) {
663
- Object.assign(elements.floating.style, {
664
- width: `${rects.reference.width}px`,
665
- // Floating will flip when smaller than 10*16 px
666
- // and never exceed 20*16 px.
667
- maxHeight: `${clamp(10 * 16, availableHeight, 20 * 16)}px`
668
- });
655
+ apply({ elements, availableHeight }) {
656
+ elements.floating.style.setProperty(
657
+ "--list-max-height",
658
+ `${clamp(10 * 16, availableHeight, 20 * 16)}px`
659
+ );
669
660
  }
670
661
  }),
671
662
  reactDom.flip({ fallbackStrategy: "initialPlacement" })
672
663
  ]
673
664
  });
674
- React.useEffect(() => {
665
+ React.useLayoutEffect(() => {
675
666
  if (isOpen && refs.reference.current && refs.floating.current) {
676
667
  return reactDom.autoUpdate(
677
668
  refs.reference.current,
@@ -702,9 +693,7 @@ const SearchableDropdown = React.forwardRef(
702
693
  labelProps: getLabelProps(),
703
694
  labelTooltip,
704
695
  onClick: (e) => {
705
- if (e.target === e.currentTarget) {
706
- getInputProps()?.onClick?.(e);
707
- }
696
+ if (e.target === e.currentTarget) getInputProps()?.onClick?.(e);
708
697
  onClick?.(e);
709
698
  },
710
699
  onKeyDown,
@@ -722,17 +711,19 @@ const SearchableDropdown = React.forwardRef(
722
711
  ariaLabelSelectedItem,
723
712
  floatingStyles,
724
713
  getItemProps,
725
- getMenuProps,
726
714
  highlightedIndex,
727
715
  isOpen,
728
716
  listItems,
729
- style: listStyle,
730
- setListRef: refs.setFloating,
731
717
  loading: loading ?? resolvedItemsLoading,
732
718
  loadingText,
733
719
  noMatchesText,
734
720
  selectedItems: selectedItem !== null ? [selectedItem] : [],
735
- readOnly
721
+ readOnly,
722
+ ...getMenuProps({
723
+ refKey: "innerRef",
724
+ ref: refs.setFloating,
725
+ style: listStyle
726
+ })
736
727
  }
737
728
  ),
738
729
  ...rest,
@@ -764,8 +755,9 @@ const SearchableDropdown = React.forwardRef(
764
755
  onKeyDown(e) {
765
756
  if (isOpen && e.key === "Tab") {
766
757
  const highlitedItem = listItems[highlightedIndex];
767
- if ((selectOnTab || selectOnBlur) && highlitedItem && highlitedItem !== selectedItem) {
758
+ if ((selectOnTab || selectOnBlur) && highlitedItem) {
768
759
  selectItem(highlitedItem);
760
+ setShowSelectedItem(true);
769
761
  }
770
762
  }
771
763
  },
@@ -887,15 +879,21 @@ const MultiSelect = React.forwardRef(
887
879
  ...!hideSelectAll ? [selectAll] : [],
888
880
  ...normalizedItems
889
881
  ]);
890
- const filterListItems = ({ inputValue: inputValue2 }) => setListItems([
891
- ...!hideSelectAll ? [selectAll] : [],
892
- ...normalizedItems.filter((item) => itemFilter(item, inputValue2))
893
- ]);
894
- const updateListItems = ({ inputValue: inputValue2 }) => {
895
- const shouldRefetchItems = isFunctionWithQueryArgument(initialItems);
896
- if (shouldRefetchItems) fetchItems(inputValue2 ?? EMPTY_INPUT);
897
- filterListItems({ inputValue: inputValue2 ?? EMPTY_INPUT });
898
- };
882
+ const filterListItems = React.useCallback(
883
+ ({ inputValue: inputValue2 }) => setListItems([
884
+ ...!hideSelectAll ? [selectAll] : [],
885
+ ...normalizedItems.filter((item) => itemFilter(item, inputValue2))
886
+ ]),
887
+ [hideSelectAll, selectAll, normalizedItems, itemFilter]
888
+ );
889
+ const updateListItems = React.useCallback(
890
+ ({ inputValue: inputValue2 }) => {
891
+ const shouldRefetchItems = isFunctionWithQueryArgument(initialItems);
892
+ if (shouldRefetchItems) fetchItems(inputValue2 ?? EMPTY_INPUT);
893
+ filterListItems({ inputValue: inputValue2 ?? EMPTY_INPUT });
894
+ },
895
+ [filterListItems, initialItems, fetchItems]
896
+ );
899
897
  React.useEffect(() => {
900
898
  filterListItems({ inputValue });
901
899
  }, [normalizedItems]);
@@ -960,6 +958,8 @@ const MultiSelect = React.forwardRef(
960
958
  case downshift.useCombobox.stateChangeTypes.InputChange: {
961
959
  const leadingWhitespaceTest = /^\s+/g;
962
960
  const isSpacePressedOnEmptyInput = changes.inputValue === " ";
961
+ if (!isSpacePressedOnEmptyInput)
962
+ setLastHighlightedIndex(hideSelectAll ? 0 : 1);
963
963
  if (changes.inputValue?.match(leadingWhitespaceTest)) {
964
964
  const sanitizedInputValue = changes.inputValue.replace(
965
965
  leadingWhitespaceTest,
@@ -981,13 +981,13 @@ const MultiSelect = React.forwardRef(
981
981
  }
982
982
  }
983
983
  }
984
- return changes;
984
+ return { ...changes, highlightedIndex: hideSelectAll ? 0 : 1 };
985
985
  }
986
986
  default:
987
987
  return changes;
988
988
  }
989
989
  },
990
- [hideSelectAll, normalizedItems, filterListItems, initialItems]
990
+ [hideSelectAll, normalizedItems, initialItems]
991
991
  );
992
992
  const {
993
993
  getInputProps,
@@ -996,7 +996,6 @@ const MultiSelect = React.forwardRef(
996
996
  getMenuProps,
997
997
  getToggleButtonProps,
998
998
  highlightedIndex,
999
- setHighlightedIndex,
1000
999
  inputValue,
1001
1000
  isOpen,
1002
1001
  setInputValue
@@ -1009,8 +1008,6 @@ const MultiSelect = React.forwardRef(
1009
1008
  stateReducer,
1010
1009
  onInputValueChange(changes) {
1011
1010
  updateListItems({ inputValue: changes.inputValue });
1012
- setHighlightedIndex(hideSelectAll ? 0 : 1);
1013
- setLastHighlightedIndex(hideSelectAll ? 0 : 1);
1014
1011
  },
1015
1012
  onSelectedItemChange({ selectedItem: clickedItem }) {
1016
1013
  if (!clickedItem) return;
@@ -1034,19 +1031,17 @@ const MultiSelect = React.forwardRef(
1034
1031
  reactDom.offset(tokens.space.extraSmall2),
1035
1032
  reactDom.shift({ padding: tokens.space.extraSmall }),
1036
1033
  reactDom.size({
1037
- apply({ rects, elements, availableHeight }) {
1038
- Object.assign(elements.floating.style, {
1039
- width: `${rects.reference.width}px`,
1040
- // Floating will flip when smaller than 10*16 px
1041
- // and never exceed 20*16 px.
1042
- maxHeight: `${clamp(10 * 16, availableHeight, 20 * 16)}px`
1043
- });
1034
+ apply({ elements, availableHeight }) {
1035
+ elements.floating.style.setProperty(
1036
+ "--list-max-height",
1037
+ `${clamp(10 * 16, availableHeight, 20 * 16)}px`
1038
+ );
1044
1039
  }
1045
1040
  }),
1046
1041
  reactDom.flip({ fallbackStrategy: "initialPlacement" })
1047
1042
  ]
1048
1043
  });
1049
- React.useEffect(() => {
1044
+ React.useLayoutEffect(() => {
1050
1045
  if (isOpen && refs.reference.current && refs.floating.current) {
1051
1046
  return reactDom.autoUpdate(
1052
1047
  refs.reference.current,
@@ -1076,14 +1071,8 @@ const MultiSelect = React.forwardRef(
1076
1071
  labelId: getLabelProps().id,
1077
1072
  labelProps: getLabelProps(),
1078
1073
  labelTooltip,
1079
- onBlur: (e) => {
1080
- setInputValue("");
1081
- onBlur?.(e);
1082
- },
1083
1074
  onClick: (e) => {
1084
- if (e.target === e.currentTarget) {
1085
- getInputProps()?.onClick?.(e);
1086
- }
1075
+ if (e.target === e.currentTarget) getInputProps()?.onClick?.(e);
1087
1076
  onClick?.(e);
1088
1077
  },
1089
1078
  onKeyDown,
@@ -1099,19 +1088,22 @@ const MultiSelect = React.forwardRef(
1099
1088
  ariaLabelSelectedItem,
1100
1089
  floatingStyles,
1101
1090
  getItemProps,
1102
- getMenuProps,
1103
1091
  highlightedIndex,
1104
1092
  isOpen,
1105
1093
  listItems,
1106
- style: listStyle,
1107
- setListRef: refs.setFloating,
1108
1094
  loading: loading ?? resolvedItemsLoading,
1109
1095
  loadingText,
1110
1096
  noMatchesText,
1111
1097
  selectAllCheckboxState,
1112
1098
  selectAllItem: selectAll,
1113
1099
  selectedItems,
1114
- readOnly
1100
+ readOnly,
1101
+ ...getMenuProps({
1102
+ "aria-multiselectable": true,
1103
+ refKey: "innerRef",
1104
+ ref: refs.setFloating,
1105
+ style: listStyle
1106
+ })
1115
1107
  }
1116
1108
  ),
1117
1109
  ...rest,
@@ -1170,6 +1162,10 @@ const MultiSelect = React.forwardRef(
1170
1162
  });
1171
1163
  }
1172
1164
  },
1165
+ onBlur: (e) => {
1166
+ setInputValue("");
1167
+ onBlur?.(e);
1168
+ },
1173
1169
  ...getDropdownProps({
1174
1170
  preventKeyAction: isOpen,
1175
1171
  value: inputValue ?? EMPTY_INPUT,
@@ -1280,19 +1276,17 @@ const Dropdown = React.forwardRef(
1280
1276
  reactDom.offset(tokens.space.extraSmall2),
1281
1277
  reactDom.shift({ padding: tokens.space.extraSmall }),
1282
1278
  reactDom.size({
1283
- apply({ rects, elements, availableHeight }) {
1284
- Object.assign(elements.floating.style, {
1285
- width: `${rects.reference.width}px`,
1286
- // Floating will flip when smaller than 10*16 px
1287
- // and never exceed 20*16 px.
1288
- maxHeight: `${clamp(10 * 16, availableHeight, 20 * 16)}px`
1289
- });
1279
+ apply({ elements, availableHeight }) {
1280
+ elements.floating.style.setProperty(
1281
+ "--list-max-height",
1282
+ `${clamp(10 * 16, availableHeight, 20 * 16)}px`
1283
+ );
1290
1284
  }
1291
1285
  }),
1292
1286
  reactDom.flip({ fallbackStrategy: "initialPlacement" })
1293
1287
  ]
1294
1288
  });
1295
- React.useEffect(() => {
1289
+ React.useLayoutEffect(() => {
1296
1290
  if (isOpen && refs.reference.current && refs.floating.current) {
1297
1291
  return reactDom.autoUpdate(
1298
1292
  refs.reference.current,
@@ -1345,17 +1339,19 @@ const Dropdown = React.forwardRef(
1345
1339
  ariaLabelSelectedItem,
1346
1340
  floatingStyles,
1347
1341
  getItemProps,
1348
- getMenuProps,
1349
1342
  highlightedIndex,
1350
1343
  isOpen,
1351
1344
  listItems: normalizedItems,
1352
- noMatchesText,
1353
- style: listStyle,
1354
- setListRef: refs.setFloating,
1355
1345
  loading: loading ?? resolvedItemsLoading,
1356
1346
  loadingText,
1347
+ noMatchesText,
1357
1348
  selectedItems: selectedItem !== null ? [selectedItem] : [],
1358
- readOnly
1349
+ readOnly,
1350
+ ...getMenuProps({
1351
+ refKey: "innerRef",
1352
+ ref: refs.setFloating,
1353
+ style: listStyle
1354
+ })
1359
1355
  }
1360
1356
  ),
1361
1357
  ...rest,