@cube-dev/ui-kit 0.0.0-canary-eceba5c → 0.0.0-canary-951e813

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 (521) hide show
  1. package/es/_internal/hooks/index.js +1 -1
  2. package/es/_internal/hooks/use-chained-callback.js +1 -1
  3. package/es/_internal/hooks/use-debounced-value.js +1 -1
  4. package/es/_internal/hooks/use-deprecation-warning.js +1 -1
  5. package/es/_internal/hooks/use-effect-once.js +1 -1
  6. package/es/_internal/hooks/use-event.js +1 -1
  7. package/es/_internal/hooks/use-is-first-render.js +1 -1
  8. package/es/_internal/hooks/use-sync-ref.js +1 -1
  9. package/es/_internal/hooks/use-timer/index.js +1 -1
  10. package/es/_internal/hooks/use-timer/timer.js +1 -1
  11. package/es/_internal/hooks/use-timer/use-timer.js +1 -1
  12. package/es/_internal/hooks/use-update-effect.js +1 -1
  13. package/es/_internal/hooks/use-warn.js +1 -1
  14. package/es/_internal/index.js +1 -1
  15. package/es/components/Block.js +1 -1
  16. package/es/components/GlobalStyles.js +1 -1
  17. package/es/components/GridProvider.js +1 -1
  18. package/es/components/HiddenInput.js +1 -1
  19. package/es/components/Item.js +1 -1
  20. package/es/components/OpenTrasition.js +1 -1
  21. package/es/components/Root.js +1 -1
  22. package/es/components/actions/Action/Action.js +1 -1
  23. package/es/components/actions/Button/Button.js +1 -1
  24. package/es/components/actions/Button/index.js +1 -1
  25. package/es/components/actions/ButtonGroup/ButtonGroup.js +1 -1
  26. package/es/components/actions/CommandMenu/CommandMenu.js +1 -1
  27. package/es/components/actions/CommandMenu/index.js +1 -1
  28. package/es/components/actions/CommandMenu/styled.js +1 -1
  29. package/es/components/actions/ItemAction/ItemAction.js +7 -2
  30. package/es/components/actions/ItemAction/index.js +1 -1
  31. package/es/components/actions/ItemButton/ItemButton.js +1 -1
  32. package/es/components/actions/ItemButton/index.js +1 -1
  33. package/es/components/actions/Link/Link.js +1 -1
  34. package/es/components/actions/Menu/Menu.js +1 -1
  35. package/es/components/actions/Menu/MenuItem.js +1 -1
  36. package/es/components/actions/Menu/MenuSection.js +1 -1
  37. package/es/components/actions/Menu/MenuTrigger.js +1 -1
  38. package/es/components/actions/Menu/SubMenuTrigger.js +1 -1
  39. package/es/components/actions/Menu/SubmenuTriggerContext.js +1 -1
  40. package/es/components/actions/Menu/context.js +1 -1
  41. package/es/components/actions/Menu/index.js +1 -1
  42. package/es/components/actions/Menu/styled.js +1 -1
  43. package/es/components/actions/index.js +1 -1
  44. package/es/components/actions/use-action.js +1 -1
  45. package/es/components/actions/use-anchored-menu.js +1 -1
  46. package/es/components/actions/use-context-menu.js +1 -1
  47. package/es/components/content/ActiveZone/ActiveZone.js +1 -1
  48. package/es/components/content/Alert/Alert.js +1 -1
  49. package/es/components/content/Alert/index.js +1 -1
  50. package/es/components/content/Alert/types.js +1 -1
  51. package/es/components/content/Alert/use-alert.js +1 -1
  52. package/es/components/content/Avatar/Avatar.js +1 -1
  53. package/es/components/content/Badge/Badge.js +1 -1
  54. package/es/components/content/Card/Card.js +1 -1
  55. package/es/components/content/Content.js +1 -1
  56. package/es/components/content/CopyPasteBlock/CopyPasteBlock.js +1 -1
  57. package/es/components/content/CopyPasteBlock/index.js +1 -1
  58. package/es/components/content/CopySnippet/CopySnippet.js +1 -1
  59. package/es/components/content/CopySnippet/index.js +1 -1
  60. package/es/components/content/Divider.js +1 -1
  61. package/es/components/content/Footer.js +1 -1
  62. package/es/components/content/Header.js +1 -1
  63. package/es/components/content/HotKeys/HotKeys.js +1 -1
  64. package/es/components/content/HotKeys/index.js +1 -1
  65. package/es/components/content/ItemBase/ItemBase.js +1 -1
  66. package/es/components/content/ItemBase/index.js +1 -1
  67. package/es/components/content/List/SectionHeading.js +1 -1
  68. package/es/components/content/List/index.js +1 -1
  69. package/es/components/content/Paragraph.js +1 -1
  70. package/es/components/content/Placeholder/Placeholder.js +1 -1
  71. package/es/components/content/PrismCode/PrismCode.js +1 -1
  72. package/es/components/content/PrismCode/prismSetup.js +1 -1
  73. package/es/components/content/PrismDiffCode/PrismDiffCode.js +1 -1
  74. package/es/components/content/Result/Result.js +1 -1
  75. package/es/components/content/Skeleton/Skeleton.js +1 -1
  76. package/es/components/content/Tag/Tag.js +1 -1
  77. package/es/components/content/Text.js +1 -1
  78. package/es/components/content/Title.js +1 -1
  79. package/es/components/fields/Checkbox/Checkbox.js +1 -1
  80. package/es/components/fields/Checkbox/CheckboxGroup.js +1 -1
  81. package/es/components/fields/Checkbox/context.js +1 -1
  82. package/es/components/fields/Checkbox/index.js +1 -1
  83. package/es/components/fields/ComboBox/ComboBox.js +693 -180
  84. package/es/components/fields/ComboBox/index.js +2 -2
  85. package/es/components/fields/DatePicker/DateInput.js +1 -1
  86. package/es/components/fields/DatePicker/DateInputBase.js +1 -1
  87. package/es/components/fields/DatePicker/DatePicker.js +1 -1
  88. package/es/components/fields/DatePicker/DatePickerButton.js +1 -1
  89. package/es/components/fields/DatePicker/DatePickerElement.js +1 -1
  90. package/es/components/fields/DatePicker/DatePickerInput.js +1 -1
  91. package/es/components/fields/DatePicker/DatePickerSegment.js +1 -1
  92. package/es/components/fields/DatePicker/DateRangePicker.js +1 -1
  93. package/es/components/fields/DatePicker/DateRangeSeparatedPicker.js +1 -1
  94. package/es/components/fields/DatePicker/TimeInput.js +1 -1
  95. package/es/components/fields/DatePicker/index.js +1 -1
  96. package/es/components/fields/DatePicker/intl.js +1 -1
  97. package/es/components/fields/DatePicker/parseDate.js +1 -1
  98. package/es/components/fields/DatePicker/props.js +1 -1
  99. package/es/components/fields/DatePicker/types.js +1 -1
  100. package/es/components/fields/DatePicker/utils.js +1 -1
  101. package/es/components/fields/FileInput/FileInput.js +1 -1
  102. package/es/components/fields/FilterListBox/FilterListBox.js +42 -47
  103. package/es/components/fields/FilterListBox/index.js +1 -1
  104. package/es/components/fields/FilterPicker/FilterPicker.js +78 -311
  105. package/es/components/fields/FilterPicker/index.js +1 -1
  106. package/es/components/fields/Input/Input.js +1 -1
  107. package/es/components/fields/Input/index.js +1 -1
  108. package/es/components/fields/LegacyComboBox/LegacyComboBox.js +290 -0
  109. package/es/components/fields/LegacyComboBox/index.js +10 -0
  110. package/es/components/fields/ListBox/ListBox.js +35 -5
  111. package/es/components/fields/ListBox/index.js +1 -1
  112. package/es/components/fields/NumberInput/NumberInput.js +1 -1
  113. package/es/components/fields/NumberInput/StepButton.js +1 -1
  114. package/es/components/fields/PasswordInput/PasswordInput.js +1 -1
  115. package/es/components/fields/RadioGroup/Radio.js +1 -1
  116. package/es/components/fields/RadioGroup/RadioGroup.js +1 -1
  117. package/es/components/fields/RadioGroup/context.js +1 -1
  118. package/es/components/fields/RadioGroup/index.js +1 -1
  119. package/es/components/fields/SearchInput/SearchInput.js +1 -1
  120. package/es/components/fields/SearchInput/index.js +1 -1
  121. package/es/components/fields/Select/Select.js +56 -50
  122. package/es/components/fields/Select/index.js +1 -1
  123. package/es/components/fields/Slider/Gradation.js +1 -1
  124. package/es/components/fields/Slider/Header.js +1 -1
  125. package/es/components/fields/Slider/RangeSlider.js +1 -1
  126. package/es/components/fields/Slider/Slider.js +1 -1
  127. package/es/components/fields/Slider/SliderBase.js +1 -1
  128. package/es/components/fields/Slider/SliderInput.js +1 -1
  129. package/es/components/fields/Slider/SliderThumb.js +1 -1
  130. package/es/components/fields/Slider/SliderTrack.js +1 -1
  131. package/es/components/fields/Slider/elements.js +1 -1
  132. package/es/components/fields/Slider/index.js +1 -1
  133. package/es/components/fields/Slider/types.js +1 -1
  134. package/es/components/fields/Switch/Switch.js +12 -19
  135. package/es/components/fields/Switch/index.js +1 -1
  136. package/es/components/fields/TextArea/TextArea.js +1 -1
  137. package/es/components/fields/TextArea/index.js +1 -1
  138. package/es/components/fields/TextInput/TextInput.js +1 -1
  139. package/es/components/fields/TextInput/TextInputBase.js +1 -1
  140. package/es/components/fields/TextInput/index.js +1 -1
  141. package/es/components/fields/TextInputMapper/TextInputMapper.js +2 -2
  142. package/es/components/fields/TextInputMapper/index.js +1 -1
  143. package/es/components/fields/index.js +2 -1
  144. package/es/components/form/FieldWrapper/FieldWrapper.js +1 -1
  145. package/es/components/form/FieldWrapper/extract-field-wrapper-props.js +1 -1
  146. package/es/components/form/FieldWrapper/index.js +1 -1
  147. package/es/components/form/FieldWrapper/types.js +1 -1
  148. package/es/components/form/Form/Field.js +1 -1
  149. package/es/components/form/Form/Form.js +1 -1
  150. package/es/components/form/Form/ResetButton/ResetButton.js +1 -1
  151. package/es/components/form/Form/ResetButton/index.js +1 -1
  152. package/es/components/form/Form/SubmitButton/SubmitButton.js +1 -1
  153. package/es/components/form/Form/SubmitButton/index.js +1 -1
  154. package/es/components/form/Form/SubmitError.js +1 -1
  155. package/es/components/form/Form/index.js +1 -1
  156. package/es/components/form/Form/types.js +1 -1
  157. package/es/components/form/Form/use-field/index.js +1 -1
  158. package/es/components/form/Form/use-field/types.js +1 -1
  159. package/es/components/form/Form/use-field/use-field-props.js +1 -1
  160. package/es/components/form/Form/use-field/use-field.js +1 -1
  161. package/es/components/form/Form/use-form.js +1 -1
  162. package/es/components/form/Form/validation.js +1 -1
  163. package/es/components/form/Label.js +1 -1
  164. package/es/components/form/index.js +1 -1
  165. package/es/components/form/wrapper.js +1 -1
  166. package/es/components/helpers/DisplayTransition/DisplayTransition.js +242 -0
  167. package/es/components/helpers/index.js +10 -0
  168. package/es/components/layout/Flex.js +1 -1
  169. package/es/components/layout/Flow.js +1 -1
  170. package/es/components/layout/Grid.js +1 -1
  171. package/es/components/layout/Panel.js +1 -1
  172. package/es/components/layout/Prefix.js +1 -1
  173. package/es/components/layout/ResizablePanel.js +1 -1
  174. package/es/components/layout/Space.js +1 -1
  175. package/es/components/layout/Suffix.js +1 -1
  176. package/es/components/navigation/LegacyTabs/LegacyTabs.js +1 -1
  177. package/es/components/organisms/FileTabs/FileTabs.js +1 -1
  178. package/es/components/organisms/StatsCard/StatsCard.js +1 -1
  179. package/es/components/other/Base64Upload/Base64Upload.js +1 -1
  180. package/es/components/other/Calendar/Calendar.js +1 -1
  181. package/es/components/other/Calendar/CalendarCell.js +1 -1
  182. package/es/components/other/Calendar/CalendarGrid.js +1 -1
  183. package/es/components/other/Calendar/RangeCalendar.js +1 -1
  184. package/es/components/other/CloudLogo/CloudLogo.js +1 -1
  185. package/es/components/overlays/AlertDialog/AlertDialog.js +1 -1
  186. package/es/components/overlays/AlertDialog/AlertDialogApiProvider.js +1 -1
  187. package/es/components/overlays/AlertDialog/AlertDialogZone.js +1 -1
  188. package/es/components/overlays/AlertDialog/index.js +1 -1
  189. package/es/components/overlays/AlertDialog/types.js +1 -1
  190. package/es/components/overlays/Dialog/Dialog.js +1 -1
  191. package/es/components/overlays/Dialog/DialogContainer.js +1 -1
  192. package/es/components/overlays/Dialog/DialogForm.js +1 -1
  193. package/es/components/overlays/Dialog/DialogTrigger.js +1 -1
  194. package/es/components/overlays/Dialog/context.js +1 -1
  195. package/es/components/overlays/Dialog/index.js +1 -1
  196. package/es/components/overlays/Dialog/use-dialog-container.js +1 -1
  197. package/es/components/overlays/Modal/Modal.js +1 -1
  198. package/es/components/overlays/Modal/OpenTransition.js +1 -1
  199. package/es/components/overlays/Modal/Overlay.js +1 -1
  200. package/es/components/overlays/Modal/Popover.js +1 -1
  201. package/es/components/overlays/Modal/Tray.js +1 -1
  202. package/es/components/overlays/Modal/Underlay.js +1 -1
  203. package/es/components/overlays/Modal/index.js +1 -1
  204. package/es/components/overlays/Modal/types.js +1 -1
  205. package/es/components/overlays/NewNotifications/Bar/FloatingNotification.js +1 -1
  206. package/es/components/overlays/NewNotifications/Bar/NotificationsBar.js +1 -1
  207. package/es/components/overlays/NewNotifications/Bar/TransitionComponent.js +1 -1
  208. package/es/components/overlays/NewNotifications/Bar/index.js +1 -1
  209. package/es/components/overlays/NewNotifications/Dialog/NotificationsDialogContext.js +1 -1
  210. package/es/components/overlays/NewNotifications/Dialog/NotificationsDialogTrigger.js +1 -1
  211. package/es/components/overlays/NewNotifications/Dialog/index.js +1 -1
  212. package/es/components/overlays/NewNotifications/Notification.js +1 -1
  213. package/es/components/overlays/NewNotifications/NotificationView/NotificationAction.js +1 -1
  214. package/es/components/overlays/NewNotifications/NotificationView/NotificationCloseButton.js +1 -1
  215. package/es/components/overlays/NewNotifications/NotificationView/NotificationDescription.js +1 -1
  216. package/es/components/overlays/NewNotifications/NotificationView/NotificationFooter.js +1 -1
  217. package/es/components/overlays/NewNotifications/NotificationView/NotificationHeader.js +1 -1
  218. package/es/components/overlays/NewNotifications/NotificationView/NotificationIcon.js +1 -1
  219. package/es/components/overlays/NewNotifications/NotificationView/NotificationProvider.js +1 -1
  220. package/es/components/overlays/NewNotifications/NotificationView/NotificationView.js +1 -1
  221. package/es/components/overlays/NewNotifications/NotificationView/index.js +1 -1
  222. package/es/components/overlays/NewNotifications/NotificationView/types.js +1 -1
  223. package/es/components/overlays/NewNotifications/NotificationsContext/NotificationsContext.js +1 -1
  224. package/es/components/overlays/NewNotifications/NotificationsContext/NotificationsProvider.js +1 -1
  225. package/es/components/overlays/NewNotifications/NotificationsContext/index.js +1 -1
  226. package/es/components/overlays/NewNotifications/NotificationsContext/use-notifications.js +1 -1
  227. package/es/components/overlays/NewNotifications/NotificationsList/NotificationsList.js +1 -1
  228. package/es/components/overlays/NewNotifications/NotificationsList/NotificationsListItem.js +1 -1
  229. package/es/components/overlays/NewNotifications/NotificationsList/index.js +1 -1
  230. package/es/components/overlays/NewNotifications/NotificationsList/types.js +1 -1
  231. package/es/components/overlays/NewNotifications/hooks/index.js +1 -1
  232. package/es/components/overlays/NewNotifications/hooks/types.js +1 -1
  233. package/es/components/overlays/NewNotifications/hooks/use-notification-list-item.js +1 -1
  234. package/es/components/overlays/NewNotifications/hooks/use-notifications-api.js +1 -1
  235. package/es/components/overlays/NewNotifications/hooks/use-notifications-list.js +1 -1
  236. package/es/components/overlays/NewNotifications/hooks/use-notifications-observer.js +1 -1
  237. package/es/components/overlays/NewNotifications/index.js +1 -1
  238. package/es/components/overlays/NewNotifications/types.js +1 -1
  239. package/es/components/overlays/Notification/Notification.js +1 -1
  240. package/es/components/overlays/OverlayWrapper.js +1 -1
  241. package/es/components/overlays/Toasts/Toast.js +1 -1
  242. package/es/components/overlays/Toasts/index.js +1 -1
  243. package/es/components/overlays/Toasts/types.js +1 -1
  244. package/es/components/overlays/Toasts/use-toasts-api.js +1 -1
  245. package/es/components/overlays/Tooltip/Tooltip.js +30 -18
  246. package/es/components/overlays/Tooltip/TooltipProvider.js +2 -2
  247. package/es/components/overlays/Tooltip/TooltipTrigger.js +25 -7
  248. package/es/components/overlays/Tooltip/context.js +1 -1
  249. package/es/components/overlays/Tooltip/index.js +1 -1
  250. package/es/components/portal/Portal.js +1 -1
  251. package/es/components/portal/PortalProvider.js +1 -1
  252. package/es/components/portal/index.js +1 -1
  253. package/es/components/portal/types.js +1 -1
  254. package/es/components/portal/usePortal.js +1 -1
  255. package/es/components/shared/InvalidIcon.js +1 -1
  256. package/es/components/shared/ValidIcon.js +1 -1
  257. package/es/components/status/LoadingAnimation/LoadingAnimation.js +1 -1
  258. package/es/components/status/LoadingAnimation/index.js +1 -1
  259. package/es/components/status/Spin/Cube.js +1 -1
  260. package/es/components/status/Spin/InternalSpinner.js +1 -1
  261. package/es/components/status/Spin/Spin.js +1 -1
  262. package/es/components/status/Spin/SpinsContainer.js +1 -1
  263. package/es/components/status/Spin/index.js +1 -1
  264. package/es/components/status/Spin/types.js +1 -1
  265. package/es/components/status/index.js +1 -1
  266. package/es/data/item-themes.js +1 -1
  267. package/es/data/themes.js +1 -1
  268. package/es/icons/AdjustmentsHorizontalIcon.js +1 -1
  269. package/es/icons/AdjustmentsIcon.js +1 -1
  270. package/es/icons/AiIcon.js +1 -1
  271. package/es/icons/AreaChartIcon.js +1 -1
  272. package/es/icons/BackwardIcon.js +1 -1
  273. package/es/icons/BarChartIcon.js +1 -1
  274. package/es/icons/BellFilledIcon.js +1 -1
  275. package/es/icons/BellIcon.js +1 -1
  276. package/es/icons/BooleanIcon.js +1 -1
  277. package/es/icons/CalendarEditIcon.js +1 -1
  278. package/es/icons/CalendarIcon.js +1 -1
  279. package/es/icons/CaretDownIcon.js +1 -1
  280. package/es/icons/CaretUpIcon.js +1 -1
  281. package/es/icons/ChartAreaStackedIcon.js +1 -1
  282. package/es/icons/ChartAreaStackedPercentageIcon.js +1 -1
  283. package/es/icons/ChartBarGroupedHorizontalIcon.js +1 -1
  284. package/es/icons/ChartBarGroupedIcon.js +1 -1
  285. package/es/icons/ChartBarHorizontalIcon.js +1 -1
  286. package/es/icons/ChartBarLineIcon.js +1 -1
  287. package/es/icons/ChartBarStackedHorizontalIcon.js +1 -1
  288. package/es/icons/ChartBarStackedIcon.js +1 -1
  289. package/es/icons/ChartBarStackedPercentageHorizontalIcon.js +1 -1
  290. package/es/icons/ChartBarStackedPercentageIcon.js +1 -1
  291. package/es/icons/ChartBoxPlot2Icon.js +1 -1
  292. package/es/icons/ChartBoxPlotIcon.js +1 -1
  293. package/es/icons/ChartBubbleIcon.js +1 -1
  294. package/es/icons/ChartDonut2Icon.js +1 -1
  295. package/es/icons/ChartFunnelIcon.js +1 -1
  296. package/es/icons/ChartHeatmapIcon.js +1 -1
  297. package/es/icons/ChartKPIIcon.js +1 -1
  298. package/es/icons/ChartPie2Icon.js +1 -1
  299. package/es/icons/ChartScatterIcon.js +1 -1
  300. package/es/icons/CheckCircleFilledIcon.js +1 -1
  301. package/es/icons/CheckCircleIcon.js +1 -1
  302. package/es/icons/CheckIcon.js +1 -1
  303. package/es/icons/CircleFilledIcon.js +1 -1
  304. package/es/icons/ClearIcon.js +1 -1
  305. package/es/icons/CloseCircleFilledIcon.js +1 -1
  306. package/es/icons/CloseCircleIcon.js +1 -1
  307. package/es/icons/CloseIcon.js +1 -1
  308. package/es/icons/CodeIcon.js +1 -1
  309. package/es/icons/CopyIcon.js +1 -1
  310. package/es/icons/CountIcon.js +1 -1
  311. package/es/icons/CubeIcon.js +1 -1
  312. package/es/icons/CubePauseIcon.js +1 -1
  313. package/es/icons/CubePlayIcon.js +1 -1
  314. package/es/icons/CurrencyDollarIcon.js +1 -1
  315. package/es/icons/DangerIcon.js +1 -1
  316. package/es/icons/DashboardIcon.js +1 -1
  317. package/es/icons/DatabaseIcon.js +1 -1
  318. package/es/icons/DecimalDecreaseIcon.js +1 -1
  319. package/es/icons/DecimalIncreaseIcon.js +1 -1
  320. package/es/icons/DirectionIcon.js +1 -1
  321. package/es/icons/DonutIcon.js +1 -1
  322. package/es/icons/DownIcon.js +1 -1
  323. package/es/icons/EditIcon.js +1 -1
  324. package/es/icons/ExclamationCircleFilledIcon.js +1 -1
  325. package/es/icons/ExclamationCircleIcon.js +1 -1
  326. package/es/icons/ExclamationIcon.js +1 -1
  327. package/es/icons/EyeIcon.js +1 -1
  328. package/es/icons/EyeInvisibleIcon.js +1 -1
  329. package/es/icons/FilterIcon.js +1 -1
  330. package/es/icons/FolderFilledIcon.js +1 -1
  331. package/es/icons/FolderIcon.js +1 -1
  332. package/es/icons/FolderOpenFilledIcon.js +1 -1
  333. package/es/icons/FolderOpenIcon.js +1 -1
  334. package/es/icons/ForwardIcon.js +1 -1
  335. package/es/icons/HierarchyIcon.js +1 -1
  336. package/es/icons/Icon.js +1 -1
  337. package/es/icons/InfoCircleIcon.js +1 -1
  338. package/es/icons/InfoIcon.js +1 -1
  339. package/es/icons/KeyIcon.js +1 -1
  340. package/es/icons/LeftIcon.js +1 -1
  341. package/es/icons/LineChartIcon.js +1 -1
  342. package/es/icons/LoadingIcon.js +1 -1
  343. package/es/icons/LockFilledIcon.js +1 -1
  344. package/es/icons/LockIcon.js +1 -1
  345. package/es/icons/MoreIcon.js +1 -1
  346. package/es/icons/NotAllowedIcon.js +1 -1
  347. package/es/icons/Number123Icon.js +1 -1
  348. package/es/icons/NumberIcon.js +1 -1
  349. package/es/icons/PauseCircleFilledIcon.js +1 -1
  350. package/es/icons/PauseCircleIcon.js +1 -1
  351. package/es/icons/PauseIcon.js +1 -1
  352. package/es/icons/PercentageIcon.js +1 -1
  353. package/es/icons/PieChartIcon.js +1 -1
  354. package/es/icons/PlayCircleIcon.js +1 -1
  355. package/es/icons/PlayIcon.js +1 -1
  356. package/es/icons/PlusIcon.js +1 -1
  357. package/es/icons/ReloadIcon.js +1 -1
  358. package/es/icons/ReportIcon.js +1 -1
  359. package/es/icons/ReturnIcon.js +1 -1
  360. package/es/icons/RightIcon.js +1 -1
  361. package/es/icons/SchemeIcon.js +1 -1
  362. package/es/icons/SearchIcon.js +1 -1
  363. package/es/icons/SettingsIcon.js +1 -1
  364. package/es/icons/ShieldFilledIcon.js +1 -1
  365. package/es/icons/ShieldIcon.js +1 -1
  366. package/es/icons/SlashIcon.js +1 -1
  367. package/es/icons/SparklesIcon.js +1 -1
  368. package/es/icons/SqlIcon.js +1 -1
  369. package/es/icons/StatsIcon.js +1 -1
  370. package/es/icons/StopIcon.js +1 -1
  371. package/es/icons/StringIcon.js +1 -1
  372. package/es/icons/SwitchIcon.js +1 -1
  373. package/es/icons/TableIcon.js +1 -1
  374. package/es/icons/ThumbsDownIcon.js +1 -1
  375. package/es/icons/ThumbsUpIcon.js +1 -1
  376. package/es/icons/ThunderboltCrossedIcon.js +1 -1
  377. package/es/icons/ThunderboltFilledIcon.js +1 -1
  378. package/es/icons/ThunderboltIcon.js +1 -1
  379. package/es/icons/TimeIcon.js +1 -1
  380. package/es/icons/UnlockIcon.js +1 -1
  381. package/es/icons/UpIcon.js +1 -1
  382. package/es/icons/UserGroupIcon.js +1 -1
  383. package/es/icons/UserIcon.js +1 -1
  384. package/es/icons/UserLockIcon.js +1 -1
  385. package/es/icons/ViewIcon.js +1 -1
  386. package/es/icons/WarningFilledIcon.js +1 -1
  387. package/es/icons/WarningIcon.js +1 -1
  388. package/es/icons/add-new-icon.js +1 -1
  389. package/es/icons/index.js +1 -1
  390. package/es/icons/wrap-icon.js +1 -1
  391. package/es/index.js +2 -1
  392. package/es/provider.js +1 -1
  393. package/es/providers/TrackingProvider.js +1 -1
  394. package/es/providers/navigation.types.js +1 -1
  395. package/es/providers/navigationAdapter.default.js +1 -1
  396. package/es/services/notification.js +1 -1
  397. package/es/shared/form.js +1 -1
  398. package/es/shared/index.js +1 -1
  399. package/es/stories/Form.legacy-stories.js +1 -1
  400. package/es/stories/FormFieldArgs.js +1 -1
  401. package/es/stories/Layout.stories.js +1 -1
  402. package/es/stories/Tasty.stories.js +1 -1
  403. package/es/stories/components/ConfirmDeletionDialogForm.js +1 -1
  404. package/es/stories/components/DialogFormApp.js +1 -1
  405. package/es/stories/components/StyledButton.js +1 -1
  406. package/es/stories/lists/baseProps.js +1 -1
  407. package/es/tasty/debug.js +1 -1
  408. package/es/tasty/index.js +1 -1
  409. package/es/tasty/injector/index.js +1 -1
  410. package/es/tasty/injector/injector.js +1 -1
  411. package/es/tasty/injector/sheet-manager.js +1 -1
  412. package/es/tasty/injector/types.js +1 -1
  413. package/es/tasty/parser/classify.js +1 -1
  414. package/es/tasty/parser/const.js +1 -1
  415. package/es/tasty/parser/lru.js +1 -1
  416. package/es/tasty/parser/parser.js +1 -1
  417. package/es/tasty/parser/tokenizer.js +1 -1
  418. package/es/tasty/parser/types.js +1 -1
  419. package/es/tasty/providers/BreakpointsProvider.js +1 -1
  420. package/es/tasty/styles/align.js +1 -1
  421. package/es/tasty/styles/border.js +1 -1
  422. package/es/tasty/styles/boxShadow.combinator.js +1 -1
  423. package/es/tasty/styles/color.js +1 -1
  424. package/es/tasty/styles/createStyle.js +1 -1
  425. package/es/tasty/styles/dimension.js +1 -1
  426. package/es/tasty/styles/display.js +1 -1
  427. package/es/tasty/styles/fade.js +1 -1
  428. package/es/tasty/styles/fill.js +1 -1
  429. package/es/tasty/styles/flow.js +1 -1
  430. package/es/tasty/styles/font.js +1 -1
  431. package/es/tasty/styles/fontStyle.js +1 -1
  432. package/es/tasty/styles/gap.js +1 -1
  433. package/es/tasty/styles/groupRadius.js +1 -1
  434. package/es/tasty/styles/height.js +1 -1
  435. package/es/tasty/styles/index.js +1 -1
  436. package/es/tasty/styles/inset.js +1 -1
  437. package/es/tasty/styles/justify.js +1 -1
  438. package/es/tasty/styles/list.js +1 -1
  439. package/es/tasty/styles/margin.js +1 -1
  440. package/es/tasty/styles/outline.js +1 -1
  441. package/es/tasty/styles/padding.js +1 -1
  442. package/es/tasty/styles/place.js +1 -1
  443. package/es/tasty/styles/predefined.js +1 -1
  444. package/es/tasty/styles/preset.js +1 -1
  445. package/es/tasty/styles/radius.js +1 -1
  446. package/es/tasty/styles/reset.js +1 -1
  447. package/es/tasty/styles/scrollbar.js +1 -1
  448. package/es/tasty/styles/shadow.js +1 -1
  449. package/es/tasty/styles/styledScrollbar.js +1 -1
  450. package/es/tasty/styles/transition.js +1 -1
  451. package/es/tasty/styles/types.js +1 -1
  452. package/es/tasty/styles/width.js +1 -1
  453. package/es/tasty/tasty.js +1 -1
  454. package/es/tasty/types.js +1 -1
  455. package/es/tasty/utils/cache-wrapper.js +1 -1
  456. package/es/tasty/utils/case-converter.js +1 -1
  457. package/es/tasty/utils/colors.js +1 -1
  458. package/es/tasty/utils/dotize.js +1 -1
  459. package/es/tasty/utils/filterBaseProps.js +1 -1
  460. package/es/tasty/utils/getDisplayName.js +1 -1
  461. package/es/tasty/utils/getModCombinations.js +1 -1
  462. package/es/tasty/utils/isDevEnv.js +1 -1
  463. package/es/tasty/utils/mergeStyles.js +1 -1
  464. package/es/tasty/utils/modAttrs.js +1 -1
  465. package/es/tasty/utils/renderStyles.js +1 -1
  466. package/es/tasty/utils/responsive.js +1 -1
  467. package/es/tasty/utils/string.js +1 -1
  468. package/es/tasty/utils/styles.js +1 -1
  469. package/es/tasty/utils/warnings.js +1 -1
  470. package/es/tokens.js +1 -1
  471. package/es/type-checks.js +1 -1
  472. package/es/utils/ResizeSensor.js +1 -1
  473. package/es/utils/modules.js +1 -1
  474. package/es/utils/promise.js +1 -1
  475. package/es/utils/random.js +1 -1
  476. package/es/utils/range.js +1 -1
  477. package/es/utils/react/Slots.js +1 -1
  478. package/es/utils/react/chain.js +1 -1
  479. package/es/utils/react/forwardRefWithGenerics.js +1 -1
  480. package/es/utils/react/index.js +2 -2
  481. package/es/utils/react/interactions.js +1 -1
  482. package/es/utils/react/isTextOnly.js +1 -1
  483. package/es/utils/react/mapProps.js +1 -1
  484. package/es/utils/react/mergeProps.js +1 -1
  485. package/es/utils/react/nullableValue.js +1 -1
  486. package/es/utils/react/sharedStore.js +1 -1
  487. package/es/utils/react/useCombinedRefs.js +11 -6
  488. package/es/utils/react/useControlledFocusVisible.js +1 -1
  489. package/es/utils/react/useEventBus.js +1 -1
  490. package/es/utils/react/useId.js +1 -1
  491. package/es/utils/react/useIsDarwin.js +1 -1
  492. package/es/utils/react/useKeySymbols.js +1 -1
  493. package/es/utils/react/useLayoutEffect.js +1 -1
  494. package/es/utils/react/useQaProps.js +1 -1
  495. package/es/utils/react/useViewportSize.js +1 -1
  496. package/es/utils/react/wrapNodeIfPlain.js +1 -1
  497. package/es/utils/transitions.js +1 -1
  498. package/es/utils/tree.js +1 -1
  499. package/es/utils/warnings.js +1 -1
  500. package/es/version.js +2 -2
  501. package/package.json +1 -1
  502. package/types/components/GridProvider.d.ts +1 -1
  503. package/types/components/fields/ComboBox/ComboBox.d.ts +91 -30
  504. package/types/components/fields/ComboBox/index.d.ts +2 -1
  505. package/types/components/fields/FilterListBox/FilterListBox.d.ts +7 -0
  506. package/types/components/fields/FilterPicker/FilterPicker.d.ts +9 -2
  507. package/types/components/fields/LegacyComboBox/LegacyComboBox.d.ts +49 -0
  508. package/types/components/fields/LegacyComboBox/index.d.ts +1 -0
  509. package/types/components/fields/ListBox/ListBox.d.ts +5 -0
  510. package/types/components/fields/Select/Select.d.ts +2 -1
  511. package/types/components/fields/Switch/Switch.d.ts +1 -1
  512. package/types/components/fields/index.d.ts +1 -0
  513. package/types/components/helpers/DisplayTransition/DisplayTransition.d.ts +24 -0
  514. package/types/components/helpers/index.d.ts +1 -0
  515. package/types/components/layout/Prefix.d.ts +1 -1
  516. package/types/components/layout/Suffix.d.ts +1 -1
  517. package/types/components/overlays/Tooltip/TooltipTrigger.d.ts +5 -0
  518. package/types/components/overlays/Tooltip/context.d.ts +6 -1
  519. package/types/index.d.ts +2 -0
  520. package/types/utils/react/index.d.ts +1 -1
  521. package/types/utils/react/useCombinedRefs.d.ts +3 -2
@@ -1,16 +1,16 @@
1
1
  /**
2
2
  * @license MIT
3
3
  * author: Cube Dev Team
4
- * @cube-dev/ui-kit v0.0.0-canary-eceba5c
4
+ * @cube-dev/ui-kit v0.0.0-canary-951e813
5
5
  * Released under the MIT license.
6
6
  */
7
7
 
8
8
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
9
- import { cloneElement, forwardRef, useEffect, useMemo, } from 'react';
10
- import { useButton, useComboBox, useFilter, useHover, useOverlayPosition, } from 'react-aria';
11
- import { Section as BaseSection, useComboBoxState } from 'react-stately';
12
- import { useEvent } from '../../../_internal/index';
13
- import { CloseIcon, DownIcon, LoadingIcon } from '../../../icons';
9
+ import React, { cloneElement, forwardRef, useCallback, useEffect, useId, useMemo, useRef, useState, } from 'react';
10
+ import { useFilter, useKeyboard, useOverlay, useOverlayPosition, } from 'react-aria';
11
+ import { Section as BaseSection, Item } from 'react-stately';
12
+ import { useEvent } from '../../../_internal';
13
+ import { CloseIcon, DirectionIcon, LoadingIcon } from '../../../icons';
14
14
  import { useProviderProps } from '../../../provider';
15
15
  import { BASE_STYLES, COLOR_STYLES, extractStyles, OUTER_STYLES, tasty, } from '../../../tasty';
16
16
  import { generateRandomId } from '../../../utils/random';
@@ -19,12 +19,11 @@ import { useFocus } from '../../../utils/react/interactions';
19
19
  import { useEventBus } from '../../../utils/react/useEventBus';
20
20
  import { ItemAction } from '../../actions';
21
21
  import { useFieldProps, useFormProps, wrapWithField } from '../../form';
22
- import { Item } from '../../Item';
23
- import { OverlayWrapper } from '../../overlays/OverlayWrapper';
22
+ import { DisplayTransition } from '../../helpers';
24
23
  import { InvalidIcon } from '../../shared/InvalidIcon';
25
24
  import { ValidIcon } from '../../shared/ValidIcon';
26
- import { DEFAULT_INPUT_STYLES, INPUT_WRAPPER_STYLES } from '../index';
27
- import { ListBoxPopup } from '../Select';
25
+ import { ListBox } from '../ListBox/ListBox';
26
+ import { DEFAULT_INPUT_STYLES, INPUT_WRAPPER_STYLES, } from '../TextInput/TextInputBase';
28
27
  const ComboBoxWrapperElement = tasty({
29
28
  styles: INPUT_WRAPPER_STYLES,
30
29
  });
@@ -32,91 +31,379 @@ const InputElement = tasty({
32
31
  as: 'input',
33
32
  styles: DEFAULT_INPUT_STYLES,
34
33
  });
35
- const TriggerElement = tasty({
36
- as: 'button',
37
- type: 'neutral',
34
+ const ComboBoxOverlayElement = tasty({
35
+ qa: 'ComboBoxOverlay',
38
36
  styles: {
39
37
  display: 'grid',
40
- placeItems: 'center',
41
- placeContent: 'center',
42
- placeSelf: 'stretch',
43
- radius: '(1r - 1bw) right',
38
+ gridRows: '1sf',
39
+ width: '30x max-content 50vw',
40
+ height: 'initial max-content (50vh - $size)',
41
+ overflow: 'auto',
42
+ background: '#white',
43
+ radius: '1cr',
44
+ shadow: '0 .5x 2x #shadow',
44
45
  padding: '0',
45
- width: '3x',
46
- boxSizing: 'border-box',
47
- color: {
48
- '': '#dark-02',
49
- hovered: '#dark-02',
50
- pressed: '#purple',
51
- disabled: '#dark.30',
46
+ border: '#border',
47
+ transition: 'translate $transition ease-out, scale $transition ease-out, theme $transition ease-out',
48
+ translate: {
49
+ '': '0 0',
50
+ 'open & [data-placement="top"]': '0 0',
51
+ '!open & [data-placement="top"]': '0 (10% + 1x)',
52
+ 'open & [data-placement="bottom"]': '0 0',
53
+ '!open & [data-placement="bottom"]': '0 (-10% - 1x)',
52
54
  },
53
- border: 'left',
54
- reset: 'button',
55
- margin: 0,
56
- fill: {
57
- '': '#dark.0',
58
- hovered: '#dark.04',
59
- pressed: '#purple.10',
60
- disabled: '#clear',
55
+ scale: {
56
+ '': '1 1',
57
+ '!open': '1 .9',
58
+ },
59
+ opacity: {
60
+ '': 1,
61
+ '!open': 0.001,
61
62
  },
62
- cursor: 'pointer',
63
63
  },
64
64
  });
65
65
  const PROP_STYLES = [...BASE_STYLES, ...OUTER_STYLES, ...COLOR_STYLES];
66
+ function useComboBoxState({ selectedKey, defaultSelectedKey, inputValue, comboBoxId, }) {
67
+ // Get event bus for menu synchronization
68
+ const { emit, on } = useEventBus();
69
+ // Internal state for uncontrolled mode
70
+ const [internalSelectedKey, setInternalSelectedKey] = useState(defaultSelectedKey ?? null);
71
+ const [internalInputValue, setInternalInputValue] = useState('');
72
+ const isControlledKey = selectedKey !== undefined;
73
+ const isControlledInput = inputValue !== undefined;
74
+ const effectiveSelectedKey = isControlledKey
75
+ ? selectedKey
76
+ : internalSelectedKey;
77
+ const effectiveInputValue = isControlledInput
78
+ ? inputValue
79
+ : internalInputValue;
80
+ // Popover state
81
+ const [isPopoverOpen, setIsPopoverOpen] = useState(false);
82
+ // Listen for other menus opening and close this one if needed
83
+ useEffect(() => {
84
+ const unsubscribe = on('popover:open', (data) => {
85
+ if (data.menuId !== comboBoxId && isPopoverOpen) {
86
+ setIsPopoverOpen(false);
87
+ }
88
+ });
89
+ return unsubscribe;
90
+ }, [on, comboBoxId, isPopoverOpen]);
91
+ // Emit event when this combobox opens
92
+ useEffect(() => {
93
+ if (isPopoverOpen) {
94
+ emit('popover:open', { menuId: comboBoxId });
95
+ }
96
+ }, [isPopoverOpen, emit, comboBoxId]);
97
+ return {
98
+ effectiveSelectedKey,
99
+ effectiveInputValue,
100
+ isPopoverOpen,
101
+ setIsPopoverOpen,
102
+ setInternalSelectedKey,
103
+ setInternalInputValue,
104
+ isControlledKey,
105
+ isControlledInput,
106
+ };
107
+ }
108
+ function useComboBoxFiltering({ children, effectiveInputValue, filter, }) {
109
+ const [isFilterActive, setIsFilterActive] = useState(false);
110
+ const { contains } = useFilter({ sensitivity: 'base' });
111
+ const textFilterFn = useMemo(() => (filter === false ? () => true : filter || contains), [filter, contains]);
112
+ // Filter children based on input value
113
+ const filteredChildren = useMemo(() => {
114
+ const term = effectiveInputValue.trim();
115
+ if (!isFilterActive || !term || !children) {
116
+ return children;
117
+ }
118
+ const nodeMatches = (node) => {
119
+ if (!node?.props)
120
+ return false;
121
+ const textValue = node.props.textValue ||
122
+ (typeof node.props.children === 'string' ? node.props.children : '') ||
123
+ String(node.props.children || '');
124
+ return textFilterFn(textValue, term);
125
+ };
126
+ const filterChildren = (childNodes) => {
127
+ if (!childNodes)
128
+ return null;
129
+ const childArray = Array.isArray(childNodes) ? childNodes : [childNodes];
130
+ const filteredNodes = [];
131
+ childArray.forEach((child) => {
132
+ if (!child || typeof child !== 'object') {
133
+ return;
134
+ }
135
+ if (child.type === BaseSection ||
136
+ child.type?.displayName === 'Section') {
137
+ const sectionChildren = Array.isArray(child.props.children)
138
+ ? child.props.children
139
+ : [child.props.children];
140
+ const filteredSectionChildren = sectionChildren.filter((sectionChild) => {
141
+ return (sectionChild &&
142
+ typeof sectionChild === 'object' &&
143
+ nodeMatches(sectionChild));
144
+ });
145
+ if (filteredSectionChildren.length > 0) {
146
+ filteredNodes.push(cloneElement(child, {
147
+ key: child.key,
148
+ children: filteredSectionChildren,
149
+ }));
150
+ }
151
+ }
152
+ else if (child.type === Item) {
153
+ if (nodeMatches(child)) {
154
+ filteredNodes.push(child);
155
+ }
156
+ }
157
+ else if (nodeMatches(child)) {
158
+ filteredNodes.push(child);
159
+ }
160
+ });
161
+ return filteredNodes;
162
+ };
163
+ return filterChildren(children);
164
+ }, [isFilterActive, children, effectiveInputValue, textFilterFn]);
165
+ return {
166
+ filteredChildren,
167
+ isFilterActive,
168
+ setIsFilterActive,
169
+ };
170
+ }
171
+ function useComboBoxKeyboard({ isPopoverOpen, listStateRef, hasResults, allowsCustomValue, effectiveInputValue, isClearable, onSelectionChange, onClearValue, onOpenPopover, onClosePopover, inputRef, setIsFilterActive, }) {
172
+ const { keyboardProps } = useKeyboard({
173
+ onKeyDown: (e) => {
174
+ if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
175
+ e.preventDefault();
176
+ // Open popover if closed
177
+ if (!isPopoverOpen) {
178
+ // If opening with no filtered results, disable filter to show all items
179
+ if (!hasResults) {
180
+ setIsFilterActive(false);
181
+ }
182
+ onOpenPopover();
183
+ return;
184
+ }
185
+ const listState = listStateRef.current;
186
+ if (!listState)
187
+ return;
188
+ const { selectionManager, collection, disabledKeys } = listState;
189
+ // Helper to collect visible item keys (supports sections)
190
+ const collectVisibleKeys = (nodes, out) => {
191
+ for (const node of nodes) {
192
+ if (node.type === 'item') {
193
+ if (!disabledKeys?.has(node.key)) {
194
+ out.push(node.key);
195
+ }
196
+ }
197
+ else if (node.childNodes) {
198
+ collectVisibleKeys(node.childNodes, out);
199
+ }
200
+ }
201
+ };
202
+ const visibleKeys = [];
203
+ collectVisibleKeys(collection, visibleKeys);
204
+ if (visibleKeys.length === 0)
205
+ return;
206
+ const isArrowDown = e.key === 'ArrowDown';
207
+ const currentKey = selectionManager.focusedKey;
208
+ let nextKey = null;
209
+ if (currentKey == null) {
210
+ nextKey = isArrowDown
211
+ ? visibleKeys[0]
212
+ : visibleKeys[visibleKeys.length - 1];
213
+ }
214
+ else {
215
+ const currentIndex = visibleKeys.indexOf(currentKey);
216
+ if (currentIndex !== -1) {
217
+ const newIndex = currentIndex + (isArrowDown ? 1 : -1);
218
+ if (newIndex >= 0 && newIndex < visibleKeys.length) {
219
+ nextKey = visibleKeys[newIndex];
220
+ }
221
+ }
222
+ else {
223
+ nextKey = isArrowDown
224
+ ? visibleKeys[0]
225
+ : visibleKeys[visibleKeys.length - 1];
226
+ }
227
+ }
228
+ if (nextKey != null) {
229
+ if (listState.lastFocusSourceRef) {
230
+ listState.lastFocusSourceRef.current = 'keyboard';
231
+ }
232
+ selectionManager.setFocusedKey(nextKey);
233
+ }
234
+ }
235
+ else if (e.key === 'Enter') {
236
+ if (!hasResults) {
237
+ e.preventDefault();
238
+ if (allowsCustomValue) {
239
+ const value = effectiveInputValue;
240
+ onSelectionChange(value ?? null);
241
+ }
242
+ else {
243
+ onSelectionChange(null);
244
+ }
245
+ return;
246
+ }
247
+ if (isPopoverOpen) {
248
+ const listState = listStateRef.current;
249
+ if (!listState)
250
+ return;
251
+ const keyToSelect = listState.selectionManager.focusedKey;
252
+ if (keyToSelect != null) {
253
+ e.preventDefault();
254
+ listState.selectionManager.select(keyToSelect, e);
255
+ // Ensure the popover closes even if selection stays the same
256
+ onClosePopover();
257
+ setTimeout(() => inputRef.current?.focus(), 0);
258
+ }
259
+ }
260
+ }
261
+ else if (e.key === 'Escape') {
262
+ if (isPopoverOpen) {
263
+ e.preventDefault();
264
+ onClosePopover();
265
+ inputRef.current?.focus();
266
+ }
267
+ else if (effectiveInputValue && isClearable) {
268
+ e.preventDefault();
269
+ onClearValue();
270
+ }
271
+ }
272
+ else if (e.key === 'Home' || e.key === 'End') {
273
+ if (isPopoverOpen) {
274
+ e.preventDefault();
275
+ const listState = listStateRef.current;
276
+ if (!listState)
277
+ return;
278
+ const { selectionManager, collection, disabledKeys } = listState;
279
+ // Helper to collect visible item keys (supports sections)
280
+ const collectVisibleKeys = (nodes, out) => {
281
+ for (const node of nodes) {
282
+ if (node.type === 'item') {
283
+ if (!disabledKeys?.has(node.key)) {
284
+ out.push(node.key);
285
+ }
286
+ }
287
+ else if (node.childNodes) {
288
+ collectVisibleKeys(node.childNodes, out);
289
+ }
290
+ }
291
+ };
292
+ const visibleKeys = [];
293
+ collectVisibleKeys(collection, visibleKeys);
294
+ if (visibleKeys.length === 0)
295
+ return;
296
+ const targetKey = e.key === 'Home'
297
+ ? visibleKeys[0]
298
+ : visibleKeys[visibleKeys.length - 1];
299
+ if (listState.lastFocusSourceRef) {
300
+ listState.lastFocusSourceRef.current = 'keyboard';
301
+ }
302
+ selectionManager.setFocusedKey(targetKey);
303
+ }
304
+ }
305
+ },
306
+ });
307
+ return { keyboardProps };
308
+ }
309
+ const ComboBoxInput = forwardRef(function ComboBoxInput({ inputRef, id, value, placeholder, isDisabled, isReadOnly, autoFocus, size, mods, inputStyles, keyboardProps, focusProps, onChange, onFocus, isPopoverOpen, hasResults, comboBoxId, listStateRef, isLoading, allowsCustomValue, }, ref) {
310
+ const combinedRef = useCombinedRefs(ref, inputRef);
311
+ return (_jsx(InputElement, { ref: combinedRef, qa: "Input", id: id, type: "text", value: value, placeholder: placeholder, isDisabled: isDisabled, readOnly: isReadOnly, autoFocus: autoFocus, "data-autofocus": autoFocus ? '' : undefined, onChange: onChange, onFocus: onFocus, onBlur: focusProps.onBlur, ...keyboardProps, styles: inputStyles, mods: mods, "data-size": size, role: "combobox", "aria-expanded": isPopoverOpen && hasResults, "aria-haspopup": "listbox", "aria-controls": isPopoverOpen && hasResults
312
+ ? `ComboBoxListBox-${comboBoxId}`
313
+ : undefined, "aria-activedescendant": isPopoverOpen &&
314
+ hasResults &&
315
+ listStateRef.current?.selectionManager.focusedKey != null
316
+ ? `ListBoxItem-${listStateRef.current?.selectionManager.focusedKey}`
317
+ : undefined }));
318
+ });
319
+ function ComboBoxOverlay({ isOpen, triggerRef, popoverRef, listBoxRef, direction, shouldFlip, overlayOffset, comboBoxWidth, comboBoxId, overlayStyles, listBoxStyles, optionStyles, sectionStyles, headingStyles, effectiveSelectedKey, isDisabled, disabledKeys, items, children, listStateRef, onSelectionChange, onClose, label, ariaLabel, }) {
320
+ // Overlay positioning
321
+ const { overlayProps: overlayPositionProps, placement, updatePosition, } = useOverlayPosition({
322
+ targetRef: triggerRef,
323
+ overlayRef: popoverRef,
324
+ placement: `${direction} start`,
325
+ shouldFlip,
326
+ isOpen,
327
+ offset: overlayOffset,
328
+ });
329
+ // Overlay behavior (dismiss on outside click, escape)
330
+ const { overlayProps: overlayBehaviorProps } = useOverlay({
331
+ onClose,
332
+ shouldCloseOnBlur: true,
333
+ isOpen,
334
+ isDismissable: true,
335
+ shouldCloseOnInteractOutside: (el) => {
336
+ const menuTriggerEl = el.closest('[data-popover-trigger]');
337
+ if (!menuTriggerEl)
338
+ return true;
339
+ if (menuTriggerEl === triggerRef?.current)
340
+ return true;
341
+ return false;
342
+ },
343
+ }, popoverRef);
344
+ // Update position when overlay opens
345
+ useLayoutEffect(() => {
346
+ if (isOpen) {
347
+ // Use double RAF to ensure layout is complete before positioning
348
+ requestAnimationFrame(() => {
349
+ requestAnimationFrame(() => {
350
+ updatePosition?.();
351
+ });
352
+ });
353
+ }
354
+ }, [isOpen, updatePosition]);
355
+ // Extract primary placement direction for consistent styling
356
+ const placementDirection = placement?.split(' ')[0] || direction;
357
+ return (_jsx(DisplayTransition, { isShown: isOpen, children: ({ phase, isShown, ref: transitionRef }) => (_jsx(ComboBoxOverlayElement, { ...mergeProps(overlayPositionProps, overlayBehaviorProps), ref: (value) => {
358
+ transitionRef(value);
359
+ popoverRef.current = value;
360
+ }, "data-placement": placementDirection, "data-phase": phase, mods: {
361
+ open: isShown,
362
+ }, styles: overlayStyles, style: {
363
+ minWidth: comboBoxWidth ? `${comboBoxWidth}px` : undefined,
364
+ ...overlayPositionProps.style,
365
+ }, children: _jsx(ListBox, { ref: listBoxRef, focusOnHover: true, disableSelectionToggle: true, id: `ComboBoxListBox-${comboBoxId}`, "aria-label": ariaLabel || (typeof label === 'string' ? label : 'Options'), selectedKey: effectiveSelectedKey, selectionMode: "single", isDisabled: isDisabled, disabledKeys: disabledKeys, shouldUseVirtualFocus: true, items: items, styles: listBoxStyles, optionStyles: optionStyles, sectionStyles: sectionStyles, headingStyles: headingStyles, stateRef: listStateRef, mods: {
366
+ popover: true,
367
+ }, onSelectionChange: onSelectionChange, children: children }) })) }));
368
+ }
369
+ // ============================================================================
370
+ // Main Component: ComboBox
371
+ // ============================================================================
66
372
  export const ComboBox = forwardRef(function ComboBox(props, ref) {
67
373
  props = useProviderProps(props);
68
374
  props = useFormProps(props);
69
375
  props = useFieldProps(props, {
70
376
  valuePropsMapper: ({ value, onChange }) => {
71
377
  return {
72
- selectedKey: !props.allowsCustomValue ? value ?? null : undefined,
73
- inputValue: props.allowsCustomValue ? value ?? '' : undefined,
74
- onInputChange(val) {
75
- if (!props.allowsCustomValue) {
76
- return;
77
- }
78
- onChange(val);
79
- },
378
+ // Form value maps to selectedKey (the committed value) in both modes
379
+ selectedKey: value ?? null,
80
380
  onSelectionChange(val) {
81
- if (val == null && props.allowsCustomValue) {
82
- return;
83
- }
381
+ // Commit selection changes to the form
84
382
  onChange(val);
85
383
  },
86
384
  };
87
385
  },
88
386
  });
89
- let { qa, label, extra, labelStyles, isRequired, necessityIndicator, validationState, icon, prefix, isDisabled, multiLine, autoFocus, wrapperRef, inputRef, triggerRef, popoverRef, listBoxRef, isLoading, loadingIndicator, overlayOffset = 8, inputStyles, optionStyles, triggerStyles, listBoxStyles, overlayStyles, wrapperStyles, suffix, hideTrigger, message, description, size = 'medium', autoComplete = 'off', direction = 'bottom', shouldFlip = true, menuTrigger = 'input', suffixPosition = 'before', loadingState, filter, styles, labelSuffix, selectedKey, defaultSelectedKey, isClearable, ...otherProps } = props;
90
- let isAsync = loadingState != null;
91
- let { contains } = useFilter({ sensitivity: 'base' });
92
- let comboBoxStateProps = {
93
- ...props,
94
- defaultFilter: filter || contains,
95
- filter: undefined,
96
- allowsEmptyCollection: isAsync,
97
- menuTrigger,
98
- };
99
- let state = useComboBoxState(comboBoxStateProps);
387
+ let { qa, label, extra, labelStyles, isRequired, necessityIndicator, validationState, id, icon, prefix, isDisabled, autoFocus, wrapperRef, inputRef, triggerRef, popoverRef, listBoxRef, isLoading, inputStyles, optionStyles, triggerStyles, listBoxStyles, overlayStyles, fieldStyles, suffix, hideTrigger, message, description, size = 'medium', direction = 'bottom', shouldFlip = true, popoverTrigger = 'input', suffixPosition = 'before', filter, styles, labelSuffix, selectedKey, defaultSelectedKey, inputValue, onInputChange, isClearable, onClear, placeholder, allowsCustomValue, shouldCommitOnBlur = true, items, children: renderChildren, sectionStyles, headingStyles, isReadOnly, overlayOffset = 8, onSelectionChange: externalOnSelectionChange, sortSelectedToTop: sortSelectedToTopProp, ...otherProps } = props;
388
+ // Generate ID for label-input linking if not provided
389
+ const generatedId = useId();
390
+ const inputId = id || generatedId;
100
391
  // Generate a unique ID for this combobox instance
101
392
  const comboBoxId = useMemo(() => generateRandomId(), []);
102
- // Get event bus for menu synchronization
103
- const { emit, on } = useEventBus();
104
- // Listen for other menus opening and close this one if needed
105
- useEffect(() => {
106
- const unsubscribe = on('popover:open', (data) => {
107
- // If another menu is opening and this combobox is open, close this one
108
- if (data.menuId !== comboBoxId && state.isOpen) {
109
- state.close();
110
- }
111
- });
112
- return unsubscribe;
113
- }, [on, comboBoxId, state]);
114
- // Emit event when this combobox opens
115
- useEffect(() => {
116
- if (state.isOpen) {
117
- emit('popover:open', { menuId: comboBoxId });
118
- }
119
- }, [state.isOpen, emit, comboBoxId]);
393
+ // State management hook
394
+ const { effectiveSelectedKey, effectiveInputValue, isPopoverOpen, setIsPopoverOpen, setInternalSelectedKey, setInternalInputValue, isControlledKey, isControlledInput, } = useComboBoxState({
395
+ selectedKey,
396
+ defaultSelectedKey,
397
+ inputValue,
398
+ comboBoxId,
399
+ });
400
+ // Track if sortSelectedToTop was explicitly provided
401
+ const sortSelectedToTopExplicit = sortSelectedToTopProp !== undefined;
402
+ // Default to true if items are provided, false otherwise
403
+ const sortSelectedToTop = sortSelectedToTopProp ?? (items ? true : false);
404
+ // Cache for sorted items array when using `items` prop
405
+ const cachedItemsOrder = useRef(null);
406
+ const selectionWhenClosed = useRef(null);
120
407
  styles = extractStyles(otherProps, PROP_STYLES, styles);
121
408
  ref = useCombinedRefs(ref);
122
409
  wrapperRef = useCombinedRefs(wrapperRef);
@@ -124,62 +411,274 @@ export const ComboBox = forwardRef(function ComboBox(props, ref) {
124
411
  triggerRef = useCombinedRefs(triggerRef);
125
412
  popoverRef = useCombinedRefs(popoverRef);
126
413
  listBoxRef = useCombinedRefs(listBoxRef);
127
- let { overlayProps, placement, updatePosition } = useOverlayPosition({
128
- targetRef: triggerRef,
129
- overlayRef: popoverRef,
130
- scrollRef: listBoxRef,
131
- placement: `${direction} end`,
132
- shouldFlip: shouldFlip,
133
- isOpen: state.isOpen,
134
- onClose: state.close,
135
- offset: overlayOffset,
414
+ // Sort items with selected on top if enabled
415
+ const getSortedItems = useCallback(() => {
416
+ if (!items)
417
+ return items;
418
+ if (!sortSelectedToTop)
419
+ return items;
420
+ // Reuse cached order if available
421
+ if (cachedItemsOrder.current) {
422
+ return cachedItemsOrder.current;
423
+ }
424
+ // Warn if explicitly requested but not supported
425
+ if (sortSelectedToTopExplicit && !items) {
426
+ console.warn('ComboBox: sortSelectedToTop only works with the items prop. ' +
427
+ 'Sorting will be skipped when using JSX children.');
428
+ return items;
429
+ }
430
+ const selectedKey = isPopoverOpen
431
+ ? effectiveSelectedKey
432
+ : selectionWhenClosed.current;
433
+ if (!selectedKey)
434
+ return items;
435
+ const itemsArray = Array.isArray(items) ? items : Array.from(items);
436
+ const selectedItem = itemsArray.find((item) => {
437
+ const key = item?.key ?? item?.id;
438
+ return key != null && String(key) === String(selectedKey);
439
+ });
440
+ if (!selectedItem)
441
+ return items;
442
+ const sorted = [
443
+ selectedItem,
444
+ ...itemsArray.filter((item) => {
445
+ const key = item?.key ?? item?.id;
446
+ return key == null || String(key) !== String(selectedKey);
447
+ }),
448
+ ];
449
+ if (isPopoverOpen) {
450
+ cachedItemsOrder.current = sorted;
451
+ }
452
+ return sorted;
453
+ }, [
454
+ items,
455
+ sortSelectedToTop,
456
+ sortSelectedToTopExplicit,
457
+ effectiveSelectedKey,
458
+ isPopoverOpen,
459
+ ]);
460
+ const sortedItems = getSortedItems();
461
+ // Preserve the original `children` (may be a render function) before we
462
+ // potentially overwrite it.
463
+ let children = renderChildren;
464
+ const renderFn = renderChildren;
465
+ if (sortedItems && typeof renderFn === 'function') {
466
+ try {
467
+ const itemsArray = Array.from(sortedItems);
468
+ children = itemsArray.map((item, idx) => {
469
+ const rendered = renderFn(item);
470
+ if (React.isValidElement(rendered) &&
471
+ rendered.key == null) {
472
+ return React.cloneElement(rendered, {
473
+ key: rendered?.key ?? item?.key ?? idx,
474
+ });
475
+ }
476
+ return rendered;
477
+ });
478
+ }
479
+ catch {
480
+ // If conversion fails, proceed with the original children
481
+ }
482
+ }
483
+ // Invalidate cached sorting whenever items change
484
+ useEffect(() => {
485
+ cachedItemsOrder.current = null;
486
+ }, [items]);
487
+ // Capture selection when popover closes
488
+ useEffect(() => {
489
+ if (!isPopoverOpen) {
490
+ selectionWhenClosed.current =
491
+ effectiveSelectedKey != null ? String(effectiveSelectedKey) : null;
492
+ cachedItemsOrder.current = null;
493
+ }
494
+ }, [isPopoverOpen, effectiveSelectedKey]);
495
+ // Filtering hook
496
+ const { filteredChildren, isFilterActive, setIsFilterActive } = useComboBoxFiltering({
497
+ children,
498
+ effectiveInputValue,
499
+ filter,
136
500
  });
137
- let { labelProps, inputProps, listBoxProps, buttonProps: triggerProps, } = useComboBox({
138
- ...comboBoxStateProps,
139
- inputRef,
140
- buttonRef: triggerRef,
141
- listBoxRef,
142
- popoverRef,
143
- menuTrigger,
144
- }, state);
145
- let { isFocused, focusProps } = useFocus({ isDisabled });
146
- let { hoverProps, isHovered } = useHover({ isDisabled });
147
- // Get props for the button based on the trigger props from useComboBox
148
- let { buttonProps, isPressed: isTriggerPressed } = useButton(triggerProps, triggerRef);
149
- let { hoverProps: triggerHoverProps, isHovered: isTriggerHovered } = useHover({ isDisabled });
150
- let { focusProps: triggerFocusProps, isFocused: isTriggerFocused } = useFocus({ isDisabled }, true);
151
- useLayoutEffect(() => {
152
- if (state.isOpen) {
153
- updatePosition();
501
+ // Freeze filtered children during close animation to prevent visual jumps
502
+ const frozenFilteredChildrenRef = useRef(null);
503
+ useEffect(() => {
504
+ // Update frozen children only when popover is open
505
+ if (isPopoverOpen) {
506
+ frozenFilteredChildrenRef.current = filteredChildren;
154
507
  }
155
- }, [state.isOpen, state.collection.size]);
508
+ }, [isPopoverOpen, filteredChildren]);
509
+ // Use frozen children during close animation, fresh children when open
510
+ const displayedFilteredChildren = isPopoverOpen
511
+ ? filteredChildren
512
+ : frozenFilteredChildrenRef.current ?? filteredChildren;
513
+ const { isFocused, focusProps } = useFocus({ isDisabled });
156
514
  let isInvalid = validationState === 'invalid';
157
515
  let validationIcon = isInvalid ? InvalidIcon : ValidIcon;
158
516
  let validation = cloneElement(validationIcon);
517
+ // Ref to access internal ListBox state
518
+ const listStateRef = useRef(null);
519
+ const focusInitAttemptsRef = useRef(0);
520
+ // Helper to get label from collection item
521
+ const getItemLabel = useCallback((key) => {
522
+ const item = listStateRef.current?.collection?.getItem(key);
523
+ return item?.textValue || String(key);
524
+ }, []);
525
+ // Selection change handler
526
+ const handleSelectionChange = useEvent((selection) => {
527
+ // Extract single key from selection (we only support single selection)
528
+ const key = Array.isArray(selection) ? selection[0] : selection;
529
+ // Update selected key
530
+ if (!isControlledKey) {
531
+ setInternalSelectedKey(key ?? null);
532
+ }
533
+ // Update input value to show selected item label
534
+ if (key != null) {
535
+ setIsFilterActive(false);
536
+ const label = getItemLabel(key);
537
+ if (!isControlledInput) {
538
+ setInternalInputValue(label);
539
+ }
540
+ onInputChange?.(label);
541
+ }
542
+ else {
543
+ // Clear input when selection is cleared
544
+ if (!isControlledInput) {
545
+ setInternalInputValue('');
546
+ }
547
+ onInputChange?.('');
548
+ setIsFilterActive(false);
549
+ }
550
+ externalOnSelectionChange?.(key);
551
+ // Close popover after selection
552
+ setIsPopoverOpen(false);
553
+ // Focus input
554
+ setTimeout(() => {
555
+ inputRef.current?.focus();
556
+ }, 0);
557
+ });
558
+ // Input change handler
559
+ const handleInputChange = useEvent((e) => {
560
+ const value = e.target.value;
561
+ // Update input value
562
+ if (!isControlledInput) {
563
+ setInternalInputValue(value);
564
+ }
565
+ onInputChange?.(value);
566
+ const trimmed = value.trim();
567
+ setIsFilterActive(trimmed.length > 0);
568
+ // Only clear selection in allowsCustomValue mode
569
+ // In normal mode, typing just filters - selection stays until explicitly changed
570
+ if (allowsCustomValue && effectiveSelectedKey != null) {
571
+ if (!isControlledKey) {
572
+ setInternalSelectedKey(null);
573
+ }
574
+ externalOnSelectionChange?.(null);
575
+ }
576
+ // Open popover based on trigger
577
+ if (popoverTrigger === 'input' && value && !isPopoverOpen) {
578
+ setIsPopoverOpen(true);
579
+ }
580
+ });
581
+ // Initialize input value from default selected key (uncontrolled mode only, one-time)
582
+ const [hasInitialized, setHasInitialized] = useState(false);
583
+ useEffect(() => {
584
+ // Only initialize once, in uncontrolled input mode, when defaultSelectedKey is provided
585
+ if (hasInitialized || isControlledInput || !defaultSelectedKey)
586
+ return;
587
+ // Wait for collection to be ready
588
+ if (!listStateRef.current?.collection)
589
+ return;
590
+ const label = getItemLabel(defaultSelectedKey);
591
+ setInternalInputValue(label);
592
+ setHasInitialized(true);
593
+ }, [
594
+ hasInitialized,
595
+ isControlledInput,
596
+ defaultSelectedKey,
597
+ getItemLabel,
598
+ children,
599
+ ]);
600
+ // Input focus handler
601
+ const handleInputFocus = useEvent((e) => {
602
+ // Call focus props handler if it exists
603
+ focusProps.onFocus?.(e);
604
+ if (popoverTrigger === 'focus' && !isPopoverOpen) {
605
+ setIsPopoverOpen(true);
606
+ }
607
+ });
608
+ // Input blur handler
609
+ const handleInputBlur = useEvent((e) => {
610
+ focusProps.onBlur?.(e);
611
+ const relatedTarget = e.relatedTarget;
612
+ // Don't do anything if focus is moving within the combobox
613
+ if (relatedTarget &&
614
+ (wrapperRef.current?.contains(relatedTarget) ||
615
+ popoverRef.current?.contains(relatedTarget))) {
616
+ return;
617
+ }
618
+ // Always disable filter on blur
619
+ setIsFilterActive(false);
620
+ // In allowsCustomValue mode with shouldCommitOnBlur, commit the input value
621
+ if (allowsCustomValue &&
622
+ shouldCommitOnBlur &&
623
+ effectiveInputValue &&
624
+ effectiveSelectedKey == null) {
625
+ externalOnSelectionChange?.(effectiveInputValue);
626
+ if (!isControlledKey) {
627
+ setInternalSelectedKey(effectiveInputValue);
628
+ }
629
+ return;
630
+ }
631
+ // Reset input to show current selection (or empty if none)
632
+ const nextValue = effectiveSelectedKey != null ? getItemLabel(effectiveSelectedKey) : '';
633
+ if (!isControlledInput) {
634
+ setInternalInputValue(nextValue);
635
+ }
636
+ onInputChange?.(nextValue);
637
+ });
159
638
  // Clear button logic
160
- let hasValue = props.allowsCustomValue
161
- ? state.inputValue !== ''
162
- : state.selectedKey != null;
163
- let showClearButton = isClearable && hasValue && !isDisabled && !props.isReadOnly;
639
+ let hasValue = allowsCustomValue
640
+ ? effectiveInputValue !== ''
641
+ : effectiveSelectedKey != null;
642
+ let showClearButton = isClearable && hasValue && !isDisabled && !isReadOnly;
643
+ const hasResults = Boolean(displayedFilteredChildren &&
644
+ (Array.isArray(displayedFilteredChildren)
645
+ ? displayedFilteredChildren.length > 0
646
+ : displayedFilteredChildren !== null));
164
647
  // Clear function
165
648
  let clearValue = useEvent(() => {
166
- // Always clear input value in state so UI resets to placeholder
167
- state.setInputValue('');
168
- // Notify external input value only when custom value mode is enabled
169
- if (props.allowsCustomValue) {
170
- props.onInputChange?.('');
649
+ // Clear input
650
+ if (!isControlledInput) {
651
+ setInternalInputValue('');
652
+ }
653
+ onInputChange?.('');
654
+ // Clear selection
655
+ if (!isControlledKey) {
656
+ setInternalSelectedKey(null);
171
657
  }
172
- props.onSelectionChange?.(null);
173
- state.setSelectedKey(null);
174
- // Close the popup if it's open
175
- if (state.isOpen) {
176
- state.close();
658
+ externalOnSelectionChange?.(null);
659
+ // Close popover
660
+ if (isPopoverOpen) {
661
+ setIsPopoverOpen(false);
177
662
  }
178
- // Focus back to the input
663
+ // Focus input
179
664
  inputRef.current?.focus();
180
- props.onClear?.();
665
+ onClear?.();
666
+ });
667
+ // Keyboard navigation hook
668
+ const { keyboardProps } = useComboBoxKeyboard({
669
+ isPopoverOpen,
670
+ listStateRef,
671
+ hasResults,
672
+ allowsCustomValue,
673
+ effectiveInputValue,
674
+ isClearable,
675
+ onSelectionChange: handleSelectionChange,
676
+ onClearValue: clearValue,
677
+ onOpenPopover: () => setIsPopoverOpen(true),
678
+ onClosePopover: () => setIsPopoverOpen(false),
679
+ inputRef,
680
+ setIsFilterActive,
181
681
  });
182
- let comboBoxWidth = wrapperRef?.current?.offsetWidth;
183
682
  if (icon) {
184
683
  icon = _jsx("div", { "data-element": "InputIcon", children: icon });
185
684
  if (prefix) {
@@ -193,7 +692,7 @@ export const ComboBox = forwardRef(function ComboBox(props, ref) {
193
692
  invalid: isInvalid,
194
693
  valid: validationState === 'valid',
195
694
  disabled: isDisabled,
196
- hovered: isHovered,
695
+ hovered: false,
197
696
  focused: isFocused,
198
697
  loading: isLoading,
199
698
  prefix: !!prefix,
@@ -203,84 +702,98 @@ export const ComboBox = forwardRef(function ComboBox(props, ref) {
203
702
  isInvalid,
204
703
  validationState,
205
704
  isDisabled,
206
- isHovered,
207
705
  isFocused,
208
706
  isLoading,
209
707
  prefix,
210
708
  showClearButton,
211
709
  ]);
212
- // If input is not full and the user presses Enter, pick the first option.
213
- let onKeyPress = useEvent((e) => {
214
- if (!props.onSelectionChange) {
215
- return;
710
+ const comboBoxWidth = wrapperRef?.current?.offsetWidth;
711
+ const shouldShowPopover = Boolean(isPopoverOpen && hasResults);
712
+ // Close popover if no results
713
+ useEffect(() => {
714
+ if (isPopoverOpen && !hasResults) {
715
+ setIsPopoverOpen(false);
216
716
  }
217
- if (e.key === 'Enter') {
218
- if (!props.allowsCustomValue) {
219
- if (state.isOpen) {
220
- // If there is a selected option then do nothing. It will be selected on Enter anyway.
221
- if (listBoxRef.current?.querySelector('li[aria-selected="true"]')) {
222
- return;
223
- }
224
- const option = [...state.collection][0]?.key;
225
- if (option && selectedKey !== option) {
226
- props.onSelectionChange?.(option);
227
- e.stopPropagation();
228
- e.preventDefault();
229
- }
717
+ }, [isPopoverOpen, hasResults]);
718
+ const ensureInitialFocus = useCallback(() => {
719
+ if (!shouldShowPopover)
720
+ return;
721
+ const listState = listStateRef.current;
722
+ if (!listState)
723
+ return;
724
+ const { selectionManager, collection, disabledKeys, lastFocusSourceRef } = listState;
725
+ if (!selectionManager || !collection)
726
+ return;
727
+ const collectFirstKey = () => {
728
+ for (const node of collection) {
729
+ if (node.type === 'item') {
730
+ if (!disabledKeys?.has(node.key))
731
+ return node.key;
230
732
  }
231
- else if (inputRef.current?.value &&
232
- ![...state.collection]
233
- .map((i) => i.textValue)
234
- .includes(inputRef.current?.value)) {
235
- // If the input value is not in the collection, we need to prevent the submitting of the form.
236
- // Also, we reset value manually.
237
- e.preventDefault();
238
- props.onSelectionChange?.(null);
733
+ else if (node.childNodes) {
734
+ for (const child of node.childNodes) {
735
+ if (child.type === 'item' && !disabledKeys?.has(child.key)) {
736
+ return child.key;
737
+ }
738
+ }
239
739
  }
240
- // If a custom value is allowed, we need to check if the input value is in the collection.
241
- }
242
- else if (props.allowsCustomValue) {
243
- const inputValue = inputRef?.current?.value;
244
- const item = [...state.collection].find((item) => item.textValue.toLowerCase() === inputValue?.toLowerCase());
245
- props.onSelectionChange?.(item ? item.key : inputRef?.current?.value ?? '');
246
740
  }
741
+ return null;
742
+ };
743
+ if (lastFocusSourceRef)
744
+ lastFocusSourceRef.current = 'keyboard';
745
+ if (selectionManager.focusedKey == null) {
746
+ const keyToFocus = effectiveSelectedKey != null ? effectiveSelectedKey : collectFirstKey();
747
+ if (keyToFocus != null)
748
+ selectionManager.setFocusedKey(keyToFocus);
247
749
  }
248
- });
249
- let onBlur = useEvent((e) => {
250
- // If the input value is not in the collection, we need to reset the value.
251
- if (!props.allowsCustomValue &&
252
- inputRef.current?.value &&
253
- ![...state.collection]
254
- .map((i) => i.textValue)
255
- .includes(inputRef.current?.value)) {
256
- props.onSelectionChange?.(null);
257
- }
258
- });
259
- useEffect(() => {
260
- inputRef.current?.addEventListener('keydown', onKeyPress, true);
261
- inputRef.current?.addEventListener('blur', onBlur, true);
262
- return () => {
263
- inputRef.current?.removeEventListener('keydown', onKeyPress, true);
264
- inputRef.current?.removeEventListener('blur', onBlur, true);
750
+ }, [shouldShowPopover, effectiveSelectedKey]);
751
+ useLayoutEffect(() => {
752
+ if (!shouldShowPopover)
753
+ return;
754
+ focusInitAttemptsRef.current = 0;
755
+ const tick = () => {
756
+ if (!shouldShowPopover)
757
+ return;
758
+ ensureInitialFocus();
759
+ focusInitAttemptsRef.current += 1;
760
+ // Try a few frames to wait for collection to mount
761
+ if (focusInitAttemptsRef.current < 8 &&
762
+ listStateRef.current?.selectionManager?.focusedKey == null) {
763
+ requestAnimationFrame(tick);
764
+ }
265
765
  };
266
- }, []);
267
- let allInputProps = useMemo(() => mergeProps(inputProps, hoverProps, focusProps), [inputProps, hoverProps, focusProps]);
268
- let comboBoxField = (_jsxs(ComboBoxWrapperElement, { ref: wrapperRef, qa: qa || 'ComboBox', mods: mods, styles: wrapperStyles, style: {
766
+ requestAnimationFrame(() => requestAnimationFrame(tick));
767
+ }, [shouldShowPopover, ensureInitialFocus]);
768
+ const comboBoxField = (_jsxs(ComboBoxWrapperElement, { ref: wrapperRef, qa: qa || 'ComboBox', mods: mods, styles: styles, style: {
269
769
  zIndex: isFocused ? 1 : 'initial',
270
- }, "data-size": size, children: [prefix ? _jsx("div", { "data-element": "Prefix", children: prefix }) : null, _jsx(InputElement, { ref: inputRef, qa: "Input", autoFocus: autoFocus, "data-autofocus": autoFocus ? '' : undefined, ...allInputProps, autoComplete: autoComplete, styles: inputStyles, mods: mods, "data-size": size }), _jsxs("div", { "data-element": "Suffix", children: [suffixPosition === 'before' ? suffix : null, validationState || isLoading ? (_jsxs(_Fragment, { children: [validationState && !isLoading ? validation : null, isLoading ? _jsx(LoadingIcon, {}) : null] })) : null, suffixPosition === 'after' ? suffix : null, showClearButton && (_jsx(ItemAction, { icon: _jsx(CloseIcon, {}), size: size, theme: validationState === 'invalid' ? 'danger' : undefined, qa: "ComboBoxClearButton", "data-no-trigger": hideTrigger ? '' : undefined, onPress: clearValue })), !hideTrigger ? (_jsx(TriggerElement, { "data-popover-trigger": true, qa: "ComboBoxTrigger", ...mergeProps(buttonProps, triggerFocusProps, triggerHoverProps), ref: triggerRef, mods: {
271
- pressed: isTriggerPressed,
272
- focused: isTriggerFocused,
273
- hovered: isTriggerHovered,
770
+ }, "data-size": size, children: [prefix ? _jsx("div", { "data-element": "Prefix", children: prefix }) : null, _jsx(ComboBoxInput, { inputRef: inputRef, id: inputId, value: effectiveInputValue, placeholder: placeholder, isDisabled: isDisabled, isReadOnly: isReadOnly, autoFocus: autoFocus, size: size, mods: mods, inputStyles: inputStyles, keyboardProps: keyboardProps, focusProps: { ...focusProps, onBlur: handleInputBlur }, isPopoverOpen: isPopoverOpen, hasResults: hasResults, comboBoxId: comboBoxId, listStateRef: listStateRef, isLoading: isLoading, allowsCustomValue: allowsCustomValue, onChange: handleInputChange, onFocus: handleInputFocus }), _jsxs("div", { "data-element": "Suffix", children: [suffixPosition === 'before' ? suffix : null, validationState || isLoading ? (_jsxs(_Fragment, { children: [validationState && !isLoading ? validation : null, isLoading ? _jsx(LoadingIcon, {}) : null] })) : null, suffixPosition === 'after' ? suffix : null, showClearButton && (_jsx(ItemAction, { icon: _jsx(CloseIcon, {}), size: size, theme: validationState === 'invalid' ? 'danger' : undefined, qa: "ComboBoxClearButton", "data-no-trigger": hideTrigger ? '' : undefined, onPress: clearValue })), !hideTrigger ? (_jsx(ItemAction, { ref: triggerRef, "data-popover-trigger": true, icon: _jsx(DirectionIcon, { to: isPopoverOpen ? 'up' : 'down' }), qa: "ComboBoxTrigger", mods: {
771
+ pressed: isPopoverOpen,
274
772
  disabled: isDisabled,
275
773
  loading: isLoading,
276
- }, "data-size": size, isDisabled: isDisabled, styles: triggerStyles, children: _jsx(DownIcon, {}) })) : null] }), _jsx(OverlayWrapper, { isOpen: state.isOpen && !isDisabled, children: _jsx(ListBoxPopup, { ...listBoxProps, shouldUseVirtualFocus: true, listBoxRef: listBoxRef, popoverRef: popoverRef, overlayProps: overlayProps, placement: placement, state: state, listBoxStyles: listBoxStyles, overlayStyles: overlayStyles, optionStyles: optionStyles, minWidth: comboBoxWidth, triggerRef: triggerRef }) })] }));
277
- return wrapWithField(comboBoxField, ref, mergeProps({ ...props, styles }, { labelProps }));
278
- });
279
- const ComboBoxSectionComponent = Object.assign(BaseSection, {
280
- displayName: 'Section',
774
+ }, "data-size": size, isDisabled: isDisabled, styles: triggerStyles, onClick: () => {
775
+ if (!isDisabled) {
776
+ const willOpen = !isPopoverOpen;
777
+ setIsPopoverOpen(willOpen);
778
+ if (willOpen) {
779
+ inputRef.current?.focus();
780
+ // If opening with no filtered results, disable filter to show all items
781
+ if (!hasResults) {
782
+ setIsFilterActive(false);
783
+ }
784
+ }
785
+ }
786
+ } })) : null] }), _jsx(ComboBoxOverlay, { isOpen: shouldShowPopover, triggerRef: wrapperRef, popoverRef: popoverRef, listBoxRef: listBoxRef, direction: direction, shouldFlip: shouldFlip, overlayOffset: overlayOffset, comboBoxWidth: comboBoxWidth, comboBoxId: comboBoxId, overlayStyles: overlayStyles, listBoxStyles: listBoxStyles, optionStyles: optionStyles, sectionStyles: sectionStyles, headingStyles: headingStyles, effectiveSelectedKey: effectiveSelectedKey, isDisabled: isDisabled, disabledKeys: props.disabledKeys, items: sortedItems, listStateRef: listStateRef, label: label, ariaLabel: props['aria-label'], onSelectionChange: handleSelectionChange, onClose: () => setIsPopoverOpen(false), children: displayedFilteredChildren })] }));
787
+ const { children: _, ...propsWithoutChildren } = props;
788
+ const finalProps = {
789
+ ...propsWithoutChildren,
790
+ styles: fieldStyles,
791
+ labelProps: { ...props.labelProps, for: inputId },
792
+ };
793
+ return wrapWithField(comboBoxField, ref, mergeProps(finalProps, {}));
281
794
  });
282
795
  ComboBox.Item = Item;
283
- ComboBox.Section = ComboBoxSectionComponent;
796
+ ComboBox.Section = BaseSection;
284
797
  Object.defineProperty(ComboBox, 'cubeInputType', {
285
798
  value: 'ComboBox',
286
799
  enumerable: false,