@octanejs/base-ui 0.1.50 → 0.1.52

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 (1179) hide show
  1. package/LICENSE +21 -0
  2. package/MIGRATION.md +47 -0
  3. package/README.md +62 -5
  4. package/UPSTREAM.md +164 -64
  5. package/package.json +458 -27
  6. package/src/accordion/header/AccordionHeader.tsrx +42 -0
  7. package/src/accordion/header/AccordionHeaderDataAttributes.ts +13 -0
  8. package/src/accordion/index.parts.ts +5 -0
  9. package/src/accordion/index.ts +16 -0
  10. package/src/accordion/item/AccordionItem.tsrx +195 -0
  11. package/src/accordion/item/AccordionItemContext.ts +26 -0
  12. package/src/accordion/item/AccordionItemDataAttributes.ts +13 -0
  13. package/src/accordion/item/stateAttributesMapping.ts +12 -0
  14. package/src/accordion/panel/AccordionPanel.tsrx +163 -0
  15. package/src/accordion/panel/AccordionPanelCssVars.ts +10 -0
  16. package/src/accordion/panel/AccordionPanelDataAttributes.ts +27 -0
  17. package/src/accordion/root/AccordionRoot.tsrx +240 -0
  18. package/src/accordion/root/AccordionRootContext.ts +31 -0
  19. package/src/accordion/root/AccordionRootDataAttributes.ts +8 -0
  20. package/src/accordion/trigger/AccordionTrigger.tsrx +81 -0
  21. package/src/accordion/trigger/AccordionTriggerDataAttributes.ts +8 -0
  22. package/src/alert-dialog/handle.ts +22 -0
  23. package/src/alert-dialog/index.parts.ts +10 -0
  24. package/src/alert-dialog/index.ts +39 -0
  25. package/src/alert-dialog/root/AlertDialogRoot.tsrx +58 -0
  26. package/src/alert-dialog/trigger/AlertDialogTrigger.tsrx +38 -0
  27. package/src/alert-dialog/trigger/AlertDialogTriggerDataAttributes.ts +10 -0
  28. package/src/autocomplete/clear/AutocompleteClearDataAttributes.ts +1 -0
  29. package/src/autocomplete/index.parts.ts +25 -0
  30. package/src/autocomplete/index.ts +78 -0
  31. package/src/autocomplete/input-group/AutocompleteInputGroup.tsrx +53 -0
  32. package/src/autocomplete/input-group/AutocompleteInputGroupDataAttributes.ts +49 -0
  33. package/src/autocomplete/item/AutocompleteItem.tsrx +56 -0
  34. package/src/autocomplete/item/AutocompleteItemDataAttributes.ts +10 -0
  35. package/src/autocomplete/root/AutocompleteRoot.tsrx +296 -0
  36. package/src/autocomplete/separator/AutocompleteSeparator.tsrx +37 -0
  37. package/src/autocomplete/trigger/AutocompleteTrigger.tsrx +57 -0
  38. package/src/autocomplete/trigger/AutocompleteTriggerDataAttributes.ts +55 -0
  39. package/src/autocomplete/value/AutocompleteValue.tsrx +38 -0
  40. package/src/avatar/fallback/AvatarFallback.tsrx +68 -0
  41. package/src/avatar/image/AvatarImage.tsrx +210 -0
  42. package/src/avatar/image/AvatarImageDataAttributes.ts +18 -0
  43. package/src/avatar/image/useImageLoadingStatus.ts +72 -0
  44. package/src/avatar/index.parts.ts +3 -0
  45. package/src/avatar/index.ts +5 -0
  46. package/src/avatar/root/AvatarRoot.tsrx +60 -0
  47. package/src/avatar/root/AvatarRootContext.ts +21 -0
  48. package/src/avatar/root/stateAttributesMapping.ts +3 -0
  49. package/src/button/Button.tsrx +63 -0
  50. package/src/button/ButtonDataAttributes.tsrx +4 -0
  51. package/src/button/index.ts +3 -0
  52. package/src/checkbox/index.parts.ts +2 -0
  53. package/src/checkbox/index.ts +4 -0
  54. package/src/checkbox/indicator/CheckboxIndicator.tsrx +96 -0
  55. package/src/checkbox/indicator/CheckboxIndicatorDataAttributes.ts +58 -0
  56. package/src/checkbox/root/CheckboxRoot.tsrx +516 -0
  57. package/src/checkbox/root/CheckboxRootContext.ts +19 -0
  58. package/src/checkbox/root/CheckboxRootDataAttributes.ts +48 -0
  59. package/src/checkbox/utils/getCheckboxStateAttributesMapping.ts +24 -0
  60. package/src/checkbox-group/CheckboxGroup.tsrx +229 -0
  61. package/src/checkbox-group/CheckboxGroupContext.ts +33 -0
  62. package/src/checkbox-group/CheckboxGroupDataAttributes.ts +4 -0
  63. package/src/checkbox-group/index.ts +2 -0
  64. package/src/checkbox-group/useCheckboxGroupParent.ts +176 -0
  65. package/src/collapsible/index.parts.ts +3 -0
  66. package/src/collapsible/index.ts +12 -0
  67. package/src/collapsible/panel/CollapsiblePanel.tsrx +168 -0
  68. package/src/collapsible/panel/CollapsiblePanelCssVars.ts +10 -0
  69. package/src/collapsible/panel/CollapsiblePanelDataAttributes.ts +18 -0
  70. package/src/collapsible/panel/useCollapsiblePanel.ts +577 -0
  71. package/src/collapsible/root/CollapsibleRoot.tsrx +116 -0
  72. package/src/collapsible/root/CollapsibleRootContext.ts +25 -0
  73. package/src/collapsible/root/CollapsibleRootDataAttributes.ts +18 -0
  74. package/src/collapsible/root/stateAttributesMapping.ts +9 -0
  75. package/src/collapsible/root/useCollapsibleRoot.ts +121 -0
  76. package/src/collapsible/trigger/CollapsibleTrigger.tsrx +78 -0
  77. package/src/collapsible/trigger/CollapsibleTriggerDataAttributes.ts +4 -0
  78. package/src/combobox/arrow/ComboboxArrow.tsrx +72 -0
  79. package/src/combobox/arrow/ComboboxArrowDataAttributes.ts +24 -0
  80. package/src/combobox/backdrop/ComboboxBackdrop.tsrx +75 -0
  81. package/src/combobox/backdrop/ComboboxBackdropDataAttributes.ts +18 -0
  82. package/src/combobox/chip/ComboboxChip.tsrx +150 -0
  83. package/src/combobox/chip/ComboboxChipContext.ts +19 -0
  84. package/src/combobox/chip-remove/ComboboxChipRemove.tsrx +138 -0
  85. package/src/combobox/chips/ComboboxChips.tsrx +78 -0
  86. package/src/combobox/chips/ComboboxChipsContext.ts +17 -0
  87. package/src/combobox/clear/ComboboxClear.tsrx +178 -0
  88. package/src/combobox/clear/ComboboxClearDataAttributes.ts +25 -0
  89. package/src/combobox/collection/ComboboxCollection.tsrx +34 -0
  90. package/src/combobox/collection/GroupCollectionContext.tsrx +31 -0
  91. package/src/combobox/empty/ComboboxEmpty.tsrx +58 -0
  92. package/src/combobox/group/ComboboxGroup.tsrx +74 -0
  93. package/src/combobox/group/ComboboxGroupContext.ts +27 -0
  94. package/src/combobox/group-label/ComboboxGroupLabel.tsrx +52 -0
  95. package/src/combobox/icon/ComboboxIcon.tsrx +41 -0
  96. package/src/combobox/index.parts.ts +31 -0
  97. package/src/combobox/index.ts +36 -0
  98. package/src/combobox/input/ComboboxInput.tsrx +507 -0
  99. package/src/combobox/input/ComboboxInputDataAttributes.ts +55 -0
  100. package/src/combobox/input-group/ComboboxInputGroup.tsrx +110 -0
  101. package/src/combobox/input-group/ComboboxInputGroupDataAttributes.ts +53 -0
  102. package/src/combobox/item/ComboboxItem.tsrx +328 -0
  103. package/src/combobox/item/ComboboxItemContext.ts +20 -0
  104. package/src/combobox/item/ComboboxItemDataAttributes.ts +12 -0
  105. package/src/combobox/item-indicator/ComboboxItemIndicator.tsrx +109 -0
  106. package/src/combobox/item-indicator/ComboboxItemIndicatorDataAttributes.ts +10 -0
  107. package/src/combobox/items/createItems.ts +168 -0
  108. package/src/combobox/items/itemCollection.ts +67 -0
  109. package/src/combobox/label/ComboboxLabel.tsrx +88 -0
  110. package/src/combobox/list/ComboboxList.tsrx +152 -0
  111. package/src/combobox/popup/ComboboxPopup.tsrx +214 -0
  112. package/src/combobox/popup/ComboboxPopupDataAttributes.ts +36 -0
  113. package/src/combobox/portal/ComboboxPortal.tsrx +56 -0
  114. package/src/combobox/portal/ComboboxPortalContext.tsrx +12 -0
  115. package/src/combobox/positioner/ComboboxPositioner.tsrx +172 -0
  116. package/src/combobox/positioner/ComboboxPositionerContext.tsrx +30 -0
  117. package/src/combobox/positioner/ComboboxPositionerCssVars.ts +25 -0
  118. package/src/combobox/positioner/ComboboxPositionerDataAttributes.ts +28 -0
  119. package/src/combobox/root/AriaCombobox.tsrx +1970 -0
  120. package/src/combobox/root/ComboboxRoot.tsrx +183 -0
  121. package/src/combobox/root/ComboboxRootContext.tsrx +66 -0
  122. package/src/combobox/root/utils/constants.ts +5 -0
  123. package/src/combobox/root/utils/index.ts +68 -0
  124. package/src/combobox/root/utils/useFilter.ts +50 -0
  125. package/src/combobox/root/utils/useFilteredItems.ts +11 -0
  126. package/src/combobox/row/ComboboxRow.tsrx +37 -0
  127. package/src/combobox/row/ComboboxRowContext.ts +9 -0
  128. package/src/combobox/separator/ComboboxSeparator.tsrx +37 -0
  129. package/src/combobox/status/ComboboxStatus.tsrx +49 -0
  130. package/src/combobox/store.ts +206 -0
  131. package/src/combobox/trigger/ComboboxTrigger.tsrx +302 -0
  132. package/src/combobox/trigger/ComboboxTriggerDataAttributes.ts +59 -0
  133. package/src/combobox/utils/ComboboxInternalDismissButton.tsrx +47 -0
  134. package/src/combobox/utils/handleInputPress.ts +38 -0
  135. package/src/combobox/utils/parts.ts +59 -0
  136. package/src/combobox/utils/stateAttributesMapping.ts +19 -0
  137. package/src/combobox/utils/useInitialLiveRegionTextMutation.ts +66 -0
  138. package/src/combobox/value/ComboboxValue.tsrx +65 -0
  139. package/src/context-menu/index.parts.ts +21 -0
  140. package/src/context-menu/index.ts +66 -0
  141. package/src/context-menu/positioner/ContextMenuPositioner.tsrx +119 -0
  142. package/src/context-menu/positioner/ContextMenuPositionerCssVars.ts +1 -0
  143. package/src/context-menu/positioner/ContextMenuPositionerDataAttributes.ts +1 -0
  144. package/src/context-menu/root/ContextMenuRoot.tsrx +98 -0
  145. package/src/context-menu/root/ContextMenuRootContext.ts +34 -0
  146. package/src/context-menu/trigger/ContextMenuTrigger.tsrx +237 -0
  147. package/src/context-menu/trigger/ContextMenuTriggerDataAttributes.ts +10 -0
  148. package/src/csp-provider/CSPProvider.tsrx +43 -0
  149. package/src/csp-provider/index.parts.ts +1 -0
  150. package/src/csp-provider/index.ts +3 -0
  151. package/src/dialog/backdrop/DialogBackdrop.tsrx +76 -0
  152. package/src/dialog/backdrop/DialogBackdropDataAttributes.ts +18 -0
  153. package/src/dialog/close/DialogClose.tsrx +67 -0
  154. package/src/dialog/close/DialogCloseDataAttributes.ts +4 -0
  155. package/src/dialog/description/DialogDescription.tsrx +41 -0
  156. package/src/dialog/index.parts.ts +10 -0
  157. package/src/dialog/index.ts +14 -0
  158. package/src/dialog/popup/DialogPopup.tsrx +170 -0
  159. package/src/dialog/popup/DialogPopupCssVars.ts +5 -0
  160. package/src/dialog/popup/DialogPopupDataAttributes.ts +26 -0
  161. package/src/dialog/portal/DialogPortal.tsrx +63 -0
  162. package/src/dialog/portal/DialogPortalContext.ts +13 -0
  163. package/src/dialog/root/DialogRoot.tsrx +117 -0
  164. package/src/dialog/root/DialogRootContext.ts +20 -0
  165. package/src/dialog/root/useDialogRoot.ts +128 -0
  166. package/src/dialog/root/useRenderDialogRoot.tsrx +108 -0
  167. package/src/dialog/store/DialogHandle.ts +83 -0
  168. package/src/dialog/store/DialogStore.ts +149 -0
  169. package/src/dialog/title/DialogTitle.tsrx +41 -0
  170. package/src/dialog/trigger/DialogTrigger.tsrx +142 -0
  171. package/src/dialog/trigger/DialogTriggerDataAttributes.ts +10 -0
  172. package/src/dialog/utils/stateAttributesMapping.ts +22 -0
  173. package/src/dialog/viewport/DialogViewport.tsrx +89 -0
  174. package/src/dialog/viewport/DialogViewportDataAttributes.ts +26 -0
  175. package/src/direction-provider/DirectionProvider.tsrx +37 -0
  176. package/src/direction-provider/index.parts.ts +5 -0
  177. package/src/direction-provider/index.ts +2 -0
  178. package/src/drawer/backdrop/DrawerBackdrop.tsrx +81 -0
  179. package/src/drawer/backdrop/DrawerBackdropCssVars.ts +5 -0
  180. package/src/drawer/backdrop/DrawerBackdropDataAttributes.ts +18 -0
  181. package/src/drawer/close/DrawerClose.tsrx +31 -0
  182. package/src/drawer/content/DrawerContent.tsrx +37 -0
  183. package/src/drawer/content/drawerContentAttribute.ts +1 -0
  184. package/src/drawer/description/DrawerDescription.tsrx +25 -0
  185. package/src/drawer/handle.ts +22 -0
  186. package/src/drawer/indent/DrawerIndent.tsrx +104 -0
  187. package/src/drawer/indent-background/DrawerIndentBackground.tsrx +61 -0
  188. package/src/drawer/index.parts.ts +16 -0
  189. package/src/drawer/index.ts +17 -0
  190. package/src/drawer/popup/DrawerPopup.tsrx +485 -0
  191. package/src/drawer/popup/DrawerPopupCssVars.ts +35 -0
  192. package/src/drawer/popup/DrawerPopupDataAttributes.ts +43 -0
  193. package/src/drawer/portal/DrawerPortal.tsrx +39 -0
  194. package/src/drawer/provider/DrawerProvider.tsrx +117 -0
  195. package/src/drawer/provider/DrawerProviderContext.ts +29 -0
  196. package/src/drawer/root/DrawerRoot.tsrx +478 -0
  197. package/src/drawer/root/DrawerRootContext.ts +115 -0
  198. package/src/drawer/root/useDrawerSnapPoints.ts +198 -0
  199. package/src/drawer/swipe-area/DrawerSwipeArea.tsrx +528 -0
  200. package/src/drawer/swipe-area/DrawerSwipeAreaDataAttributes.ts +23 -0
  201. package/src/drawer/title/DrawerTitle.tsrx +25 -0
  202. package/src/drawer/trigger/DrawerTrigger.tsrx +53 -0
  203. package/src/drawer/viewport/DrawerViewport.tsrx +1237 -0
  204. package/src/drawer/viewport/DrawerViewportContext.tsrx +15 -0
  205. package/src/drawer/viewport/DrawerViewportCssVars.ts +6 -0
  206. package/src/drawer/viewport/DrawerViewportDataAttributes.ts +22 -0
  207. package/src/drawer/virtual-keyboard-provider/DrawerVirtualKeyboardContext.tsrx +19 -0
  208. package/src/drawer/virtual-keyboard-provider/DrawerVirtualKeyboardProvider.tsrx +858 -0
  209. package/src/field/control/FieldControl.tsrx +241 -0
  210. package/src/field/control/FieldControlDataAttributes.ts +28 -0
  211. package/src/field/description/FieldDescription.tsrx +67 -0
  212. package/src/field/description/FieldDescriptionDataAttributes.ts +28 -0
  213. package/src/field/error/FieldError.tsrx +160 -0
  214. package/src/field/error/FieldErrorDataAttributes.ts +38 -0
  215. package/src/field/index.parts.ts +9 -0
  216. package/src/field/index.ts +9 -0
  217. package/src/field/item/FieldItem.tsrx +66 -0
  218. package/src/field/item/FieldItemContext.ts +15 -0
  219. package/src/field/item/FieldItemDataAttributes.ts +28 -0
  220. package/src/field/label/FieldLabel.tsrx +107 -0
  221. package/src/field/label/FieldLabelDataAttributes.ts +28 -0
  222. package/src/field/root/FieldRoot.tsrx +336 -0
  223. package/src/field/root/FieldRootDataAttributes.ts +28 -0
  224. package/src/field/root/useFieldValidation.ts +418 -0
  225. package/src/field/utils/getCombinedFieldValidityData.ts +18 -0
  226. package/src/field/validity/FieldValidity.tsrx +69 -0
  227. package/src/fieldset/index.parts.ts +2 -0
  228. package/src/fieldset/index.ts +4 -0
  229. package/src/fieldset/legend/FieldsetLegend.tsrx +51 -0
  230. package/src/fieldset/root/FieldsetRoot.tsrx +74 -0
  231. package/src/fieldset/root/FieldsetRootContext.ts +23 -0
  232. package/src/floating-ui-react/components/FloatingDelayGroup.tsrx +281 -0
  233. package/src/floating-ui-react/components/FloatingFocusManager.tsrx +1004 -0
  234. package/src/floating-ui-react/components/FloatingPortal.tsrx +319 -0
  235. package/src/floating-ui-react/components/FloatingRootStore.ts +136 -0
  236. package/src/floating-ui-react/components/FloatingTree.tsrx +95 -0
  237. package/src/floating-ui-react/components/FloatingTreeStore.ts +24 -0
  238. package/src/floating-ui-react/hooks/gridNavigation.ts +50 -0
  239. package/src/floating-ui-react/hooks/useClick.ts +229 -0
  240. package/src/floating-ui-react/hooks/useClientPoint.ts +261 -0
  241. package/src/floating-ui-react/hooks/useDismiss.ts +808 -0
  242. package/src/floating-ui-react/hooks/useFloating.ts +205 -0
  243. package/src/floating-ui-react/hooks/useFloatingRootContext.ts +84 -0
  244. package/src/floating-ui-react/hooks/useFocus.ts +253 -0
  245. package/src/floating-ui-react/hooks/useHover.ts +468 -0
  246. package/src/floating-ui-react/hooks/useHoverFloatingInteraction.ts +274 -0
  247. package/src/floating-ui-react/hooks/useHoverInteractionSharedState.ts +132 -0
  248. package/src/floating-ui-react/hooks/useHoverReferenceInteraction.ts +523 -0
  249. package/src/floating-ui-react/hooks/useHoverShared.ts +72 -0
  250. package/src/floating-ui-react/hooks/useListNavigation.ts +941 -0
  251. package/src/floating-ui-react/hooks/useSyncedFloatingRootContext.ts +115 -0
  252. package/src/floating-ui-react/hooks/useTypeahead.ts +248 -0
  253. package/src/floating-ui-react/index.ts +48 -0
  254. package/src/floating-ui-react/middleware/arrow.ts +128 -0
  255. package/src/floating-ui-react/middleware/positioning.ts +28 -0
  256. package/src/floating-ui-react/safePolygon.ts +451 -0
  257. package/src/floating-ui-react/types.ts +206 -0
  258. package/src/floating-ui-react/utils/composite.ts +528 -0
  259. package/src/floating-ui-react/utils/constants.ts +10 -0
  260. package/src/floating-ui-react/utils/createAttribute.ts +3 -0
  261. package/src/floating-ui-react/utils/createEventEmitter.ts +19 -0
  262. package/src/floating-ui-react/utils/element.ts +96 -0
  263. package/src/floating-ui-react/utils/enqueueFocus.ts +37 -0
  264. package/src/floating-ui-react/utils/event.ts +60 -0
  265. package/src/floating-ui-react/utils/getEmptyRootContext.ts +17 -0
  266. package/src/floating-ui-react/utils/markOthers.ts +219 -0
  267. package/src/floating-ui-react/utils/nodes.ts +54 -0
  268. package/src/floating-ui-react/utils/tabbable.ts +283 -0
  269. package/src/floating-ui-react/utils.ts +5 -0
  270. package/src/form/Form.tsrx +248 -0
  271. package/src/form/index.ts +3 -0
  272. package/src/global.d.ts +9 -0
  273. package/src/index.ts +45 -39
  274. package/src/input/Input.tsrx +44 -0
  275. package/src/input/InputDataAttributes.ts +28 -0
  276. package/src/input/index.ts +3 -0
  277. package/src/internals/PrehydrationScript.tsrx +59 -0
  278. package/src/internals/RequestQueue.ts +126 -0
  279. package/src/internals/TimeoutManager.ts +29 -0
  280. package/src/internals/TransitionStatusDataAttributes.ts +9 -0
  281. package/src/internals/composite/composite.ts +174 -0
  282. package/src/internals/composite/constants.ts +1 -0
  283. package/src/internals/composite/index.ts +19 -0
  284. package/src/internals/composite/item/CompositeItem.tsrx +57 -0
  285. package/src/internals/composite/item/useCompositeItem.ts +50 -0
  286. package/src/internals/composite/list/CompositeList.tsrx +325 -0
  287. package/src/internals/composite/list/CompositeListContext.ts +28 -0
  288. package/src/internals/composite/list/useCompositeListItem.ts +100 -0
  289. package/src/internals/composite/root/CompositeRoot.tsrx +138 -0
  290. package/src/internals/composite/root/CompositeRootContext.ts +33 -0
  291. package/src/internals/composite/root/gridNavigation.ts +127 -0
  292. package/src/internals/composite/root/useCompositeRoot.ts +378 -0
  293. package/src/internals/constants.ts +41 -0
  294. package/src/internals/createBaseUIEventDetails.ts +166 -0
  295. package/src/internals/csp-context/CSPContext.tsrx +17 -0
  296. package/src/internals/csp-context/index.ts +2 -0
  297. package/src/internals/direction-context/DirectionContext.tsrx +16 -0
  298. package/src/internals/direction-context/index.ts +5 -0
  299. package/src/internals/field-constants/constants.ts +44 -0
  300. package/src/internals/field-constants/index.ts +6 -0
  301. package/src/internals/field-register-control/index.ts +6 -0
  302. package/src/internals/field-register-control/useFieldControlRegistration.ts +185 -0
  303. package/src/internals/field-register-control/useRegisterFieldControl.ts +47 -0
  304. package/src/internals/field-root-context/FieldRootContext.ts +79 -0
  305. package/src/internals/field-root-context/index.ts +2 -0
  306. package/src/internals/filter.ts +82 -0
  307. package/src/internals/form-context/FormContext.ts +51 -0
  308. package/src/internals/form-context/index.ts +2 -0
  309. package/src/internals/getDisabledMountTransitionStyles.ts +10 -0
  310. package/src/internals/getStateAttributesProps.ts +32 -0
  311. package/src/internals/itemEquality.ts +134 -0
  312. package/src/internals/labelable-provider/LabelableContext.ts +49 -0
  313. package/src/internals/labelable-provider/LabelableProvider.tsrx +120 -0
  314. package/src/internals/labelable-provider/index.ts +6 -0
  315. package/src/internals/labelable-provider/useAriaLabelledBy.ts +73 -0
  316. package/src/internals/labelable-provider/useLabel.ts +113 -0
  317. package/src/internals/labelable-provider/useLabelableId.ts +101 -0
  318. package/src/internals/noop.ts +1 -0
  319. package/src/internals/prehydrationScript.stub.ts +6 -0
  320. package/src/internals/reason-parts.ts +42 -0
  321. package/src/internals/reasons.ts +5 -0
  322. package/src/internals/resolveValueLabel.tsrx +158 -0
  323. package/src/internals/serializeValue.ts +13 -0
  324. package/src/internals/stateAttributesMapping.ts +20 -0
  325. package/src/internals/temporal/index.ts +2 -0
  326. package/src/internals/temporal/temporal-adapter.ts +382 -0
  327. package/src/internals/temporal/temporal.ts +49 -0
  328. package/src/internals/temporal-adapter-date-fns/TemporalAdapterDateFns.ts +474 -0
  329. package/src/internals/temporal-adapter-date-fns/index.ts +1 -0
  330. package/src/internals/temporal-adapter-luxon/TemporalAdapterLuxon.ts +380 -0
  331. package/src/internals/temporal-adapter-luxon/index.ts +1 -0
  332. package/src/internals/types.ts +97 -0
  333. package/src/internals/use-button/index.ts +1 -0
  334. package/src/internals/use-button/useButton.ts +309 -0
  335. package/src/internals/useAnchorPositioning.ts +828 -0
  336. package/src/internals/useAnimationsFinished.ts +161 -0
  337. package/src/internals/useBaseUiId.ts +12 -0
  338. package/src/internals/useOpenChangeComplete.tsrx +56 -0
  339. package/src/internals/usePressAndHold.ts +287 -0
  340. package/src/internals/useRenderElement.tsrx +284 -0
  341. package/src/internals/useTransitionStatus.ts +98 -0
  342. package/src/internals/useValueChanged.ts +18 -0
  343. package/src/menu/arrow/MenuArrow.tsrx +71 -0
  344. package/src/menu/arrow/MenuArrowDataAttributes.ts +24 -0
  345. package/src/menu/backdrop/MenuBackdrop.tsrx +75 -0
  346. package/src/menu/backdrop/MenuBackdropDataAttributes.ts +18 -0
  347. package/src/menu/checkbox-item/MenuCheckboxItem.tsrx +184 -0
  348. package/src/menu/checkbox-item/MenuCheckboxItemContext.ts +24 -0
  349. package/src/menu/checkbox-item/MenuCheckboxItemDataAttributes.ts +16 -0
  350. package/src/menu/checkbox-item-indicator/MenuCheckboxItemIndicator.tsrx +96 -0
  351. package/src/menu/checkbox-item-indicator/MenuCheckboxItemIndicatorDataAttributes.ts +22 -0
  352. package/src/menu/group/MenuGroup.tsrx +47 -0
  353. package/src/menu/group/MenuGroupContext.ts +18 -0
  354. package/src/menu/group-label/MenuGroupLabel.tsrx +51 -0
  355. package/src/menu/index.parts.ts +21 -0
  356. package/src/menu/index.ts +24 -0
  357. package/src/menu/item/MenuItem.tsrx +107 -0
  358. package/src/menu/item/MenuItemDataAttributes.ts +8 -0
  359. package/src/menu/item/useMenuItem.ts +142 -0
  360. package/src/menu/item/useMenuItemCommonProps.ts +139 -0
  361. package/src/menu/link-item/MenuLinkItem.tsrx +106 -0
  362. package/src/menu/link-item/MenuLinkItemDataAttributes.ts +4 -0
  363. package/src/menu/popup/MenuPopup.tsrx +199 -0
  364. package/src/menu/popup/MenuPopupDataAttributes.ts +33 -0
  365. package/src/menu/portal/MenuPortal.tsrx +60 -0
  366. package/src/menu/portal/MenuPortalContext.ts +13 -0
  367. package/src/menu/positioner/MenuPositioner.tsrx +378 -0
  368. package/src/menu/positioner/MenuPositionerContext.ts +25 -0
  369. package/src/menu/positioner/MenuPositionerCssVars.ts +37 -0
  370. package/src/menu/positioner/MenuPositionerDataAttributes.ts +24 -0
  371. package/src/menu/radio-group/MenuRadioGroup.tsrx +129 -0
  372. package/src/menu/radio-group/MenuRadioGroupContext.ts +25 -0
  373. package/src/menu/radio-item/MenuRadioItem.tsrx +156 -0
  374. package/src/menu/radio-item/MenuRadioItemContext.ts +24 -0
  375. package/src/menu/radio-item/MenuRadioItemDataAttributes.ts +16 -0
  376. package/src/menu/radio-item-indicator/MenuRadioItemIndicator.tsrx +96 -0
  377. package/src/menu/radio-item-indicator/MenuRadioItemIndicatorDataAttributes.ts +22 -0
  378. package/src/menu/root/MenuRoot.tsrx +818 -0
  379. package/src/menu/root/MenuRootContext.ts +25 -0
  380. package/src/menu/store/MenuHandle.ts +54 -0
  381. package/src/menu/store/MenuStore.ts +234 -0
  382. package/src/menu/submenu-root/MenuSubmenuRoot.tsrx +64 -0
  383. package/src/menu/submenu-root/MenuSubmenuRootContext.ts +16 -0
  384. package/src/menu/submenu-trigger/MenuSubmenuTrigger.tsrx +278 -0
  385. package/src/menu/submenu-trigger/MenuSubmenuTriggerDataAttributes.ts +14 -0
  386. package/src/menu/trigger/MenuTrigger.tsrx +395 -0
  387. package/src/menu/trigger/MenuTriggerDataAttributes.ts +14 -0
  388. package/src/menu/utils/findRootOwnerId.ts +13 -0
  389. package/src/menu/utils/stateAttributesMapping.ts +17 -0
  390. package/src/menu/utils/types.ts +8 -0
  391. package/src/menu/viewport/MenuViewport.tsrx +75 -0
  392. package/src/menu/viewport/MenuViewportCssVars.ts +12 -0
  393. package/src/menu/viewport/MenuViewportDataAttributes.ts +24 -0
  394. package/src/menubar/Menubar.tsrx +173 -0
  395. package/src/menubar/MenubarContext.ts +31 -0
  396. package/src/menubar/MenubarDataAttributes.ts +13 -0
  397. package/src/menubar/index.ts +3 -0
  398. package/src/merge-props/index.ts +1 -0
  399. package/src/merge-props/mergeProps.ts +302 -0
  400. package/src/meter/index.parts.ts +5 -0
  401. package/src/meter/index.ts +7 -0
  402. package/src/meter/indicator/MeterIndicator.tsrx +46 -0
  403. package/src/meter/label/MeterLabel.tsrx +46 -0
  404. package/src/meter/root/MeterRoot.tsrx +129 -0
  405. package/src/meter/root/MeterRootContext.ts +26 -0
  406. package/src/meter/track/MeterTrack.tsrx +34 -0
  407. package/src/meter/value/MeterValue.tsrx +51 -0
  408. package/src/navigation-menu/arrow/NavigationMenuArrow.tsrx +77 -0
  409. package/src/navigation-menu/arrow/NavigationMenuArrowDataAttributes.ts +24 -0
  410. package/src/navigation-menu/backdrop/NavigationMenuBackdrop.tsrx +69 -0
  411. package/src/navigation-menu/backdrop/NavigationMenuBackdropDataAttributes.ts +18 -0
  412. package/src/navigation-menu/content/NavigationMenuContent.tsrx +208 -0
  413. package/src/navigation-menu/content/NavigationMenuContentDataAttributes.ts +23 -0
  414. package/src/navigation-menu/icon/NavigationMenuIcon.tsrx +56 -0
  415. package/src/navigation-menu/icon/NavigationMenuIconDataAttributes.ts +6 -0
  416. package/src/navigation-menu/index.parts.ts +13 -0
  417. package/src/navigation-menu/index.ts +15 -0
  418. package/src/navigation-menu/item/NavigationMenuItem.tsrx +59 -0
  419. package/src/navigation-menu/item/NavigationMenuItemContext.ts +21 -0
  420. package/src/navigation-menu/link/NavigationMenuLink.tsrx +108 -0
  421. package/src/navigation-menu/link/NavigationMenuLinkDataAttributes.ts +4 -0
  422. package/src/navigation-menu/list/NavigationMenuDismissContext.ts +12 -0
  423. package/src/navigation-menu/list/NavigationMenuList.tsrx +144 -0
  424. package/src/navigation-menu/popup/NavigationMenuPopup.tsrx +106 -0
  425. package/src/navigation-menu/popup/NavigationMenuPopupCssVars.ts +10 -0
  426. package/src/navigation-menu/popup/NavigationMenuPopupDataAttributes.ts +32 -0
  427. package/src/navigation-menu/portal/NavigationMenuPortal.tsrx +58 -0
  428. package/src/navigation-menu/portal/NavigationMenuPortalContext.ts +13 -0
  429. package/src/navigation-menu/positioner/NavigationMenuPositioner.tsrx +219 -0
  430. package/src/navigation-menu/positioner/NavigationMenuPositionerContext.ts +26 -0
  431. package/src/navigation-menu/positioner/NavigationMenuPositionerCssVars.ts +35 -0
  432. package/src/navigation-menu/positioner/NavigationMenuPositionerDataAttributes.ts +28 -0
  433. package/src/navigation-menu/root/NavigationMenuRoot.tsrx +439 -0
  434. package/src/navigation-menu/root/NavigationMenuRootContext.ts +84 -0
  435. package/src/navigation-menu/trigger/NavigationMenuTrigger.tsrx +846 -0
  436. package/src/navigation-menu/trigger/NavigationMenuTriggerDataAttributes.ts +14 -0
  437. package/src/navigation-menu/utils/constants.ts +3 -0
  438. package/src/navigation-menu/utils/isOutsideMenuEvent.ts +36 -0
  439. package/src/navigation-menu/utils/setSharedFixedSize.ts +20 -0
  440. package/src/navigation-menu/utils/useNavigationMenuAnchorPositioning.ts +18 -0
  441. package/src/navigation-menu/viewport/NavigationMenuViewport.tsrx +146 -0
  442. package/src/number-field/decrement/NumberFieldDecrement.tsrx +30 -0
  443. package/src/number-field/decrement/NumberFieldDecrementDataAttributes.ts +40 -0
  444. package/src/number-field/group/NumberFieldGroup.tsrx +42 -0
  445. package/src/number-field/group/NumberFieldGroupDataAttributes.ts +40 -0
  446. package/src/number-field/increment/NumberFieldIncrement.tsrx +30 -0
  447. package/src/number-field/increment/NumberFieldIncrementDataAttributes.ts +40 -0
  448. package/src/number-field/index.parts.ts +7 -0
  449. package/src/number-field/index.ts +9 -0
  450. package/src/number-field/input/NumberFieldInput.tsrx +488 -0
  451. package/src/number-field/input/NumberFieldInputDataAttributes.ts +40 -0
  452. package/src/number-field/root/NumberFieldRoot.tsrx +735 -0
  453. package/src/number-field/root/NumberFieldRootContext.ts +52 -0
  454. package/src/number-field/root/NumberFieldRootDataAttributes.ts +40 -0
  455. package/src/number-field/root/useNumberFieldStepperButton.ts +191 -0
  456. package/src/number-field/scrub-area/NumberFieldScrubArea.tsrx +395 -0
  457. package/src/number-field/scrub-area/NumberFieldScrubAreaContext.ts +24 -0
  458. package/src/number-field/scrub-area/NumberFieldScrubAreaDataAttributes.ts +40 -0
  459. package/src/number-field/scrub-area-cursor/NumberFieldScrubAreaCursor.tsrx +73 -0
  460. package/src/number-field/scrub-area-cursor/NumberFieldScrubAreaCursorDataAttributes.ts +40 -0
  461. package/src/number-field/utils/constants.ts +2 -0
  462. package/src/number-field/utils/getViewportRect.ts +34 -0
  463. package/src/number-field/utils/parse.ts +221 -0
  464. package/src/number-field/utils/stateAttributesMapping.ts +9 -0
  465. package/src/number-field/utils/types.ts +27 -0
  466. package/src/number-field/utils/validate.ts +136 -0
  467. package/src/otp-field/index.parts.ts +3 -0
  468. package/src/otp-field/index.ts +4 -0
  469. package/src/otp-field/input/OTPFieldInput.tsrx +356 -0
  470. package/src/otp-field/input/OTPFieldInputDataAttributes.ts +40 -0
  471. package/src/otp-field/root/OTPFieldRoot.tsrx +679 -0
  472. package/src/otp-field/root/OTPFieldRootContext.ts +58 -0
  473. package/src/otp-field/root/OTPFieldRootDataAttributes.ts +40 -0
  474. package/src/otp-field/utils/otp.ts +118 -0
  475. package/src/otp-field/utils/stateAttributesMapping.ts +16 -0
  476. package/src/popover/arrow/PopoverArrow.tsrx +69 -0
  477. package/src/popover/arrow/PopoverArrowDataAttributes.ts +24 -0
  478. package/src/popover/backdrop/PopoverBackdrop.tsrx +71 -0
  479. package/src/popover/backdrop/PopoverBackdropDataAttributes.ts +18 -0
  480. package/src/popover/close/PopoverClose.tsrx +65 -0
  481. package/src/popover/description/PopoverDescription.tsrx +46 -0
  482. package/src/popover/index.parts.ts +15 -0
  483. package/src/popover/index.ts +16 -0
  484. package/src/popover/popup/PopoverPopup.tsrx +188 -0
  485. package/src/popover/popup/PopoverPopupCssVars.ts +8 -0
  486. package/src/popover/popup/PopoverPopupDataAttributes.ts +33 -0
  487. package/src/popover/portal/PopoverPortal.tsrx +54 -0
  488. package/src/popover/portal/PopoverPortalContext.ts +13 -0
  489. package/src/popover/positioner/PopoverPositioner.tsrx +196 -0
  490. package/src/popover/positioner/PopoverPositionerContext.ts +28 -0
  491. package/src/popover/positioner/PopoverPositionerCssVars.ts +37 -0
  492. package/src/popover/positioner/PopoverPositionerDataAttributes.ts +24 -0
  493. package/src/popover/root/PopoverRoot.tsrx +262 -0
  494. package/src/popover/root/PopoverRootContext.ts +20 -0
  495. package/src/popover/store/PopoverHandle.ts +54 -0
  496. package/src/popover/store/PopoverStore.ts +229 -0
  497. package/src/popover/title/PopoverTitle.tsrx +46 -0
  498. package/src/popover/trigger/PopoverTrigger.tsrx +233 -0
  499. package/src/popover/trigger/PopoverTriggerDataAttributes.ts +14 -0
  500. package/src/popover/utils/constants.ts +1 -0
  501. package/src/popover/viewport/PopoverViewport.tsrx +75 -0
  502. package/src/popover/viewport/PopoverViewportCssVars.ts +12 -0
  503. package/src/popover/viewport/PopoverViewportDataAttributes.ts +24 -0
  504. package/src/preview-card/arrow/PreviewCardArrow.tsrx +70 -0
  505. package/src/preview-card/arrow/PreviewCardArrowDataAttributes.ts +24 -0
  506. package/src/preview-card/backdrop/PreviewCardBackdrop.tsrx +73 -0
  507. package/src/preview-card/backdrop/PreviewCardBackdropDataAttributes.ts +18 -0
  508. package/src/preview-card/index.parts.ts +12 -0
  509. package/src/preview-card/index.ts +16 -0
  510. package/src/preview-card/popup/PreviewCardPopup.tsrx +104 -0
  511. package/src/preview-card/popup/PreviewCardPopupDataAttributes.ts +28 -0
  512. package/src/preview-card/portal/PreviewCardPortal.tsrx +59 -0
  513. package/src/preview-card/portal/PreviewCardPortalContext.ts +13 -0
  514. package/src/preview-card/positioner/PreviewCardPositioner.tsrx +145 -0
  515. package/src/preview-card/positioner/PreviewCardPositionerContext.ts +24 -0
  516. package/src/preview-card/positioner/PreviewCardPositionerCssVars.ts +37 -0
  517. package/src/preview-card/positioner/PreviewCardPositionerDataAttributes.ts +24 -0
  518. package/src/preview-card/root/PreviewCardContext.ts +23 -0
  519. package/src/preview-card/root/PreviewCardRoot.tsrx +210 -0
  520. package/src/preview-card/store/PreviewCardHandle.ts +58 -0
  521. package/src/preview-card/store/PreviewCardStore.ts +140 -0
  522. package/src/preview-card/trigger/PreviewCardTrigger.tsrx +148 -0
  523. package/src/preview-card/trigger/PreviewCardTriggerDataAttributes.ts +6 -0
  524. package/src/preview-card/utils/constants.ts +2 -0
  525. package/src/preview-card/viewport/PreviewCardViewport.tsrx +78 -0
  526. package/src/preview-card/viewport/PreviewCardViewportCssVars.ts +12 -0
  527. package/src/preview-card/viewport/PreviewCardViewportDataAttributes.ts +24 -0
  528. package/src/progress/index.parts.ts +7 -0
  529. package/src/progress/index.ts +7 -0
  530. package/src/progress/indicator/ProgressIndicator.tsrx +59 -0
  531. package/src/progress/indicator/ProgressIndicatorDataAttributes.ts +12 -0
  532. package/src/progress/label/ProgressLabel.tsrx +51 -0
  533. package/src/progress/label/ProgressLabelDataAttributes.ts +12 -0
  534. package/src/progress/root/ProgressRoot.tsrx +154 -0
  535. package/src/progress/root/ProgressRootContext.tsrx +37 -0
  536. package/src/progress/root/ProgressRootDataAttributes.ts +12 -0
  537. package/src/progress/root/stateAttributesMapping.ts +18 -0
  538. package/src/progress/track/ProgressTrack.tsrx +42 -0
  539. package/src/progress/track/ProgressTrackDataAttributes.ts +12 -0
  540. package/src/progress/value/ProgressValue.tsrx +62 -0
  541. package/src/progress/value/ProgressValueDataAttributes.ts +12 -0
  542. package/src/radio/index.parts.ts +2 -0
  543. package/src/radio/index.ts +4 -0
  544. package/src/radio/indicator/RadioIndicator.tsrx +84 -0
  545. package/src/radio/indicator/RadioIndicatorDataAttributes.ts +54 -0
  546. package/src/radio/root/RadioRoot.tsrx +337 -0
  547. package/src/radio/root/RadioRootContext.ts +19 -0
  548. package/src/radio/root/RadioRootDataAttributes.ts +44 -0
  549. package/src/radio/utils/stateAttributesMapping.ts +20 -0
  550. package/src/radio-group/RadioGroup.tsrx +337 -0
  551. package/src/radio-group/RadioGroupContext.ts +29 -0
  552. package/src/radio-group/RadioGroupDataAttributes.ts +4 -0
  553. package/src/radio-group/index.ts +3 -0
  554. package/src/scroll-area/constants.ts +2 -0
  555. package/src/scroll-area/content/ScrollAreaContent.tsrx +90 -0
  556. package/src/scroll-area/content/ScrollAreaContentDataAttributes.ts +28 -0
  557. package/src/scroll-area/corner/ScrollAreaCorner.tsrx +54 -0
  558. package/src/scroll-area/index.parts.ts +6 -0
  559. package/src/scroll-area/index.ts +8 -0
  560. package/src/scroll-area/root/ScrollAreaRoot.tsrx +424 -0
  561. package/src/scroll-area/root/ScrollAreaRootContext.ts +61 -0
  562. package/src/scroll-area/root/ScrollAreaRootCssVars.ts +10 -0
  563. package/src/scroll-area/root/ScrollAreaRootDataAttributes.ts +28 -0
  564. package/src/scroll-area/root/stateAttributes.ts +15 -0
  565. package/src/scroll-area/scrollbar/ScrollAreaScrollbar.tsrx +275 -0
  566. package/src/scroll-area/scrollbar/ScrollAreaScrollbarContext.ts +19 -0
  567. package/src/scroll-area/scrollbar/ScrollAreaScrollbarCssVars.ts +10 -0
  568. package/src/scroll-area/scrollbar/ScrollAreaScrollbarDataAttributes.ts +37 -0
  569. package/src/scroll-area/thumb/ScrollAreaThumb.tsrx +80 -0
  570. package/src/scroll-area/thumb/ScrollAreaThumbDataAttributes.ts +9 -0
  571. package/src/scroll-area/utils/getOffset.ts +21 -0
  572. package/src/scroll-area/viewport/ScrollAreaViewport.tsrx +492 -0
  573. package/src/scroll-area/viewport/ScrollAreaViewportContext.ts +21 -0
  574. package/src/scroll-area/viewport/ScrollAreaViewportCssVars.ts +20 -0
  575. package/src/scroll-area/viewport/ScrollAreaViewportDataAttributes.ts +28 -0
  576. package/src/select/arrow/SelectArrow.tsrx +75 -0
  577. package/src/select/arrow/SelectArrowDataAttributes.ts +24 -0
  578. package/src/select/backdrop/SelectBackdrop.tsrx +77 -0
  579. package/src/select/backdrop/SelectBackdropDataAttributes.ts +18 -0
  580. package/src/select/group/SelectGroup.tsrx +52 -0
  581. package/src/select/group/SelectGroupContext.ts +20 -0
  582. package/src/select/group-label/SelectGroupLabel.tsrx +49 -0
  583. package/src/select/icon/SelectIcon.tsrx +51 -0
  584. package/src/select/icon/SelectIconDataAttributes.ts +6 -0
  585. package/src/select/index.parts.ts +19 -0
  586. package/src/select/index.ts +21 -0
  587. package/src/select/item/SelectItem.tsrx +291 -0
  588. package/src/select/item/SelectItemContext.ts +22 -0
  589. package/src/select/item/SelectItemDataAttributes.ts +12 -0
  590. package/src/select/item-indicator/SelectItemIndicator.tsrx +108 -0
  591. package/src/select/item-indicator/SelectItemIndicatorDataAttributes.ts +10 -0
  592. package/src/select/item-text/SelectItemText.tsrx +56 -0
  593. package/src/select/label/SelectLabel.tsrx +64 -0
  594. package/src/select/list/SelectList.tsrx +62 -0
  595. package/src/select/popup/SelectPopup.tsrx +596 -0
  596. package/src/select/popup/SelectPopupDataAttributes.ts +28 -0
  597. package/src/select/popup/utils.ts +13 -0
  598. package/src/select/portal/SelectPortal.tsrx +45 -0
  599. package/src/select/positioner/SelectPositioner.tsrx +268 -0
  600. package/src/select/positioner/SelectPositionerContext.ts +26 -0
  601. package/src/select/positioner/SelectPositionerCssVars.ts +25 -0
  602. package/src/select/positioner/SelectPositionerDataAttributes.ts +24 -0
  603. package/src/select/root/SelectRoot.tsrx +752 -0
  604. package/src/select/root/SelectRootContext.ts +57 -0
  605. package/src/select/scroll-arrow/SelectScrollArrow.tsrx +236 -0
  606. package/src/select/scroll-down-arrow/SelectScrollDownArrow.tsrx +37 -0
  607. package/src/select/scroll-down-arrow/SelectScrollDownArrowDataAttributes.ts +24 -0
  608. package/src/select/scroll-up-arrow/SelectScrollUpArrow.tsrx +37 -0
  609. package/src/select/scroll-up-arrow/SelectScrollUpArrowDataAttributes.ts +24 -0
  610. package/src/select/separator/SelectSeparator.tsrx +34 -0
  611. package/src/select/store.ts +155 -0
  612. package/src/select/trigger/SelectTrigger.tsrx +270 -0
  613. package/src/select/trigger/SelectTriggerDataAttributes.ts +55 -0
  614. package/src/select/value/SelectValue.tsrx +112 -0
  615. package/src/select/value/SelectValueDataAttributes.ts +4 -0
  616. package/src/separator/Separator.tsrx +49 -0
  617. package/src/separator/SeparatorDataAttributes.ts +5 -0
  618. package/src/separator/index.ts +3 -0
  619. package/src/slider/control/SliderControl.tsrx +540 -0
  620. package/src/slider/control/SliderControlDataAttributes.ts +33 -0
  621. package/src/slider/index.parts.ts +7 -0
  622. package/src/slider/index.ts +9 -0
  623. package/src/slider/indicator/SliderIndicator.tsrx +102 -0
  624. package/src/slider/indicator/SliderIndicatorDataAttributes.ts +33 -0
  625. package/src/slider/label/SliderLabel.tsrx +71 -0
  626. package/src/slider/root/SliderRoot.tsrx +610 -0
  627. package/src/slider/root/SliderRootContext.ts +115 -0
  628. package/src/slider/root/SliderRootDataAttributes.ts +33 -0
  629. package/src/slider/root/stateAttributesMapping.ts +15 -0
  630. package/src/slider/thumb/SliderThumb.tsrx +567 -0
  631. package/src/slider/thumb/SliderThumbDataAttributes.ts +37 -0
  632. package/src/slider/thumb/prehydrationScript.min.ts +5 -0
  633. package/src/slider/track/SliderTrack.tsrx +49 -0
  634. package/src/slider/track/SliderTrackDataAttributes.ts +33 -0
  635. package/src/slider/utils/asc.ts +3 -0
  636. package/src/slider/utils/getMidpoint.ts +4 -0
  637. package/src/slider/utils/getPushedThumbValues.ts +60 -0
  638. package/src/slider/utils/getSliderValue.ts +22 -0
  639. package/src/slider/utils/resolveThumbCollision.ts +154 -0
  640. package/src/slider/utils/roundValueToStep.ts +21 -0
  641. package/src/slider/utils/test-utils.ts +18 -0
  642. package/src/slider/utils/validateMinimumDistance.ts +17 -0
  643. package/src/slider/value/SliderValue.tsrx +82 -0
  644. package/src/slider/value/SliderValueDataAttributes.ts +33 -0
  645. package/src/switch/index.parts.ts +2 -0
  646. package/src/switch/index.ts +4 -0
  647. package/src/switch/root/SwitchRoot.tsrx +335 -0
  648. package/src/switch/root/SwitchRootContext.ts +19 -0
  649. package/src/switch/root/SwitchRootDataAttributes.ts +44 -0
  650. package/src/switch/stateAttributesMapping.ts +15 -0
  651. package/src/switch/thumb/SwitchThumb.tsrx +40 -0
  652. package/src/switch/thumb/SwitchThumbDataAttributes.ts +44 -0
  653. package/src/tabs/index.parts.ts +5 -0
  654. package/src/tabs/index.ts +21 -0
  655. package/src/tabs/indicator/TabsIndicator.tsrx +292 -0
  656. package/src/tabs/indicator/TabsIndicatorCssVars.ts +30 -0
  657. package/src/tabs/indicator/TabsIndicatorDataAttributes.ts +10 -0
  658. package/src/tabs/indicator/prehydrationScript.min.ts +5 -0
  659. package/src/tabs/list/TabsList.tsrx +153 -0
  660. package/src/tabs/list/TabsListContext.ts +23 -0
  661. package/src/tabs/list/TabsListDataAttributes.ts +10 -0
  662. package/src/tabs/panel/TabsPanel.tsrx +145 -0
  663. package/src/tabs/panel/TabsPanelDataAttributes.ts +28 -0
  664. package/src/tabs/root/TabsRoot.tsrx +477 -0
  665. package/src/tabs/root/TabsRootContext.ts +55 -0
  666. package/src/tabs/root/TabsRootDataAttributes.ts +10 -0
  667. package/src/tabs/root/stateAttributesMapping.ts +9 -0
  668. package/src/tabs/tab/TabsTab.tsrx +280 -0
  669. package/src/tabs/tab/TabsTabDataAttributes.ts +18 -0
  670. package/src/toast/action/ToastAction.tsrx +72 -0
  671. package/src/toast/action/ToastActionDataAttributes.ts +5 -0
  672. package/src/toast/arrow/ToastArrow.tsrx +57 -0
  673. package/src/toast/arrow/ToastArrowDataAttributes.ts +16 -0
  674. package/src/toast/close/ToastClose.tsrx +79 -0
  675. package/src/toast/close/ToastCloseDataAttributes.ts +5 -0
  676. package/src/toast/content/ToastContent.tsrx +76 -0
  677. package/src/toast/content/ToastContentDataAttributes.ts +10 -0
  678. package/src/toast/createToastManager.ts +104 -0
  679. package/src/toast/description/ToastDescription.tsrx +54 -0
  680. package/src/toast/description/ToastDescriptionDataAttributes.ts +5 -0
  681. package/src/toast/index.parts.ts +14 -0
  682. package/src/toast/index.ts +18 -0
  683. package/src/toast/portal/ToastPortal.tsrx +33 -0
  684. package/src/toast/positioner/ToastPositioner.tsrx +154 -0
  685. package/src/toast/positioner/ToastPositionerContext.ts +23 -0
  686. package/src/toast/positioner/ToastPositionerCssVars.ts +25 -0
  687. package/src/toast/positioner/ToastPositionerDataAttributes.ts +16 -0
  688. package/src/toast/provider/ToastProvider.tsrx +109 -0
  689. package/src/toast/provider/ToastProviderContext.ts +16 -0
  690. package/src/toast/root/ToastRoot.tsrx +563 -0
  691. package/src/toast/root/ToastRootContext.ts +25 -0
  692. package/src/toast/root/ToastRootCssVars.ts +25 -0
  693. package/src/toast/root/ToastRootDataAttributes.ts +35 -0
  694. package/src/toast/store.ts +527 -0
  695. package/src/toast/title/ToastTitle.tsrx +53 -0
  696. package/src/toast/title/ToastTitleDataAttributes.ts +5 -0
  697. package/src/toast/useToastManager.ts +150 -0
  698. package/src/toast/utils/focusVisible.ts +1 -0
  699. package/src/toast/utils/isRenderableNode.ts +18 -0
  700. package/src/toast/utils/resolvePromiseOptions.ts +22 -0
  701. package/src/toast/utils/test-utils.tsrx +39 -0
  702. package/src/toast/utils/useToastLabelPart.ts +53 -0
  703. package/src/toast/viewport/ToastViewport.tsrx +293 -0
  704. package/src/toast/viewport/ToastViewportCssVars.ts +5 -0
  705. package/src/toast/viewport/ToastViewportDataAttributes.ts +5 -0
  706. package/src/toggle/Toggle.tsrx +198 -0
  707. package/src/toggle/ToggleDataAttributes.ts +8 -0
  708. package/src/toggle/index.ts +3 -0
  709. package/src/toggle-group/ToggleGroup.tsrx +201 -0
  710. package/src/toggle-group/ToggleGroupContext.ts +28 -0
  711. package/src/toggle-group/ToggleGroupDataAttributes.ts +13 -0
  712. package/src/toggle-group/index.ts +3 -0
  713. package/src/toolbar/button/ToolbarButton.tsrx +108 -0
  714. package/src/toolbar/button/ToolbarButtonDataAttributes.ts +13 -0
  715. package/src/toolbar/group/ToolbarGroup.tsrx +69 -0
  716. package/src/toolbar/group/ToolbarGroupContext.ts +13 -0
  717. package/src/toolbar/group/ToolbarGroupDataAttributes.ts +9 -0
  718. package/src/toolbar/index.parts.ts +8 -0
  719. package/src/toolbar/index.ts +9 -0
  720. package/src/toolbar/input/ToolbarInput.tsrx +108 -0
  721. package/src/toolbar/input/ToolbarInputDataAttributes.ts +13 -0
  722. package/src/toolbar/link/ToolbarLink.tsrx +64 -0
  723. package/src/toolbar/link/ToolbarLinkDataAttributes.ts +5 -0
  724. package/src/toolbar/root/ToolbarRoot.tsrx +121 -0
  725. package/src/toolbar/root/ToolbarRootContext.ts +24 -0
  726. package/src/toolbar/root/ToolbarRootDataAttributes.ts +9 -0
  727. package/src/toolbar/separator/ToolbarSeparator.tsrx +37 -0
  728. package/src/toolbar/separator/ToolbarSeparatorDataAttributes.ts +5 -0
  729. package/src/tooltip/arrow/TooltipArrow.tsrx +76 -0
  730. package/src/tooltip/arrow/TooltipArrowDataAttributes.ts +29 -0
  731. package/src/tooltip/index.parts.ts +12 -0
  732. package/src/tooltip/index.ts +13 -0
  733. package/src/tooltip/popup/TooltipPopup.tsrx +108 -0
  734. package/src/tooltip/popup/TooltipPopupDataAttributes.ts +33 -0
  735. package/src/tooltip/portal/TooltipPortal.tsrx +54 -0
  736. package/src/tooltip/portal/TooltipPortalContext.ts +13 -0
  737. package/src/tooltip/positioner/TooltipPositioner.tsrx +150 -0
  738. package/src/tooltip/positioner/TooltipPositionerContext.ts +23 -0
  739. package/src/tooltip/positioner/TooltipPositionerCssVars.ts +37 -0
  740. package/src/tooltip/positioner/TooltipPositionerDataAttributes.ts +24 -0
  741. package/src/tooltip/provider/TooltipProvider.tsrx +49 -0
  742. package/src/tooltip/provider/TooltipProviderContext.ts +12 -0
  743. package/src/tooltip/root/TooltipRoot.tsrx +282 -0
  744. package/src/tooltip/root/TooltipRootContext.ts +21 -0
  745. package/src/tooltip/store/TooltipHandle.ts +54 -0
  746. package/src/tooltip/store/TooltipStore.ts +148 -0
  747. package/src/tooltip/trigger/TooltipTrigger.tsrx +351 -0
  748. package/src/tooltip/trigger/TooltipTriggerDataAttributes.ts +10 -0
  749. package/src/tooltip/utils/constants.ts +1 -0
  750. package/src/tooltip/viewport/TooltipViewport.tsrx +75 -0
  751. package/src/tooltip/viewport/TooltipViewportCssVars.ts +12 -0
  752. package/src/tooltip/viewport/TooltipViewportDataAttributes.ts +24 -0
  753. package/src/types/index.ts +29 -0
  754. package/src/unstable-use-media-query/index.ts +94 -0
  755. package/src/use-render/index.ts +2 -0
  756. package/src/use-render/useRender.ts +113 -0
  757. package/src/utils/CommonPopupCssVars.ts +12 -0
  758. package/src/utils/CommonPopupDataAttributes.ts +38 -0
  759. package/src/utils/CommonPositionerCssVars.ts +37 -0
  760. package/src/utils/CommonTriggerDataAttributes.ts +9 -0
  761. package/src/utils/CommonViewportDataAttributes.ts +7 -0
  762. package/src/utils/FloatingPortalLite.tsrx +51 -0
  763. package/src/utils/FocusGuard.tsrx +44 -0
  764. package/src/utils/InternalBackdrop.tsrx +50 -0
  765. package/src/utils/NullStore.ts +26 -0
  766. package/src/utils/adaptiveOriginConstants.ts +12 -0
  767. package/src/utils/adaptiveOriginMiddleware.ts +5 -14
  768. package/src/utils/closePart.tsrx +37 -0
  769. package/src/utils/collapsibleOpenStateMapping.ts +28 -23
  770. package/src/utils/dispatchClickWithModifiers.ts +36 -0
  771. package/src/utils/getCssDimensions.ts +11 -15
  772. package/src/utils/getElementAtPoint.ts +12 -0
  773. package/src/utils/getElementTransform.ts +33 -0
  774. package/src/utils/getPseudoElementBounds.ts +22 -7
  775. package/src/utils/hideMiddleware.ts +15 -12
  776. package/src/utils/listbox-separator/ListboxSeparator.tsrx +47 -0
  777. package/src/utils/mergeStyles.ts +15 -0
  778. package/src/utils/popupStateMapping.ts +57 -35
  779. package/src/utils/popups/index.ts +4 -8
  780. package/src/utils/popups/inlineRect.ts +19 -16
  781. package/src/utils/popups/popupHandle.ts +291 -0
  782. package/src/utils/popups/popupStoreUtils.ts +482 -320
  783. package/src/utils/popups/popupTriggerMap.ts +102 -28
  784. package/src/utils/popups/store.ts +146 -66
  785. package/src/utils/popups/usePopupHandleStore.ts +37 -0
  786. package/src/utils/popups/useTriggerFocusGuards.ts +36 -21
  787. package/src/utils/resolveAriaLabelledBy.ts +2 -1
  788. package/src/utils/resolveClassName.ts +8 -3
  789. package/src/utils/resolveRef.ts +8 -4
  790. package/src/utils/resolveStyle.ts +10 -6
  791. package/src/utils/scrollEdges.ts +33 -0
  792. package/src/utils/scrollable.ts +77 -0
  793. package/src/utils/styles.tsrx +21 -0
  794. package/src/utils/useAnchoredPopupScrollLock.ts +31 -37
  795. package/src/utils/useFocusableWhenDisabled.ts +81 -65
  796. package/src/utils/useIsHydrating.ts +12 -15
  797. package/src/utils/useMixedToggleClickHandler.ts +45 -60
  798. package/src/utils/useOpenInteractionType.ts +43 -45
  799. package/src/utils/usePopupAutoResize.ts +198 -207
  800. package/src/utils/usePopupViewport.tsrx +396 -0
  801. package/src/utils/usePositioner.tsrx +50 -0
  802. package/src/utils/useRegisteredLabelId.ts +16 -27
  803. package/src/utils/useSwipeDismiss.ts +1161 -0
  804. package/src/utils/valueToPercent.ts +1 -2
  805. package/dist/cjs/accordion.cjs +0 -497
  806. package/dist/cjs/alert-dialog.cjs +0 -65
  807. package/dist/cjs/avatar.cjs +0 -234
  808. package/dist/cjs/button.cjs +0 -54
  809. package/dist/cjs/checkbox-group.cjs +0 -165
  810. package/dist/cjs/checkbox.cjs +0 -475
  811. package/dist/cjs/collapsible.cjs +0 -700
  812. package/dist/cjs/context-menu.cjs +0 -257
  813. package/dist/cjs/csp-provider.cjs +0 -40
  814. package/dist/cjs/dialog.cjs +0 -741
  815. package/dist/cjs/direction-provider.cjs +0 -35
  816. package/dist/cjs/field.cjs +0 -559
  817. package/dist/cjs/fieldset.cjs +0 -101
  818. package/dist/cjs/form.cjs +0 -177
  819. package/dist/cjs/index.cjs +0 -133
  820. package/dist/cjs/input.cjs +0 -32
  821. package/dist/cjs/internal.cjs +0 -43
  822. package/dist/cjs/menu.cjs +0 -2420
  823. package/dist/cjs/menubar.cjs +0 -132
  824. package/dist/cjs/merge-props.cjs +0 -34
  825. package/dist/cjs/meter.cjs +0 -169
  826. package/dist/cjs/number-field.cjs +0 -812
  827. package/dist/cjs/popover.cjs +0 -966
  828. package/dist/cjs/preview-card.cjs +0 -632
  829. package/dist/cjs/progress.cjs +0 -206
  830. package/dist/cjs/radio-group.cjs +0 -264
  831. package/dist/cjs/radio.cjs +0 -327
  832. package/dist/cjs/separator.cjs +0 -44
  833. package/dist/cjs/slider.cjs +0 -1384
  834. package/dist/cjs/switch.cjs +0 -306
  835. package/dist/cjs/tabs.cjs +0 -727
  836. package/dist/cjs/toast.cjs +0 -1766
  837. package/dist/cjs/toggle-group.cjs +0 -118
  838. package/dist/cjs/toggle.cjs +0 -121
  839. package/dist/cjs/tooltip.cjs +0 -835
  840. package/dist/cjs/unstable-use-media-query.cjs +0 -79
  841. package/dist/cjs/use-render.cjs +0 -40
  842. package/dist/cjs/utils/CSPContext.cjs +0 -38
  843. package/dist/cjs/utils/CheckboxGroupContext.cjs +0 -40
  844. package/dist/cjs/utils/CompositeRootContext.cjs +0 -40
  845. package/dist/cjs/utils/ContextMenuRootContext.cjs +0 -42
  846. package/dist/cjs/utils/DirectionContext.cjs +0 -34
  847. package/dist/cjs/utils/FloatingPortalLite.cjs +0 -47
  848. package/dist/cjs/utils/InternalBackdrop.cjs +0 -49
  849. package/dist/cjs/utils/MenubarContext.cjs +0 -40
  850. package/dist/cjs/utils/RadioGroupContext.cjs +0 -34
  851. package/dist/cjs/utils/RequestQueue.cjs +0 -111
  852. package/dist/cjs/utils/TimeoutManager.cjs +0 -50
  853. package/dist/cjs/utils/ToggleGroupContext.cjs +0 -40
  854. package/dist/cjs/utils/adaptiveOriginMiddleware.cjs +0 -94
  855. package/dist/cjs/utils/addEventListener.cjs +0 -33
  856. package/dist/cjs/utils/areArraysEqual.cjs +0 -30
  857. package/dist/cjs/utils/clamp.cjs +0 -30
  858. package/dist/cjs/utils/closePart.cjs +0 -70
  859. package/dist/cjs/utils/collapsibleOpenStateMapping.cjs +0 -42
  860. package/dist/cjs/utils/composeRefs.cjs +0 -68
  861. package/dist/cjs/utils/composite/CompositeItem.cjs +0 -59
  862. package/dist/cjs/utils/composite/CompositeList.cjs +0 -177
  863. package/dist/cjs/utils/composite/CompositeListContext.cjs +0 -43
  864. package/dist/cjs/utils/composite/CompositeRoot.cjs +0 -118
  865. package/dist/cjs/utils/composite/grid-utils.cjs +0 -343
  866. package/dist/cjs/utils/composite/gridNavigation.cjs +0 -92
  867. package/dist/cjs/utils/composite/keys.cjs +0 -174
  868. package/dist/cjs/utils/composite/list-utils.cjs +0 -90
  869. package/dist/cjs/utils/composite/useCompositeItem.cjs +0 -63
  870. package/dist/cjs/utils/composite/useCompositeListItem.cjs +0 -104
  871. package/dist/cjs/utils/composite/useCompositeRoot.cjs +0 -263
  872. package/dist/cjs/utils/constants.cjs +0 -56
  873. package/dist/cjs/utils/contains.cjs +0 -46
  874. package/dist/cjs/utils/createChangeEventDetails.cjs +0 -92
  875. package/dist/cjs/utils/dom.cjs +0 -35
  876. package/dist/cjs/utils/empty.cjs +0 -34
  877. package/dist/cjs/utils/field/FieldItemContext.cjs +0 -34
  878. package/dist/cjs/utils/field/FieldRootContext.cjs +0 -80
  879. package/dist/cjs/utils/field/FormContext.cjs +0 -41
  880. package/dist/cjs/utils/field/LabelableContext.cjs +0 -43
  881. package/dist/cjs/utils/field/LabelableProvider.cjs +0 -115
  882. package/dist/cjs/utils/field/constants.cjs +0 -68
  883. package/dist/cjs/utils/field/getCombinedFieldValidityData.cjs +0 -36
  884. package/dist/cjs/utils/field/useAriaLabelledBy.cjs +0 -87
  885. package/dist/cjs/utils/field/useFieldControlRegistration.cjs +0 -165
  886. package/dist/cjs/utils/field/useFieldValidation.cjs +0 -285
  887. package/dist/cjs/utils/field/useLabel.cjs +0 -99
  888. package/dist/cjs/utils/field/useLabelableId.cjs +0 -105
  889. package/dist/cjs/utils/field/useRegisterFieldControl.cjs +0 -60
  890. package/dist/cjs/utils/findRootOwnerId.cjs +0 -37
  891. package/dist/cjs/utils/floating/FloatingDelayGroup.cjs +0 -219
  892. package/dist/cjs/utils/floating/FloatingFocusManager.cjs +0 -685
  893. package/dist/cjs/utils/floating/FloatingPortal.cjs +0 -230
  894. package/dist/cjs/utils/floating/FloatingRootStore.cjs +0 -87
  895. package/dist/cjs/utils/floating/FloatingTree.cjs +0 -86
  896. package/dist/cjs/utils/floating/FloatingTreeStore.cjs +0 -41
  897. package/dist/cjs/utils/floating/FocusGuard.cjs +0 -54
  898. package/dist/cjs/utils/floating/composite.cjs +0 -42
  899. package/dist/cjs/utils/floating/constants.cjs +0 -34
  900. package/dist/cjs/utils/floating/createAttribute.cjs +0 -30
  901. package/dist/cjs/utils/floating/createEventEmitter.cjs +0 -44
  902. package/dist/cjs/utils/floating/element.cjs +0 -103
  903. package/dist/cjs/utils/floating/enqueueFocus.cjs +0 -51
  904. package/dist/cjs/utils/floating/event.cjs +0 -65
  905. package/dist/cjs/utils/floating/getEmptyRootContext.cjs +0 -42
  906. package/dist/cjs/utils/floating/gridNavigation.cjs +0 -45
  907. package/dist/cjs/utils/floating/markOthers.cjs +0 -181
  908. package/dist/cjs/utils/floating/nodes.cjs +0 -48
  909. package/dist/cjs/utils/floating/safePolygon.cjs +0 -301
  910. package/dist/cjs/utils/floating/tabbable.cjs +0 -242
  911. package/dist/cjs/utils/floating/types.cjs +0 -16
  912. package/dist/cjs/utils/floating/useClick.cjs +0 -153
  913. package/dist/cjs/utils/floating/useClientPoint.cjs +0 -225
  914. package/dist/cjs/utils/floating/useDismiss.cjs +0 -506
  915. package/dist/cjs/utils/floating/useFloating.cjs +0 -186
  916. package/dist/cjs/utils/floating/useFloatingRootContext.cjs +0 -75
  917. package/dist/cjs/utils/floating/useFocus.cjs +0 -184
  918. package/dist/cjs/utils/floating/useHoverFloatingInteraction.cjs +0 -231
  919. package/dist/cjs/utils/floating/useHoverInteractionSharedState.cjs +0 -113
  920. package/dist/cjs/utils/floating/useHoverReferenceInteraction.cjs +0 -380
  921. package/dist/cjs/utils/floating/useHoverShared.cjs +0 -65
  922. package/dist/cjs/utils/floating/useListNavigation.cjs +0 -665
  923. package/dist/cjs/utils/floating/useSyncedFloatingRootContext.cjs +0 -91
  924. package/dist/cjs/utils/floating/useTypeahead.cjs +0 -187
  925. package/dist/cjs/utils/formatNumber.cjs +0 -60
  926. package/dist/cjs/utils/generateId.cjs +0 -32
  927. package/dist/cjs/utils/getCssDimensions.cjs +0 -42
  928. package/dist/cjs/utils/getDefaultFormSubmitter.cjs +0 -42
  929. package/dist/cjs/utils/getDisabledMountTransitionStyles.cjs +0 -32
  930. package/dist/cjs/utils/getElementRef.cjs +0 -35
  931. package/dist/cjs/utils/getPseudoElementBounds.cjs +0 -56
  932. package/dist/cjs/utils/getStateAttributesProps.cjs +0 -46
  933. package/dist/cjs/utils/hideMiddleware.cjs +0 -42
  934. package/dist/cjs/utils/inertValue.cjs +0 -30
  935. package/dist/cjs/utils/matchesFocusVisible.cjs +0 -38
  936. package/dist/cjs/utils/mergeCleanups.cjs +0 -37
  937. package/dist/cjs/utils/mergeObjects.cjs +0 -39
  938. package/dist/cjs/utils/mergeProps.cjs +0 -182
  939. package/dist/cjs/utils/noop.cjs +0 -29
  940. package/dist/cjs/utils/number/constants.cjs +0 -34
  941. package/dist/cjs/utils/number/parse.cjs +0 -258
  942. package/dist/cjs/utils/number/types.cjs +0 -16
  943. package/dist/cjs/utils/number/validate.cjs +0 -104
  944. package/dist/cjs/utils/owner.cjs +0 -35
  945. package/dist/cjs/utils/platform.cjs +0 -83
  946. package/dist/cjs/utils/popupStateMapping.cjs +0 -74
  947. package/dist/cjs/utils/popups/index.cjs +0 -39
  948. package/dist/cjs/utils/popups/inlineRect.cjs +0 -218
  949. package/dist/cjs/utils/popups/popupStoreUtils.cjs +0 -379
  950. package/dist/cjs/utils/popups/popupTriggerMap.cjs +0 -76
  951. package/dist/cjs/utils/popups/store.cjs +0 -118
  952. package/dist/cjs/utils/popups/useTriggerFocusGuards.cjs +0 -72
  953. package/dist/cjs/utils/resolveAriaLabelledBy.cjs +0 -35
  954. package/dist/cjs/utils/resolveClassName.cjs +0 -30
  955. package/dist/cjs/utils/resolveRef.cjs +0 -33
  956. package/dist/cjs/utils/resolveStyle.cjs +0 -30
  957. package/dist/cjs/utils/serializeValue.cjs +0 -40
  958. package/dist/cjs/utils/slider/asc.cjs +0 -30
  959. package/dist/cjs/utils/slider/getMidpoint.cjs +0 -34
  960. package/dist/cjs/utils/slider/getPushedThumbValues.cjs +0 -73
  961. package/dist/cjs/utils/slider/getSliderValue.cjs +0 -42
  962. package/dist/cjs/utils/slider/replaceArrayItemAtIndex.cjs +0 -33
  963. package/dist/cjs/utils/slider/resolveThumbCollision.cjs +0 -155
  964. package/dist/cjs/utils/slider/roundValueToStep.cjs +0 -45
  965. package/dist/cjs/utils/slider/validateMinimumDistance.cjs +0 -40
  966. package/dist/cjs/utils/slider/valueArrayToPercentages.cjs +0 -36
  967. package/dist/cjs/utils/store/ReactStore.cjs +0 -135
  968. package/dist/cjs/utils/store/Store.cjs +0 -83
  969. package/dist/cjs/utils/store/createSelector.cjs +0 -74
  970. package/dist/cjs/utils/store/useStore.cjs +0 -51
  971. package/dist/cjs/utils/stringifyLocale.cjs +0 -36
  972. package/dist/cjs/utils/useAnchorPositioning.cjs +0 -421
  973. package/dist/cjs/utils/useAnchoredPopupScrollLock.cjs +0 -59
  974. package/dist/cjs/utils/useAnimationFrame.cjs +0 -93
  975. package/dist/cjs/utils/useAnimationsFinished.cjs +0 -98
  976. package/dist/cjs/utils/useBaseUiId.cjs +0 -36
  977. package/dist/cjs/utils/useButton.cjs +0 -177
  978. package/dist/cjs/utils/useCheckboxGroupParent.cjs +0 -114
  979. package/dist/cjs/utils/useControlled.cjs +0 -47
  980. package/dist/cjs/utils/useEnhancedClickHandler.cjs +0 -60
  981. package/dist/cjs/utils/useFocusableWhenDisabled.cjs +0 -77
  982. package/dist/cjs/utils/useForcedRerendering.cjs +0 -35
  983. package/dist/cjs/utils/useIsHydrating.cjs +0 -44
  984. package/dist/cjs/utils/useMixedToggleClickHandler.cjs +0 -66
  985. package/dist/cjs/utils/useOnFirstRender.cjs +0 -35
  986. package/dist/cjs/utils/useOnMount.cjs +0 -36
  987. package/dist/cjs/utils/useOpenChangeComplete.cjs +0 -57
  988. package/dist/cjs/utils/useOpenInteractionType.cjs +0 -69
  989. package/dist/cjs/utils/usePopupAutoResize.cjs +0 -191
  990. package/dist/cjs/utils/usePopupViewport.cjs +0 -283
  991. package/dist/cjs/utils/usePositioner.cjs +0 -53
  992. package/dist/cjs/utils/usePressAndHold.cjs +0 -51
  993. package/dist/cjs/utils/usePreviousValue.cjs +0 -47
  994. package/dist/cjs/utils/useRefWithInit.cjs +0 -41
  995. package/dist/cjs/utils/useRegisteredLabelId.cjs +0 -48
  996. package/dist/cjs/utils/useRenderElement.cjs +0 -106
  997. package/dist/cjs/utils/useScrollLock.cjs +0 -232
  998. package/dist/cjs/utils/useStableCallback.cjs +0 -41
  999. package/dist/cjs/utils/useTimeout.cjs +0 -66
  1000. package/dist/cjs/utils/useTransitionStatus.cjs +0 -116
  1001. package/dist/cjs/utils/useValueAsRef.cjs +0 -43
  1002. package/dist/cjs/utils/useValueChanged.cjs +0 -55
  1003. package/dist/cjs/utils/valueToPercent.cjs +0 -30
  1004. package/dist/cjs/utils/visuallyHidden.cjs +0 -49
  1005. package/src/accordion.ts +0 -615
  1006. package/src/alert-dialog.ts +0 -49
  1007. package/src/avatar.ts +0 -308
  1008. package/src/button.ts +0 -63
  1009. package/src/checkbox-group.ts +0 -183
  1010. package/src/checkbox.ts +0 -576
  1011. package/src/collapsible.ts +0 -916
  1012. package/src/context-menu.ts +0 -317
  1013. package/src/csp-provider.ts +0 -37
  1014. package/src/dialog.ts +0 -930
  1015. package/src/direction-provider.ts +0 -32
  1016. package/src/field.ts +0 -650
  1017. package/src/fieldset.ts +0 -150
  1018. package/src/form.ts +0 -183
  1019. package/src/input.ts +0 -9
  1020. package/src/internal.ts +0 -29
  1021. package/src/menu.ts +0 -3387
  1022. package/src/menubar.ts +0 -160
  1023. package/src/merge-props.ts +0 -2
  1024. package/src/meter.ts +0 -211
  1025. package/src/number-field.ts +0 -951
  1026. package/src/popover.ts +0 -1282
  1027. package/src/preview-card.ts +0 -812
  1028. package/src/progress.ts +0 -267
  1029. package/src/radio-group.ts +0 -285
  1030. package/src/radio.ts +0 -393
  1031. package/src/separator.ts +0 -43
  1032. package/src/slider.ts +0 -1624
  1033. package/src/switch.ts +0 -363
  1034. package/src/tabs.ts +0 -947
  1035. package/src/toast.ts +0 -2462
  1036. package/src/toggle-group.ts +0 -136
  1037. package/src/toggle.ts +0 -145
  1038. package/src/tooltip.ts +0 -1053
  1039. package/src/unstable-use-media-query.ts +0 -101
  1040. package/src/use-render.ts +0 -41
  1041. package/src/utils/CSPContext.ts +0 -21
  1042. package/src/utils/CheckboxGroupContext.ts +0 -30
  1043. package/src/utils/CompositeRootContext.ts +0 -27
  1044. package/src/utils/ContextMenuRootContext.ts +0 -44
  1045. package/src/utils/DirectionContext.ts +0 -15
  1046. package/src/utils/FloatingPortalLite.ts +0 -34
  1047. package/src/utils/InternalBackdrop.ts +0 -28
  1048. package/src/utils/MenubarContext.ts +0 -38
  1049. package/src/utils/RadioGroupContext.ts +0 -27
  1050. package/src/utils/RequestQueue.ts +0 -132
  1051. package/src/utils/TimeoutManager.ts +0 -32
  1052. package/src/utils/ToggleGroupContext.ts +0 -33
  1053. package/src/utils/addEventListener.ts +0 -13
  1054. package/src/utils/areArraysEqual.ts +0 -11
  1055. package/src/utils/clamp.ts +0 -8
  1056. package/src/utils/closePart.ts +0 -61
  1057. package/src/utils/composeRefs.ts +0 -53
  1058. package/src/utils/composite/CompositeItem.ts +0 -56
  1059. package/src/utils/composite/CompositeList.ts +0 -190
  1060. package/src/utils/composite/CompositeListContext.ts +0 -23
  1061. package/src/utils/composite/CompositeRoot.ts +0 -132
  1062. package/src/utils/composite/grid-utils.ts +0 -437
  1063. package/src/utils/composite/gridNavigation.ts +0 -127
  1064. package/src/utils/composite/keys.ts +0 -179
  1065. package/src/utils/composite/list-utils.ts +0 -106
  1066. package/src/utils/composite/useCompositeItem.ts +0 -58
  1067. package/src/utils/composite/useCompositeListItem.ts +0 -108
  1068. package/src/utils/composite/useCompositeRoot.ts +0 -344
  1069. package/src/utils/constants.ts +0 -41
  1070. package/src/utils/contains.ts +0 -22
  1071. package/src/utils/createChangeEventDetails.ts +0 -95
  1072. package/src/utils/dom.ts +0 -9
  1073. package/src/utils/empty.ts +0 -7
  1074. package/src/utils/field/FieldItemContext.ts +0 -13
  1075. package/src/utils/field/FieldRootContext.ts +0 -98
  1076. package/src/utils/field/FormContext.ts +0 -37
  1077. package/src/utils/field/LabelableContext.ts +0 -32
  1078. package/src/utils/field/LabelableProvider.ts +0 -108
  1079. package/src/utils/field/constants.ts +0 -80
  1080. package/src/utils/field/getCombinedFieldValidityData.ts +0 -16
  1081. package/src/utils/field/useAriaLabelledBy.ts +0 -86
  1082. package/src/utils/field/useFieldControlRegistration.ts +0 -179
  1083. package/src/utils/field/useFieldValidation.ts +0 -311
  1084. package/src/utils/field/useLabel.ts +0 -95
  1085. package/src/utils/field/useLabelableId.ts +0 -99
  1086. package/src/utils/field/useRegisterFieldControl.ts +0 -41
  1087. package/src/utils/findRootOwnerId.ts +0 -19
  1088. package/src/utils/floating/FloatingDelayGroup.ts +0 -280
  1089. package/src/utils/floating/FloatingFocusManager.ts +0 -837
  1090. package/src/utils/floating/FloatingPortal.ts +0 -280
  1091. package/src/utils/floating/FloatingRootStore.ts +0 -127
  1092. package/src/utils/floating/FloatingTree.ts +0 -70
  1093. package/src/utils/floating/FloatingTreeStore.ts +0 -22
  1094. package/src/utils/floating/FocusGuard.ts +0 -34
  1095. package/src/utils/floating/composite.ts +0 -20
  1096. package/src/utils/floating/constants.ts +0 -8
  1097. package/src/utils/floating/createAttribute.ts +0 -4
  1098. package/src/utils/floating/createEventEmitter.ts +0 -20
  1099. package/src/utils/floating/element.ts +0 -88
  1100. package/src/utils/floating/enqueueFocus.ts +0 -38
  1101. package/src/utils/floating/event.ts +0 -53
  1102. package/src/utils/floating/getEmptyRootContext.ts +0 -19
  1103. package/src/utils/floating/gridNavigation.ts +0 -54
  1104. package/src/utils/floating/markOthers.ts +0 -197
  1105. package/src/utils/floating/nodes.ts +0 -31
  1106. package/src/utils/floating/safePolygon.ts +0 -448
  1107. package/src/utils/floating/tabbable.ts +0 -260
  1108. package/src/utils/floating/types.ts +0 -57
  1109. package/src/utils/floating/useClick.ts +0 -174
  1110. package/src/utils/floating/useClientPoint.ts +0 -276
  1111. package/src/utils/floating/useDismiss.ts +0 -639
  1112. package/src/utils/floating/useFloating.ts +0 -198
  1113. package/src/utils/floating/useFloatingRootContext.ts +0 -81
  1114. package/src/utils/floating/useFocus.ts +0 -248
  1115. package/src/utils/floating/useHoverFloatingInteraction.ts +0 -302
  1116. package/src/utils/floating/useHoverInteractionSharedState.ts +0 -139
  1117. package/src/utils/floating/useHoverReferenceInteraction.ts +0 -510
  1118. package/src/utils/floating/useHoverShared.ts +0 -78
  1119. package/src/utils/floating/useListNavigation.ts +0 -1018
  1120. package/src/utils/floating/useSyncedFloatingRootContext.ts +0 -93
  1121. package/src/utils/floating/useTypeahead.ts +0 -287
  1122. package/src/utils/formatNumber.ts +0 -44
  1123. package/src/utils/generateId.ts +0 -10
  1124. package/src/utils/getDefaultFormSubmitter.ts +0 -19
  1125. package/src/utils/getDisabledMountTransitionStyles.ts +0 -12
  1126. package/src/utils/getElementRef.ts +0 -13
  1127. package/src/utils/getStateAttributesProps.ts +0 -34
  1128. package/src/utils/inertValue.ts +0 -5
  1129. package/src/utils/matchesFocusVisible.ts +0 -16
  1130. package/src/utils/mergeCleanups.ts +0 -13
  1131. package/src/utils/mergeObjects.ts +0 -18
  1132. package/src/utils/mergeProps.ts +0 -206
  1133. package/src/utils/noop.ts +0 -4
  1134. package/src/utils/number/constants.ts +0 -4
  1135. package/src/utils/number/parse.ts +0 -227
  1136. package/src/utils/number/types.ts +0 -21
  1137. package/src/utils/number/validate.ts +0 -129
  1138. package/src/utils/owner.ts +0 -9
  1139. package/src/utils/platform.ts +0 -69
  1140. package/src/utils/serializeValue.ts +0 -15
  1141. package/src/utils/slider/asc.ts +0 -4
  1142. package/src/utils/slider/getMidpoint.ts +0 -14
  1143. package/src/utils/slider/getPushedThumbValues.ts +0 -73
  1144. package/src/utils/slider/getSliderValue.ts +0 -27
  1145. package/src/utils/slider/replaceArrayItemAtIndex.ts +0 -8
  1146. package/src/utils/slider/resolveThumbCollision.ts +0 -178
  1147. package/src/utils/slider/roundValueToStep.ts +0 -22
  1148. package/src/utils/slider/validateMinimumDistance.ts +0 -22
  1149. package/src/utils/slider/valueArrayToPercentages.ts +0 -11
  1150. package/src/utils/store/ReactStore.ts +0 -168
  1151. package/src/utils/store/Store.ts +0 -84
  1152. package/src/utils/store/createSelector.ts +0 -66
  1153. package/src/utils/store/useStore.ts +0 -49
  1154. package/src/utils/stringifyLocale.ts +0 -10
  1155. package/src/utils/useAnchorPositioning.ts +0 -581
  1156. package/src/utils/useAnimationFrame.ts +0 -82
  1157. package/src/utils/useAnimationsFinished.ts +0 -100
  1158. package/src/utils/useBaseUiId.ts +0 -19
  1159. package/src/utils/useButton.ts +0 -217
  1160. package/src/utils/useCheckboxGroupParent.ts +0 -113
  1161. package/src/utils/useControlled.ts +0 -42
  1162. package/src/utils/useEnhancedClickHandler.ts +0 -47
  1163. package/src/utils/useForcedRerendering.ts +0 -11
  1164. package/src/utils/useOnFirstRender.ts +0 -11
  1165. package/src/utils/useOnMount.ts +0 -17
  1166. package/src/utils/useOpenChangeComplete.ts +0 -46
  1167. package/src/utils/usePopupViewport.ts +0 -375
  1168. package/src/utils/usePositioner.ts +0 -48
  1169. package/src/utils/usePressAndHold.ts +0 -35
  1170. package/src/utils/usePreviousValue.ts +0 -33
  1171. package/src/utils/useRefWithInit.ts +0 -23
  1172. package/src/utils/useRenderElement.ts +0 -164
  1173. package/src/utils/useScrollLock.ts +0 -253
  1174. package/src/utils/useStableCallback.ts +0 -26
  1175. package/src/utils/useTimeout.ts +0 -51
  1176. package/src/utils/useTransitionStatus.ts +0 -115
  1177. package/src/utils/useValueAsRef.ts +0 -25
  1178. package/src/utils/useValueChanged.ts +0 -37
  1179. package/src/utils/visuallyHidden.ts +0 -24
@@ -0,0 +1,1970 @@
1
+ 'use client';
2
+ import * as React from 'octane';
3
+ import { useControlled } from '@octanejs/base-ui-utils/useControlled';
4
+ import { useIsoLayoutEffect } from '@octanejs/base-ui-utils/useIsoLayoutEffect';
5
+ import { useOnFirstRender } from '@octanejs/base-ui-utils/useOnFirstRender';
6
+ import { useStableCallback } from '@octanejs/base-ui-utils/useStableCallback';
7
+ import { useMergedRefs } from '@octanejs/base-ui-utils/useMergedRefs';
8
+ import { useValueAsRef } from '@octanejs/base-ui-utils/useValueAsRef';
9
+ import { visuallyHidden, visuallyHiddenInput } from '@octanejs/base-ui-utils/visuallyHidden';
10
+ import { useRefWithInit } from '@octanejs/base-ui-utils/useRefWithInit';
11
+ import { ReactStore } from '@octanejs/base-ui-utils/store';
12
+ import { EMPTY_ARRAY, EMPTY_OBJECT } from '@octanejs/base-ui-utils/empty';
13
+ import { isHTMLElement } from '@floating-ui/utils/dom';
14
+ import {
15
+ type ElementProps,
16
+ getOverflowAncestors,
17
+ useDismiss,
18
+ useFloatingRootContext,
19
+ useListNavigation,
20
+ useClick,
21
+ } from '../../floating-ui-react';
22
+ import { gridNavigation } from '../../floating-ui-react/hooks/gridNavigation';
23
+ import { contains, getTarget } from '../../floating-ui-react/utils';
24
+ import {
25
+ createChangeEventDetails,
26
+ createGenericEventDetails,
27
+ type BaseUIChangeEventDetails,
28
+ type BaseUIGenericEventDetails,
29
+ } from '../../internals/createBaseUIEventDetails';
30
+ import { REASONS } from '../../internals/reasons';
31
+ import {
32
+ ComboboxFloatingContext,
33
+ ComboboxDerivedItemsContext,
34
+ ComboboxHasItemsContext,
35
+ ComboboxRootContext,
36
+ ComboboxInputValueContext,
37
+ } from './ComboboxRootContext.tsrx';
38
+ import { selectors, type ComboboxStoreContext, type State as StoreState } from '../store';
39
+ import { useOpenChangeComplete } from '../../internals/useOpenChangeComplete.tsrx';
40
+ import { useFieldRootContext } from '../../internals/field-root-context/FieldRootContext';
41
+ import { useRegisterFieldControl } from '../../internals/field-register-control/useRegisterFieldControl';
42
+ import { useFormContext } from '../../internals/form-context/FormContext';
43
+ import { useLabelableId } from '../../internals/labelable-provider/useLabelableId';
44
+ import { createCollatorItemFilter, type FilterItemToString } from './utils';
45
+ import { useCoreFilter } from './utils/useFilter';
46
+ import { useTransitionStatus } from '../../internals/useTransitionStatus';
47
+ import { useOpenInteractionType } from '../../utils/useOpenInteractionType';
48
+ import { isScrollableY } from '../../utils/scrollable';
49
+ import type { BaseUIEvent, HTMLProps } from '../../internals/types';
50
+ import { useValueChanged } from '../../internals/useValueChanged';
51
+ import { NOOP } from '../../internals/noop';
52
+ import { FOCUSABLE_POPUP_PROPS } from '../../utils/popups';
53
+ import { mergeProps } from '../../merge-props';
54
+ import {
55
+ stringifyAsLabel,
56
+ stringifyAsValue,
57
+ type Group,
58
+ flattenLeafItems,
59
+ isGroupedItems,
60
+ } from '../../internals/resolveValueLabel.tsrx';
61
+ import {
62
+ compareItemEquality,
63
+ defaultItemEquality,
64
+ findItemIndex,
65
+ findSelectionIndex,
66
+ isSelectedValueDirty,
67
+ removeItem,
68
+ selectedValueIncludes,
69
+ } from '../../internals/itemEquality';
70
+ import { INITIAL_LAST_HIGHLIGHT, NO_ACTIVE_VALUE } from './utils/constants';
71
+ import { useDirection } from '../../internals/direction-context/DirectionContext.tsrx';
72
+ import {
73
+ findCollectionItem,
74
+ type ComboboxItemCollection,
75
+ type ItemCollection,
76
+ } from '../items/itemCollection';
77
+
78
+ type InternalAriaComboboxProps<Value, Mode extends SelectionMode, Item = Value> = AriaComboboxProps<
79
+ Value,
80
+ Mode,
81
+ Item
82
+ > & {
83
+ filterQuery?: string | undefined;
84
+ };
85
+
86
+ /**
87
+ * @internal
88
+ */
89
+ export function AriaCombobox<Value, Mode extends SelectionMode = 'none', Item = Value>(
90
+ props: Omit<InternalAriaComboboxProps<Value, Mode, Item>, 'items'> & {
91
+ items: readonly Group<any>[];
92
+ },
93
+ ): React.ReactElement;
94
+ export function AriaCombobox<Value, Mode extends SelectionMode = 'none', Item = Value>(
95
+ props: Omit<InternalAriaComboboxProps<Value, Mode, Item>, 'items'> & {
96
+ items?: readonly any[] | ComboboxItemCollection<Item, any> | undefined;
97
+ },
98
+ ): React.ReactElement;
99
+ export function AriaCombobox<Value = any, Mode extends SelectionMode = 'none', Item = Value>(
100
+ props: InternalAriaComboboxProps<Value, Mode, Item>,
101
+ ): React.ReactElement {
102
+ const {
103
+ id: idProp,
104
+ onOpenChangeComplete: onOpenChangeCompleteProp,
105
+ defaultSelectedValue = null,
106
+ selectedValue: selectedValueProp,
107
+ onSelectedValueChange,
108
+ defaultInputValue,
109
+ inputValue: inputValueProp,
110
+ open: openProp,
111
+ defaultOpen = false,
112
+ selectionMode,
113
+ onItemHighlighted: onItemHighlightedProp,
114
+ name: nameProp,
115
+ form,
116
+ disabled: disabledProp = false,
117
+ readOnly = false,
118
+ required = false,
119
+ inputRef: inputRefProp,
120
+ grid = false,
121
+ items: itemsProp,
122
+ filteredItems: filteredItemsProp,
123
+ filter: filterProp,
124
+ filterQuery: filterQueryProp,
125
+ openOnInputClick = true,
126
+ autoHighlight = false,
127
+ keepHighlight = false,
128
+ highlightItemOnHover = true,
129
+ loopFocus = true,
130
+ itemToStringLabel: itemToStringLabelProp,
131
+ itemToStringValue,
132
+ isItemEqualToValue = defaultItemEquality,
133
+ virtualized = false,
134
+ inline: inlineProp = false,
135
+ fillInputOnItemPress = true,
136
+ modal = false,
137
+ limit = -1,
138
+ autoComplete = 'list',
139
+ formAutoComplete,
140
+ locale,
141
+ submitOnItemClick = false,
142
+ } = props;
143
+
144
+ const { clearErrors } = useFormContext();
145
+ const {
146
+ setDirty,
147
+ validityData,
148
+ setFilled,
149
+ name: fieldName,
150
+ disabled: fieldDisabled,
151
+ setTouched,
152
+ setFocused,
153
+ validationMode,
154
+ validation,
155
+ } = useFieldRootContext();
156
+
157
+ const direction = useDirection();
158
+ const id = useLabelableId({ id: idProp });
159
+ const collatorFilter = useCoreFilter({ locale });
160
+
161
+ // Plain items are arrays; normalized `createItems()` collections are objects.
162
+ const collection = Array.isArray(itemsProp)
163
+ ? null
164
+ : (itemsProp as unknown as ItemCollection<Item, Value> | undefined);
165
+
166
+ if (collection && typeof collection.label !== 'function') {
167
+ throw new Error(
168
+ 'Base UI: the `items` prop received an object that is not a collection, ' +
169
+ 'so its items cannot be read. Pass an array of items, an array of groups with items, ' +
170
+ 'or the result of `createItems()`. ' +
171
+ 'See https://base-ui.com/react/components/combobox#createitems',
172
+ );
173
+ }
174
+
175
+ const items = (collection ? collection.data : itemsProp) as
176
+ readonly Item[] | readonly Group<Item>[] | undefined;
177
+ const itemToValue = collection?.value;
178
+
179
+ // A projected collection's items live in the source domain, not the selection-value domain the
180
+ // store matches against, so they are withheld from the store.
181
+ const storeItems = itemToValue ? undefined : items;
182
+
183
+ // The externally filtered items projected to their selection values, with a lookup back to the
184
+ // source items. Declared before `itemToStringLabel`, which resolves labels from it on the
185
+ // first render (initial input value).
186
+ const externalWindow = React.useMemo(() => {
187
+ if (!filteredItemsProp || !itemToValue) {
188
+ return undefined;
189
+ }
190
+ const flat = flattenLeafItems(filteredItemsProp);
191
+ const values = flat.map(itemToValue);
192
+ let valueToItem: Map<any, any> | undefined;
193
+
194
+ return {
195
+ values,
196
+ findItem(itemValue: any, isEqual: (item: any, value: any) => boolean) {
197
+ if (!valueToItem) {
198
+ valueToItem = new Map();
199
+ for (let i = 0; i < values.length; i += 1) {
200
+ if (!valueToItem.has(values[i])) {
201
+ valueToItem.set(values[i], flat[i]);
202
+ }
203
+ }
204
+ }
205
+
206
+ return findCollectionItem(valueToItem, itemValue, isEqual);
207
+ },
208
+ };
209
+ }, [filteredItemsProp, itemToValue]);
210
+
211
+ // Labels selection values from current props only: collection data first, then the current
212
+ // external window, then the prop. Nothing from a past window is remembered — keeping a value
213
+ // resolvable over time means keeping its item in the collection's data.
214
+ const itemToStringLabel = React.useMemo(() => {
215
+ if (!collection) {
216
+ return itemToStringLabelProp;
217
+ }
218
+ return (itemValue: Value) => {
219
+ return collection.label(itemValue, isItemEqualToValue, (unresolvedValue: any) => {
220
+ const externalItem = externalWindow?.findItem(unresolvedValue, isItemEqualToValue);
221
+ if (externalItem != null) {
222
+ return collection.itemLabel(externalItem);
223
+ }
224
+ return stringifyAsLabel(unresolvedValue, itemToStringLabelProp);
225
+ });
226
+ };
227
+ }, [collection, itemToStringLabelProp, externalWindow, isItemEqualToValue]);
228
+
229
+ const filterItemToString = React.useMemo<FilterItemToString | undefined>(() => {
230
+ if (!collection) {
231
+ return itemToStringLabelProp;
232
+ }
233
+
234
+ return Object.assign((item: any) => collection.itemLabel(item), {
235
+ selected: (value: any) => stringifyAsLabel(value, itemToStringLabel),
236
+ });
237
+ }, [collection, itemToStringLabel, itemToStringLabelProp]);
238
+
239
+ function stringifyValueLabel(item: any) {
240
+ return stringifyAsLabel(item, itemToStringLabel);
241
+ }
242
+
243
+ const [queryChangedAfterOpen, setQueryChangedAfterOpen] = React.useState(false);
244
+ const [closeQuery, setCloseQuery] = React.useState<string | null>(null);
245
+ const previousCloseQueryRef = React.useRef(closeQuery);
246
+
247
+ const listRef = React.useRef<Array<HTMLElement | null>>([]);
248
+ const labelsRef = React.useRef<Array<string | null>>([]);
249
+ const popupRef = React.useRef<HTMLDivElement | null>(null);
250
+ const inputRef = React.useRef<HTMLInputElement | null>(null);
251
+ const startDismissRef = React.useRef<HTMLSpanElement | null>(null);
252
+ const endDismissRef = React.useRef<HTMLSpanElement | null>(null);
253
+ const emptyRef = React.useRef<HTMLDivElement | null>(null);
254
+ const keyboardActiveRef = React.useRef(true);
255
+ const hadInputClearRef = React.useRef(false);
256
+ const chipsContainerRef = React.useRef<HTMLDivElement | null>(null);
257
+ const clearRef = React.useRef<HTMLButtonElement | null>(null);
258
+ const selectionEventRef = React.useRef<MouseEvent | PointerEvent | KeyboardEvent | null>(null);
259
+ const lastHighlightRef = React.useRef(INITIAL_LAST_HIGHLIGHT);
260
+ const pendingQueryHighlightRef = React.useRef<null | {
261
+ hasQuery: boolean;
262
+ selection?: boolean | undefined;
263
+ // The value a selection-driven clear just added, so the restore can keep it
264
+ // highlighted instead of returning to the open anchor.
265
+ toggledValue?: any;
266
+ }>(null);
267
+
268
+ /**
269
+ * Contains the currently visible list of item values post-filtering.
270
+ */
271
+ const valuesRef = React.useRef<any[]>([]);
272
+ /**
273
+ * The item element that received the last `pointerdown`, used to detect whether a
274
+ * `mouseup` on an item belongs to a drag-select gesture that started elsewhere.
275
+ */
276
+ const pointerDownItemRef = React.useRef<Element | null>(null);
277
+
278
+ const disabled = fieldDisabled || disabledProp;
279
+ const name = fieldName ?? nameProp;
280
+ const multiple = selectionMode === 'multiple';
281
+ const single = selectionMode === 'single';
282
+ const hasInputValue = inputValueProp !== undefined || defaultInputValue !== undefined;
283
+ const hasItems = items !== undefined;
284
+ const hasFilteredItemsProp = filteredItemsProp !== undefined;
285
+
286
+ let autoHighlightMode: false | 'input-change' | 'always';
287
+ if (autoHighlight === 'always') {
288
+ autoHighlightMode = 'always';
289
+ } else {
290
+ autoHighlightMode = autoHighlight ? 'input-change' : false;
291
+ }
292
+
293
+ const [selectedValue, setSelectedValueUnwrapped] = useControlled<any>({
294
+ controlled: selectedValueProp,
295
+ default: multiple ? (defaultSelectedValue ?? EMPTY_ARRAY) : defaultSelectedValue,
296
+ name: 'Combobox',
297
+ state: 'selectedValue',
298
+ });
299
+
300
+ const filter = React.useMemo(() => {
301
+ if (filterProp === null) {
302
+ return () => true;
303
+ }
304
+ if (filterProp !== undefined) {
305
+ return filterProp;
306
+ }
307
+ // `shouldBypassFiltering` already empties the query whenever a single selection's label
308
+ // matches it exactly, so the filter never needs a selection-aware variant here.
309
+ return createCollatorItemFilter(collatorFilter, filterItemToString);
310
+ }, [filterProp, collatorFilter, filterItemToString]);
311
+
312
+ // If neither inputValue nor defaultInputValue are provided, derive it from the
313
+ // selected value for single mode so the input reflects the selection on mount.
314
+ const initialDefaultInputValue = useRefWithInit(() => {
315
+ if (hasInputValue) {
316
+ return defaultInputValue ?? '';
317
+ }
318
+ if (single) {
319
+ return stringifyValueLabel(selectedValue);
320
+ }
321
+ return '';
322
+ }).current;
323
+
324
+ const [inputValue, setInputValueUnwrapped] = useControlled({
325
+ controlled: inputValueProp,
326
+ default: initialDefaultInputValue,
327
+ name: 'Combobox',
328
+ state: 'inputValue',
329
+ });
330
+
331
+ const [open, setOpenUnwrapped] = useControlled({
332
+ controlled: openProp,
333
+ default: defaultOpen,
334
+ name: 'Combobox',
335
+ state: 'open',
336
+ });
337
+
338
+ const isGrouped = isGroupedItems(items);
339
+ const query = !open && closeQuery !== null ? closeQuery : String(inputValue).trim();
340
+
341
+ const selectedLabelString = single ? stringifyValueLabel(selectedValue) : '';
342
+
343
+ const shouldBypassFiltering =
344
+ single &&
345
+ !queryChangedAfterOpen &&
346
+ query !== '' &&
347
+ selectedLabelString.length === query.length &&
348
+ collatorFilter.contains(selectedLabelString, query);
349
+
350
+ const filterQuery = shouldBypassFiltering ? '' : (filterQueryProp ?? query);
351
+ const shouldIgnoreExternalFiltering =
352
+ hasItems &&
353
+ hasFilteredItemsProp &&
354
+ shouldBypassFiltering &&
355
+ (!collection || collection.hasValue(selectedValue, isItemEqualToValue));
356
+
357
+ const flatItems: readonly Item[] = React.useMemo(
358
+ () => (items ? flattenLeafItems<Item>(items) : EMPTY_ARRAY),
359
+ [items],
360
+ );
361
+
362
+ const filteredItems: Item[] | Group<Item>[] = React.useMemo(() => {
363
+ if (filteredItemsProp && !shouldIgnoreExternalFiltering) {
364
+ return filteredItemsProp as Item[] | Group<Item>[];
365
+ }
366
+
367
+ if (!items) {
368
+ return EMPTY_ARRAY;
369
+ }
370
+
371
+ if (isGrouped) {
372
+ const groupedItems = items;
373
+ const resultingGroups: Group<Item>[] = [];
374
+ let currentCount = 0;
375
+
376
+ for (const group of groupedItems) {
377
+ if (limit > -1 && currentCount >= limit) {
378
+ break;
379
+ }
380
+
381
+ const remainingLimit = limit > -1 ? limit - currentCount : Infinity;
382
+ const itemsToTake = filterQuery === '' ? group.items.slice(0, remainingLimit) : [];
383
+
384
+ if (filterQuery !== '') {
385
+ for (const item of group.items) {
386
+ if (itemsToTake.length >= remainingLimit) {
387
+ break;
388
+ }
389
+ if (filter(item, filterQuery, filterItemToString)) {
390
+ itemsToTake.push(item);
391
+ }
392
+ }
393
+ }
394
+
395
+ if (itemsToTake.length > 0) {
396
+ const newGroup = { ...group, items: itemsToTake };
397
+ resultingGroups.push(newGroup);
398
+ currentCount += itemsToTake.length;
399
+ }
400
+ }
401
+
402
+ return resultingGroups;
403
+ }
404
+
405
+ if (filterQuery === '') {
406
+ return limit > -1
407
+ ? flatItems.slice(0, limit)
408
+ : // The cast here is done as `flatItems` is readonly.
409
+ // valuesRef.current, a mutable ref, can be set to `flatFilteredValues`, which may
410
+ // reference this exact readonly value, creating a mutation risk.
411
+ // However, <Combobox.Item> can never mutate this value as the mutating effect
412
+ // bails early when `items` is provided, and this is only ever returned
413
+ // when `items` is provided due to the early return at the top of this hook.
414
+ (flatItems as Item[]);
415
+ }
416
+
417
+ const limitedItems: Item[] = [];
418
+ for (const item of flatItems) {
419
+ if (limit > -1 && limitedItems.length >= limit) {
420
+ break;
421
+ }
422
+ if (filter(item, filterQuery, filterItemToString)) {
423
+ limitedItems.push(item);
424
+ }
425
+ }
426
+
427
+ return limitedItems;
428
+ }, [
429
+ filteredItemsProp,
430
+ shouldIgnoreExternalFiltering,
431
+ items,
432
+ isGrouped,
433
+ filterQuery,
434
+ limit,
435
+ filter,
436
+ filterItemToString,
437
+ flatItems,
438
+ ]);
439
+
440
+ /**
441
+ * The filtered items flattened across groups and projected to their selection values.
442
+ */
443
+ const flatFilteredValues: any[] = React.useMemo(() => {
444
+ if (externalWindow && filteredItems === filteredItemsProp) {
445
+ return externalWindow.values;
446
+ }
447
+ // Explicit type argument: inferring it from a union of both shapes resolves `Item` to
448
+ // `Group<Item>`, which tsc rejects and tsgo does not.
449
+ const flat = flattenLeafItems<Item>(filteredItems);
450
+ return itemToValue ? flat.map((item) => itemToValue(item)) : (flat as any[]);
451
+ }, [filteredItems, filteredItemsProp, externalWindow, itemToValue]);
452
+
453
+ const store = useRefWithInit(() => {
454
+ // An inline list open on the first render never gets a closed pass of the closed-state
455
+ // sync effect below, and `items`-prop lists don't self-register their index the way
456
+ // individually rendered `<Combobox.Item>`s do, so the selected item was never highlighted.
457
+ // Seeding the index here lets list navigation highlight and scroll to the selection on
458
+ // mount. Computed once by construction, so a selection or list that resolves after mount
459
+ // doesn't move an existing highlight or scroll the list away.
460
+ let initialSelectedIndex: number | null = null;
461
+ if (inlineProp && open && hasItems && selectionMode !== 'none') {
462
+ initialSelectedIndex = findSelectionIndex(
463
+ flatFilteredValues,
464
+ selectedValue,
465
+ isItemEqualToValue,
466
+ multiple,
467
+ );
468
+ }
469
+
470
+ return new ReactStore<StoreState, ComboboxStoreContext, typeof selectors>(
471
+ {
472
+ id,
473
+ labelId: undefined,
474
+ selectedValue,
475
+ open,
476
+ items: storeItems,
477
+ selectionMode,
478
+ name,
479
+ form,
480
+ disabled,
481
+ readOnly,
482
+ required,
483
+ grid,
484
+ virtualized,
485
+ openOnInputClick,
486
+ itemToStringLabel,
487
+ isItemEqualToValue,
488
+ modal,
489
+ autoHighlight: autoHighlightMode,
490
+ submitOnItemClick,
491
+ hasInputValue,
492
+ mounted: false,
493
+ forceMounted: false,
494
+ transitionStatus: 'idle',
495
+ inline: inlineProp,
496
+ activeIndex: null,
497
+ selectedIndex: initialSelectedIndex,
498
+ popupProps: {},
499
+ listProps: {},
500
+ inputProps: {},
501
+ triggerProps: {},
502
+ itemProps: EMPTY_OBJECT,
503
+ positionerElement: null,
504
+ listElement: null,
505
+ popupId: undefined,
506
+ triggerElement: null,
507
+ inputElement: null,
508
+ inputGroupElement: null,
509
+ popupSide: null,
510
+ openMethod: null,
511
+ inputInsidePopup: true,
512
+ // Avoid duplicate names in the server HTML. Popup inputs aren't rendered
513
+ // until after hydration, so the hidden input takes over then if needed.
514
+ inputOwnsFormValue: selectionMode === 'none',
515
+ },
516
+ {
517
+ // Placeholder callbacks replaced on first render
518
+ onOpenChangeComplete: NOOP,
519
+ setOpen: NOOP,
520
+ setInputValue: NOOP,
521
+ setSelectedValue: NOOP,
522
+ setIndices: NOOP,
523
+ handleSelection: NOOP,
524
+ forceMount: NOOP,
525
+ requestSubmit: NOOP,
526
+ listRef,
527
+ labelsRef,
528
+ popupRef,
529
+ emptyRef,
530
+ inputRef,
531
+ startDismissRef,
532
+ endDismissRef,
533
+ keyboardActiveRef,
534
+ chipsContainerRef,
535
+ clearRef,
536
+ valuesRef,
537
+ pointerDownItemRef,
538
+ selectionEventRef,
539
+ },
540
+ selectors,
541
+ );
542
+ }).current;
543
+
544
+ const fieldRawValue = selectionMode === 'none' ? inputValue : selectedValue;
545
+ const fieldStringValue = React.useMemo(() => {
546
+ if (selectionMode === 'none') {
547
+ return fieldRawValue;
548
+ }
549
+ if (Array.isArray(selectedValue)) {
550
+ return selectedValue.map((value) => stringifyAsValue(value, itemToStringValue));
551
+ }
552
+ return stringifyAsValue(selectedValue, itemToStringValue);
553
+ }, [fieldRawValue, itemToStringValue, selectionMode, selectedValue]);
554
+
555
+ const onItemHighlighted = useStableCallback(onItemHighlightedProp);
556
+ const onOpenChangeComplete = useStableCallback(onOpenChangeCompleteProp);
557
+
558
+ const activeIndex = store.useState('activeIndex');
559
+ const selectedIndex = store.useState('selectedIndex');
560
+ const positionerElement = store.useState('positionerElement');
561
+ const listElement = store.useState('listElement');
562
+ const triggerElement = store.useState('triggerElement');
563
+ const inputElement = store.useState('inputElement');
564
+ const inputGroupElement = store.useState('inputGroupElement');
565
+ const inline = store.useState('inline');
566
+ const inputInsidePopup = store.useState('inputInsidePopup');
567
+ const inputOwnsFormValue = store.useState('inputOwnsFormValue');
568
+ const inputMatchesSelectedValue =
569
+ single && !inputInsidePopup && inputValue === selectedLabelString;
570
+
571
+ const triggerRef = useValueAsRef(triggerElement);
572
+
573
+ const { mounted, setMounted, transitionStatus } = useTransitionStatus(open);
574
+ const { openMethod, triggerProps } = useOpenInteractionType(open);
575
+
576
+ const getStringifiedValueForForm = useStableCallback(() => fieldStringValue);
577
+
578
+ useRegisterFieldControl(
579
+ inputInsidePopup ? triggerRef : inputRef,
580
+ id,
581
+ fieldRawValue,
582
+ getStringifiedValueForForm,
583
+ !disabled,
584
+ nameProp,
585
+ );
586
+
587
+ const forceMount = useStableCallback(() => {
588
+ if (items) {
589
+ // Ensure typeahead works on a closed list.
590
+ labelsRef.current = flatFilteredValues.map(stringifyValueLabel);
591
+ } else {
592
+ store.set('forceMounted', true);
593
+ }
594
+ });
595
+
596
+ /**
597
+ * Emits `onItemHighlighted` for the item at `index`, or clears the highlight when `index` is `-1`
598
+ * (a no-op if nothing was highlighted). Keeps `lastHighlightRef` in sync with what was emitted.
599
+ */
600
+ const emitHighlight = useStableCallback(
601
+ (value: any, index: number, type: AriaCombobox.HighlightEventReason) => {
602
+ if (index === -1) {
603
+ if (lastHighlightRef.current === INITIAL_LAST_HIGHLIGHT) {
604
+ return;
605
+ }
606
+ lastHighlightRef.current = INITIAL_LAST_HIGHLIGHT;
607
+ } else {
608
+ lastHighlightRef.current = { value, index };
609
+ }
610
+
611
+ onItemHighlighted(value, createGenericEventDetails(type, undefined, { index }));
612
+ },
613
+ );
614
+
615
+ const setIndices = useStableCallback(
616
+ (options: {
617
+ activeIndex?: number | null | undefined;
618
+ selectedIndex?: number | null | undefined;
619
+ type?: AriaCombobox.HighlightEventReason | undefined;
620
+ }) => {
621
+ const update = {} as Pick<StoreState, 'activeIndex' | 'selectedIndex'>;
622
+
623
+ if (options.activeIndex !== undefined) {
624
+ update.activeIndex = options.activeIndex;
625
+ }
626
+
627
+ if (options.selectedIndex !== undefined) {
628
+ update.selectedIndex = options.selectedIndex;
629
+ }
630
+
631
+ store.update(update);
632
+
633
+ const activeIndexOption = options.activeIndex;
634
+ if (activeIndexOption === undefined) {
635
+ return;
636
+ }
637
+
638
+ const type: AriaCombobox.HighlightEventReason = options.type || REASONS.none;
639
+
640
+ if (activeIndexOption === null) {
641
+ emitHighlight(undefined, -1, type);
642
+ } else {
643
+ emitHighlight(valuesRef.current[activeIndexOption], activeIndexOption, type);
644
+ }
645
+ },
646
+ );
647
+
648
+ const setInputValue = useStableCallback(
649
+ (next: string, eventDetails: AriaCombobox.ChangeEventDetails) => {
650
+ props.onInputValueChange?.(next, eventDetails);
651
+
652
+ if (eventDetails.isCanceled) {
653
+ return;
654
+ }
655
+
656
+ // A canceled selection clear must not suppress close-completion cleanup.
657
+ hadInputClearRef.current = eventDetails.reason === REASONS.inputClear;
658
+
659
+ // If user is typing, ensure we don't auto-highlight on open due to a race
660
+ // with the post-open effect that sets this flag.
661
+ if (eventDetails.reason === REASONS.inputChange) {
662
+ // A controlled popup may ignore a close request. Resuming input proves the popup
663
+ // is remaining open, so release the query captured for an exit animation.
664
+ if (open && closeQuery !== null) {
665
+ setCloseQuery(null);
666
+ }
667
+
668
+ const event = eventDetails.event as Event;
669
+ const inputType = (event as InputEvent).inputType;
670
+ // Treat composition commits as typed input; autofill may omit `inputType` or
671
+ // report `insertReplacementText`.
672
+ const isTypedInput =
673
+ event.type === 'compositionend' ||
674
+ (inputType != null && inputType !== '' && inputType !== 'insertReplacementText');
675
+ if (isTypedInput) {
676
+ const hasQuery = next.trim() !== '';
677
+ if (hasQuery) {
678
+ setQueryChangedAfterOpen(true);
679
+ }
680
+ // Defer index updates until after the filtered items have been derived to ensure
681
+ // `onItemHighlighted` receives the latest item.
682
+ pendingQueryHighlightRef.current = { hasQuery };
683
+
684
+ // Virtualized lists own their scroller. Reset regular lists directly so a stale
685
+ // composite registry cannot select a reordered item and scrolling cannot escape
686
+ // the popup.
687
+ const list = store.state.listElement;
688
+ if (!store.state.virtualized && list) {
689
+ const popup = popupRef.current;
690
+ for (const ancestor of getOverflowAncestors(list.firstElementChild ?? list)) {
691
+ if (
692
+ !isHTMLElement(ancestor) ||
693
+ (popup ? !contains(popup, ancestor) : ancestor.getAttribute('role') === 'dialog')
694
+ ) {
695
+ break;
696
+ }
697
+
698
+ if (isScrollableY(ancestor)) {
699
+ ancestor.scrollTop = 0;
700
+ break;
701
+ }
702
+ }
703
+ }
704
+
705
+ if (
706
+ hasQuery &&
707
+ autoHighlightMode &&
708
+ store.state.activeIndex == null &&
709
+ (open || inline)
710
+ ) {
711
+ store.set('activeIndex', 0);
712
+ }
713
+ }
714
+ } else if (
715
+ eventDetails.reason === REASONS.inputClear &&
716
+ next === '' &&
717
+ store.state.inputInsidePopup
718
+ ) {
719
+ // A programmatic clear of an active query (e.g. after selecting an item with the
720
+ // input inside the popup): restore the highlight to the selected item.
721
+ pendingQueryHighlightRef.current = { hasQuery: false, selection: true };
722
+ }
723
+
724
+ setInputValueUnwrapped(next);
725
+ },
726
+ );
727
+
728
+ const handleInterruptedReopen = useStableCallback((isInputChange: boolean) => {
729
+ // Preserve values supplied with the reopen rather than owned by the interrupted close.
730
+ const clearsPendingInput =
731
+ !isInputChange &&
732
+ inputInsidePopup &&
733
+ !inline &&
734
+ inputValue !== '' &&
735
+ (String(inputValue).trim() === closeQuery || inputValue === selectedLabelString);
736
+
737
+ // Keep the flag while a visible filter survives so the `items` sync cannot overwrite it.
738
+ if (!isInputChange && (clearsPendingInput || inputValue === '' || inputMatchesSelectedValue)) {
739
+ setQueryChangedAfterOpen(false);
740
+ }
741
+
742
+ setCloseQuery(null);
743
+
744
+ if (clearsPendingInput) {
745
+ // Cleanup clears omit the selection flag and reopening gesture.
746
+ setInputValue('', createChangeEventDetails(REASONS.inputClear));
747
+ }
748
+ });
749
+
750
+ const setOpen = useStableCallback(
751
+ (nextOpen: boolean, eventDetails: AriaCombobox.ChangeEventDetails) => {
752
+ if (open === nextOpen) {
753
+ return;
754
+ }
755
+
756
+ // If the `Empty` component is not used, the positioner or popup should be hidden
757
+ // with CSS. In this case, allow the Escape key to bubble to close a parent popup
758
+ // if there are no items to show.
759
+ if (
760
+ eventDetails.reason === REASONS.escapeKey &&
761
+ hasItems &&
762
+ flatFilteredValues.length === 0 &&
763
+ !emptyRef.current
764
+ ) {
765
+ eventDetails.allowPropagation();
766
+ }
767
+
768
+ props.onOpenChange?.(nextOpen, eventDetails);
769
+
770
+ if (eventDetails.isCanceled) {
771
+ return;
772
+ }
773
+
774
+ if (nextOpen && closeQuery !== null) {
775
+ // `ComboboxInput` calls `setInputValue` before `setOpen`, so on an input-change reopen
776
+ // `inputValue` is still the pre-keystroke value and the typed filter always survives.
777
+ handleInterruptedReopen(eventDetails.reason === REASONS.inputChange);
778
+ }
779
+
780
+ if (!nextOpen && queryChangedAfterOpen) {
781
+ if (single) {
782
+ if (!inline) {
783
+ setCloseQuery(query);
784
+ }
785
+ // Avoid a flicker when closing the popup with an empty query.
786
+ if (query === '') {
787
+ setQueryChangedAfterOpen(false);
788
+ }
789
+ } else if (multiple) {
790
+ if (!inline) {
791
+ // Freeze the current query so filtering remains stable while exiting.
792
+ setCloseQuery(query);
793
+ }
794
+
795
+ if (inputInsidePopup) {
796
+ setIndices({ activeIndex: null });
797
+ }
798
+
799
+ // Clear the input immediately on close while retaining filtering via closeQuery for exit animations
800
+ // if the input is outside the popup. When the input is inside the popup, defer the clear until
801
+ // unmount so the filtered list doesn't flash to unfiltered during the exit animation.
802
+ if (!inputInsidePopup || inline) {
803
+ setInputValue(
804
+ '',
805
+ createChangeEventDetails(REASONS.inputClear, eventDetails.event, undefined, {
806
+ isItemPress: eventDetails.reason === REASONS.itemPress,
807
+ }),
808
+ );
809
+ }
810
+ }
811
+ }
812
+
813
+ setOpenUnwrapped(nextOpen);
814
+
815
+ if (
816
+ !nextOpen &&
817
+ inputInsidePopup &&
818
+ (eventDetails.reason === REASONS.focusOut || eventDetails.reason === REASONS.outsidePress)
819
+ ) {
820
+ setTouched(true);
821
+ setFocused(false);
822
+
823
+ if (validationMode === 'onBlur') {
824
+ const valueToValidate = selectionMode === 'none' ? inputValue : selectedValue;
825
+ validation.commit(valueToValidate);
826
+ }
827
+ }
828
+ },
829
+ );
830
+
831
+ const setSelectedValue = useStableCallback(
832
+ (nextValue: Value | Value[] | null, eventDetails: AriaCombobox.ChangeEventDetails) => {
833
+ // Cast to `any` due to conditional value type (single vs. multiple).
834
+ // The runtime implementation already ensures the correct value shape.
835
+ onSelectedValueChange?.(nextValue as any, eventDetails);
836
+
837
+ if (eventDetails.isCanceled) {
838
+ return;
839
+ }
840
+
841
+ setSelectedValueUnwrapped(nextValue);
842
+
843
+ const shouldFillInput =
844
+ (selectionMode === 'none' && popupRef.current && fillInputOnItemPress) ||
845
+ (single && !store.state.inputInsidePopup);
846
+
847
+ if (shouldFillInput) {
848
+ setInputValue(
849
+ stringifyValueLabel(nextValue),
850
+ createChangeEventDetails(eventDetails.reason, eventDetails.event),
851
+ );
852
+ }
853
+ },
854
+ );
855
+
856
+ const handleSelection = useStableCallback(
857
+ (event: MouseEvent | PointerEvent | KeyboardEvent, itemValue: any) => {
858
+ const targetEl = getTarget(event) as HTMLElement | null;
859
+ const overrideEvent = selectionEventRef.current ?? event;
860
+ selectionEventRef.current = null;
861
+ const eventDetails = createChangeEventDetails(REASONS.itemPress, overrideEvent);
862
+
863
+ // Let the link handle the click.
864
+ const href = targetEl?.closest('a')?.getAttribute('href');
865
+ if (href) {
866
+ if (href.startsWith('#')) {
867
+ setOpen(false, eventDetails);
868
+ }
869
+ return;
870
+ }
871
+
872
+ if (multiple) {
873
+ const currentSelectedValue = Array.isArray(selectedValue) ? selectedValue : [];
874
+ const isCurrentlySelected = selectedValueIncludes(
875
+ currentSelectedValue,
876
+ itemValue,
877
+ isItemEqualToValue,
878
+ );
879
+ const nextValue = isCurrentlySelected
880
+ ? removeItem(currentSelectedValue, itemValue, isItemEqualToValue)
881
+ : [...currentSelectedValue, itemValue];
882
+
883
+ setSelectedValue(nextValue, eventDetails);
884
+
885
+ if (eventDetails.isCanceled) {
886
+ return;
887
+ }
888
+
889
+ const wasFiltering = inputRef.current ? inputRef.current.value.trim() !== '' : false;
890
+ if (!wasFiltering) {
891
+ return;
892
+ }
893
+
894
+ if (store.state.inputInsidePopup) {
895
+ setInputValue(
896
+ '',
897
+ createChangeEventDetails(REASONS.inputClear, eventDetails.event, undefined, {
898
+ isItemPress: true,
899
+ }),
900
+ );
901
+ // A newly selected item stays highlighted through the clear; a deselection
902
+ // falls back to the standard selection anchor.
903
+ const pendingHighlight = pendingQueryHighlightRef.current;
904
+ if (pendingHighlight && !isCurrentlySelected) {
905
+ pendingHighlight.toggledValue = itemValue;
906
+ }
907
+ } else {
908
+ setOpen(false, eventDetails);
909
+ }
910
+ } else {
911
+ setSelectedValue(itemValue, eventDetails);
912
+
913
+ if (eventDetails.isCanceled) {
914
+ return;
915
+ }
916
+
917
+ setOpen(false, eventDetails);
918
+ }
919
+ },
920
+ );
921
+
922
+ const requestSubmit = useStableCallback(() => {
923
+ const formElement = validation.inputRef.current?.form ?? store.state.inputElement?.form;
924
+ if (formElement && typeof formElement.requestSubmit === 'function') {
925
+ formElement.requestSubmit();
926
+ }
927
+ });
928
+
929
+ const handleUnmount = useStableCallback(() => {
930
+ setMounted(false);
931
+ onOpenChangeComplete?.(false);
932
+ setQueryChangedAfterOpen(false);
933
+ setCloseQuery(null);
934
+
935
+ if (selectionMode === 'none') {
936
+ setIndices({ activeIndex: null, selectedIndex: null });
937
+ } else {
938
+ setIndices({ activeIndex: null });
939
+ }
940
+
941
+ // Multiple selection mode:
942
+ // If the user typed a filter and didn't select in multiple mode, clear the input
943
+ // after close completes to avoid mid-exit flicker and start fresh on next open.
944
+ if (
945
+ multiple &&
946
+ inputRef.current &&
947
+ inputRef.current.value !== '' &&
948
+ !hadInputClearRef.current
949
+ ) {
950
+ setInputValue('', createChangeEventDetails(REASONS.inputClear));
951
+ }
952
+
953
+ // Single selection mode:
954
+ // - If input is rendered inside the popup, clear it so the next open is blank
955
+ // - If input is outside the popup, sync it to the selected value
956
+ if (single) {
957
+ if (store.state.inputInsidePopup) {
958
+ if (inputRef.current && inputRef.current.value !== '') {
959
+ setInputValue('', createChangeEventDetails(REASONS.inputClear));
960
+ }
961
+ } else {
962
+ const stringVal = stringifyValueLabel(selectedValue);
963
+ if (inputRef.current && inputRef.current.value !== stringVal) {
964
+ // If no selection was made, treat this as clearing the typed filter.
965
+ const reason = stringVal === '' ? REASONS.inputClear : REASONS.none;
966
+ setInputValue(stringVal, createChangeEventDetails(reason));
967
+ }
968
+ }
969
+ }
970
+ });
971
+
972
+ // Support composing the Dialog component around an inline combobox.
973
+ // `[role="dialog"]` is more interoperable than using a context, e.g. it can work
974
+ // with third-party modal libraries, though the limitation is that the closest
975
+ // `role=dialog` part must be the animated element.
976
+ const resolvedPopupRef: React.RefObject<HTMLElement | null> = React.useMemo(() => {
977
+ if (inline && positionerElement) {
978
+ return { current: positionerElement.closest('[role="dialog"]') };
979
+ }
980
+ return popupRef;
981
+ }, [inline, positionerElement]);
982
+
983
+ useOpenChangeComplete({
984
+ enabled: !props.actionsRef,
985
+ open,
986
+ ref: resolvedPopupRef,
987
+ onComplete() {
988
+ if (!open) {
989
+ handleUnmount();
990
+ }
991
+ },
992
+ });
993
+
994
+ React.useImperativeHandle(props.actionsRef, () => ({ unmount: handleUnmount }), [handleUnmount]);
995
+
996
+ useIsoLayoutEffect(
997
+ function syncSelectedIndex() {
998
+ const closeQueryReleased = previousCloseQueryRef.current !== null && closeQuery === null;
999
+ previousCloseQueryRef.current = closeQuery;
1000
+
1001
+ // Closing indexes against the frozen filtered list. Reopening releases that query, so its
1002
+ // rendered coordinates must be synchronized again even though the popup is already open.
1003
+ if (open && (!closeQueryReleased || !hasItems)) {
1004
+ return;
1005
+ }
1006
+
1007
+ // State-driven (not tied to the internal event path) so controlled closes
1008
+ // also clear a pointerdown that never received a matching item mouseup.
1009
+ if (!open) {
1010
+ pointerDownItemRef.current = null;
1011
+ }
1012
+
1013
+ if (selectionMode === 'none') {
1014
+ return;
1015
+ }
1016
+
1017
+ // Without `items`, look the selection up in the live registry of mounted item
1018
+ // values (the list stays mounted while closed when closed-state features need
1019
+ // it — trigger interaction and rendered-label autofill force-mount it). Mounted
1020
+ // items re-assert the index themselves when their registration moves; when
1021
+ // nothing is mounted the lookup resolves to `null` and each item re-registers
1022
+ // the index on the next open.
1023
+ // Keep the selected index in the coordinates of the list that is actually rendered.
1024
+ const registry: readonly any[] = hasItems ? flatFilteredValues : valuesRef.current;
1025
+
1026
+ setIndices({
1027
+ selectedIndex: findSelectionIndex(registry, selectedValue, isItemEqualToValue, multiple),
1028
+ });
1029
+ },
1030
+ [
1031
+ open,
1032
+ closeQuery,
1033
+ selectedValue,
1034
+ selectionMode,
1035
+ multiple,
1036
+ hasItems,
1037
+ flatFilteredValues,
1038
+ isItemEqualToValue,
1039
+ setIndices,
1040
+ ],
1041
+ );
1042
+
1043
+ useIsoLayoutEffect(() => {
1044
+ if (items) {
1045
+ valuesRef.current = flatFilteredValues;
1046
+ listRef.current.length = flatFilteredValues.length;
1047
+ }
1048
+ }, [items, flatFilteredValues]);
1049
+
1050
+ useIsoLayoutEffect(() => {
1051
+ const pendingHighlight = pendingQueryHighlightRef.current;
1052
+ if (pendingHighlight) {
1053
+ // A directly rendered list remains visible when the popup state is closed, while a
1054
+ // kept-mounted Positioner is hidden and should stay inert.
1055
+ const listIsNavigable = open || inline || store.state.positionerElement?.hidden === false;
1056
+ if (pendingHighlight.hasQuery) {
1057
+ if (autoHighlightMode && listIsNavigable) {
1058
+ store.set('activeIndex', 0);
1059
+ }
1060
+ pendingQueryHighlightRef.current = null;
1061
+ } else if (String(inputValue).trim() === '') {
1062
+ // Only handle the clear once it has committed (a controlled input may reject it),
1063
+ // so a restore cannot fire while a query is still active.
1064
+ pendingQueryHighlightRef.current = null;
1065
+ if (listIsNavigable) {
1066
+ const clearedBySelection = pendingHighlight.selection;
1067
+ if (
1068
+ autoHighlightMode === 'always' &&
1069
+ !clearedBySelection &&
1070
+ store.state.selectionMode === 'none'
1071
+ ) {
1072
+ // There is no selection to restore in Autocomplete. Keep the first-item reset
1073
+ // synchronous so list navigation sees it before a directly rendered list closes.
1074
+ store.set('activeIndex', 0);
1075
+ }
1076
+
1077
+ // Items re-mounted by the clear publish their composite indices in a follow-up
1078
+ // commit, so the item registries are mid-update here. Defer past React's cascade.
1079
+ queueMicrotask(() => {
1080
+ if (
1081
+ (!store.state.open && !store.state.inline) ||
1082
+ (inputRef.current && inputRef.current.value.trim() !== '')
1083
+ ) {
1084
+ return;
1085
+ }
1086
+
1087
+ // Return the highlight to the selected item, the same anchor the popup uses
1088
+ // when it first opens. Read the selection through the store so consumers can
1089
+ // pass an inline `isItemEqualToValue` or a fresh `selectedValue` array without
1090
+ // re-running this effect on every render.
1091
+ const currentSelectedValue = store.state.selectedValue;
1092
+ const isMultiple = store.state.selectionMode === 'multiple';
1093
+ const hasSelection =
1094
+ isMultiple && Array.isArray(currentSelectedValue)
1095
+ ? currentSelectedValue.length > 0
1096
+ : store.state.selectionMode !== 'none' && currentSelectedValue != null;
1097
+
1098
+ if (hasSelection) {
1099
+ const registry =
1100
+ hasItems || hasFilteredItemsProp ? flatFilteredValues : valuesRef.current;
1101
+ // A selection-driven clear keeps the just-selected item highlighted;
1102
+ // otherwise return to the open anchor. A selection that is no longer in
1103
+ // the list drops the highlight rather than leaving it on whichever item
1104
+ // now occupies that index.
1105
+ // `findItemIndex` resolves to -1 when no value was toggled.
1106
+ const toggledIndex = findItemIndex(
1107
+ registry,
1108
+ pendingHighlight.toggledValue,
1109
+ store.state.isItemEqualToValue,
1110
+ );
1111
+ store.set(
1112
+ 'activeIndex',
1113
+ toggledIndex !== -1
1114
+ ? toggledIndex
1115
+ : findSelectionIndex(
1116
+ registry,
1117
+ currentSelectedValue,
1118
+ store.state.isItemEqualToValue,
1119
+ isMultiple,
1120
+ ),
1121
+ );
1122
+ } else if (clearedBySelection) {
1123
+ store.set('activeIndex', null);
1124
+ } else if (autoHighlightMode === 'always') {
1125
+ store.set('activeIndex', 0);
1126
+ }
1127
+ });
1128
+ }
1129
+ }
1130
+ }
1131
+
1132
+ if (!open && !inline) {
1133
+ return;
1134
+ }
1135
+
1136
+ const shouldUseFlatFilteredValues = hasItems || hasFilteredItemsProp;
1137
+ const candidateItems = shouldUseFlatFilteredValues ? flatFilteredValues : valuesRef.current;
1138
+ const storeActiveIndex = store.state.activeIndex;
1139
+
1140
+ if (storeActiveIndex == null) {
1141
+ if (autoHighlightMode === 'always' && candidateItems.length > 0) {
1142
+ store.set('activeIndex', 0);
1143
+ return;
1144
+ }
1145
+ emitHighlight(undefined, -1, REASONS.none);
1146
+ return;
1147
+ }
1148
+
1149
+ if (storeActiveIndex >= candidateItems.length) {
1150
+ emitHighlight(undefined, -1, REASONS.none);
1151
+ store.set('activeIndex', null);
1152
+ return;
1153
+ }
1154
+
1155
+ const itemValue = candidateItems[storeActiveIndex];
1156
+ const previouslyHighlightedItemValue = lastHighlightRef.current.value;
1157
+ const isSameItem =
1158
+ previouslyHighlightedItemValue !== NO_ACTIVE_VALUE &&
1159
+ compareItemEquality(
1160
+ itemValue,
1161
+ previouslyHighlightedItemValue,
1162
+ store.state.isItemEqualToValue,
1163
+ );
1164
+
1165
+ if (lastHighlightRef.current.index !== storeActiveIndex || !isSameItem) {
1166
+ emitHighlight(itemValue, storeActiveIndex, REASONS.none);
1167
+ }
1168
+ }, [
1169
+ activeIndex,
1170
+ autoHighlightMode,
1171
+ emitHighlight,
1172
+ hasFilteredItemsProp,
1173
+ hasItems,
1174
+ flatFilteredValues,
1175
+ inline,
1176
+ open,
1177
+ store,
1178
+ // Reruns the effect when the query changes without affecting the deps above, such as
1179
+ // clearing the input when no items are filtered out (individually rendered items).
1180
+ inputValue,
1181
+ ]);
1182
+
1183
+ useIsoLayoutEffect(() => {
1184
+ if (selectionMode === 'none') {
1185
+ setFilled(String(inputValue) !== '');
1186
+ return;
1187
+ }
1188
+ setFilled(
1189
+ multiple ? Array.isArray(selectedValue) && selectedValue.length > 0 : selectedValue != null,
1190
+ );
1191
+ }, [setFilled, selectionMode, inputValue, selectedValue, multiple]);
1192
+
1193
+ // Ensures that the active index is not set to 0 when the list is empty.
1194
+ // This avoids needing to press ArrowDown twice under certain conditions.
1195
+ React.useEffect(() => {
1196
+ if (hasItems && autoHighlightMode && flatFilteredValues.length === 0) {
1197
+ setIndices({ activeIndex: null });
1198
+ }
1199
+ }, [hasItems, autoHighlightMode, flatFilteredValues.length, setIndices]);
1200
+
1201
+ function handleQueryChanged() {
1202
+ if (
1203
+ open &&
1204
+ query !== '' &&
1205
+ query !== String(initialDefaultInputValue) &&
1206
+ !inputMatchesSelectedValue
1207
+ ) {
1208
+ setQueryChangedAfterOpen(true);
1209
+ }
1210
+ }
1211
+
1212
+ function handleOpenChanged() {
1213
+ // A controlled `open` prop can interrupt the close without calling `setOpen`.
1214
+ if (open && closeQuery !== null) {
1215
+ handleInterruptedReopen(false);
1216
+ }
1217
+ }
1218
+
1219
+ // These sync triggers can run in the same commit while still seeing the pre-commit `inputValue`.
1220
+ // This render-scoped flag prevents duplicate callbacks and resets so canceled writes can retry.
1221
+ let syncedSelectedLabel = false;
1222
+
1223
+ function syncInputToSelectedLabel() {
1224
+ if (!syncedSelectedLabel && inputValue !== selectedLabelString) {
1225
+ syncedSelectedLabel = true;
1226
+ setInputValue(selectedLabelString, createChangeEventDetails(REASONS.none));
1227
+ }
1228
+ }
1229
+
1230
+ function handleSelectedValueChanged() {
1231
+ if (selectionMode === 'none') {
1232
+ return;
1233
+ }
1234
+
1235
+ clearErrors(name);
1236
+ setDirty(isSelectedValueDirty(selectedValue, validityData.initialValue, isItemEqualToValue));
1237
+
1238
+ validation.change(selectedValue);
1239
+
1240
+ if (single && !hasInputValue && !inputInsidePopup) {
1241
+ syncInputToSelectedLabel();
1242
+ }
1243
+ }
1244
+
1245
+ // The label catches accessor changes while the items identity restores the selected label after
1246
+ // a one-step input clear followed by a data reload. The shared sync prevents duplicate writes
1247
+ // when both change in the same commit.
1248
+ function syncInputAfterItemsOrLabelChange() {
1249
+ if (single && !hasInputValue && !inputInsidePopup && !queryChangedAfterOpen) {
1250
+ syncInputToSelectedLabel();
1251
+ }
1252
+ }
1253
+
1254
+ function handleInputValueChanged() {
1255
+ if (selectionMode !== 'none') {
1256
+ return;
1257
+ }
1258
+
1259
+ clearErrors(name);
1260
+ setDirty(inputValue !== validityData.initialValue);
1261
+
1262
+ validation.change(inputValue);
1263
+ }
1264
+
1265
+ useValueChanged(query, handleQueryChanged);
1266
+ useValueChanged(open, handleOpenChanged);
1267
+ useValueChanged(selectedValue, handleSelectedValueChanged);
1268
+ useValueChanged(selectedLabelString, syncInputAfterItemsOrLabelChange);
1269
+ useValueChanged(items, syncInputAfterItemsOrLabelChange);
1270
+ useValueChanged(inputValue, handleInputValueChanged);
1271
+
1272
+ const floatingRootContext = useFloatingRootContext({
1273
+ open: inline ? true : open,
1274
+ onOpenChange: setOpen,
1275
+ elements: {
1276
+ reference: inputInsidePopup ? triggerElement : inputElement,
1277
+ floating: positionerElement,
1278
+ },
1279
+ });
1280
+
1281
+ const ariaHasPopup = grid ? 'grid' : 'listbox';
1282
+ // An inline list isn't gated on `open`: it renders for as long as it's in the tree, so the
1283
+ // combobox is permanently expanded even while the internal open state is `false`.
1284
+ const expanded = open || inline;
1285
+ const ariaExpanded = expanded ? 'true' : 'false';
1286
+
1287
+ const role: ElementProps = React.useMemo(() => {
1288
+ const isPlainInput = inputElement?.tagName === 'INPUT';
1289
+ // During SSR and initial hydration, the input ref is not available yet.
1290
+ // Assume an input-like control so combobox ARIA attributes are present.
1291
+ const shouldTreatAsInput = inputElement == null || isPlainInput;
1292
+ // A non-input control only takes on combobox semantics while the list is exposed, which for
1293
+ // an inline list is the whole time.
1294
+ const shouldApplyAria = shouldTreatAsInput || expanded;
1295
+
1296
+ const reference = shouldTreatAsInput
1297
+ ? ({
1298
+ autoComplete: 'off',
1299
+ spellCheck: 'false',
1300
+ autoCorrect: 'off',
1301
+ autoCapitalize: 'none',
1302
+ } as HTMLProps<HTMLInputElement>)
1303
+ : {};
1304
+
1305
+ if (shouldApplyAria) {
1306
+ reference.role = 'combobox';
1307
+ reference['aria-expanded'] = ariaExpanded;
1308
+ reference['aria-haspopup'] = ariaHasPopup;
1309
+ reference['aria-controls'] = expanded ? listElement?.id : undefined;
1310
+ // `readOnly` accepts no input, so no completion of any kind is offered.
1311
+ reference['aria-autocomplete'] = readOnly ? 'none' : autoComplete;
1312
+ }
1313
+
1314
+ return {
1315
+ reference,
1316
+ floating: { role: 'presentation' },
1317
+ };
1318
+ }, [inputElement, expanded, ariaExpanded, ariaHasPopup, listElement?.id, autoComplete, readOnly]);
1319
+
1320
+ // `readOnly` locks the value, not the interaction: the popup opens and can be browsed.
1321
+ // Value changes stay blocked in `ComboboxItem`, `ComboboxInput`'s keydown, `ComboboxTrigger`'s
1322
+ // typeahead, the clear/remove parts, and the hidden input's autofill handler.
1323
+ const click = useClick(floatingRootContext, {
1324
+ enabled: !disabled && openOnInputClick,
1325
+ event: 'mousedown-only',
1326
+ toggle: false,
1327
+ // Apply a small delay for touch to let mobile viewport/keyboard positioning settle.
1328
+ // This avoids top-bottom flip flickers if the preferred position is "top" when first tapping.
1329
+ touchOpenDelay: inputInsidePopup ? 0 : 100,
1330
+ reason: REASONS.inputPress,
1331
+ });
1332
+
1333
+ const dismiss = useDismiss(floatingRootContext, {
1334
+ enabled: !disabled && !inline,
1335
+ outsidePressEvent: {
1336
+ mouse: 'sloppy',
1337
+ // The visual viewport (affected by the mobile software keyboard) can be
1338
+ // somewhat small. The user may want to scroll the screen to see more of
1339
+ // the popup.
1340
+ touch: 'intentional',
1341
+ },
1342
+ // Without a popup, let the Escape key bubble the event up to other popups' handlers.
1343
+ bubbles: inline ? true : undefined,
1344
+ outsidePress(event) {
1345
+ const target = getTarget(event) as Element | null;
1346
+ return (
1347
+ !contains(triggerElement, target) &&
1348
+ !contains(clearRef.current, target) &&
1349
+ !contains(chipsContainerRef.current, target) &&
1350
+ !contains(inputGroupElement, target)
1351
+ );
1352
+ },
1353
+ });
1354
+
1355
+ const listNavigation = useListNavigation(floatingRootContext, {
1356
+ enabled: !disabled,
1357
+ id,
1358
+ listRef,
1359
+ activeIndex,
1360
+ selectedIndex,
1361
+ virtual: true,
1362
+ loopFocus,
1363
+ allowEscape: loopFocus && !autoHighlightMode,
1364
+ focusItemOnOpen:
1365
+ queryChangedAfterOpen || (selectionMode === 'none' && !autoHighlightMode) ? false : 'auto',
1366
+ focusItemOnHover: highlightItemOnHover,
1367
+ resetOnPointerLeave: !keepHighlight,
1368
+ orientation: grid ? 'horizontal' : undefined,
1369
+ rtl: direction === 'rtl',
1370
+ disabledIndices: EMPTY_ARRAY,
1371
+ grid: grid ? gridNavigation : undefined,
1372
+ onNavigate(nextActiveIndex, event) {
1373
+ // Retain the highlight only while actually transitioning out or closed.
1374
+ if ((!event && !open) || transitionStatus === 'ending') {
1375
+ return;
1376
+ }
1377
+
1378
+ if (!event) {
1379
+ setIndices({
1380
+ activeIndex: nextActiveIndex,
1381
+ });
1382
+ } else {
1383
+ setIndices({
1384
+ activeIndex: nextActiveIndex,
1385
+ type: keyboardActiveRef.current ? REASONS.keyboard : REASONS.pointer,
1386
+ });
1387
+ }
1388
+ },
1389
+ });
1390
+
1391
+ const inputProps = React.useMemo(
1392
+ () =>
1393
+ mergeProps(
1394
+ listNavigation.reference,
1395
+ {
1396
+ onKeyDown(event: BaseUIEvent<React.KeyboardEvent>) {
1397
+ // In grid mode the navigation hook treats ArrowLeft/ArrowRight as horizontal
1398
+ // grid movement. When the input has focus and no item is highlighted the user
1399
+ // is still editing the query, so let the input keep its native caret behavior.
1400
+ if (
1401
+ grid &&
1402
+ store.state.activeIndex == null &&
1403
+ (event.key === 'ArrowLeft' || event.key === 'ArrowRight')
1404
+ ) {
1405
+ event.preventBaseUIHandler();
1406
+ }
1407
+ },
1408
+ },
1409
+ dismiss.reference,
1410
+ click.reference,
1411
+ role.reference,
1412
+ ),
1413
+ [listNavigation.reference, dismiss.reference, click.reference, role.reference, grid, store],
1414
+ );
1415
+
1416
+ const popupProps = React.useMemo(
1417
+ () => mergeProps(FOCUSABLE_POPUP_PROPS, dismiss.floating),
1418
+ [dismiss.floating],
1419
+ );
1420
+
1421
+ const listProps = React.useMemo(
1422
+ () => mergeProps(listNavigation.floating, role.floating),
1423
+ [listNavigation.floating, role.floating],
1424
+ );
1425
+
1426
+ const itemProps = React.useMemo<HTMLProps>(() => {
1427
+ const listNavigationItemProps = listNavigation.item as HTMLProps | undefined;
1428
+ if (!listNavigationItemProps) {
1429
+ return EMPTY_OBJECT;
1430
+ }
1431
+
1432
+ // Combobox keeps focus on the input; item focus would incorrectly sync
1433
+ // list navigation state from DOM focus.
1434
+ return { ...listNavigationItemProps, onFocus: undefined };
1435
+ }, [listNavigation.item]);
1436
+
1437
+ store.useContextCallback('setOpen', setOpen);
1438
+ store.useContextCallback('setInputValue', setInputValue);
1439
+ store.useContextCallback('setSelectedValue', setSelectedValue);
1440
+ store.useContextCallback('setIndices', setIndices);
1441
+ store.useContextCallback('handleSelection', handleSelection);
1442
+ store.useContextCallback('forceMount', forceMount);
1443
+ store.useContextCallback('requestSubmit', requestSubmit);
1444
+ store.useContextCallback('onOpenChangeComplete', onOpenChangeCompleteProp);
1445
+
1446
+ // The prop bags must be in the store before the parts render: they read them with `useStore`
1447
+ // during render, and a layout effect commits only after all children have rendered.
1448
+ useOnFirstRender(() => {
1449
+ store.update({
1450
+ inline: inlineProp,
1451
+ popupProps,
1452
+ listProps,
1453
+ inputProps,
1454
+ triggerProps,
1455
+ itemProps,
1456
+ });
1457
+ });
1458
+
1459
+ const syncedValues = {
1460
+ id,
1461
+ selectedValue,
1462
+ open,
1463
+ mounted,
1464
+ transitionStatus,
1465
+ items: storeItems,
1466
+ inline: inlineProp,
1467
+ popupProps,
1468
+ listProps,
1469
+ inputProps,
1470
+ triggerProps,
1471
+ itemProps,
1472
+ openMethod,
1473
+ selectionMode,
1474
+ name,
1475
+ form,
1476
+ disabled,
1477
+ readOnly,
1478
+ required,
1479
+ grid,
1480
+ virtualized,
1481
+ openOnInputClick,
1482
+ itemToStringLabel,
1483
+ modal,
1484
+ autoHighlight: autoHighlightMode,
1485
+ isItemEqualToValue,
1486
+ submitOnItemClick,
1487
+ hasInputValue,
1488
+ };
1489
+
1490
+ useIsoLayoutEffect(() => {
1491
+ // `inputOwnsFormValue` is derived here rather than during render because `ComboboxInput`
1492
+ // writes it from a ref callback earlier in the same commit, and it has to land in this same
1493
+ // `update` so subscribers never observe an intermediate snapshot. That is also why
1494
+ // `store.useSyncedValues` can't be used yet: it would need a second write. The dependencies
1495
+ // are derived from `syncedValues` so a newly synchronized field can't be forgotten here.
1496
+ store.update({
1497
+ ...syncedValues,
1498
+ inputOwnsFormValue: selectionMode === 'none' && (inlineProp || !store.state.inputInsidePopup),
1499
+ });
1500
+ // eslint-disable-next-line react-hooks/exhaustive-deps
1501
+ }, [store, ...Object.values(syncedValues)]);
1502
+
1503
+ const hiddenInputRef = useMergedRefs(inputRefProp, validation.inputRef);
1504
+
1505
+ const itemsContextValue: ComboboxDerivedItemsContext = React.useMemo(
1506
+ () => ({
1507
+ query,
1508
+ hasItems,
1509
+ filteredItems,
1510
+ flatFilteredValues,
1511
+ }),
1512
+ [query, hasItems, filteredItems, flatFilteredValues],
1513
+ );
1514
+
1515
+ const serializedValue = React.useMemo(() => {
1516
+ if (Array.isArray(fieldRawValue)) {
1517
+ return '';
1518
+ }
1519
+ return stringifyAsValue(fieldRawValue, itemToStringValue);
1520
+ }, [fieldRawValue, itemToStringValue]);
1521
+
1522
+ const hasMultipleSelection = multiple && Array.isArray(selectedValue) && selectedValue.length > 0;
1523
+ const hiddenInputName =
1524
+ multiple || (selectionMode === 'none' && inputOwnsFormValue) ? undefined : name;
1525
+
1526
+ const hiddenInputs = React.useMemo(() => {
1527
+ if (!multiple || !Array.isArray(selectedValue) || !name) {
1528
+ return null;
1529
+ }
1530
+
1531
+ return selectedValue.map((value: Value) => {
1532
+ const currentSerializedValue = stringifyAsValue(value, itemToStringValue);
1533
+ return (
1534
+ <input
1535
+ key={currentSerializedValue}
1536
+ type="hidden"
1537
+ form={form}
1538
+ name={name}
1539
+ value={currentSerializedValue}
1540
+ disabled={disabled}
1541
+ />
1542
+ );
1543
+ });
1544
+ }, [multiple, selectedValue, form, name, itemToStringValue, disabled]);
1545
+
1546
+ const children = (
1547
+ <React.Fragment>
1548
+ {props.children}
1549
+ <input
1550
+ {...validation.getValidationProps(disabled, {
1551
+ // Move focus when the hidden input is focused.
1552
+ onFocus() {
1553
+ if (inputInsidePopup) {
1554
+ triggerElement?.focus();
1555
+ return;
1556
+ }
1557
+
1558
+ (inputRef.current || triggerElement)?.focus();
1559
+ },
1560
+ // Handle browser autofill.
1561
+ onChange(event: React.ChangeEvent<HTMLInputElement>) {
1562
+ // Workaround for https://github.com/react/react/issues/9023
1563
+ if (event.defaultPrevented || disabled || readOnly) {
1564
+ return;
1565
+ }
1566
+
1567
+ const nextValue = event.currentTarget.value;
1568
+ const nextValueLower = nextValue.toLowerCase();
1569
+ const details = createChangeEventDetails(REASONS.none, event);
1570
+
1571
+ const findSerializedMatchIndex = () =>
1572
+ valuesRef.current.findIndex(
1573
+ (candidate) =>
1574
+ stringifyAsValue(candidate, itemToStringValue).toLowerCase() === nextValueLower ||
1575
+ stringifyValueLabel(candidate).toLowerCase() === nextValueLower,
1576
+ );
1577
+
1578
+ function handleChange() {
1579
+ // Browser autofill only writes a single scalar value.
1580
+ if (multiple) {
1581
+ return;
1582
+ }
1583
+
1584
+ if (selectionMode === 'none') {
1585
+ setInputValue(nextValue, details);
1586
+ return;
1587
+ }
1588
+
1589
+ // Preserve the original serialized matching, then fall back to rendered text,
1590
+ // which browsers can autofill for primitive values like `value="US">United States`.
1591
+ let matchingIndex = findSerializedMatchIndex();
1592
+
1593
+ if (matchingIndex === -1) {
1594
+ matchingIndex = valuesRef.current.findIndex((_, index) => {
1595
+ const renderedLabel = labelsRef.current[index];
1596
+ return renderedLabel != null && renderedLabel.toLowerCase() === nextValueLower;
1597
+ });
1598
+ }
1599
+
1600
+ const matchingValue =
1601
+ matchingIndex === -1 ? undefined : valuesRef.current[matchingIndex];
1602
+ if (matchingValue != null) {
1603
+ // `setSelectedValue` may be canceled by `onValueChange`; rely on
1604
+ // `useValueChanged` to mark the field dirty and run validation only
1605
+ // when the value actually changes.
1606
+ setSelectedValue?.(matchingValue, details);
1607
+ }
1608
+ }
1609
+
1610
+ // Only single-selection autofill matches against the registered values/labels.
1611
+ // `multiple` ignores autofill and `none` just writes the input value, so avoid the
1612
+ // sticky `forceMounted` mount (which never resets) for those modes.
1613
+ if (single) {
1614
+ forceMount();
1615
+ if (items && findSerializedMatchIndex() === -1) {
1616
+ // `forceMount` only refreshes the derived labels for the `items` prop. When
1617
+ // serialized matching misses, also mount the list so rendered labels (which can
1618
+ // differ from the serialized values) are registered for autofill matching.
1619
+ store.set('forceMounted', true);
1620
+ }
1621
+ }
1622
+ queueMicrotask(handleChange);
1623
+ },
1624
+ })}
1625
+ id={id && hiddenInputName == null ? `${id}-hidden-input` : undefined}
1626
+ form={form}
1627
+ name={hiddenInputName}
1628
+ autoComplete={formAutoComplete}
1629
+ disabled={disabled}
1630
+ required={required && !hasMultipleSelection}
1631
+ readOnly={readOnly}
1632
+ value={serializedValue}
1633
+ ref={hiddenInputRef}
1634
+ style={hiddenInputName ? visuallyHiddenInput : visuallyHidden}
1635
+ tabIndex={-1}
1636
+ aria-hidden
1637
+ suppressHydrationWarning
1638
+ />
1639
+ {hiddenInputs}
1640
+ </React.Fragment>
1641
+ );
1642
+
1643
+ return (
1644
+ <ComboboxRootContext.Provider value={store}>
1645
+ <ComboboxFloatingContext.Provider value={floatingRootContext}>
1646
+ <ComboboxHasItemsContext.Provider value={hasItems}>
1647
+ <ComboboxDerivedItemsContext.Provider value={itemsContextValue}>
1648
+ <ComboboxInputValueContext.Provider value={inputValue}>
1649
+ {children}
1650
+ </ComboboxInputValueContext.Provider>
1651
+ </ComboboxDerivedItemsContext.Provider>
1652
+ </ComboboxHasItemsContext.Provider>
1653
+ </ComboboxFloatingContext.Provider>
1654
+ </ComboboxRootContext.Provider>
1655
+ );
1656
+ }
1657
+
1658
+ type SelectionMode = 'single' | 'multiple' | 'none';
1659
+
1660
+ type ComboboxItemValueType<ItemValue, Mode extends SelectionMode> = Mode extends 'multiple'
1661
+ ? ItemValue[]
1662
+ : ItemValue;
1663
+
1664
+ interface ComboboxRootProps<ItemValue, Item = ItemValue> {
1665
+ children?: React.OctaneNode;
1666
+ /**
1667
+ * Identifies the field when a form is submitted.
1668
+ */
1669
+ name?: string | undefined;
1670
+ /**
1671
+ * Identifies the form that owns the internal input.
1672
+ * Useful when the combobox is rendered outside the form.
1673
+ */
1674
+ form?: string | undefined;
1675
+ /**
1676
+ * The id of the component.
1677
+ */
1678
+ id?: string | undefined;
1679
+ /**
1680
+ * Whether the user must choose a value before submitting a form.
1681
+ * @default false
1682
+ */
1683
+ required?: boolean | undefined;
1684
+ /**
1685
+ * Whether the user should be unable to choose a different option from the popup.
1686
+ * @default false
1687
+ */
1688
+ readOnly?: boolean | undefined;
1689
+ /**
1690
+ * Whether the component should ignore user interaction.
1691
+ * @default false
1692
+ */
1693
+ disabled?: boolean | undefined;
1694
+ /**
1695
+ * Whether the popup is initially open.
1696
+ *
1697
+ * To render a controlled popup, use the `open` prop instead.
1698
+ * @default false
1699
+ */
1700
+ defaultOpen?: boolean | undefined;
1701
+ /**
1702
+ * Whether the popup is currently open. Use when controlled.
1703
+ */
1704
+ open?: boolean | undefined;
1705
+ /**
1706
+ * Event handler called when the popup is opened or closed.
1707
+ */
1708
+ onOpenChange?:
1709
+ ((open: boolean, eventDetails: AriaCombobox.ChangeEventDetails) => void) | undefined;
1710
+ /**
1711
+ * Event handler called after any animations complete when the popup is opened or closed.
1712
+ */
1713
+ onOpenChangeComplete?: ((open: boolean) => void) | undefined;
1714
+ /**
1715
+ * Whether the popup opens when clicking the input.
1716
+ * @default true
1717
+ */
1718
+ openOnInputClick?: boolean | undefined;
1719
+ /**
1720
+ * Whether the first matching item is highlighted automatically.
1721
+ * - `false`: do not highlight automatically.
1722
+ * - `true`: highlight after the user types and keep the highlight while the query changes.
1723
+ * - `'always'`: highlight the first item as soon as the list opens.
1724
+ * @default false
1725
+ */
1726
+ autoHighlight?: boolean | 'always' | undefined;
1727
+ /**
1728
+ * Whether the highlighted item should be preserved when the pointer leaves the list.
1729
+ * @default false
1730
+ */
1731
+ keepHighlight?: boolean | undefined;
1732
+ /**
1733
+ * Whether moving the pointer over items should highlight them.
1734
+ * Disabling this prop allows CSS `:hover` to be differentiated from the `:focus` (`data-highlighted`) state.
1735
+ * @default true
1736
+ */
1737
+ highlightItemOnHover?: boolean | undefined;
1738
+ /**
1739
+ * Whether to loop keyboard focus back to the input when the end of the list is reached while using the arrow keys. The first item can then be reached by pressing <kbd>ArrowDown</kbd> again from the input, or the last item can be reached by pressing <kbd>ArrowUp</kbd> from the input.
1740
+ * The input is always included in the focus loop per [ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/).
1741
+ * When disabled, focus does not move when on the last element and the user presses <kbd>ArrowDown</kbd>, or when on the first element and the user presses <kbd>ArrowUp</kbd>.
1742
+ * @default true
1743
+ */
1744
+ loopFocus?: boolean | undefined;
1745
+ /**
1746
+ * The input value of the combobox. Use when controlled.
1747
+ */
1748
+ inputValue?: React.ComponentProps<'input'>['value'] | undefined;
1749
+ /**
1750
+ * Callback fired when the input value of the combobox changes.
1751
+ */
1752
+ onInputValueChange?:
1753
+ ((value: string, eventDetails: AriaCombobox.ChangeEventDetails) => void) | undefined;
1754
+ /**
1755
+ * The uncontrolled input value when initially rendered.
1756
+ *
1757
+ * To render a controlled input, use the `inputValue` prop instead.
1758
+ */
1759
+ defaultInputValue?: React.ComponentProps<'input'>['defaultValue'] | undefined;
1760
+ /**
1761
+ * A ref to imperative actions.
1762
+ * - `unmount`: Manually unmounts the combobox.
1763
+ * Call this after any externally controlled closing animation finishes.
1764
+ */
1765
+ actionsRef?: React.RefObject<AriaCombobox.Actions | null> | undefined;
1766
+ /**
1767
+ * Callback fired when an item is highlighted or unhighlighted.
1768
+ * Receives the highlighted item value (or `undefined` if no item is highlighted) and event details with a `reason` property describing why the highlight changed.
1769
+ * The `reason` can be:
1770
+ * - `'keyboard'`: the highlight changed due to keyboard navigation.
1771
+ * - `'pointer'`: the highlight changed due to pointer hovering.
1772
+ * - `'none'`: the highlight changed programmatically.
1773
+ */
1774
+ onItemHighlighted?:
1775
+ | ((itemValue: ItemValue | undefined, eventDetails: AriaCombobox.HighlightEventDetails) => void)
1776
+ | undefined;
1777
+ /**
1778
+ * A ref to the hidden input element.
1779
+ */
1780
+ inputRef?: React.Ref<HTMLInputElement> | undefined;
1781
+ /**
1782
+ * Whether list items are presented in a grid layout.
1783
+ * When enabled, arrow keys navigate across rows and columns inferred from DOM rows.
1784
+ * @default false
1785
+ */
1786
+ grid?: boolean | undefined;
1787
+ /**
1788
+ * The items to be displayed in the list.
1789
+ * Can be a flat array of items, an array of groups with items, or a collection created by
1790
+ * the `createItems()` function, which derives each item's selection value and label.
1791
+ * Nullish entries are not supported: remove them from the data before passing it.
1792
+ */
1793
+ items?:
1794
+ readonly any[] | readonly Group<any>[] | ComboboxItemCollection<Item, ItemValue> | undefined;
1795
+ /**
1796
+ * Filtered items to display in the list.
1797
+ * When provided, the list uses these items instead of filtering the `items` prop internally.
1798
+ * When `items` is also provided, this array must preserve its flat or grouped structure.
1799
+ * With a `createItems()` collection, pass source items rather than derived values.
1800
+ * Nullish entries are not supported, as in `items`.
1801
+ * Use when you want to control filtering logic externally with the `useFilter()` hook.
1802
+ */
1803
+ filteredItems?: readonly Item[] | readonly Group<Item>[] | undefined;
1804
+ /**
1805
+ * Filter function used to match items vs input query.
1806
+ * Receives the source item, which is the derived value's item when `items` is a `createItems()`
1807
+ * collection, and the item itself otherwise.
1808
+ */
1809
+ filter?:
1810
+ | null
1811
+ | ((item: Item, query: string, itemToString?: (item: Item) => string) => boolean)
1812
+ | undefined;
1813
+ /**
1814
+ * When the item values are objects (`<Combobox.Item value={object}>`), this function converts the object value to a string representation for display in the input.
1815
+ * If the shape of the object is `{ value, label }`, the label will be used automatically without needing to specify this prop.
1816
+ * With a `createItems()` collection, this receives the derived value, and the collection's
1817
+ * `getLabel` takes precedence for values it can resolve.
1818
+ */
1819
+ itemToStringLabel?: ((itemValue: ItemValue) => string) | undefined;
1820
+ /**
1821
+ * When the item values are objects (`<Combobox.Item value={object}>`), this function converts the object value to a string representation for form submission.
1822
+ * If the shape of the object is `{ value, label }`, the value will be used automatically without needing to specify this prop.
1823
+ * With a `createItems()` collection, this receives the derived value.
1824
+ */
1825
+ itemToStringValue?: ((itemValue: ItemValue) => string) | undefined;
1826
+ /**
1827
+ * Custom comparison logic used to determine if a combobox item value matches the current selected value. Useful when item values are objects without matching referentially.
1828
+ * With a `createItems()` collection, both arguments are derived values.
1829
+ * Defaults to `Object.is` comparison.
1830
+ */
1831
+ isItemEqualToValue?: ((itemValue: ItemValue, value: ItemValue) => boolean) | undefined;
1832
+ /**
1833
+ * Whether the items are being externally virtualized.
1834
+ * @default false
1835
+ */
1836
+ virtualized?: boolean | undefined;
1837
+ /**
1838
+ * Whether the list is rendered inline without using the component's own popup.
1839
+ *
1840
+ * Specify `open` unconditionally in conjunction with this prop so the list is considered
1841
+ * visible: `<Combobox.Root inline open>`
1842
+ *
1843
+ * In a `Combobox.Root` > `Dialog.Root` composition, bind the Combobox's `open` and
1844
+ * `onOpenChange` props to the `Dialog`'s `open` and `onOpenChange` state instead so the
1845
+ * component resets its transient state (filter query, highlighted item, and input value) when
1846
+ * the dialog closes.
1847
+ * @default false
1848
+ */
1849
+ inline?: boolean | undefined;
1850
+ /**
1851
+ * Determines if the popup enters a modal state when open.
1852
+ * - `true`: user interaction is limited to the popup: document page scroll is locked and pointer interactions on outside elements are disabled.
1853
+ * - `false`: user interaction with the rest of the document is allowed.
1854
+ *
1855
+ * On touch devices, a `true` modal blocks outside taps but leaves the page scrollable unless the popup spans nearly the full viewport width, matching native iOS behavior.
1856
+ * @default false
1857
+ */
1858
+ modal?: boolean | undefined;
1859
+ /**
1860
+ * The maximum number of items to display in the list.
1861
+ * @default -1
1862
+ */
1863
+ limit?: number | undefined;
1864
+ /**
1865
+ * Controls how the component behaves with respect to list filtering and inline autocompletion.
1866
+ * - `list` (default): items are dynamically filtered based on the input value. The input value does not change based on the active item.
1867
+ * - `both`: items are dynamically filtered based on the input value, which will temporarily change based on the active item (inline autocompletion).
1868
+ * - `inline`: items are static (not filtered), and the input value will temporarily change based on the active item (inline autocompletion).
1869
+ * - `none`: items are static (not filtered), and the input value will not change based on the active item.
1870
+ * @default 'list'
1871
+ */
1872
+ autoComplete?: 'list' | 'both' | 'inline' | 'none' | undefined;
1873
+ /**
1874
+ * Provides a hint to the browser for autofill on the hidden input element.
1875
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/autocomplete
1876
+ */
1877
+ formAutoComplete?: string | undefined;
1878
+ /**
1879
+ * The locale to use for string comparison.
1880
+ * Defaults to the user's runtime locale.
1881
+ */
1882
+ locale?: Intl.LocalesArgument | undefined;
1883
+ /**
1884
+ * Whether clicking an item should submit the owning form.
1885
+ * @default false
1886
+ */
1887
+ submitOnItemClick?: boolean | undefined;
1888
+ /**
1889
+ * INTERNAL: When `selectionMode` is `none`, controls whether selecting an item fills the input.
1890
+ */
1891
+ fillInputOnItemPress?: boolean | undefined;
1892
+ }
1893
+
1894
+ export interface AriaComboboxState {}
1895
+
1896
+ export type AriaComboboxProps<
1897
+ Value,
1898
+ Mode extends SelectionMode = 'none',
1899
+ Item = Value,
1900
+ > = ComboboxRootProps<Value, Item> & {
1901
+ /**
1902
+ * How the combobox should remember the selected value.
1903
+ * - `single`: Remembers the last selected value.
1904
+ * - `multiple`: Remember all selected values.
1905
+ * - `none`: Do not remember the selected value.
1906
+ */
1907
+ selectionMode: Mode;
1908
+ /**
1909
+ * The selected value of the combobox. Use when controlled.
1910
+ */
1911
+ selectedValue?: ComboboxItemValueType<Value, Mode> | undefined;
1912
+ /**
1913
+ * The uncontrolled selected value of the combobox when it's initially rendered.
1914
+ *
1915
+ * To render a controlled combobox, use the `selectedValue` prop instead.
1916
+ */
1917
+ defaultSelectedValue?: ComboboxItemValueType<Value, Mode> | null | undefined;
1918
+ /**
1919
+ * Callback fired when the selected value of the combobox changes.
1920
+ */
1921
+ onSelectedValueChange?:
1922
+ | ((
1923
+ value: ComboboxItemValueType<Value, Mode>,
1924
+ eventDetails: AriaCombobox.ChangeEventDetails,
1925
+ ) => void)
1926
+ | undefined;
1927
+ };
1928
+
1929
+ export namespace AriaCombobox {
1930
+ export type Props<Value, Mode extends SelectionMode = 'none', Item = Value> = AriaComboboxProps<
1931
+ Value,
1932
+ Mode,
1933
+ Item
1934
+ >;
1935
+ export type State = AriaComboboxState;
1936
+
1937
+ export interface Actions {
1938
+ unmount: () => void;
1939
+ }
1940
+
1941
+ export type HighlightEventReason =
1942
+ typeof REASONS.keyboard | typeof REASONS.pointer | typeof REASONS.none;
1943
+ export type HighlightEventDetails = BaseUIGenericEventDetails<
1944
+ HighlightEventReason,
1945
+ { index: number }
1946
+ >;
1947
+
1948
+ export type ChangeEventReason =
1949
+ | typeof REASONS.triggerPress
1950
+ | typeof REASONS.inputPress
1951
+ | typeof REASONS.outsidePress
1952
+ | typeof REASONS.itemPress
1953
+ | typeof REASONS.closePress
1954
+ | typeof REASONS.escapeKey
1955
+ | typeof REASONS.listNavigation
1956
+ | typeof REASONS.focusOut
1957
+ | typeof REASONS.inputChange
1958
+ | typeof REASONS.inputClear
1959
+ | typeof REASONS.clearPress
1960
+ | typeof REASONS.chipRemovePress
1961
+ | typeof REASONS.cancelOpen
1962
+ | typeof REASONS.none;
1963
+ export type ChangeEventDetails = BaseUIChangeEventDetails<ChangeEventReason> & {
1964
+ /**
1965
+ * When `reason` is `input-clear` in multiple mode, indicates whether an item press caused the
1966
+ * clear. Automatic cleanup clears omit this property.
1967
+ */
1968
+ isItemPress?: boolean | undefined;
1969
+ };
1970
+ }