@jobber/components 6.85.2 → 6.85.3-CLEANUPre-6d043f4.28

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.
Files changed (277) hide show
  1. package/dist/AtlantisThemeContext/AtlantisThemeContext.d.ts +1 -1
  2. package/dist/AtlantisThemeContext/index.d.ts +1 -1
  3. package/dist/AtlantisThemeContext/types.d.ts +17 -0
  4. package/dist/AtlantisThemeContext-cjs.js +38 -12
  5. package/dist/AtlantisThemeContext-es.js +40 -14
  6. package/dist/Autocomplete/Autocomplete.d.ts +3 -3
  7. package/dist/Autocomplete/Autocomplete.rebuilt.d.ts +8 -0
  8. package/dist/Autocomplete/Autocomplete.types.d.ts +388 -4
  9. package/dist/Autocomplete/components/MenuList.d.ts +37 -0
  10. package/dist/Autocomplete/components/PersistentRegion.d.ts +18 -0
  11. package/dist/Autocomplete/hooks/useAutocompleteListNav.d.ts +22 -0
  12. package/dist/Autocomplete/index.cjs +1335 -37
  13. package/dist/Autocomplete/index.d.ts +32 -2
  14. package/dist/Autocomplete/index.mjs +1326 -21
  15. package/dist/Autocomplete/tests/Autocomplete.setup.d.ts +38 -0
  16. package/dist/Autocomplete/useAutocomplete.d.ts +66 -0
  17. package/dist/Autocomplete/utils/menuModel.d.ts +14 -0
  18. package/dist/Banner/index.cjs +1 -6
  19. package/dist/Banner/index.mjs +1 -6
  20. package/dist/Banner-cjs.js +2 -2
  21. package/dist/Banner-es.js +2 -2
  22. package/dist/Button-cjs.js +2 -2
  23. package/dist/Button-es.js +2 -2
  24. package/dist/Card/CardClickable.d.ts +3 -1
  25. package/dist/Card/CardHeader.d.ts +1 -1
  26. package/dist/Card/index.cjs +2 -4
  27. package/dist/Card/index.mjs +2 -4
  28. package/dist/Card/types.d.ts +19 -1
  29. package/dist/Card-cjs.js +14 -13
  30. package/dist/Card-es.js +14 -13
  31. package/dist/Chip/index.cjs +2 -3
  32. package/dist/Chip/index.mjs +2 -3
  33. package/dist/Chip-cjs.js +3 -3
  34. package/dist/Chip-es.js +3 -3
  35. package/dist/Chips/InternalChipDismissible/hooks/index.cjs +2 -0
  36. package/dist/Chips/InternalChipDismissible/hooks/index.mjs +2 -0
  37. package/dist/Chips/InternalChipDismissible/index.cjs +2 -3
  38. package/dist/Chips/InternalChipDismissible/index.mjs +2 -3
  39. package/dist/Chips/index.cjs +2 -3
  40. package/dist/Chips/index.mjs +2 -3
  41. package/dist/Combobox/Combobox.types.d.ts +3 -1
  42. package/dist/Combobox/components/ComboboxActivator/index.cjs +2 -3
  43. package/dist/Combobox/components/ComboboxActivator/index.mjs +2 -3
  44. package/dist/Combobox/components/ComboboxContent/ComboboxContentList/index.cjs +1 -1
  45. package/dist/Combobox/components/ComboboxContent/ComboboxContentList/index.mjs +1 -1
  46. package/dist/Combobox/components/ComboboxContent/ComboboxLoadMore/index.cjs +1 -1
  47. package/dist/Combobox/components/ComboboxContent/ComboboxLoadMore/index.mjs +1 -1
  48. package/dist/Combobox/components/ComboboxContent/index.cjs +2 -3
  49. package/dist/Combobox/components/ComboboxContent/index.mjs +2 -3
  50. package/dist/Combobox/components/ComboboxTrigger/index.cjs +2 -3
  51. package/dist/Combobox/components/ComboboxTrigger/index.mjs +2 -3
  52. package/dist/Combobox/index.cjs +2 -6
  53. package/dist/Combobox/index.mjs +2 -6
  54. package/dist/Combobox-cjs.js +2 -2
  55. package/dist/Combobox-es.js +2 -2
  56. package/dist/ComboboxAction-cjs.js +5 -3
  57. package/dist/ComboboxAction-es.js +5 -3
  58. package/dist/ComboboxContent-cjs.js +3 -4
  59. package/dist/ComboboxContent-es.js +4 -5
  60. package/dist/ComboboxLoadMore-cjs.js +2 -2
  61. package/dist/ComboboxLoadMore-es.js +2 -2
  62. package/dist/ComboboxOption-cjs.js +1 -1
  63. package/dist/ComboboxOption-es.js +1 -1
  64. package/dist/ConfirmationModal/index.cjs +2 -4
  65. package/dist/ConfirmationModal/index.mjs +2 -4
  66. package/dist/ConfirmationModal-cjs.js +2 -2
  67. package/dist/ConfirmationModal-es.js +2 -2
  68. package/dist/ContentBlock/index.cjs +1 -6
  69. package/dist/ContentBlock/index.mjs +1 -6
  70. package/dist/ContentBlock-cjs.js +2 -2
  71. package/dist/ContentBlock-es.js +2 -2
  72. package/dist/Countdown-cjs.js +0 -1
  73. package/dist/Countdown-es.js +0 -1
  74. package/dist/DataDump/index.cjs +2 -4
  75. package/dist/DataDump/index.mjs +2 -4
  76. package/dist/DataList/components/DataListActions/index.cjs +2 -5
  77. package/dist/DataList/components/DataListActions/index.mjs +2 -5
  78. package/dist/DataList/components/DataListActionsMenu/index.cjs +1 -5
  79. package/dist/DataList/components/DataListActionsMenu/index.mjs +1 -5
  80. package/dist/DataList/components/DataListBulkActions/index.cjs +2 -5
  81. package/dist/DataList/components/DataListBulkActions/index.mjs +2 -5
  82. package/dist/DataList/components/DataListFilters/components/DataListSort/index.cjs +2 -6
  83. package/dist/DataList/components/DataListFilters/components/DataListSort/index.mjs +2 -6
  84. package/dist/DataList/components/DataListFilters/index.cjs +2 -7
  85. package/dist/DataList/components/DataListFilters/index.mjs +2 -7
  86. package/dist/DataList/components/DataListHeader/DataListHeaderCheckbox.d.ts +1 -2
  87. package/dist/DataList/components/DataListHeader/index.cjs +2 -5
  88. package/dist/DataList/components/DataListHeader/index.mjs +2 -5
  89. package/dist/DataList/components/DataListHeaderTile/components/index.cjs +1 -2
  90. package/dist/DataList/components/DataListHeaderTile/components/index.mjs +1 -2
  91. package/dist/DataList/components/DataListHeaderTile/index.cjs +1 -3
  92. package/dist/DataList/components/DataListHeaderTile/index.mjs +1 -3
  93. package/dist/DataList/components/DataListItem/index.cjs +2 -5
  94. package/dist/DataList/components/DataListItem/index.mjs +2 -5
  95. package/dist/DataList/components/DataListItemActions/index.cjs +2 -5
  96. package/dist/DataList/components/DataListItemActions/index.mjs +2 -5
  97. package/dist/DataList/components/DataListItemActionsOverflow/index.cjs +2 -5
  98. package/dist/DataList/components/DataListItemActionsOverflow/index.mjs +2 -5
  99. package/dist/DataList/components/DataListItems/index.cjs +2 -5
  100. package/dist/DataList/components/DataListItems/index.mjs +2 -5
  101. package/dist/DataList/components/DataListLayout/index.cjs +2 -5
  102. package/dist/DataList/components/DataListLayout/index.mjs +2 -5
  103. package/dist/DataList/components/DataListLayoutActions/index.cjs +2 -5
  104. package/dist/DataList/components/DataListLayoutActions/index.mjs +2 -5
  105. package/dist/DataList/components/DataListLoadMore/index.cjs +1 -1
  106. package/dist/DataList/components/DataListLoadMore/index.mjs +1 -1
  107. package/dist/DataList/components/DataListOverflowFade/index.cjs +1 -1
  108. package/dist/DataList/components/DataListOverflowFade/index.mjs +1 -1
  109. package/dist/DataList/components/DataListSearch/index.cjs +1 -2
  110. package/dist/DataList/components/DataListSearch/index.mjs +1 -2
  111. package/dist/DataList/components/DataListStatusBar/index.cjs +1 -3
  112. package/dist/DataList/components/DataListStatusBar/index.mjs +1 -3
  113. package/dist/DataList/index.cjs +2 -7
  114. package/dist/DataList/index.mjs +2 -7
  115. package/dist/DataListActionsMenu-cjs.js +5 -8
  116. package/dist/DataListActionsMenu-es.js +5 -8
  117. package/dist/DataListHeaderTile-cjs.js +2 -2
  118. package/dist/DataListHeaderTile-es.js +2 -2
  119. package/dist/DataListItem-cjs.js +2 -0
  120. package/dist/DataListItem-es.js +2 -0
  121. package/dist/DataListLoadMore-cjs.js +2 -2
  122. package/dist/DataListLoadMore-es.js +2 -2
  123. package/dist/DataListOverflowFade-cjs.js +3 -3
  124. package/dist/DataListOverflowFade-es.js +3 -3
  125. package/dist/DataListSearch-cjs.js +2 -2
  126. package/dist/DataListSearch-es.js +2 -2
  127. package/dist/DataListSortingOptions-cjs.js +3 -4
  128. package/dist/DataListSortingOptions-es.js +3 -4
  129. package/dist/DataTable/index.cjs +4 -6
  130. package/dist/DataTable/index.mjs +4 -6
  131. package/dist/DataTable/test-utilities/index.cjs +1 -7
  132. package/dist/DataTable/test-utilities/index.mjs +1 -7
  133. package/dist/DataTable-cjs.js +4 -4
  134. package/dist/DataTable-es.js +4 -4
  135. package/dist/DataTableTable-cjs.js +8 -8
  136. package/dist/DataTableTable-es.js +8 -8
  137. package/dist/DatePicker/DatePickerActivator.d.ts +2 -4
  138. package/dist/DatePicker/index.cjs +5 -3
  139. package/dist/DatePicker/index.mjs +5 -3
  140. package/dist/DatePicker-cjs.js +11478 -8531
  141. package/dist/DatePicker-es.js +11483 -8517
  142. package/dist/Disclosure/index.cjs +1 -6
  143. package/dist/Disclosure/index.mjs +1 -6
  144. package/dist/Disclosure-cjs.js +3 -3
  145. package/dist/Disclosure-es.js +3 -3
  146. package/dist/FeatureSwitch/index.cjs +1 -1
  147. package/dist/FeatureSwitch/index.mjs +1 -1
  148. package/dist/FormField/FormFieldWrapper.d.ts +1 -1
  149. package/dist/FormField/hooks/useAtlantisReactHookForm.d.ts +1 -0
  150. package/dist/FormField/index.cjs +1 -0
  151. package/dist/FormField/index.mjs +1 -0
  152. package/dist/FormField-cjs.js +2 -21
  153. package/dist/FormField-es.js +2 -21
  154. package/dist/FormatFile/index.cjs +2 -4
  155. package/dist/FormatFile/index.mjs +2 -4
  156. package/dist/Gallery/index.cjs +2 -7
  157. package/dist/Gallery/index.mjs +2 -7
  158. package/dist/Heading/Heading.d.ts +7 -1
  159. package/dist/Heading-cjs.js +2 -2
  160. package/dist/Heading-es.js +2 -2
  161. package/dist/InlineLabel/InlineLabel.d.ts +1 -1
  162. package/dist/InlineLabel-cjs.js +2 -1
  163. package/dist/InlineLabel-es.js +2 -1
  164. package/dist/InputDate/InputDate.types.d.ts +0 -12
  165. package/dist/InputDate/index.cjs +9 -30
  166. package/dist/InputDate/index.mjs +9 -30
  167. package/dist/InputEmail/index.cjs +1 -0
  168. package/dist/InputEmail/index.mjs +1 -0
  169. package/dist/InputFile/InputFile.d.ts +5 -1
  170. package/dist/InputFile-cjs.js +2 -2
  171. package/dist/InputFile-es.js +2 -2
  172. package/dist/InputNumber/index.cjs +3698 -2959
  173. package/dist/InputNumber/index.mjs +3698 -2959
  174. package/dist/InputPassword/index.cjs +1 -0
  175. package/dist/InputPassword/index.mjs +1 -0
  176. package/dist/InputPassword-cjs.js +1 -0
  177. package/dist/InputPassword-es.js +1 -0
  178. package/dist/InputPhoneNumber/InputPhoneNumber.types.d.ts +1 -1
  179. package/dist/InputPhoneNumber/index.cjs +1 -0
  180. package/dist/InputPhoneNumber/index.mjs +1 -0
  181. package/dist/InputText/InputText.d.ts +2 -2
  182. package/dist/InputText/index.cjs +3 -3
  183. package/dist/InputText/index.mjs +3 -3
  184. package/dist/InputText/useInputTextFormField.d.ts +6 -6
  185. package/dist/InputTime/index.cjs +1 -0
  186. package/dist/InputTime/index.mjs +2 -1
  187. package/dist/InternalChipDismissible-cjs.js +1 -0
  188. package/dist/InternalChipDismissible-es.js +1 -0
  189. package/dist/LightBox/index.cjs +1 -6
  190. package/dist/LightBox/index.mjs +1 -6
  191. package/dist/LightBox-cjs.js +12 -74
  192. package/dist/LightBox-es.js +12 -74
  193. package/dist/List/index.cjs +1 -1
  194. package/dist/List/index.mjs +1 -1
  195. package/dist/Markdown/index.cjs +1 -1
  196. package/dist/Markdown/index.mjs +1 -1
  197. package/dist/Markdown-cjs.js +20540 -18350
  198. package/dist/Markdown-es.js +20541 -18351
  199. package/dist/Menu/index.cjs +2 -4
  200. package/dist/Menu/index.mjs +2 -4
  201. package/dist/Menu-cjs.js +5 -37
  202. package/dist/Menu-es.js +6 -38
  203. package/dist/Modal/Modal.rebuilt.d.ts +1 -1
  204. package/dist/Modal/index.cjs +25 -22
  205. package/dist/Modal/index.mjs +26 -23
  206. package/dist/Page/index.cjs +3 -11
  207. package/dist/Page/index.mjs +3 -11
  208. package/dist/Page-cjs.js +5 -5
  209. package/dist/Page-es.js +5 -5
  210. package/dist/Popover/index.cjs +2 -1
  211. package/dist/Popover/index.mjs +2 -1
  212. package/dist/Popover/usePopover.d.ts +1 -1
  213. package/dist/Popover-cjs.js +2 -2
  214. package/dist/Popover-es.js +3 -3
  215. package/dist/RecurringSelect/index.cjs +2 -0
  216. package/dist/RecurringSelect/index.mjs +2 -0
  217. package/dist/Select/index.cjs +1 -0
  218. package/dist/Select/index.mjs +1 -0
  219. package/dist/SideDrawer/index.cjs +1 -5
  220. package/dist/SideDrawer/index.mjs +1 -5
  221. package/dist/SideDrawer-cjs.js +7 -10
  222. package/dist/SideDrawer-es.js +7 -10
  223. package/dist/Tabs/index.cjs +0 -1
  224. package/dist/Tabs/index.mjs +0 -1
  225. package/dist/Tabs-cjs.js +76 -2
  226. package/dist/Tabs-es.js +76 -2
  227. package/dist/Tooltip/index.cjs +2 -2
  228. package/dist/Tooltip/index.mjs +2 -2
  229. package/dist/Tooltip/useTooltipPositioning.d.ts +1 -1
  230. package/dist/Tooltip-cjs.js +3 -4
  231. package/dist/Tooltip-es.js +4 -5
  232. package/dist/_baseEach-es.js +1 -1
  233. package/dist/_commonjsHelpers-cjs.js +0 -26
  234. package/dist/_commonjsHelpers-es.js +1 -26
  235. package/dist/_isIterateeCall-es.js +1 -1
  236. package/dist/clsx-cjs.js +5 -0
  237. package/dist/clsx-es.js +3 -0
  238. package/dist/debounce-es.js +2 -2
  239. package/dist/floating-ui.react-cjs.js +2106 -2225
  240. package/dist/floating-ui.react-es.js +2105 -2226
  241. package/dist/helpers-cjs.js +21 -2
  242. package/dist/helpers-es.js +1 -1
  243. package/dist/index.cjs +15 -21
  244. package/dist/index.mjs +11 -17
  245. package/dist/isObjectLike-es.js +1 -1
  246. package/dist/isSymbol-es.js +1 -1
  247. package/dist/isTypedArray-es.js +1 -1
  248. package/dist/keysIn-es.js +1 -1
  249. package/dist/omit-es.js +1 -1
  250. package/dist/styles.css +719 -509
  251. package/dist/tslib.es6-cjs.js +3 -3
  252. package/dist/tslib.es6-es.js +3 -3
  253. package/dist/useScrollToActive-cjs.js +3 -45
  254. package/dist/useScrollToActive-es.js +5 -47
  255. package/dist/utils/mockLargeViewport.d.ts +33 -0
  256. package/package.json +13 -19
  257. package/rollup.config.mjs +1 -15
  258. package/dist/Autocomplete-cjs.js +0 -357
  259. package/dist/Autocomplete-es.js +0 -344
  260. package/dist/throttle-cjs.js +0 -80
  261. package/dist/throttle-es.js +0 -77
  262. package/dist/useDebounce-cjs.js +0 -4415
  263. package/dist/useDebounce-es.js +0 -4413
  264. package/dist/useFocusTrap-cjs.js +0 -75
  265. package/dist/useFocusTrap-es.js +0 -73
  266. package/dist/useInView-cjs.js +0 -26
  267. package/dist/useInView-es.js +0 -24
  268. package/dist/useIsMounted-cjs.js +0 -51
  269. package/dist/useIsMounted-es.js +0 -49
  270. package/dist/useOnKeyDown-cjs.js +0 -41
  271. package/dist/useOnKeyDown-es.js +0 -39
  272. package/dist/useRefocusOnActivator-cjs.js +0 -33
  273. package/dist/useRefocusOnActivator-es.js +0 -31
  274. package/dist/useResizeObserver-cjs.js +0 -1131
  275. package/dist/useResizeObserver-es.js +0 -1128
  276. package/dist/useSafeLayoutEffect-cjs.js +0 -14
  277. package/dist/useSafeLayoutEffect-es.js +0 -12
@@ -1,28 +1,23 @@
1
- export { A as Autocomplete, d as BaseAutocompleteMenuWrapper, a as BaseMenuGroupOption, B as BaseMenuOption, K as KeyboardAction, M as MenuOption, g as getRequestedIndexChange, f as isOptionGroup, i as isOptionSelected, e as useAutocompleteMenu, b as useCustomKeyboardNavigation, u as useKeyboardNavigation, c as useRepositionMenu } from '../Autocomplete-es.js';
2
- import '../tslib.es6-es.js';
3
- import 'react';
4
- import '../useDebounce-es.js';
5
- import 'classnames';
6
- import '../useIsMounted-es.js';
7
- import '../useSafeLayoutEffect-es.js';
8
- import '../floating-ui.react-es.js';
1
+ import React__default, { useState, useRef, useEffect, useCallback, useMemo, forwardRef } from 'react';
2
+ import { u as useFloating, c as autoUpdate, o as offset, f as flip, s as size, q as useListNavigation, a as useDismiss, b as useInteractions, r as useTransitionStyles, F as FloatingPortal, n as FloatingFocusManager } from '../floating-ui.react-es.js';
3
+ import classnames from 'classnames';
4
+ import { tokens } from '@jobber/design';
5
+ import { useCallbackRef, useDebounce, useSafeLayoutEffect, useIsMounted, useOnKeyDown } from '@jobber/hooks';
6
+ import { c as calculateMaxHeight } from '../maxHeight-es.js';
7
+ import { H as Heading } from '../Heading-es.js';
8
+ import { T as Text } from '../Text-es.js';
9
+ import { T as Typography } from '../Typography-es.js';
10
+ import { I as Icon } from '../Icon-es.js';
11
+ import { InputText } from '../InputText/index.mjs';
12
+ import { G as Glimmer } from '../Glimmer-es.js';
13
+ import { m as mergeRefs } from '../FormField-es.js';
14
+ import { _ as __rest, a as __awaiter } from '../tslib.es6-es.js';
15
+ import 'react/jsx-runtime';
9
16
  import 'react-dom';
10
- import '../maxHeight-es.js';
11
- import '@jobber/design';
12
- import '../Heading-es.js';
13
- import '../Typography-es.js';
14
- import '../Text-es.js';
15
- import '../Icon-es.js';
16
- import '../useOnKeyDown-es.js';
17
- import '../InputText/index.mjs';
18
- import '../FormField-es.js';
17
+ import 'react-hook-form';
19
18
  import 'framer-motion';
20
19
  import '../Button-es.js';
21
20
  import 'react-router-dom';
22
- import '../useFormFieldFocus-es.js';
23
- import '../InputValidation-es.js';
24
- import '../Spinner-es.js';
25
- import 'react-hook-form';
26
21
  import '../omit-es.js';
27
22
  import '../_commonjsHelpers-es.js';
28
23
  import '../_baseGet-es.js';
@@ -35,3 +30,1313 @@ import '../keysIn-es.js';
35
30
  import '../_baseAssignValue-es.js';
36
31
  import '../_baseFlatten-es.js';
37
32
  import '../_setToString-es.js';
33
+ import '../useFormFieldFocus-es.js';
34
+ import '../InputValidation-es.js';
35
+ import '../Spinner-es.js';
36
+ import '../Content-es.js';
37
+
38
+ var styles$1 = {"list":"_37kZB-nYE08-","loadingList":"ULib3TUQja0-","option":"h5-1Pp0eRyo-","defaultOptionContent":"iBkyj85vd-E-","icon":"I6wAbSJJHNQ-","optionActive":"_4yhnonWAWRY-","actionActive":"oGLMF6n8C74-","action":"LBrwH6TEUYA-","section":"DDOv4DR8bJQ-","emptyStateMessage":"Twgjn26oldE-","stickyTop":"mc1-CEwZtHE-","scrollRegion":"kOR88SFNOn0-","persistentHeader":"_0O-kEf3h9ZI-","persistentFooter":"rQ9ZS7Rb7Z4-","textPersistent":"vxk57ZhP8GU-","spinning":"_0d8hyvaCPAw-"};
39
+
40
+ function flattenMenu(menu) {
41
+ const optionItems = [];
42
+ const sections = [];
43
+ const persistentsHeaders = [];
44
+ const persistentsFooters = [];
45
+ menu.forEach(item => {
46
+ if (item.type === "header") {
47
+ persistentsHeaders.push(item);
48
+ return;
49
+ }
50
+ if (item.type === "footer") {
51
+ persistentsFooters.push(item);
52
+ return;
53
+ }
54
+ const group = item;
55
+ sections.push(group);
56
+ optionItems.push(...group.options);
57
+ });
58
+ return { optionItems, sections, persistentsHeaders, persistentsFooters };
59
+ }
60
+ function buildItemsForGroup(group, optionsFilter) {
61
+ var _a;
62
+ const isSection = group.type === "section";
63
+ const filtered = optionsFilter ? optionsFilter(group.options) : group.options;
64
+ const actions = (_a = group.actions) !== null && _a !== void 0 ? _a : [];
65
+ const result = [];
66
+ // Only render a section header when that section has at least one option after filtering
67
+ if (isSection && filtered.length > 0) {
68
+ result.push({
69
+ kind: "section",
70
+ section: group,
71
+ });
72
+ }
73
+ if (filtered.length > 0) {
74
+ result.push(...filtered.map(o => ({
75
+ kind: "option",
76
+ value: o,
77
+ })));
78
+ }
79
+ // Only render actions for a group when that group has at least one option after filtering
80
+ if (actions.length > 0 && filtered.length > 0) {
81
+ result.push(...actions.map(action => ({
82
+ kind: "action",
83
+ action,
84
+ origin: "menu",
85
+ })));
86
+ }
87
+ return result;
88
+ }
89
+ function buildRenderableList(sections, optionsFilter) {
90
+ const items = [];
91
+ for (const group of sections) {
92
+ items.push(...buildItemsForGroup(group, optionsFilter));
93
+ }
94
+ return items;
95
+ }
96
+ function getNavigableItemAtIndex(activeIndex, renderable) {
97
+ if (activeIndex == null)
98
+ return null;
99
+ let navigableIndex = -1;
100
+ for (const item of renderable) {
101
+ // Ignore sections
102
+ if (item.kind === "section")
103
+ continue;
104
+ navigableIndex += 1;
105
+ if (navigableIndex === activeIndex)
106
+ return item;
107
+ }
108
+ return null;
109
+ }
110
+ function findNavigableIndexForValue(renderable, equals, selectedValue) {
111
+ let navigableIndex = -1;
112
+ for (const item of renderable) {
113
+ // Ignore sections
114
+ if (item.kind === "section")
115
+ continue;
116
+ navigableIndex += 1;
117
+ if (item.kind === "option" && equals(item.value, selectedValue)) {
118
+ return navigableIndex;
119
+ }
120
+ }
121
+ return null;
122
+ }
123
+ function invokeActiveItemOnEnter(event, activeIndex, renderable, onSelect, onAction) {
124
+ const activeItem = getNavigableItemAtIndex(activeIndex, renderable);
125
+ if (!activeItem)
126
+ return;
127
+ event.preventDefault();
128
+ if (activeItem.kind === "option") {
129
+ onSelect(activeItem.value);
130
+ }
131
+ else if (activeItem.kind === "action") {
132
+ onAction({
133
+ run: activeItem.action.onClick,
134
+ closeOnRun: activeItem.action.shouldClose,
135
+ });
136
+ }
137
+ }
138
+
139
+ const MENU_OFFSET = tokens["space-small"];
140
+ const AUTOCOMPLETE_MAX_HEIGHT$1 = 300;
141
+ function useAutocompleteListNav({ navigableCount, shouldResetActiveIndexOnClose, onMenuClose, selectedIndex, }) {
142
+ const [open, setOpen] = useState(false);
143
+ const [activeIndex, setActiveIndex] = useState(null);
144
+ const listRef = useRef([]);
145
+ const { refs, floatingStyles, context } = useFloating({
146
+ placement: "bottom",
147
+ whileElementsMounted: autoUpdate,
148
+ open,
149
+ onOpenChange: (isOpen, _event, reason) => {
150
+ setOpen(isOpen);
151
+ if (isOpen === false) {
152
+ if (shouldResetActiveIndexOnClose === null || shouldResetActiveIndexOnClose === void 0 ? void 0 : shouldResetActiveIndexOnClose()) {
153
+ setActiveIndex(null);
154
+ }
155
+ onMenuClose === null || onMenuClose === void 0 ? void 0 : onMenuClose(String(reason !== null && reason !== void 0 ? reason : ""));
156
+ }
157
+ },
158
+ middleware: [
159
+ offset(MENU_OFFSET),
160
+ flip({ fallbackPlacements: ["top"] }),
161
+ size({
162
+ apply({ availableHeight, elements }) {
163
+ const maxHeight = calculateMaxHeight(availableHeight, {
164
+ maxHeight: AUTOCOMPLETE_MAX_HEIGHT$1,
165
+ });
166
+ Object.assign(elements.floating.style, {
167
+ maxHeight: `${maxHeight}px`,
168
+ });
169
+ },
170
+ }),
171
+ ],
172
+ });
173
+ const listNav = useListNavigation(context, {
174
+ listRef,
175
+ activeIndex,
176
+ selectedIndex,
177
+ scrollItemIntoView: {
178
+ behavior: "smooth",
179
+ block: "end",
180
+ },
181
+ loop: true,
182
+ onNavigate: setActiveIndex,
183
+ virtual: true,
184
+ enabled: open,
185
+ openOnArrowKeyDown: false,
186
+ focusItemOnOpen: "auto",
187
+ focusItemOnHover: false,
188
+ });
189
+ const dismiss = useDismiss(context, {
190
+ outsidePress: true,
191
+ escapeKey: true,
192
+ outsidePressEvent: "click",
193
+ });
194
+ const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([listNav, dismiss]);
195
+ useEffect(() => {
196
+ listRef.current.length = navigableCount;
197
+ setActiveIndex(prev => {
198
+ if (navigableCount <= 0)
199
+ return null;
200
+ if (prev == null)
201
+ return null;
202
+ return prev >= navigableCount ? navigableCount - 1 : prev;
203
+ });
204
+ }, [navigableCount, setActiveIndex, listRef]);
205
+ return {
206
+ refs,
207
+ floatingStyles,
208
+ context,
209
+ getReferenceProps,
210
+ getFloatingProps,
211
+ getItemProps,
212
+ activeIndex,
213
+ setActiveIndex,
214
+ listRef,
215
+ open,
216
+ setOpen,
217
+ setReferenceElement: (el) => refs.setReference(el),
218
+ };
219
+ }
220
+
221
+ // Keeping this hook cohesive improves readability by centralizing related
222
+ // interactions and state transitions.
223
+ // eslint-disable-next-line max-statements
224
+ function useAutocomplete(props) {
225
+ const { menu, emptyActions, getOptionLabel: getOptionLabelProp, isOptionEqualToValue, inputValue, onInputChange, value, onChange, multiple, openOnFocus = true, readOnly = false, debounce: debounceMs = 300, } = props;
226
+ // TODO: Clean up the types in these refs by enhancing the type system in useCallbackRef
227
+ const getOptionLabelPropRef = useCallbackRef((opt) => getOptionLabelProp === null || getOptionLabelProp === void 0 ? void 0 : getOptionLabelProp(opt));
228
+ const getOptionLabel = useCallback((opt) => {
229
+ const maybe = getOptionLabelPropRef(opt);
230
+ return maybe !== null && maybe !== void 0 ? maybe : opt.label;
231
+ }, [getOptionLabelPropRef]);
232
+ const isOptionEqualToValueRef = useCallbackRef((a, b) => isOptionEqualToValue === null || isOptionEqualToValue === void 0 ? void 0 : isOptionEqualToValue(a, b));
233
+ const equals = useCallback((a, b) => {
234
+ const custom = isOptionEqualToValueRef(a, b);
235
+ return custom != null ? custom : getOptionLabel(a) === getOptionLabel(b);
236
+ }, [isOptionEqualToValueRef, getOptionLabel]);
237
+ const isOptionSelected = useCallback((opt) => {
238
+ var _a;
239
+ if (multiple) {
240
+ const current = (_a = value) !== null && _a !== void 0 ? _a : [];
241
+ return current.some(v => equals(v, opt));
242
+ }
243
+ const current = value;
244
+ return current != null ? equals(current, opt) : false;
245
+ }, [multiple, value, equals]);
246
+ const flatInitial = useMemo(() => flattenMenu(menu), [menu]);
247
+ const sections = flatInitial.sections;
248
+ const optionItems = flatInitial.optionItems;
249
+ const persistentsHeaders = flatInitial.persistentsHeaders;
250
+ const persistentsFooters = flatInitial.persistentsFooters;
251
+ // Stable wrappers for function props
252
+ const inputEqualsOptionRef = useCallbackRef((text, o) => {
253
+ const fn = props.inputEqualsOption;
254
+ return fn ? fn(text, o) : undefined;
255
+ });
256
+ const inputEquals = useCallback((text, o) => {
257
+ const custom = inputEqualsOptionRef(text, o);
258
+ return custom != null ? custom : getOptionLabel(o) === text;
259
+ }, [inputEqualsOptionRef, getOptionLabel]);
260
+ // inputValue changes very often, is this worth memoizing?
261
+ const exactLabelMatch = useMemo(() => {
262
+ return optionItems.some(o => inputEquals(inputValue, o));
263
+ }, [optionItems, inputEquals, inputValue]);
264
+ const lastInputWasUser = useRef(false);
265
+ const [debouncedInputValue, setDebouncedInputValue] = useState(inputValue);
266
+ const debouncedSetter = useDebounce(setDebouncedInputValue, debounceMs);
267
+ useEffect(() => {
268
+ if (debounceMs === 0) {
269
+ setDebouncedInputValue(inputValue);
270
+ return;
271
+ }
272
+ debouncedSetter(inputValue);
273
+ }, [inputValue, debounceMs, debouncedSetter]);
274
+ const filterOptionsRef = useCallbackRef((opts, term) => {
275
+ const fn = (typeof props.filterOptions === "function"
276
+ ? props.filterOptions
277
+ : undefined) || undefined;
278
+ return fn ? fn(opts, term) : undefined;
279
+ });
280
+ const applyFilter = useCallback((opts, term) => {
281
+ if (props.filterOptions === false)
282
+ return opts;
283
+ const override = filterOptionsRef(opts, term);
284
+ if (override)
285
+ return override;
286
+ const lowered = term.toLowerCase();
287
+ return opts.filter(opt => getOptionLabel(opt).toLowerCase().includes(lowered));
288
+ }, [props.filterOptions, filterOptionsRef, getOptionLabel]);
289
+ const renderable = useMemo(() => {
290
+ const filter = (opts) => {
291
+ if (exactLabelMatch && !lastInputWasUser.current)
292
+ return opts;
293
+ return applyFilter(opts, debouncedInputValue);
294
+ };
295
+ const items = buildRenderableList(sections, filter);
296
+ const hasAnyOptions = items.some(i => i.kind === "option");
297
+ if (!hasAnyOptions) {
298
+ if (emptyActions) {
299
+ const derived = typeof emptyActions === "function"
300
+ ? emptyActions({ inputValue })
301
+ : emptyActions;
302
+ return derived.map(act => ({
303
+ kind: "action",
304
+ action: act,
305
+ origin: "empty",
306
+ }));
307
+ }
308
+ // No options and no emptyActions: render empty state
309
+ return [];
310
+ }
311
+ return items;
312
+ }, [
313
+ sections,
314
+ applyFilter,
315
+ debouncedInputValue,
316
+ exactLabelMatch,
317
+ emptyActions,
318
+ inputValue,
319
+ ]);
320
+ // This is only options
321
+ const optionCount = renderable.reduce((count, item) => count + (item.kind === "option" ? 1 : 0), 0);
322
+ const hasSelection = useMemo(() => {
323
+ var _a;
324
+ if (multiple) {
325
+ const current = (_a = value) !== null && _a !== void 0 ? _a : [];
326
+ return Array.isArray(current) && current.length > 0;
327
+ }
328
+ return value != null;
329
+ }, [multiple, value]);
330
+ const headerInteractivePersistents = persistentsHeaders.filter(p => Boolean(p.onClick));
331
+ const footerInteractivePersistents = persistentsFooters.filter(p => Boolean(p.onClick));
332
+ const mainNavigableCount = renderable.reduce((c, i) => c + (i.kind === "section" ? 0 : 1), 0);
333
+ const totalNavigableCount = headerInteractivePersistents.length +
334
+ mainNavigableCount +
335
+ footerInteractivePersistents.length;
336
+ // Compute the currently selected index in the global navigable list (header -> middle -> footer)
337
+ const selectedIndex = useMemo(() => {
338
+ const selectedValue = multiple
339
+ ? value === null || value === void 0 ? void 0 : value[0]
340
+ : value;
341
+ if (!selectedValue)
342
+ return null;
343
+ const middleIndex = findNavigableIndexForValue(renderable, equals, selectedValue);
344
+ if (middleIndex == null)
345
+ return null;
346
+ return headerInteractivePersistents.length + middleIndex;
347
+ }, [
348
+ multiple,
349
+ value,
350
+ renderable,
351
+ equals,
352
+ headerInteractivePersistents.length,
353
+ ]);
354
+ const { refs, floatingStyles, context, getReferenceProps, getFloatingProps, getItemProps, activeIndex, setActiveIndex, listRef, open, setOpen, setReferenceElement, } = useAutocompleteListNav({
355
+ navigableCount: totalNavigableCount,
356
+ shouldResetActiveIndexOnClose: () => !hasSelection,
357
+ selectedIndex,
358
+ onMenuClose: () => {
359
+ if (props.allowFreeForm !== true) {
360
+ const hasText = inputValue.trim().length > 0;
361
+ if (hasText && !hasSelection) {
362
+ lastInputWasUser.current = false;
363
+ onInputChange === null || onInputChange === void 0 ? void 0 : onInputChange("");
364
+ setActiveIndex(null);
365
+ }
366
+ }
367
+ },
368
+ });
369
+ const [inputFocused, setInputFocused] = useState(false);
370
+ // Handles activeIndex reset and, in single-select mode only, clearing selection when input is empty
371
+ useEffect(() => {
372
+ const hasText = inputValue.trim().length > 0;
373
+ if (hasText)
374
+ return;
375
+ // Always reset highlight when input is empty
376
+ setActiveIndex(null);
377
+ // In multiple mode, clearing the input should NOT clear the selection
378
+ if (multiple)
379
+ return;
380
+ // For single-select, treat clearing input as clearing the selection
381
+ if (hasSelection) {
382
+ onChange === null || onChange === void 0 ? void 0 : onChange(undefined);
383
+ }
384
+ }, [inputValue, multiple, hasSelection, setActiveIndex, onChange, open]);
385
+ function selectOption(option) {
386
+ var _a;
387
+ if (multiple) {
388
+ const current = (_a = value) !== null && _a !== void 0 ? _a : [];
389
+ const exists = current.some(v => equals(v, option));
390
+ const next = exists
391
+ ? current.filter(v => !equals(v, option))
392
+ : [...current, option];
393
+ onChange(next);
394
+ }
395
+ else {
396
+ onChange(option);
397
+ lastInputWasUser.current = false;
398
+ onInputChange === null || onInputChange === void 0 ? void 0 : onInputChange(getOptionLabel(option));
399
+ }
400
+ }
401
+ function tryCommitFreeFormOnEnter() {
402
+ if (props.allowFreeForm !== true)
403
+ return false;
404
+ if (open && activeIndex != null)
405
+ return false;
406
+ const inputText = inputValue.trim();
407
+ if (inputText.length === 0)
408
+ return false;
409
+ commitFromInputText(inputText);
410
+ return true;
411
+ }
412
+ // Keep the selected item highlighted when deleting characters from the input
413
+ const prevInputLengthRef = useRef(inputValue.length);
414
+ useEffect(() => {
415
+ const previousLength = prevInputLengthRef.current;
416
+ prevInputLengthRef.current = inputValue.length;
417
+ if (!open)
418
+ return;
419
+ if (!lastInputWasUser.current)
420
+ return;
421
+ if (previousLength <= inputValue.length)
422
+ return; // only on deletion
423
+ if (!hasSelection)
424
+ return;
425
+ const selectedValue = multiple
426
+ ? value === null || value === void 0 ? void 0 : value[0]
427
+ : value;
428
+ if (!selectedValue)
429
+ return;
430
+ const idx = findNavigableIndexForValue(renderable, equals, selectedValue);
431
+ if (idx != null)
432
+ setActiveIndex(idx);
433
+ }, [
434
+ inputValue,
435
+ renderable,
436
+ equals,
437
+ value,
438
+ open,
439
+ hasSelection,
440
+ multiple,
441
+ setActiveIndex,
442
+ ]);
443
+ useEffect(() => {
444
+ if (!open)
445
+ return;
446
+ // When opening the menu, initialize the highlight consistently:
447
+ // - If there is a current selection, highlight that option
448
+ // - Otherwise, leave the highlight unset (null)
449
+ const selectedValue = multiple
450
+ ? value === null || value === void 0 ? void 0 : value[0]
451
+ : value;
452
+ if (selectedValue) {
453
+ const selectedNavigableIndex = findNavigableIndexForValue(renderable, equals, selectedValue);
454
+ if (selectedNavigableIndex != null) {
455
+ setActiveIndex(selectedNavigableIndex);
456
+ return;
457
+ }
458
+ }
459
+ setActiveIndex(null);
460
+ }, [open, multiple, value, renderable, equals, setActiveIndex]);
461
+ const onSelection = useCallback((option) => {
462
+ selectOption(option);
463
+ // Might not always want to close on selection. Multi for example.
464
+ setOpen(false);
465
+ }, [selectOption, setOpen]);
466
+ const onAction = useCallback((action) => {
467
+ action.run();
468
+ setActiveIndex(null);
469
+ if (action.closeOnRun !== false)
470
+ setOpen(false);
471
+ }, [setOpen, setActiveIndex]);
472
+ function commitFromInputText(inputText) {
473
+ var _a;
474
+ if (inputText.length === 0)
475
+ return false;
476
+ const match = optionItems.find(o => inputEquals(inputText, o));
477
+ if (match) {
478
+ onSelection(match);
479
+ return true;
480
+ }
481
+ setOpen(false);
482
+ if (props.allowFreeForm !== true)
483
+ return false;
484
+ const freeFormCreated = (_a = props.createFreeFormValue) === null || _a === void 0 ? void 0 : _a.call(props, inputText);
485
+ if (!freeFormCreated)
486
+ return false;
487
+ props.onChange(freeFormCreated);
488
+ return true;
489
+ }
490
+ const tryRestoreInputToSelectedLabel = useCallback(() => {
491
+ if (props.allowFreeForm === true)
492
+ return;
493
+ const selectedValue = multiple
494
+ ? value === null || value === void 0 ? void 0 : value[0]
495
+ : value;
496
+ if (!selectedValue)
497
+ return;
498
+ const selectedLabel = getOptionLabel(selectedValue);
499
+ if (inputValue === selectedLabel)
500
+ return;
501
+ lastInputWasUser.current = false;
502
+ onInputChange === null || onInputChange === void 0 ? void 0 : onInputChange(selectedLabel);
503
+ }, [
504
+ props.allowFreeForm,
505
+ getOptionLabel,
506
+ inputValue,
507
+ onInputChange,
508
+ multiple,
509
+ value,
510
+ ]);
511
+ const onInputFocus = useCallback(() => {
512
+ var _a;
513
+ setInputFocused(true);
514
+ if (!readOnly && openOnFocus)
515
+ setOpen(true);
516
+ (_a = props.onFocus) === null || _a === void 0 ? void 0 : _a.call(props);
517
+ }, [props.onFocus, readOnly, openOnFocus, setOpen]);
518
+ const onInputBlur = useCallback(() => {
519
+ var _a, _b;
520
+ setInputFocused(false);
521
+ if (readOnly) {
522
+ (_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props);
523
+ return;
524
+ }
525
+ if (props.allowFreeForm === true) {
526
+ const inputText = inputValue.trim();
527
+ if (inputText.length > 0)
528
+ commitFromInputText(inputText);
529
+ }
530
+ else {
531
+ tryRestoreInputToSelectedLabel();
532
+ }
533
+ lastInputWasUser.current = false;
534
+ (_b = props.onBlur) === null || _b === void 0 ? void 0 : _b.call(props);
535
+ }, [
536
+ readOnly,
537
+ props.allowFreeForm,
538
+ inputValue,
539
+ props.onBlur,
540
+ tryRestoreInputToSelectedLabel,
541
+ setOpen,
542
+ ]);
543
+ function getRegionByActiveIndex(index) {
544
+ const headerCount = headerInteractivePersistents.length;
545
+ const mainCount = mainNavigableCount;
546
+ if (index < headerCount)
547
+ return { region: "header", regionIndex: index };
548
+ const middleIndex = index - headerCount;
549
+ if (middleIndex < mainCount) {
550
+ return { region: "middle", regionIndex: middleIndex };
551
+ }
552
+ return {
553
+ region: "footer",
554
+ regionIndex: middleIndex - mainCount,
555
+ };
556
+ }
557
+ function computeInitialIndexForArrowUp() {
558
+ // If there are interactive footers, prefer the very last navigable item
559
+ if (footerInteractivePersistents.length > 0) {
560
+ return totalNavigableCount > 0 ? totalNavigableCount - 1 : null;
561
+ }
562
+ // Otherwise, prefer the last OPTION (not action), matching legacy behavior
563
+ let navigable = -1;
564
+ let lastOptionIdx = -1;
565
+ for (const item of renderable) {
566
+ if (item.kind === "section")
567
+ continue;
568
+ navigable += 1;
569
+ if (item.kind === "option")
570
+ lastOptionIdx = navigable;
571
+ }
572
+ if (lastOptionIdx >= 0) {
573
+ return headerInteractivePersistents.length + lastOptionIdx;
574
+ }
575
+ return totalNavigableCount > 0 ? totalNavigableCount - 1 : null;
576
+ }
577
+ function handleArrowNavigation(key, event) {
578
+ if (!open) {
579
+ setOpen(true);
580
+ return;
581
+ }
582
+ if (activeIndex == null) {
583
+ setActiveIndex(key === "ArrowDown" ? 0 : computeInitialIndexForArrowUp());
584
+ event.preventDefault();
585
+ }
586
+ }
587
+ function handleEnterKey(event) {
588
+ if (tryCommitFreeFormOnEnter()) {
589
+ event.preventDefault();
590
+ return;
591
+ }
592
+ if (!open || activeIndex == null)
593
+ return;
594
+ const { region, regionIndex } = getRegionByActiveIndex(activeIndex);
595
+ if (region === "middle") {
596
+ invokeActiveItemOnEnter(event, regionIndex, renderable, onSelection, onAction);
597
+ return;
598
+ }
599
+ const persistent = region === "header"
600
+ ? headerInteractivePersistents[regionIndex]
601
+ : footerInteractivePersistents[regionIndex];
602
+ if (persistent === null || persistent === void 0 ? void 0 : persistent.onClick) {
603
+ onAction({
604
+ run: persistent.onClick,
605
+ closeOnRun: persistent.shouldClose,
606
+ });
607
+ }
608
+ }
609
+ const onInputKeyDown = useCallback((event) => {
610
+ const key = event.key;
611
+ if (key !== "ArrowDown" && key !== "ArrowUp" && key !== "Enter")
612
+ return;
613
+ if (key === "ArrowDown" || key === "ArrowUp") {
614
+ handleArrowNavigation(key, event);
615
+ return;
616
+ }
617
+ handleEnterKey(event);
618
+ }, [open, onSelection, onAction]);
619
+ const onInputChangeFromUser = useCallback((val) => {
620
+ lastInputWasUser.current = true;
621
+ // Reset highlight (activeIndex) on additions to the search term
622
+ if (val.length > inputValue.length) {
623
+ setActiveIndex(null);
624
+ }
625
+ // Important: update open state before propagating the change so that downstream effects
626
+ // don’t see an intermediate state where inputValue changed but open was stale
627
+ if (!readOnly) {
628
+ const hasText = val.trim().length > 0;
629
+ const mustSelectFromOptions = hasText && !props.allowFreeForm;
630
+ const keepOpenOnEmpty = openOnFocus && inputFocused;
631
+ setOpen(mustSelectFromOptions || keepOpenOnEmpty);
632
+ }
633
+ onInputChange === null || onInputChange === void 0 ? void 0 : onInputChange(val);
634
+ }, [
635
+ onInputChange,
636
+ inputValue,
637
+ setActiveIndex,
638
+ readOnly,
639
+ props.allowFreeForm,
640
+ openOnFocus,
641
+ inputFocused,
642
+ setOpen,
643
+ ]);
644
+ return {
645
+ // rendering data
646
+ renderable,
647
+ optionCount,
648
+ persistentsHeaders,
649
+ persistentsFooters,
650
+ headerInteractiveCount: headerInteractivePersistents.length,
651
+ middleNavigableCount: mainNavigableCount,
652
+ getOptionLabel,
653
+ isOptionSelected,
654
+ // floating-ui
655
+ refs,
656
+ floatingStyles,
657
+ context,
658
+ getReferenceProps,
659
+ getFloatingProps,
660
+ getItemProps,
661
+ // state
662
+ open,
663
+ setOpen,
664
+ activeIndex,
665
+ setActiveIndex,
666
+ listRef,
667
+ // actions
668
+ onSelection,
669
+ onAction,
670
+ // input handlers
671
+ onInputChangeFromUser,
672
+ onInputBlur,
673
+ onInputFocus,
674
+ onInputKeyDown,
675
+ // ref attachment
676
+ setReferenceElement,
677
+ };
678
+ }
679
+
680
+ function MenuList({ items, activeIndex, indexOffset = 0, getItemProps, listRef, listboxId, customRenderOption, customRenderSection, customRenderAction, getOptionLabel, onSelect, onAction, isOptionSelected, slotOverrides, }) {
681
+ let navigableIndex = -1;
682
+ function renderItemNode(item) {
683
+ var _a, _b, _c, _d, _e, _f;
684
+ if (item.kind === "section") {
685
+ return handleSectionRendering({
686
+ section: item.section,
687
+ customRenderSection,
688
+ sectionClassName: (_a = slotOverrides === null || slotOverrides === void 0 ? void 0 : slotOverrides.section) === null || _a === void 0 ? void 0 : _a.className,
689
+ sectionStyle: (_b = slotOverrides === null || slotOverrides === void 0 ? void 0 : slotOverrides.section) === null || _b === void 0 ? void 0 : _b.style,
690
+ });
691
+ }
692
+ if (item.kind === "option") {
693
+ const result = handleOptionRendering({
694
+ option: item.value,
695
+ activeIndex,
696
+ navigableIndex,
697
+ getItemProps,
698
+ listRef,
699
+ listboxId,
700
+ isOptionSelected,
701
+ customRenderOption,
702
+ getOptionLabel,
703
+ onSelect,
704
+ indexOffset,
705
+ optionClassName: (_c = slotOverrides === null || slotOverrides === void 0 ? void 0 : slotOverrides.option) === null || _c === void 0 ? void 0 : _c.className,
706
+ optionStyle: (_d = slotOverrides === null || slotOverrides === void 0 ? void 0 : slotOverrides.option) === null || _d === void 0 ? void 0 : _d.style,
707
+ });
708
+ navigableIndex = result.nextNavigableIndex;
709
+ return result.node;
710
+ }
711
+ const result = handleActionRendering({
712
+ action: item.action,
713
+ activeIndex,
714
+ navigableIndex,
715
+ getItemProps,
716
+ listRef,
717
+ listboxId,
718
+ customRenderAction,
719
+ onAction,
720
+ indexOffset,
721
+ actionClassName: (_e = slotOverrides === null || slotOverrides === void 0 ? void 0 : slotOverrides.action) === null || _e === void 0 ? void 0 : _e.className,
722
+ actionStyle: (_f = slotOverrides === null || slotOverrides === void 0 ? void 0 : slotOverrides.action) === null || _f === void 0 ? void 0 : _f.style,
723
+ origin: item.origin,
724
+ });
725
+ navigableIndex = result.nextNavigableIndex;
726
+ return result.node;
727
+ }
728
+ return React__default.createElement(React__default.Fragment, null, items.map(renderItemNode));
729
+ }
730
+ function handleSectionRendering({ customRenderSection, section, sectionClassName, sectionStyle, }) {
731
+ var _a;
732
+ const headerContent = customRenderSection ? (customRenderSection(section)) : (React__default.createElement(DefaultSectionContent, { section: section }));
733
+ return (React__default.createElement("div", { key: `section-${String((_a = section.key) !== null && _a !== void 0 ? _a : section.label)}`, role: "presentation", tabIndex: -1, "data-testid": "ATL-AutocompleteRebuilt-Section", className: classnames(styles$1.section, styles$1.stickyTop, sectionClassName), style: sectionStyle }, headerContent));
734
+ }
735
+ function DefaultSectionContent({ section, }) {
736
+ return React__default.createElement(Heading, { level: 5 }, section.label);
737
+ }
738
+ function handleOptionRendering({ option, activeIndex, navigableIndex, getItemProps, listRef, listboxId, isOptionSelected, customRenderOption, getOptionLabel, onSelect, indexOffset = 0, optionClassName, optionStyle, }) {
739
+ var _a;
740
+ const nextNavigableIndex = navigableIndex + 1;
741
+ const isActive = activeIndex === nextNavigableIndex;
742
+ const isSelected = isOptionSelected(option);
743
+ const optionContent = customRenderOption ? (customRenderOption({ value: option, isActive, isSelected })) : (React__default.createElement(DefaultOptionContent, { isSelected: isSelected, text: getOptionLabel(option) }));
744
+ return {
745
+ node: (React__default.createElement("div", Object.assign({ key: `option-${String((_a = option.key) !== null && _a !== void 0 ? _a : getOptionLabel(option))}` }, getItemProps({
746
+ ref(node) {
747
+ const idx = nextNavigableIndex + indexOffset;
748
+ if (node)
749
+ listRef.current[idx] = node;
750
+ },
751
+ onClick: () => onSelect(option),
752
+ className: classnames(styles$1.option, isActive && styles$1.optionActive, optionClassName),
753
+ style: optionStyle,
754
+ }), { role: "option", tabIndex: -1, "aria-selected": isSelected ? true : false, id: `${listboxId}-item-${nextNavigableIndex + indexOffset}`, "data-index": nextNavigableIndex + indexOffset, "data-active": isActive ? true : undefined }), optionContent)),
755
+ nextNavigableIndex,
756
+ };
757
+ }
758
+ function DefaultOptionContent({ isSelected, text, }) {
759
+ return (React__default.createElement("div", { className: styles$1.defaultOptionContent },
760
+ React__default.createElement("div", { className: styles$1.icon }, isSelected && React__default.createElement(Icon, { name: "checkmark", size: "small" })),
761
+ React__default.createElement(Text, null, text)));
762
+ }
763
+ function handleActionRendering({ action, activeIndex, navigableIndex, getItemProps, listRef, listboxId, customRenderAction, onAction, indexOffset = 0, actionClassName, actionStyle, origin, }) {
764
+ var _a;
765
+ const nextNavigableIndex = navigableIndex + 1;
766
+ const isActive = activeIndex === nextNavigableIndex;
767
+ const actionContent = customRenderAction ? (customRenderAction({ value: action, isActive, origin })) : (React__default.createElement(DefaultActionContent, { textContent: action.label }));
768
+ const computedIndex = nextNavigableIndex + indexOffset;
769
+ const itemProps = getItemProps({
770
+ ref(node) {
771
+ if (node) {
772
+ listRef.current[computedIndex] = node;
773
+ }
774
+ },
775
+ onClick: () => {
776
+ onAction({
777
+ run: action.onClick,
778
+ closeOnRun: action.shouldClose,
779
+ });
780
+ },
781
+ className: classnames(styles$1.action, isActive && styles$1.actionActive, actionClassName),
782
+ style: actionStyle,
783
+ });
784
+ return {
785
+ node: (React__default.createElement("div", Object.assign({ key: `action-${String((origin !== null && origin !== void 0 ? origin : "menu") + "-" + ((_a = action.key) !== null && _a !== void 0 ? _a : action.label))}` }, itemProps, { role: "button", tabIndex: -1, "data-testid": "ATL-AutocompleteRebuilt-Action", id: `${listboxId}-item-${computedIndex}`, "data-index": computedIndex, "data-origin": origin, "data-active": isActive ? true : undefined }), actionContent)),
786
+ nextNavigableIndex,
787
+ };
788
+ }
789
+ function DefaultActionContent({ textContent, }) {
790
+ return (React__default.createElement(Typography, { textColor: "interactive", fontWeight: "semiBold", underline: "solid color-interactive", UNSAFE_style: {
791
+ textStyle: {
792
+ textDecorationThickness: "var(--border-thick)",
793
+ textUnderlineOffset: "var(--space-smallest)",
794
+ },
795
+ } }, textContent));
796
+ }
797
+
798
+ function PersistentRegion({ items, position, activeIndex, indexOffset, getItemProps, listRef, customRenderHeader, customRenderFooter, className, style, onAction, }) {
799
+ if (!items || items.length === 0)
800
+ return null;
801
+ let navigableIndex = -1;
802
+ return (React__default.createElement("div", { className: className, style: style, "data-region": position, "data-testid": `ATL-AutocompleteRebuilt-${position}` }, items.map(persistent => {
803
+ const result = handlePersistentRendering({
804
+ persistent,
805
+ position,
806
+ activeIndex,
807
+ indexOffset,
808
+ getItemProps,
809
+ customRenderHeader,
810
+ customRenderFooter,
811
+ listRef,
812
+ onAction,
813
+ navigableIndex,
814
+ });
815
+ navigableIndex = result.nextNavigableIndex;
816
+ return result.node;
817
+ })));
818
+ }
819
+ function handlePersistentRendering({ persistent, position, activeIndex, indexOffset, getItemProps, customRenderHeader, customRenderFooter, listRef, onAction, navigableIndex, }) {
820
+ const interactive = Boolean(persistent.onClick);
821
+ if (!interactive) {
822
+ const node = handleTextPersistentRendering({
823
+ persistent,
824
+ position,
825
+ customRenderHeader,
826
+ customRenderFooter,
827
+ });
828
+ return { node, nextNavigableIndex: navigableIndex };
829
+ }
830
+ return handleActionPersistentRendering({
831
+ persistent,
832
+ position,
833
+ activeIndex,
834
+ indexOffset,
835
+ getItemProps,
836
+ customRenderHeader,
837
+ customRenderFooter,
838
+ listRef,
839
+ onAction,
840
+ navigableIndex,
841
+ });
842
+ }
843
+ function handleTextPersistentRendering({ persistent, position, customRenderHeader, customRenderFooter, }) {
844
+ var _a;
845
+ let content;
846
+ if (position === "header" && customRenderHeader) {
847
+ content = customRenderHeader({ value: persistent });
848
+ }
849
+ else if (position === "footer" && customRenderFooter) {
850
+ content = customRenderFooter({ value: persistent });
851
+ }
852
+ else {
853
+ content = React__default.createElement(DefaultTextPersistentContent, { persistent: persistent });
854
+ }
855
+ return (React__default.createElement("div", { key: `persistent-${position}-${String((_a = persistent.key) !== null && _a !== void 0 ? _a : persistent.label)}`, role: "presentation", tabIndex: -1, className: styles$1.textPersistent }, content));
856
+ }
857
+ function handleActionPersistentRendering({ persistent, position, activeIndex, indexOffset, getItemProps, customRenderHeader, customRenderFooter, listRef, onAction, navigableIndex, }) {
858
+ var _a;
859
+ const nextNavigableIndex = navigableIndex + 1;
860
+ const isActive = activeIndex === indexOffset + nextNavigableIndex;
861
+ let content;
862
+ if (position === "header" && customRenderHeader) {
863
+ content = customRenderHeader({
864
+ value: persistent,
865
+ isActive,
866
+ });
867
+ }
868
+ else if (position === "footer" && customRenderFooter) {
869
+ content = customRenderFooter({
870
+ value: persistent,
871
+ isActive,
872
+ });
873
+ }
874
+ else {
875
+ content = React__default.createElement(DefaultActionContent, { textContent: persistent.label });
876
+ }
877
+ return {
878
+ node: (React__default.createElement("div", Object.assign({ key: `persistent-${position}-${String((_a = persistent.key) !== null && _a !== void 0 ? _a : persistent.label)}`, "data-index": indexOffset + nextNavigableIndex, id: `${position}-persistent-${indexOffset + nextNavigableIndex}`, "data-active": isActive ? true : undefined }, getItemProps({
879
+ ref(persistNode) {
880
+ const idx = indexOffset + nextNavigableIndex;
881
+ if (persistNode)
882
+ listRef.current[idx] = persistNode;
883
+ },
884
+ onClick: () => onAction({
885
+ run: () => {
886
+ var _a;
887
+ (_a = persistent.onClick) === null || _a === void 0 ? void 0 : _a.call(persistent);
888
+ },
889
+ closeOnRun: persistent.shouldClose,
890
+ }),
891
+ className: classnames(styles$1.action, isActive && styles$1.actionActive),
892
+ }), { role: "button", tabIndex: -1 }), content)),
893
+ nextNavigableIndex,
894
+ };
895
+ }
896
+ function DefaultTextPersistentContent({ persistent, }) {
897
+ return React__default.createElement("div", { className: styles$1.textPersistent }, persistent.label);
898
+ }
899
+
900
+ const AutocompleteRebuilt = forwardRef(AutocompleteRebuiltInternal);
901
+ // eslint-disable-next-line max-statements
902
+ function AutocompleteRebuiltInternal(props, forwardedRef) {
903
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
904
+ const { inputValue, placeholder, disabled, error, invalid, description, size: sizeProp, loading = false, } = props;
905
+ const { renderable, optionCount, persistentsHeaders, persistentsFooters, headerInteractiveCount, middleNavigableCount, getOptionLabel, isOptionSelected, refs, floatingStyles, context, getReferenceProps, getFloatingProps, getItemProps, activeIndex, open, listRef, onSelection, onAction, onInputChangeFromUser, onInputBlur, onInputFocus, onInputKeyDown, setReferenceElement, } = useAutocomplete(props);
906
+ const listboxId = React__default.useId();
907
+ // Provides mount/unmount-aware transition styles for the floating element
908
+ const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {
909
+ initial: { opacity: 0 },
910
+ open: { opacity: 1 },
911
+ close: { opacity: 0 },
912
+ duration: { open: tokens["timing-base"], close: tokens["timing-base"] },
913
+ });
914
+ const [menuWidth, setMenuWidth] = React__default.useState(undefined);
915
+ const [positionRefEl, setPositionRefEl] = React__default.useState(null);
916
+ const composedReferenceProps = getReferenceProps({
917
+ onKeyDown: onInputKeyDown,
918
+ onFocus: onInputFocus,
919
+ onBlur: onInputBlur,
920
+ });
921
+ const inputProps = Object.assign(Object.assign(Object.assign(Object.assign({ version: 2, value: inputValue, onChange: props.readOnly ? undefined : onInputChangeFromUser }, (props.readOnly ? { onFocus: onInputFocus, onBlur: onInputBlur } : {})), { placeholder,
922
+ disabled, readOnly: props.readOnly, error: error !== null && error !== void 0 ? error : undefined, name: props.name, invalid, autoComplete: "off", description, size: sizeProp ? sizeProp : undefined, prefix: props.prefix, suffix: props.suffix }), (props.readOnly ? {} : composedReferenceProps)), { role: "combobox", "aria-autocomplete": "list", "aria-expanded": open ? true : false, "aria-controls": listboxId, "aria-activedescendant": open && activeIndex != null
923
+ ? `${listboxId}-item-${activeIndex}`
924
+ : undefined });
925
+ const referenceInputRef = (node) => {
926
+ setReferenceElement(node);
927
+ // Workaround to get the width of the visual InputText element, which is not the same as
928
+ // the literal input reference element when props like suffix/prefix/clearable are present.
929
+ const visualInputTextElement = node === null || node === void 0 ? void 0 : node.closest("[data-testid='Form-Field-Wrapper']");
930
+ if (visualInputTextElement) {
931
+ setMenuWidth(visualInputTextElement.clientWidth);
932
+ setPositionRefEl(visualInputTextElement);
933
+ }
934
+ };
935
+ const mergedInputRef = mergeRefs([
936
+ referenceInputRef,
937
+ forwardedRef,
938
+ ]);
939
+ useEffect(() => {
940
+ if (!positionRefEl)
941
+ return;
942
+ // Set the reference element to the visual InputText element so the menu aligns with the input.
943
+ refs.setPositionReference(positionRefEl);
944
+ }, [positionRefEl, refs]);
945
+ const menuClassName = classnames(styles$1.list, (_a = props.UNSAFE_className) === null || _a === void 0 ? void 0 : _a.menu);
946
+ const showEmptyStateMessage = optionCount === 0 && props.emptyStateMessage !== false;
947
+ const activeIndexForMiddle = activeIndex != null ? activeIndex - headerInteractiveCount : null;
948
+ return (React__default.createElement("div", { "data-testid": "ATL-AutocompleteRebuilt" },
949
+ props.customRenderInput ? (props.customRenderInput({ inputRef: mergedInputRef, inputProps })) : (React__default.createElement(InputText, Object.assign({ ref: mergedInputRef }, inputProps))),
950
+ isMounted && !props.readOnly && (React__default.createElement(FloatingPortal, null,
951
+ React__default.createElement(FloatingFocusManager, { context: context, modal: false, initialFocus: -1, closeOnFocusOut: true, returnFocus: false },
952
+ React__default.createElement("div", Object.assign({}, getFloatingProps({
953
+ ref(node) {
954
+ if (node)
955
+ refs.setFloating(node);
956
+ },
957
+ id: listboxId,
958
+ role: "listbox",
959
+ className: menuClassName,
960
+ style: Object.assign(Object.assign(Object.assign(Object.assign({}, floatingStyles), transitionStyles), (_b = props.UNSAFE_styles) === null || _b === void 0 ? void 0 : _b.menu), (menuWidth
961
+ ? { width: menuWidth, maxWidth: menuWidth }
962
+ : {})),
963
+ })),
964
+ React__default.createElement(PersistentRegion, { items: persistentsHeaders, position: "header", activeIndex: activeIndex, indexOffset: 0, listboxId: listboxId, getItemProps: getItemProps, listRef: listRef, customRenderHeader: props.customRenderHeader, customRenderFooter: props.customRenderFooter, onAction: onAction, className: classnames(styles$1.persistentHeader, (_c = props.UNSAFE_className) === null || _c === void 0 ? void 0 : _c.header), style: (_d = props.UNSAFE_styles) === null || _d === void 0 ? void 0 : _d.header }),
965
+ React__default.createElement("div", { className: styles$1.scrollRegion }, loading ? ((_e = props.customRenderLoading) !== null && _e !== void 0 ? _e : React__default.createElement(LoadingContent, null)) : (React__default.createElement(React__default.Fragment, null,
966
+ showEmptyStateMessage && (React__default.createElement(EmptyStateMessage, { emptyState: props.emptyStateMessage })),
967
+ renderable.length > 0 && (React__default.createElement(MenuList, { items: renderable, activeIndex: activeIndexForMiddle, indexOffset: headerInteractiveCount, listboxId: listboxId, getItemProps: getItemProps, listRef: listRef, customRenderOption: props.customRenderOption, customRenderSection: props.customRenderSection, customRenderAction: props.customRenderAction, getOptionLabel: getOptionLabel, onSelect: onSelection, onAction: onAction, isOptionSelected: isOptionSelected, slotOverrides: {
968
+ option: {
969
+ className: (_f = props.UNSAFE_className) === null || _f === void 0 ? void 0 : _f.option,
970
+ style: (_g = props.UNSAFE_styles) === null || _g === void 0 ? void 0 : _g.option,
971
+ },
972
+ action: {
973
+ className: (_h = props.UNSAFE_className) === null || _h === void 0 ? void 0 : _h.action,
974
+ style: (_j = props.UNSAFE_styles) === null || _j === void 0 ? void 0 : _j.action,
975
+ },
976
+ section: {
977
+ className: (_k = props.UNSAFE_className) === null || _k === void 0 ? void 0 : _k.section,
978
+ style: (_l = props.UNSAFE_styles) === null || _l === void 0 ? void 0 : _l.section,
979
+ },
980
+ } }))))),
981
+ React__default.createElement(PersistentRegion, { items: persistentsFooters, position: "footer", activeIndex: activeIndex, indexOffset: headerInteractiveCount + middleNavigableCount, listboxId: listboxId, getItemProps: getItemProps, listRef: listRef, customRenderHeader: props.customRenderHeader, customRenderFooter: props.customRenderFooter, onAction: onAction, className: classnames(styles$1.persistentFooter, (_m = props.UNSAFE_className) === null || _m === void 0 ? void 0 : _m.footer), style: (_o = props.UNSAFE_styles) === null || _o === void 0 ? void 0 : _o.footer })))))));
982
+ }
983
+ function LoadingContent() {
984
+ return (React__default.createElement("div", { className: styles$1.loadingList },
985
+ React__default.createElement(Glimmer, { shape: "rectangle", size: "base" }),
986
+ React__default.createElement(Glimmer, { shape: "rectangle", size: "base" }),
987
+ React__default.createElement(Glimmer, { shape: "rectangle", size: "base" })));
988
+ }
989
+ function EmptyStateMessage({ emptyState, }) {
990
+ const emptyStateDefault = "No options";
991
+ const emptyStateContent = emptyState !== null && emptyState !== void 0 ? emptyState : emptyStateDefault;
992
+ return React__default.createElement("div", { className: styles$1.emptyStateMessage }, emptyStateContent);
993
+ }
994
+
995
+ var styles = {"autocomplete":"_7mObJiwfPh4-","options":"dL5JShAJlKM-","heading":"PWZL-94hH7k-","visible":"_2RzcnTdaPyc-","option":"y9zhi8Wr8QA-","active":"_3Xg49dtL1Q8-","separator":"LIeh390F3W8-","icon":"K2phy6IC3TY-","text":"a6-LbUm5WnY-","label":"tQNbuxcE9nU-","details":"qacStG9-XbE-","spinning":"P9cQDL4MZ-s-"};
996
+
997
+ const AUTOCOMPLETE_MAX_HEIGHT = 300;
998
+
999
+ function useRepositionMenu(attachTo, visible, cssManagedVisibility) {
1000
+ const { refs, floatingStyles, update } = useFloating(Object.assign({ placement: "bottom", middleware: [
1001
+ offset(8),
1002
+ flip({ fallbackPlacements: ["top"] }),
1003
+ size({
1004
+ apply({ availableHeight, elements }) {
1005
+ const maxHeight = calculateMaxHeight(availableHeight, {
1006
+ maxHeight: AUTOCOMPLETE_MAX_HEIGHT,
1007
+ });
1008
+ Object.assign(elements.floating.style, {
1009
+ maxHeight: `${maxHeight}px`,
1010
+ });
1011
+ },
1012
+ }),
1013
+ ], elements: {
1014
+ reference: attachTo,
1015
+ } }, (!cssManagedVisibility
1016
+ ? {
1017
+ whileElementsMounted: autoUpdate,
1018
+ }
1019
+ : {})));
1020
+ // While DefaultMenu leverages conditional rendering, CustomMenu is hidden with CSS
1021
+ // We need to apply the correct update method to each case
1022
+ useSafeLayoutEffect(() => {
1023
+ if (cssManagedVisibility && visible && attachTo && refs.floating.current) {
1024
+ const cleanup = autoUpdate(attachTo, refs.floating.current, update);
1025
+ return cleanup;
1026
+ }
1027
+ return undefined;
1028
+ }, [
1029
+ cssManagedVisibility,
1030
+ visible,
1031
+ attachTo,
1032
+ refs.floating.current,
1033
+ update,
1034
+ autoUpdate,
1035
+ ]);
1036
+ const targetWidth = attachTo === null || attachTo === void 0 ? void 0 : attachTo.clientWidth;
1037
+ return {
1038
+ menuRef: refs.floating.current,
1039
+ setMenuRef: refs.setFloating,
1040
+ targetWidth,
1041
+ styles: {
1042
+ float: floatingStyles,
1043
+ },
1044
+ };
1045
+ }
1046
+
1047
+ function BaseAutocompleteMenuWrapperInternal({ setMenuRef, floatStyles, targetWidth, visible, children, }) {
1048
+ return (React__default.createElement("div", { className: classnames(styles.options, { [styles.visible]: visible }), ref: setMenuRef, style: Object.assign(Object.assign({}, floatStyles.float), { width: targetWidth }), "data-elevation": "elevated" }, children));
1049
+ }
1050
+ /**
1051
+ * Provides a wrapper for the Autocomplete menu that handles positioning and visibility.
1052
+ * @param attachTo - The element that the menu should be attached to.
1053
+ */
1054
+ function useAutocompleteMenu({ attachTo, }) {
1055
+ const [menuRef, setMenuRef] = React__default.useState(null);
1056
+ const AutocompleteMenuWrapper = useCallback(({ children, visible, }) => {
1057
+ const menuFloatProps = useRepositionMenu(attachTo, visible, true);
1058
+ useEffect(() => {
1059
+ setMenuRef(menuFloatProps.menuRef);
1060
+ }, [menuFloatProps.menuRef]);
1061
+ return (React__default.createElement(BaseAutocompleteMenuWrapper, { floatStyles: menuFloatProps.styles, setMenuRef: menuFloatProps.setMenuRef, targetWidth: menuFloatProps.targetWidth, visible: visible }, children));
1062
+ }, [attachTo]);
1063
+ return { MenuWrapper: AutocompleteMenuWrapper, menuRef };
1064
+ }
1065
+ function BaseAutocompleteMenuWrapper(props) {
1066
+ const mounted = useIsMounted();
1067
+ const menu = React__default.createElement(BaseAutocompleteMenuWrapperInternal, Object.assign({}, props));
1068
+ return mounted.current ? React__default.createElement(FloatingPortal, null, menu) : menu;
1069
+ }
1070
+
1071
+ function isOptionSelected(selectedOption, option) {
1072
+ return Boolean(selectedOption && selectedOption.value === option.value);
1073
+ }
1074
+ /**
1075
+ * Helper function to determine if the option is a group. This is used to
1076
+ * determine if the option contains a list of options for rendering Section
1077
+ * Labels in the Autocomplete component.
1078
+ */
1079
+ function isOptionGroup(option) {
1080
+ return "options" in option;
1081
+ }
1082
+
1083
+ /**
1084
+ * The rendering of the default MenuOption
1085
+ */
1086
+ function MenuOption({ isHighlighted, option, onOptionSelect, isSelected, addSeparators, UNSAFE_className = {}, UNSAFE_style = {}, }) {
1087
+ if (isOptionGroup(option)) {
1088
+ return (React__default.createElement(MenuGroupOptions, { UNSAFE_className: UNSAFE_className.groupOption, option: option, UNSAFE_style: UNSAFE_style.groupOption }));
1089
+ }
1090
+ return (React__default.createElement(BaseMenuOption, { UNSAFE_className: UNSAFE_className.option, UNSAFE_style: UNSAFE_style.option, option: option, isHighlighted: isHighlighted, onOptionSelect: onOptionSelect, addSeparators: addSeparators },
1091
+ React__default.createElement(MenuOptionContent, { option: option, isSelected: isSelected, UNSAFE_className: UNSAFE_className.content, UNSAFE_style: UNSAFE_style.content })));
1092
+ }
1093
+ function MenuOptionContent({ option, isSelected, UNSAFE_className = {}, UNSAFE_style = {}, }) {
1094
+ const iconClassName = classnames(styles.icon, UNSAFE_className.icon);
1095
+ const textClassName = classnames(styles.text, UNSAFE_className.text);
1096
+ const labelClassName = classnames(styles.label, UNSAFE_className.label);
1097
+ const detailsClassName = classnames(styles.details, UNSAFE_className.details);
1098
+ return (React__default.createElement(React__default.Fragment, null,
1099
+ React__default.createElement("div", { className: iconClassName, style: UNSAFE_style.icon }, isSelected && React__default.createElement(Icon, { name: "checkmark", size: "small" })),
1100
+ React__default.createElement("div", { className: textClassName, style: UNSAFE_style.text },
1101
+ React__default.createElement("div", { className: labelClassName, style: UNSAFE_style.label },
1102
+ React__default.createElement(Text, null, option.label),
1103
+ option.description !== undefined && (React__default.createElement(Text, { variation: "subdued" }, option.description))),
1104
+ option.details !== undefined && (React__default.createElement("div", { className: detailsClassName, style: UNSAFE_style.details },
1105
+ React__default.createElement(Text, null, option.details))))));
1106
+ }
1107
+ /**
1108
+ * The rendering of the default MenuGroupOption
1109
+ */
1110
+ function MenuGroupOptions({ option, UNSAFE_className = {}, UNSAFE_style = {}, }) {
1111
+ return (React__default.createElement(BaseMenuGroupOption, { UNSAFE_className: UNSAFE_className.heading, UNSAFE_style: UNSAFE_style.heading },
1112
+ React__default.createElement(Heading, { level: 5 }, option.label)));
1113
+ }
1114
+ function BaseMenuGroupOption({ children, UNSAFE_className = "", UNSAFE_style = {}, }) {
1115
+ const headingClassName = classnames(styles.heading, UNSAFE_className);
1116
+ return (React__default.createElement("div", { className: headingClassName, style: UNSAFE_style }, children));
1117
+ }
1118
+ /**
1119
+ * Renders the base option component. The component takes children and renders them inside a button.
1120
+ */
1121
+ function BaseMenuOption({ option, isHighlighted, onOptionSelect, addSeparators, children, UNSAFE_className = "", UNSAFE_style = {}, }) {
1122
+ const optionClass = classnames(styles.option, {
1123
+ [styles.active]: isHighlighted,
1124
+ [styles.separator]: addSeparators,
1125
+ }, UNSAFE_className);
1126
+ return (React__default.createElement("button", { role: "option", type: "button", className: optionClass, onMouseDown: onOptionSelect === null || onOptionSelect === void 0 ? void 0 : onOptionSelect.bind(undefined, option), style: UNSAFE_style }, children));
1127
+ }
1128
+
1129
+ var KeyboardAction;
1130
+ (function (KeyboardAction) {
1131
+ KeyboardAction[KeyboardAction["Previous"] = -1] = "Previous";
1132
+ KeyboardAction[KeyboardAction["Next"] = 1] = "Next";
1133
+ KeyboardAction[KeyboardAction["Select"] = 0] = "Select";
1134
+ })(KeyboardAction || (KeyboardAction = {}));
1135
+ /**
1136
+ * Hook to handle custom keyboard navigation for the Autocomplete component.
1137
+ * Use this hook if you are using components in the menu that aren't MenuOption or BaseMenuOption.
1138
+ */
1139
+ function useCustomKeyboardNavigation({ onRequestHighlightChange, }) {
1140
+ useOnKeyDown((event) => {
1141
+ onRequestHighlightChange === null || onRequestHighlightChange === void 0 ? void 0 : onRequestHighlightChange(event, KeyboardAction.Next);
1142
+ }, "ArrowDown");
1143
+ useOnKeyDown((event) => {
1144
+ onRequestHighlightChange === null || onRequestHighlightChange === void 0 ? void 0 : onRequestHighlightChange(event, KeyboardAction.Previous);
1145
+ }, "ArrowUp");
1146
+ useOnKeyDown((event) => {
1147
+ onRequestHighlightChange === null || onRequestHighlightChange === void 0 ? void 0 : onRequestHighlightChange(event, KeyboardAction.Select);
1148
+ }, "Enter");
1149
+ }
1150
+ /**
1151
+ * Hook to handle keyboard navigation for the Menu in the Autocomplete component.
1152
+ * If using components in the menu that aren't MenuOption or BaseMenuOption, you should use the `useCustomKeyboardNavigation` hook.
1153
+ */
1154
+ function useKeyboardNavigation({ options, onOptionSelect, menuRef, visible, }) {
1155
+ const [highlightedIndex, setHighlightedIndex] = useState(0);
1156
+ const initialHighlight = options.some(isOptionGroup) ? 1 : 0;
1157
+ useEffect(() => setHighlightedIndex(initialHighlight), [options]);
1158
+ useEffect(() => {
1159
+ var _a, _b;
1160
+ (_b = (_a = menuRef === null || menuRef === void 0 ? void 0 : menuRef.children[highlightedIndex]) === null || _a === void 0 ? void 0 : _a.scrollIntoView) === null || _b === void 0 ? void 0 : _b.call(_a, {
1161
+ behavior: "smooth",
1162
+ block: "nearest",
1163
+ inline: "start",
1164
+ });
1165
+ }, [highlightedIndex]);
1166
+ const onRequestHighlightChange = useCallback((event, direction) => {
1167
+ if (!visible)
1168
+ return;
1169
+ const indexChange = getRequestedIndexChange({
1170
+ event,
1171
+ options,
1172
+ direction,
1173
+ highlightedIndex,
1174
+ });
1175
+ switch (direction) {
1176
+ case KeyboardAction.Previous:
1177
+ setHighlightedIndex(prev => Math.max(0, prev + indexChange));
1178
+ break;
1179
+ case KeyboardAction.Next:
1180
+ setHighlightedIndex(prev => Math.min(options.length - 1, prev + indexChange));
1181
+ break;
1182
+ case KeyboardAction.Select:
1183
+ if (isOptionGroup(options[highlightedIndex]))
1184
+ return;
1185
+ onOptionSelect(options[highlightedIndex]);
1186
+ break;
1187
+ }
1188
+ }, [highlightedIndex, options, onOptionSelect, visible]);
1189
+ useCustomKeyboardNavigation({ onRequestHighlightChange });
1190
+ return { highlightedIndex };
1191
+ }
1192
+ /**
1193
+ * Function to get the requested index change based on the current highlighted index and the direction of the keyboard action.
1194
+ * Accounts for groups in the options array.
1195
+ */
1196
+ function getRequestedIndexChange({ event, options, direction, highlightedIndex, }) {
1197
+ event.preventDefault();
1198
+ const requestedIndex = options[highlightedIndex + direction];
1199
+ return requestedIndex && isOptionGroup(requestedIndex)
1200
+ ? direction + direction
1201
+ : direction;
1202
+ }
1203
+
1204
+ /**
1205
+ * Renders the default Menu for the Autocomplete component.
1206
+ */
1207
+ function DefaultMenu({ options, selectedOption, onOptionSelect, attachTo, visible, }) {
1208
+ const { menuRef, setMenuRef, styles: floatStyles, targetWidth, } = useRepositionMenu(attachTo, visible, false);
1209
+ const detectSeparatorCondition = (option) => option.description || option.details;
1210
+ const addSeparators = options.some(detectSeparatorCondition);
1211
+ const { highlightedIndex } = useKeyboardNavigation({
1212
+ onOptionSelect,
1213
+ options,
1214
+ visible,
1215
+ menuRef,
1216
+ });
1217
+ return (React__default.createElement(BaseAutocompleteMenuWrapper, { setMenuRef, floatStyles, targetWidth, visible }, options === null || options === void 0 ? void 0 : options.map((option, index) => {
1218
+ return (React__default.createElement(MenuOption, { key: index, option: option, isHighlighted: index === highlightedIndex, onOptionSelect: onOptionSelect, isSelected: isOptionSelected(selectedOption, option), addSeparators: addSeparators }));
1219
+ })));
1220
+ }
1221
+
1222
+ function Menu({ options, selectedOption, onOptionSelect, inputFocused, attachTo, inputRef, customRenderMenu, }) {
1223
+ if (customRenderMenu) {
1224
+ return (React__default.createElement(CustomMenu, { attachTo: attachTo, inputFocused: inputFocused, inputRef: inputRef, customRenderMenu: customRenderMenu, options: options, onOptionSelect: onOptionSelect, selectedOption: selectedOption }));
1225
+ }
1226
+ if (!inputFocused || !options.length)
1227
+ return null;
1228
+ return (React__default.createElement(DefaultMenu, { attachTo: attachTo, options: options, onOptionSelect: onOptionSelect, selectedOption: selectedOption, visible: inputFocused }));
1229
+ }
1230
+ /**
1231
+ * Renders the custom Menu for the Autocomplete component.
1232
+ * Provides the menuRef and MenuWrapper to the customRenderMenu function.
1233
+ */
1234
+ function CustomMenu({ options, selectedOption, onOptionSelect, customRenderMenu, attachTo, inputFocused, inputRef, }) {
1235
+ const { MenuWrapper, menuRef } = useAutocompleteMenu({ attachTo });
1236
+ const menuContent = customRenderMenu({
1237
+ options,
1238
+ menuRef,
1239
+ onOptionSelect,
1240
+ selectedOption,
1241
+ inputFocused,
1242
+ MenuWrapper,
1243
+ inputRef,
1244
+ });
1245
+ return menuContent;
1246
+ }
1247
+
1248
+ // Max statements increased to make room for the debounce functions
1249
+ // eslint-disable-next-line max-statements
1250
+ function AutocompleteInternal(_a, ref) {
1251
+ var _b;
1252
+ var { initialOptions = [], value, allowFreeForm = true, size = undefined, debounce: debounceRate = 300, onChange, getOptions, placeholder, onBlur, onFocus, validations, customRenderMenu } = _a, inputProps = __rest(_a, ["initialOptions", "value", "allowFreeForm", "size", "debounce", "onChange", "getOptions", "placeholder", "onBlur", "onFocus", "validations", "customRenderMenu"]);
1253
+ const initialOptionsMemo = useMemo(() => mapToOptions(initialOptions), [initialOptions]);
1254
+ const [options, setOptions] = useState(initialOptionsMemo);
1255
+ const [inputFocused, setInputFocused] = useState(false);
1256
+ const [inputText, setInputText] = useState((_b = value === null || value === void 0 ? void 0 : value.label) !== null && _b !== void 0 ? _b : "");
1257
+ const [autocompleteRef, setAutocompleteRef] = useState(null);
1258
+ const delayedSearch = useDebounce(updateSearch, debounceRate);
1259
+ const inputRef = useRef(null);
1260
+ useEffect(() => {
1261
+ delayedSearch();
1262
+ }, [inputText]);
1263
+ useEffect(() => {
1264
+ var _a;
1265
+ updateInput((_a = value === null || value === void 0 ? void 0 : value.label) !== null && _a !== void 0 ? _a : "");
1266
+ }, [value]);
1267
+ return (React__default.createElement("div", { className: styles.autocomplete, ref: setAutocompleteRef },
1268
+ React__default.createElement(InputText, Object.assign({ ref: mergeRefs([ref, inputRef]), autocomplete: false, size: size, value: inputText, onChange: handleInputChange, placeholder: placeholder, onFocus: handleInputFocus, onBlur: handleInputBlur, validations: validations }, inputProps)),
1269
+ React__default.createElement(Menu, { attachTo: autocompleteRef, inputRef: inputRef, inputFocused: inputFocused, options: options, customRenderMenu: customRenderMenu, selectedOption: value, onOptionSelect: handleMenuChange })));
1270
+ function updateInput(newText) {
1271
+ setInputText(newText);
1272
+ if (newText === "") {
1273
+ setOptions(mapToOptions(initialOptions));
1274
+ }
1275
+ }
1276
+ function updateSearch() {
1277
+ return __awaiter(this, void 0, void 0, function* () {
1278
+ const updatedOptions = yield getOptions(inputText);
1279
+ const filteredOptions = updatedOptions.filter(option => isOptionGroup(option) ? option.options.length > 0 : true);
1280
+ setOptions(mapToOptions(filteredOptions));
1281
+ });
1282
+ }
1283
+ function handleMenuChange(chosenOption) {
1284
+ var _a;
1285
+ onChange(chosenOption);
1286
+ updateInput((_a = chosenOption === null || chosenOption === void 0 ? void 0 : chosenOption.label) !== null && _a !== void 0 ? _a : "");
1287
+ setInputFocused(false);
1288
+ }
1289
+ function handleInputChange(newText) {
1290
+ updateInput(newText);
1291
+ if (allowFreeForm) {
1292
+ onChange({ label: newText });
1293
+ }
1294
+ }
1295
+ function handleInputBlur() {
1296
+ setInputFocused(false);
1297
+ if (value == undefined || value.label !== inputText) {
1298
+ setInputText("");
1299
+ onChange(undefined);
1300
+ }
1301
+ onBlur && onBlur();
1302
+ }
1303
+ function handleInputFocus() {
1304
+ setInputFocused(true);
1305
+ if (onFocus) {
1306
+ onFocus();
1307
+ }
1308
+ }
1309
+ }
1310
+ function mapToOptions(items) {
1311
+ const retVal = items.reduce((result, item) => {
1312
+ result.push(item);
1313
+ if (isOptionGroup(item) && item.options) {
1314
+ result = result.concat(item.options);
1315
+ }
1316
+ return result;
1317
+ }, []);
1318
+ return retVal;
1319
+ }
1320
+ // Casts the Generics to the forward ref so autocomplete works as expected for consumers
1321
+ const Autocomplete$1 = forwardRef(AutocompleteInternal);
1322
+
1323
+ // Convenience builder helpers (optional usage)
1324
+ // Helper to improve inference from inline menu literals
1325
+ function defineMenu(menu) {
1326
+ return menu;
1327
+ }
1328
+
1329
+ function isNewAutocompleteProps(props) {
1330
+ return props.version === 2;
1331
+ }
1332
+ function AutocompleteShim(props, ref) {
1333
+ if (isNewAutocompleteProps(props)) {
1334
+ return (React__default.createElement(AutocompleteRebuilt, Object.assign({}, props, { ref: ref })));
1335
+ }
1336
+ return React__default.createElement(Autocomplete$1, Object.assign({}, props, { ref: ref }));
1337
+ }
1338
+ const AutocompleteForwarded = forwardRef(AutocompleteShim);
1339
+ AutocompleteForwarded.displayName = "Autocomplete";
1340
+ const Autocomplete = AutocompleteForwarded;
1341
+
1342
+ export { Autocomplete, BaseAutocompleteMenuWrapper, BaseMenuGroupOption, BaseMenuOption, KeyboardAction, MenuOption, defineMenu, getRequestedIndexChange, isOptionGroup, isOptionSelected, useAutocompleteMenu, useCustomKeyboardNavigation, useKeyboardNavigation, useRepositionMenu };