@base-ui/react 1.4.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (579) hide show
  1. package/CHANGELOG.md +125 -8
  2. package/README.md +1 -1
  3. package/accordion/item/AccordionItem.d.ts +4 -0
  4. package/accordion/item/AccordionItem.js +5 -4
  5. package/accordion/panel/AccordionPanel.js +29 -51
  6. package/accordion/root/AccordionRoot.js +5 -6
  7. package/accordion/trigger/AccordionTrigger.js +3 -4
  8. package/alert-dialog/handle.d.ts +14 -1
  9. package/alert-dialog/handle.js +22 -5
  10. package/alert-dialog/index.d.ts +1 -1
  11. package/alert-dialog/index.parts.d.ts +2 -3
  12. package/alert-dialog/index.parts.js +4 -5
  13. package/alert-dialog/root/AlertDialogRoot.d.ts +7 -7
  14. package/alert-dialog/root/AlertDialogRoot.js +2 -56
  15. package/alert-dialog/trigger/AlertDialogTrigger.d.ts +25 -0
  16. package/alert-dialog/trigger/AlertDialogTrigger.js +15 -0
  17. package/alert-dialog/trigger/AlertDialogTriggerDataAttributes.d.ts +10 -0
  18. package/alert-dialog/trigger/AlertDialogTriggerDataAttributes.js +18 -0
  19. package/autocomplete/root/AutocompleteRoot.js +9 -10
  20. package/avatar/image/AvatarImage.js +4 -4
  21. package/checkbox/indicator/CheckboxIndicator.js +2 -2
  22. package/checkbox/root/CheckboxRoot.js +49 -11
  23. package/checkbox-group/CheckboxGroup.js +1 -5
  24. package/collapsible/panel/CollapsiblePanel.js +29 -51
  25. package/collapsible/panel/useCollapsiblePanel.d.ts +9 -23
  26. package/collapsible/panel/useCollapsiblePanel.js +308 -268
  27. package/collapsible/root/CollapsibleRoot.d.ts +1 -1
  28. package/collapsible/root/CollapsibleRootContext.d.ts +0 -2
  29. package/collapsible/root/useCollapsibleRoot.d.ts +0 -27
  30. package/collapsible/root/useCollapsibleRoot.js +2 -64
  31. package/collapsible/trigger/CollapsibleTrigger.js +5 -6
  32. package/combobox/arrow/ComboboxArrow.js +1 -1
  33. package/combobox/backdrop/ComboboxBackdrop.js +1 -1
  34. package/combobox/chip/ComboboxChip.js +7 -2
  35. package/combobox/clear/ComboboxClear.d.ts +4 -0
  36. package/combobox/clear/ComboboxClear.js +1 -0
  37. package/combobox/clear/ComboboxClearDataAttributes.d.ts +4 -0
  38. package/combobox/clear/ComboboxClearDataAttributes.js +4 -0
  39. package/combobox/icon/ComboboxIcon.js +1 -1
  40. package/combobox/input/ComboboxInput.js +15 -6
  41. package/combobox/item/ComboboxItem.js +8 -14
  42. package/combobox/item-indicator/ComboboxItemIndicator.js +1 -2
  43. package/combobox/root/AriaCombobox.js +61 -28
  44. package/combobox/store.d.ts +4 -8
  45. package/combobox/store.js +2 -1
  46. package/combobox/utils/ComboboxInternalDismissButton.js +2 -3
  47. package/csp-provider/CSPProvider.js +1 -1
  48. package/dialog/close/DialogClose.js +6 -6
  49. package/dialog/popup/DialogPopup.js +9 -4
  50. package/dialog/root/DialogRoot.d.ts +1 -2
  51. package/dialog/root/DialogRoot.js +3 -73
  52. package/dialog/root/DialogRootContext.d.ts +1 -0
  53. package/dialog/root/DialogRootContext.js +3 -1
  54. package/dialog/root/useDialogRoot.d.ts +12 -4
  55. package/dialog/root/useDialogRoot.js +27 -25
  56. package/dialog/root/useRenderDialogRoot.d.ts +4 -0
  57. package/dialog/root/useRenderDialogRoot.js +96 -0
  58. package/dialog/store/DialogHandle.d.ts +1 -1
  59. package/dialog/store/DialogHandle.js +2 -2
  60. package/dialog/store/DialogStore.d.ts +88 -1
  61. package/dialog/store/DialogStore.js +12 -17
  62. package/dialog/trigger/DialogTrigger.d.ts +1 -1
  63. package/dialog/trigger/DialogTrigger.js +11 -4
  64. package/dialog/viewport/DialogViewport.js +4 -3
  65. package/drawer/popup/DrawerPopup.js +13 -9
  66. package/drawer/root/DrawerRoot.js +11 -11
  67. package/drawer/root/DrawerRootContext.d.ts +1 -1
  68. package/drawer/swipe-area/DrawerSwipeArea.js +6 -5
  69. package/drawer/viewport/DrawerViewport.js +13 -14
  70. package/esm/accordion/item/AccordionItem.d.ts +4 -0
  71. package/esm/accordion/item/AccordionItem.js +5 -4
  72. package/esm/accordion/panel/AccordionPanel.js +29 -51
  73. package/esm/accordion/root/AccordionRoot.js +5 -6
  74. package/esm/accordion/trigger/AccordionTrigger.js +4 -5
  75. package/esm/alert-dialog/handle.d.ts +14 -1
  76. package/esm/alert-dialog/handle.js +20 -5
  77. package/esm/alert-dialog/index.d.ts +1 -1
  78. package/esm/alert-dialog/index.parts.d.ts +2 -3
  79. package/esm/alert-dialog/index.parts.js +2 -3
  80. package/esm/alert-dialog/root/AlertDialogRoot.d.ts +7 -7
  81. package/esm/alert-dialog/root/AlertDialogRoot.js +2 -55
  82. package/esm/alert-dialog/trigger/AlertDialogTrigger.d.ts +25 -0
  83. package/esm/alert-dialog/trigger/AlertDialogTrigger.js +10 -0
  84. package/esm/alert-dialog/trigger/AlertDialogTriggerDataAttributes.d.ts +10 -0
  85. package/esm/alert-dialog/trigger/AlertDialogTriggerDataAttributes.js +12 -0
  86. package/esm/autocomplete/root/AutocompleteRoot.js +9 -10
  87. package/esm/avatar/image/AvatarImage.js +4 -4
  88. package/esm/checkbox/indicator/CheckboxIndicator.js +2 -2
  89. package/esm/checkbox/root/CheckboxRoot.js +49 -11
  90. package/esm/checkbox-group/CheckboxGroup.js +1 -5
  91. package/esm/collapsible/panel/CollapsiblePanel.js +29 -51
  92. package/esm/collapsible/panel/useCollapsiblePanel.d.ts +9 -23
  93. package/esm/collapsible/panel/useCollapsiblePanel.js +309 -269
  94. package/esm/collapsible/root/CollapsibleRoot.d.ts +1 -1
  95. package/esm/collapsible/root/CollapsibleRootContext.d.ts +0 -2
  96. package/esm/collapsible/root/useCollapsibleRoot.d.ts +0 -27
  97. package/esm/collapsible/root/useCollapsibleRoot.js +2 -64
  98. package/esm/collapsible/trigger/CollapsibleTrigger.js +5 -6
  99. package/esm/combobox/arrow/ComboboxArrow.js +1 -1
  100. package/esm/combobox/backdrop/ComboboxBackdrop.js +1 -1
  101. package/esm/combobox/chip/ComboboxChip.js +7 -2
  102. package/esm/combobox/clear/ComboboxClear.d.ts +4 -0
  103. package/esm/combobox/clear/ComboboxClear.js +1 -0
  104. package/esm/combobox/clear/ComboboxClearDataAttributes.d.ts +4 -0
  105. package/esm/combobox/clear/ComboboxClearDataAttributes.js +4 -0
  106. package/esm/combobox/icon/ComboboxIcon.js +1 -1
  107. package/esm/combobox/input/ComboboxInput.js +16 -7
  108. package/esm/combobox/item/ComboboxItem.js +8 -14
  109. package/esm/combobox/item-indicator/ComboboxItemIndicator.js +1 -2
  110. package/esm/combobox/root/AriaCombobox.js +62 -29
  111. package/esm/combobox/store.d.ts +4 -8
  112. package/esm/combobox/store.js +2 -1
  113. package/esm/combobox/utils/ComboboxInternalDismissButton.js +2 -3
  114. package/esm/csp-provider/CSPProvider.js +1 -1
  115. package/esm/dialog/close/DialogClose.js +6 -6
  116. package/esm/dialog/popup/DialogPopup.js +9 -4
  117. package/esm/dialog/root/DialogRoot.d.ts +1 -2
  118. package/esm/dialog/root/DialogRoot.js +4 -72
  119. package/esm/dialog/root/DialogRootContext.d.ts +1 -0
  120. package/esm/dialog/root/DialogRootContext.js +2 -0
  121. package/esm/dialog/root/useDialogRoot.d.ts +12 -4
  122. package/esm/dialog/root/useDialogRoot.js +28 -27
  123. package/esm/dialog/root/useRenderDialogRoot.d.ts +4 -0
  124. package/esm/dialog/root/useRenderDialogRoot.js +90 -0
  125. package/esm/dialog/store/DialogHandle.d.ts +1 -1
  126. package/esm/dialog/store/DialogHandle.js +2 -2
  127. package/esm/dialog/store/DialogStore.d.ts +88 -1
  128. package/esm/dialog/store/DialogStore.js +13 -18
  129. package/esm/dialog/trigger/DialogTrigger.d.ts +1 -1
  130. package/esm/dialog/trigger/DialogTrigger.js +12 -5
  131. package/esm/dialog/viewport/DialogViewport.js +4 -3
  132. package/esm/drawer/popup/DrawerPopup.js +14 -9
  133. package/esm/drawer/root/DrawerRoot.js +11 -11
  134. package/esm/drawer/root/DrawerRootContext.d.ts +1 -1
  135. package/esm/drawer/swipe-area/DrawerSwipeArea.js +6 -5
  136. package/esm/drawer/viewport/DrawerViewport.js +13 -14
  137. package/esm/field/control/FieldControl.js +2 -6
  138. package/esm/field/item/FieldItem.js +1 -4
  139. package/esm/field/root/FieldRoot.js +11 -3
  140. package/esm/field/root/useFieldValidation.d.ts +1 -0
  141. package/esm/field/root/useFieldValidation.js +23 -20
  142. package/esm/field/utils/getCombinedFieldValidityData.d.ts +1 -1
  143. package/esm/field/validity/FieldValidity.d.ts +1 -1
  144. package/esm/floating-ui-react/components/FloatingDelayGroup.js +3 -3
  145. package/esm/floating-ui-react/components/FloatingFocusManager.d.ts +1 -1
  146. package/esm/floating-ui-react/components/FloatingFocusManager.js +20 -8
  147. package/esm/floating-ui-react/components/FloatingPortal.js +3 -3
  148. package/esm/floating-ui-react/hooks/useClick.js +83 -74
  149. package/esm/floating-ui-react/hooks/useClientPoint.js +29 -20
  150. package/esm/floating-ui-react/hooks/useDismiss.d.ts +1 -1
  151. package/esm/floating-ui-react/hooks/useDismiss.js +82 -93
  152. package/esm/floating-ui-react/hooks/useFloating.js +37 -32
  153. package/esm/floating-ui-react/hooks/useFloatingRootContext.d.ts +1 -1
  154. package/esm/floating-ui-react/hooks/useFloatingRootContext.js +2 -2
  155. package/esm/floating-ui-react/hooks/useFocus.js +84 -81
  156. package/esm/floating-ui-react/hooks/useHover.js +72 -76
  157. package/esm/floating-ui-react/hooks/useHoverFloatingInteraction.js +49 -44
  158. package/esm/floating-ui-react/hooks/useHoverInteractionSharedState.js +1 -1
  159. package/esm/floating-ui-react/hooks/useHoverReferenceInteraction.d.ts +7 -2
  160. package/esm/floating-ui-react/hooks/useHoverReferenceInteraction.js +44 -39
  161. package/esm/floating-ui-react/hooks/useHoverShared.d.ts +2 -1
  162. package/esm/floating-ui-react/hooks/useHoverShared.js +4 -0
  163. package/esm/floating-ui-react/hooks/useListNavigation.d.ts +1 -3
  164. package/esm/floating-ui-react/hooks/useListNavigation.js +83 -74
  165. package/esm/floating-ui-react/hooks/useSyncedFloatingRootContext.d.ts +9 -6
  166. package/esm/floating-ui-react/hooks/useSyncedFloatingRootContext.js +25 -20
  167. package/esm/floating-ui-react/hooks/useTypeahead.d.ts +2 -2
  168. package/esm/floating-ui-react/hooks/useTypeahead.js +33 -52
  169. package/esm/floating-ui-react/index.d.ts +0 -2
  170. package/esm/floating-ui-react/index.js +0 -2
  171. package/esm/floating-ui-react/types.d.ts +2 -7
  172. package/esm/floating-ui-react/utils/composite.js +2 -0
  173. package/esm/floating-ui-react/utils/enqueueFocus.d.ts +1 -1
  174. package/esm/floating-ui-react/utils/enqueueFocus.js +10 -7
  175. package/esm/floating-ui-react/utils/getEmptyRootContext.js +1 -1
  176. package/esm/form/Form.js +2 -2
  177. package/esm/index.js +1 -1
  178. package/esm/internals/composite/composite.d.ts +0 -1
  179. package/esm/internals/composite/composite.js +1 -2
  180. package/esm/internals/composite/root/useCompositeRoot.js +2 -2
  181. package/esm/internals/createBaseUIEventDetails.d.ts +2 -0
  182. package/esm/internals/csp-context/index.d.ts +2 -0
  183. package/esm/internals/csp-context/index.js +1 -0
  184. package/esm/internals/field-register-control/index.d.ts +0 -1
  185. package/esm/internals/field-register-control/useFieldControlRegistration.d.ts +2 -1
  186. package/esm/internals/field-register-control/useFieldControlRegistration.js +11 -14
  187. package/esm/internals/field-register-control/useRegisterFieldControl.d.ts +1 -4
  188. package/esm/internals/field-register-control/useRegisterFieldControl.js +6 -11
  189. package/esm/internals/field-root-context/FieldRootContext.d.ts +1 -0
  190. package/esm/internals/field-root-context/FieldRootContext.js +3 -2
  191. package/esm/internals/form-context/FormContext.d.ts +5 -1
  192. package/esm/internals/reason-parts.d.ts +2 -0
  193. package/esm/internals/reason-parts.js +2 -0
  194. package/esm/internals/types.d.ts +1 -0
  195. package/esm/internals/use-button/useButton.js +4 -4
  196. package/esm/internals/usePressAndHold.js +2 -2
  197. package/esm/internals/useRenderElement.js +2 -0
  198. package/esm/menu/arrow/MenuArrow.js +1 -1
  199. package/esm/menu/backdrop/MenuBackdrop.js +1 -1
  200. package/esm/menu/checkbox-item/MenuCheckboxItem.js +5 -7
  201. package/esm/menu/group/MenuGroup.js +1 -4
  202. package/esm/menu/group/MenuGroupContext.d.ts +1 -3
  203. package/esm/menu/group/MenuGroupContext.js +1 -1
  204. package/esm/menu/group-label/MenuGroupLabel.js +4 -6
  205. package/esm/menu/link-item/MenuLinkItem.js +2 -2
  206. package/esm/menu/popup/MenuPopup.js +5 -5
  207. package/esm/menu/radio-group/MenuRadioGroup.js +11 -5
  208. package/esm/menu/radio-item/MenuRadioItem.js +5 -7
  209. package/esm/menu/root/MenuRoot.js +63 -68
  210. package/esm/menu/store/MenuHandle.js +1 -1
  211. package/esm/menu/store/MenuStore.d.ts +87 -0
  212. package/esm/menu/submenu-trigger/MenuSubmenuTrigger.js +8 -5
  213. package/esm/menu/trigger/MenuTrigger.js +13 -10
  214. package/esm/menu/viewport/MenuViewport.d.ts +2 -2
  215. package/esm/menu/viewport/MenuViewport.js +2 -2
  216. package/esm/navigation-menu/arrow/NavigationMenuArrow.js +1 -1
  217. package/esm/navigation-menu/backdrop/NavigationMenuBackdrop.js +1 -1
  218. package/esm/navigation-menu/content/NavigationMenuContent.js +8 -5
  219. package/esm/navigation-menu/icon/NavigationMenuIcon.js +1 -1
  220. package/esm/navigation-menu/item/NavigationMenuItem.js +2 -2
  221. package/esm/navigation-menu/list/NavigationMenuList.js +1 -1
  222. package/esm/navigation-menu/popup/NavigationMenuPopup.js +2 -2
  223. package/esm/navigation-menu/root/NavigationMenuRoot.js +1 -3
  224. package/esm/navigation-menu/trigger/NavigationMenuTrigger.js +24 -17
  225. package/esm/navigation-menu/utils/isOutsideMenuEvent.d.ts +0 -1
  226. package/esm/navigation-menu/utils/isOutsideMenuEvent.js +1 -5
  227. package/esm/navigation-menu/viewport/NavigationMenuViewport.js +2 -3
  228. package/esm/number-field/input/NumberFieldInput.js +3 -5
  229. package/esm/number-field/root/NumberFieldRoot.js +5 -2
  230. package/esm/number-field/scrub-area/NumberFieldScrubArea.js +7 -3
  231. package/esm/otp-field/input/OTPFieldInput.js +43 -29
  232. package/esm/otp-field/root/OTPFieldRoot.d.ts +17 -8
  233. package/esm/otp-field/root/OTPFieldRoot.js +33 -33
  234. package/esm/otp-field/root/OTPFieldRootContext.d.ts +1 -1
  235. package/esm/otp-field/utils/otp.d.ts +5 -4
  236. package/esm/otp-field/utils/otp.js +23 -12
  237. package/esm/popover/arrow/PopoverArrow.js +1 -1
  238. package/esm/popover/backdrop/PopoverBackdrop.js +1 -1
  239. package/esm/popover/close/PopoverClose.js +2 -2
  240. package/esm/popover/description/PopoverDescription.js +1 -7
  241. package/esm/popover/popup/PopoverPopup.d.ts +1 -1
  242. package/esm/popover/popup/PopoverPopup.js +16 -10
  243. package/esm/popover/popup/PopoverPopupDataAttributes.d.ts +1 -1
  244. package/esm/popover/popup/PopoverPopupDataAttributes.js +1 -1
  245. package/esm/popover/positioner/PopoverPositioner.js +5 -5
  246. package/esm/popover/root/PopoverRoot.d.ts +1 -1
  247. package/esm/popover/root/PopoverRoot.js +42 -47
  248. package/esm/popover/store/PopoverHandle.js +1 -1
  249. package/esm/popover/store/PopoverStore.d.ts +91 -4
  250. package/esm/popover/store/PopoverStore.js +17 -18
  251. package/esm/popover/title/PopoverTitle.js +1 -7
  252. package/esm/popover/trigger/PopoverTrigger.js +24 -17
  253. package/esm/popover/viewport/PopoverViewport.d.ts +3 -3
  254. package/esm/popover/viewport/PopoverViewport.js +2 -2
  255. package/esm/popover/viewport/PopoverViewportDataAttributes.d.ts +1 -1
  256. package/esm/popover/viewport/PopoverViewportDataAttributes.js +1 -1
  257. package/esm/preview-card/positioner/PreviewCardPositioner.js +11 -1
  258. package/esm/preview-card/root/PreviewCardRoot.d.ts +1 -1
  259. package/esm/preview-card/root/PreviewCardRoot.js +32 -22
  260. package/esm/preview-card/store/PreviewCardHandle.js +1 -1
  261. package/esm/preview-card/store/PreviewCardStore.d.ts +90 -2
  262. package/esm/preview-card/store/PreviewCardStore.js +19 -31
  263. package/esm/preview-card/trigger/PreviewCardTrigger.js +6 -3
  264. package/esm/preview-card/viewport/PreviewCardViewport.d.ts +2 -2
  265. package/esm/preview-card/viewport/PreviewCardViewport.js +2 -2
  266. package/esm/preview-card/viewport/PreviewCardViewportDataAttributes.d.ts +2 -2
  267. package/esm/preview-card/viewport/PreviewCardViewportDataAttributes.js +2 -2
  268. package/esm/progress/indicator/ProgressIndicator.js +6 -11
  269. package/esm/progress/root/ProgressRoot.d.ts +1 -1
  270. package/esm/radio/root/RadioRoot.js +7 -3
  271. package/esm/radio-group/RadioGroup.js +4 -11
  272. package/esm/radio-group/RadioGroupContext.d.ts +0 -1
  273. package/esm/scroll-area/content/ScrollAreaContent.js +4 -4
  274. package/esm/scroll-area/root/ScrollAreaRoot.js +1 -1
  275. package/esm/scroll-area/scrollbar/ScrollAreaScrollbar.js +16 -20
  276. package/esm/scroll-area/viewport/ScrollAreaViewport.js +6 -10
  277. package/esm/select/arrow/SelectArrow.js +1 -1
  278. package/esm/select/backdrop/SelectBackdrop.js +1 -1
  279. package/esm/select/group/SelectGroup.js +1 -1
  280. package/esm/select/group-label/SelectGroupLabel.js +2 -2
  281. package/esm/select/icon/SelectIcon.js +1 -1
  282. package/esm/select/item/SelectItem.js +46 -32
  283. package/esm/select/item/SelectItemContext.d.ts +1 -1
  284. package/esm/select/item-indicator/SelectItemIndicator.js +1 -2
  285. package/esm/select/item-text/SelectItemText.js +9 -6
  286. package/esm/select/list/SelectList.js +1 -1
  287. package/esm/select/popup/SelectPopup.js +8 -3
  288. package/esm/select/positioner/SelectPositioner.js +3 -0
  289. package/esm/select/root/SelectRoot.js +46 -40
  290. package/esm/select/root/SelectRootContext.d.ts +4 -5
  291. package/esm/select/store.d.ts +3 -0
  292. package/esm/select/store.js +1 -0
  293. package/esm/select/trigger/SelectTrigger.d.ts +5 -0
  294. package/esm/select/trigger/SelectTrigger.js +19 -33
  295. package/esm/select/trigger/SelectTriggerDataAttributes.d.ts +5 -0
  296. package/esm/select/trigger/SelectTriggerDataAttributes.js +5 -0
  297. package/esm/slider/control/SliderControl.js +10 -12
  298. package/esm/slider/root/SliderRoot.js +1 -4
  299. package/esm/slider/thumb/SliderThumb.js +32 -30
  300. package/esm/slider/value/SliderValue.js +7 -15
  301. package/esm/switch/root/SwitchRoot.js +10 -10
  302. package/esm/switch/thumb/SwitchThumb.js +1 -9
  303. package/esm/tabs/indicator/TabsIndicator.js +14 -19
  304. package/esm/tabs/list/TabsList.js +4 -10
  305. package/esm/tabs/list/TabsListContext.d.ts +2 -1
  306. package/esm/tabs/panel/TabsPanel.js +1 -1
  307. package/esm/tabs/root/TabsRoot.d.ts +16 -1
  308. package/esm/tabs/root/TabsRoot.js +73 -25
  309. package/esm/tabs/root/TabsRootContext.d.ts +0 -2
  310. package/esm/toast/provider/ToastProvider.js +1 -1
  311. package/esm/toast/root/ToastRoot.d.ts +1 -1
  312. package/esm/toast/root/ToastRoot.js +108 -131
  313. package/esm/toast/root/ToastRootDataAttributes.d.ts +1 -1
  314. package/esm/toast/root/ToastRootDataAttributes.js +1 -1
  315. package/esm/toast/store.d.ts +9 -1
  316. package/esm/toast/store.js +19 -13
  317. package/esm/toast/useToastManager.d.ts +1 -1
  318. package/esm/toast/viewport/ToastViewport.js +1 -1
  319. package/esm/toggle/Toggle.js +5 -9
  320. package/esm/toggle-group/ToggleGroup.d.ts +2 -2
  321. package/esm/toggle-group/ToggleGroup.js +6 -13
  322. package/esm/toolbar/link/ToolbarLink.d.ts +1 -1
  323. package/esm/toolbar/link/ToolbarLink.js +1 -2
  324. package/esm/tooltip/arrow/TooltipArrow.js +3 -3
  325. package/esm/tooltip/popup/TooltipPopup.js +5 -4
  326. package/esm/tooltip/root/TooltipRoot.js +35 -26
  327. package/esm/tooltip/store/TooltipHandle.js +1 -1
  328. package/esm/tooltip/store/TooltipStore.d.ts +90 -2
  329. package/esm/tooltip/store/TooltipStore.js +18 -31
  330. package/esm/tooltip/trigger/TooltipTrigger.js +151 -20
  331. package/esm/tooltip/viewport/TooltipViewport.d.ts +2 -2
  332. package/esm/tooltip/viewport/TooltipViewport.js +2 -2
  333. package/esm/tooltip/viewport/TooltipViewportDataAttributes.d.ts +1 -1
  334. package/esm/tooltip/viewport/TooltipViewportDataAttributes.js +1 -1
  335. package/esm/unstable-use-media-query/index.js +1 -1
  336. package/esm/utils/popups/index.d.ts +1 -0
  337. package/esm/utils/popups/index.js +1 -0
  338. package/esm/utils/popups/inlineRect.d.ts +15 -0
  339. package/esm/utils/popups/inlineRect.js +191 -0
  340. package/esm/utils/popups/popupStoreUtils.d.ts +28 -10
  341. package/esm/utils/popups/popupStoreUtils.js +105 -20
  342. package/esm/utils/popups/popupTriggerMap.js +2 -0
  343. package/esm/utils/popups/store.d.ts +15 -2
  344. package/esm/utils/popups/store.js +38 -2
  345. package/esm/utils/popups/useTriggerFocusGuards.js +4 -5
  346. package/esm/utils/useAnchorPositioning.d.ts +5 -0
  347. package/esm/utils/useAnchorPositioning.js +12 -9
  348. package/esm/utils/useOpenInteractionType.d.ts +4 -0
  349. package/esm/utils/useOpenInteractionType.js +23 -18
  350. package/field/control/FieldControl.js +2 -6
  351. package/field/item/FieldItem.js +1 -4
  352. package/field/root/FieldRoot.js +11 -3
  353. package/field/root/useFieldValidation.d.ts +1 -0
  354. package/field/root/useFieldValidation.js +23 -20
  355. package/field/utils/getCombinedFieldValidityData.d.ts +1 -1
  356. package/field/validity/FieldValidity.d.ts +1 -1
  357. package/floating-ui-react/components/FloatingDelayGroup.js +3 -3
  358. package/floating-ui-react/components/FloatingFocusManager.d.ts +1 -1
  359. package/floating-ui-react/components/FloatingFocusManager.js +20 -8
  360. package/floating-ui-react/components/FloatingPortal.js +3 -3
  361. package/floating-ui-react/hooks/useClick.js +82 -73
  362. package/floating-ui-react/hooks/useClientPoint.js +29 -20
  363. package/floating-ui-react/hooks/useDismiss.d.ts +1 -1
  364. package/floating-ui-react/hooks/useDismiss.js +82 -92
  365. package/floating-ui-react/hooks/useFloating.js +36 -32
  366. package/floating-ui-react/hooks/useFloatingRootContext.d.ts +1 -1
  367. package/floating-ui-react/hooks/useFloatingRootContext.js +2 -2
  368. package/floating-ui-react/hooks/useFocus.js +84 -81
  369. package/floating-ui-react/hooks/useHover.js +74 -78
  370. package/floating-ui-react/hooks/useHoverFloatingInteraction.js +48 -43
  371. package/floating-ui-react/hooks/useHoverInteractionSharedState.js +1 -1
  372. package/floating-ui-react/hooks/useHoverReferenceInteraction.d.ts +7 -2
  373. package/floating-ui-react/hooks/useHoverReferenceInteraction.js +43 -38
  374. package/floating-ui-react/hooks/useHoverShared.d.ts +2 -1
  375. package/floating-ui-react/hooks/useHoverShared.js +11 -0
  376. package/floating-ui-react/hooks/useListNavigation.d.ts +1 -3
  377. package/floating-ui-react/hooks/useListNavigation.js +83 -74
  378. package/floating-ui-react/hooks/useSyncedFloatingRootContext.d.ts +9 -6
  379. package/floating-ui-react/hooks/useSyncedFloatingRootContext.js +26 -20
  380. package/floating-ui-react/hooks/useTypeahead.d.ts +2 -2
  381. package/floating-ui-react/hooks/useTypeahead.js +33 -52
  382. package/floating-ui-react/index.d.ts +0 -2
  383. package/floating-ui-react/index.js +0 -14
  384. package/floating-ui-react/types.d.ts +2 -7
  385. package/floating-ui-react/utils/composite.js +2 -0
  386. package/floating-ui-react/utils/enqueueFocus.d.ts +1 -1
  387. package/floating-ui-react/utils/enqueueFocus.js +10 -7
  388. package/floating-ui-react/utils/getEmptyRootContext.js +1 -1
  389. package/form/Form.js +2 -2
  390. package/index.js +1 -1
  391. package/internals/composite/composite.d.ts +0 -1
  392. package/internals/composite/composite.js +2 -3
  393. package/internals/composite/root/useCompositeRoot.js +1 -1
  394. package/internals/createBaseUIEventDetails.d.ts +2 -0
  395. package/internals/csp-context/index.d.ts +2 -0
  396. package/internals/csp-context/index.js +18 -0
  397. package/internals/field-register-control/index.d.ts +0 -1
  398. package/internals/field-register-control/useFieldControlRegistration.d.ts +2 -1
  399. package/internals/field-register-control/useFieldControlRegistration.js +11 -14
  400. package/internals/field-register-control/useRegisterFieldControl.d.ts +1 -4
  401. package/internals/field-register-control/useRegisterFieldControl.js +6 -11
  402. package/internals/field-root-context/FieldRootContext.d.ts +1 -0
  403. package/internals/field-root-context/FieldRootContext.js +4 -3
  404. package/internals/form-context/FormContext.d.ts +5 -1
  405. package/internals/reason-parts.d.ts +2 -0
  406. package/internals/reason-parts.js +3 -1
  407. package/internals/types.d.ts +1 -0
  408. package/internals/use-button/useButton.js +4 -4
  409. package/internals/usePressAndHold.js +2 -2
  410. package/internals/useRenderElement.js +2 -0
  411. package/menu/arrow/MenuArrow.js +1 -1
  412. package/menu/backdrop/MenuBackdrop.js +1 -1
  413. package/menu/checkbox-item/MenuCheckboxItem.js +5 -7
  414. package/menu/group/MenuGroup.js +1 -4
  415. package/menu/group/MenuGroupContext.d.ts +1 -3
  416. package/menu/group/MenuGroupContext.js +1 -1
  417. package/menu/group-label/MenuGroupLabel.js +4 -6
  418. package/menu/link-item/MenuLinkItem.js +2 -2
  419. package/menu/popup/MenuPopup.js +5 -5
  420. package/menu/radio-group/MenuRadioGroup.js +11 -5
  421. package/menu/radio-item/MenuRadioItem.js +5 -7
  422. package/menu/root/MenuRoot.js +60 -65
  423. package/menu/store/MenuHandle.js +1 -1
  424. package/menu/store/MenuStore.d.ts +87 -0
  425. package/menu/submenu-trigger/MenuSubmenuTrigger.js +7 -4
  426. package/menu/trigger/MenuTrigger.js +12 -9
  427. package/menu/viewport/MenuViewport.d.ts +2 -2
  428. package/menu/viewport/MenuViewport.js +2 -2
  429. package/navigation-menu/arrow/NavigationMenuArrow.js +1 -1
  430. package/navigation-menu/backdrop/NavigationMenuBackdrop.js +1 -1
  431. package/navigation-menu/content/NavigationMenuContent.js +8 -5
  432. package/navigation-menu/icon/NavigationMenuIcon.js +1 -1
  433. package/navigation-menu/item/NavigationMenuItem.js +2 -2
  434. package/navigation-menu/list/NavigationMenuList.js +1 -1
  435. package/navigation-menu/popup/NavigationMenuPopup.js +2 -2
  436. package/navigation-menu/root/NavigationMenuRoot.js +1 -3
  437. package/navigation-menu/trigger/NavigationMenuTrigger.js +23 -16
  438. package/navigation-menu/utils/isOutsideMenuEvent.d.ts +0 -1
  439. package/navigation-menu/utils/isOutsideMenuEvent.js +1 -5
  440. package/navigation-menu/viewport/NavigationMenuViewport.js +2 -3
  441. package/number-field/input/NumberFieldInput.js +3 -5
  442. package/number-field/root/NumberFieldRoot.js +5 -2
  443. package/number-field/scrub-area/NumberFieldScrubArea.js +7 -3
  444. package/otp-field/input/OTPFieldInput.js +42 -28
  445. package/otp-field/root/OTPFieldRoot.d.ts +17 -8
  446. package/otp-field/root/OTPFieldRoot.js +32 -32
  447. package/otp-field/root/OTPFieldRootContext.d.ts +1 -1
  448. package/otp-field/utils/otp.d.ts +5 -4
  449. package/otp-field/utils/otp.js +24 -12
  450. package/package.json +331 -317
  451. package/popover/arrow/PopoverArrow.js +1 -1
  452. package/popover/backdrop/PopoverBackdrop.js +1 -1
  453. package/popover/close/PopoverClose.js +2 -2
  454. package/popover/description/PopoverDescription.js +1 -7
  455. package/popover/popup/PopoverPopup.d.ts +1 -1
  456. package/popover/popup/PopoverPopup.js +16 -10
  457. package/popover/popup/PopoverPopupDataAttributes.d.ts +1 -1
  458. package/popover/popup/PopoverPopupDataAttributes.js +1 -1
  459. package/popover/positioner/PopoverPositioner.js +5 -5
  460. package/popover/root/PopoverRoot.d.ts +1 -1
  461. package/popover/root/PopoverRoot.js +39 -44
  462. package/popover/store/PopoverHandle.js +1 -1
  463. package/popover/store/PopoverStore.d.ts +91 -4
  464. package/popover/store/PopoverStore.js +16 -19
  465. package/popover/title/PopoverTitle.js +1 -7
  466. package/popover/trigger/PopoverTrigger.js +23 -16
  467. package/popover/viewport/PopoverViewport.d.ts +3 -3
  468. package/popover/viewport/PopoverViewport.js +2 -2
  469. package/popover/viewport/PopoverViewportDataAttributes.d.ts +1 -1
  470. package/popover/viewport/PopoverViewportDataAttributes.js +1 -1
  471. package/preview-card/positioner/PreviewCardPositioner.js +11 -1
  472. package/preview-card/root/PreviewCardRoot.d.ts +1 -1
  473. package/preview-card/root/PreviewCardRoot.js +30 -20
  474. package/preview-card/store/PreviewCardHandle.js +1 -1
  475. package/preview-card/store/PreviewCardStore.d.ts +90 -2
  476. package/preview-card/store/PreviewCardStore.js +18 -30
  477. package/preview-card/trigger/PreviewCardTrigger.js +5 -2
  478. package/preview-card/viewport/PreviewCardViewport.d.ts +2 -2
  479. package/preview-card/viewport/PreviewCardViewport.js +2 -2
  480. package/preview-card/viewport/PreviewCardViewportDataAttributes.d.ts +2 -2
  481. package/preview-card/viewport/PreviewCardViewportDataAttributes.js +2 -2
  482. package/progress/indicator/ProgressIndicator.js +6 -11
  483. package/progress/root/ProgressRoot.d.ts +1 -1
  484. package/radio/root/RadioRoot.js +7 -3
  485. package/radio-group/RadioGroup.js +4 -11
  486. package/radio-group/RadioGroupContext.d.ts +0 -1
  487. package/scroll-area/content/ScrollAreaContent.js +4 -4
  488. package/scroll-area/root/ScrollAreaRoot.js +1 -1
  489. package/scroll-area/scrollbar/ScrollAreaScrollbar.js +16 -20
  490. package/scroll-area/viewport/ScrollAreaViewport.js +6 -10
  491. package/select/arrow/SelectArrow.js +1 -1
  492. package/select/backdrop/SelectBackdrop.js +1 -1
  493. package/select/group/SelectGroup.js +1 -1
  494. package/select/group-label/SelectGroupLabel.js +2 -2
  495. package/select/icon/SelectIcon.js +1 -1
  496. package/select/item/SelectItem.js +46 -32
  497. package/select/item/SelectItemContext.d.ts +1 -1
  498. package/select/item-indicator/SelectItemIndicator.js +1 -2
  499. package/select/item-text/SelectItemText.js +9 -6
  500. package/select/list/SelectList.js +1 -1
  501. package/select/popup/SelectPopup.js +8 -3
  502. package/select/positioner/SelectPositioner.js +3 -0
  503. package/select/root/SelectRoot.js +45 -39
  504. package/select/root/SelectRootContext.d.ts +4 -5
  505. package/select/store.d.ts +3 -0
  506. package/select/store.js +1 -0
  507. package/select/trigger/SelectTrigger.d.ts +5 -0
  508. package/select/trigger/SelectTrigger.js +19 -33
  509. package/select/trigger/SelectTriggerDataAttributes.d.ts +5 -0
  510. package/select/trigger/SelectTriggerDataAttributes.js +5 -0
  511. package/slider/control/SliderControl.js +9 -11
  512. package/slider/root/SliderRoot.js +1 -4
  513. package/slider/thumb/SliderThumb.js +32 -30
  514. package/slider/value/SliderValue.js +7 -15
  515. package/switch/root/SwitchRoot.js +10 -10
  516. package/switch/thumb/SwitchThumb.js +1 -9
  517. package/tabs/indicator/TabsIndicator.js +14 -19
  518. package/tabs/list/TabsList.js +4 -10
  519. package/tabs/list/TabsListContext.d.ts +2 -1
  520. package/tabs/panel/TabsPanel.js +1 -1
  521. package/tabs/root/TabsRoot.d.ts +16 -1
  522. package/tabs/root/TabsRoot.js +71 -24
  523. package/tabs/root/TabsRootContext.d.ts +0 -2
  524. package/toast/provider/ToastProvider.js +1 -1
  525. package/toast/root/ToastRoot.d.ts +1 -1
  526. package/toast/root/ToastRoot.js +110 -133
  527. package/toast/root/ToastRootDataAttributes.d.ts +1 -1
  528. package/toast/root/ToastRootDataAttributes.js +1 -1
  529. package/toast/store.d.ts +9 -1
  530. package/toast/store.js +18 -12
  531. package/toast/useToastManager.d.ts +1 -1
  532. package/toast/viewport/ToastViewport.js +1 -1
  533. package/toggle/Toggle.js +5 -9
  534. package/toggle-group/ToggleGroup.d.ts +2 -2
  535. package/toggle-group/ToggleGroup.js +6 -13
  536. package/toolbar/link/ToolbarLink.d.ts +1 -1
  537. package/toolbar/link/ToolbarLink.js +1 -2
  538. package/tooltip/arrow/TooltipArrow.js +3 -3
  539. package/tooltip/popup/TooltipPopup.js +5 -4
  540. package/tooltip/root/TooltipRoot.js +32 -23
  541. package/tooltip/store/TooltipHandle.js +1 -1
  542. package/tooltip/store/TooltipStore.d.ts +90 -2
  543. package/tooltip/store/TooltipStore.js +17 -30
  544. package/tooltip/trigger/TooltipTrigger.js +152 -20
  545. package/tooltip/viewport/TooltipViewport.d.ts +2 -2
  546. package/tooltip/viewport/TooltipViewport.js +2 -2
  547. package/tooltip/viewport/TooltipViewportDataAttributes.d.ts +1 -1
  548. package/tooltip/viewport/TooltipViewportDataAttributes.js +1 -1
  549. package/unstable-use-media-query/index.js +1 -1
  550. package/utils/popups/index.d.ts +1 -0
  551. package/utils/popups/index.js +11 -0
  552. package/utils/popups/inlineRect.d.ts +15 -0
  553. package/utils/popups/inlineRect.js +198 -0
  554. package/utils/popups/popupStoreUtils.d.ts +28 -10
  555. package/utils/popups/popupStoreUtils.js +110 -20
  556. package/utils/popups/popupTriggerMap.js +2 -0
  557. package/utils/popups/store.d.ts +15 -2
  558. package/utils/popups/store.js +39 -2
  559. package/utils/popups/useTriggerFocusGuards.js +4 -5
  560. package/utils/useAnchorPositioning.d.ts +5 -0
  561. package/utils/useAnchorPositioning.js +12 -9
  562. package/utils/useOpenInteractionType.d.ts +4 -0
  563. package/utils/useOpenInteractionType.js +24 -17
  564. package/checkbox-group/index.parts.d.ts +0 -1
  565. package/checkbox-group/index.parts.js +0 -12
  566. package/esm/checkbox-group/index.parts.d.ts +0 -1
  567. package/esm/checkbox-group/index.parts.js +0 -1
  568. package/esm/floating-ui-react/hooks/useInteractions.d.ts +0 -20
  569. package/esm/floating-ui-react/hooks/useInteractions.js +0 -88
  570. package/esm/floating-ui-react/hooks/useRole.d.ts +0 -17
  571. package/esm/floating-ui-react/hooks/useRole.js +0 -113
  572. package/floating-ui-react/hooks/useInteractions.d.ts +0 -20
  573. package/floating-ui-react/hooks/useInteractions.js +0 -95
  574. package/floating-ui-react/hooks/useRole.d.ts +0 -17
  575. package/floating-ui-react/hooks/useRole.js +0 -120
  576. /package/{csp-provider → esm/internals/csp-context}/CSPContext.d.ts +0 -0
  577. /package/esm/{csp-provider → internals/csp-context}/CSPContext.js +0 -0
  578. /package/{esm/csp-provider → internals/csp-context}/CSPContext.d.ts +0 -0
  579. /package/{csp-provider → internals/csp-context}/CSPContext.js +0 -0
@@ -8,7 +8,6 @@ Object.defineProperty(exports, "__esModule", {
8
8
  exports.SelectItem = void 0;
9
9
  var React = _interopRequireWildcard(require("react"));
10
10
  var _useIsoLayoutEffect = require("@base-ui/utils/useIsoLayoutEffect");
11
- var _useValueAsRef = require("@base-ui/utils/useValueAsRef");
12
11
  var _store = require("@base-ui/utils/store");
13
12
  var _SelectRootContext = require("../root/SelectRootContext");
14
13
  var _useCompositeListItem = require("../../internals/composite/list/useCompositeListItem");
@@ -19,6 +18,7 @@ var _useButton = require("../../internals/use-button");
19
18
  var _createBaseUIEventDetails = require("../../internals/createBaseUIEventDetails");
20
19
  var _reasons = require("../../internals/reasons");
21
20
  var _itemEquality = require("../../internals/itemEquality");
21
+ var _event = require("../../floating-ui-react/utils/event");
22
22
  var _jsxRuntime = require("react/jsx-runtime");
23
23
  /**
24
24
  * An individual option in the select popup.
@@ -30,11 +30,11 @@ const SelectItem = exports.SelectItem = /*#__PURE__*/React.memo(/*#__PURE__*/Rea
30
30
  const {
31
31
  render,
32
32
  className,
33
+ style,
33
34
  value: itemValue = null,
34
35
  label,
35
36
  disabled = false,
36
37
  nativeButton = false,
37
- style,
38
38
  ...elementProps
39
39
  } = componentProps;
40
40
  const textRef = React.useRef(null);
@@ -45,7 +45,7 @@ const SelectItem = exports.SelectItem = /*#__PURE__*/React.memo(/*#__PURE__*/Rea
45
45
  });
46
46
  const {
47
47
  store,
48
- getItemProps,
48
+ itemProps,
49
49
  setOpen,
50
50
  setValue,
51
51
  selectionRef,
@@ -61,7 +61,6 @@ const SelectItem = exports.SelectItem = /*#__PURE__*/React.memo(/*#__PURE__*/Rea
61
61
  const index = listItem.index;
62
62
  const hasRegistered = index !== -1;
63
63
  const itemRef = React.useRef(null);
64
- const indexRef = (0, _useValueAsRef.useValueAsRef)(index);
65
64
  (0, _useIsoLayoutEffect.useIsoLayoutEffect)(() => {
66
65
  if (!hasRegistered) {
67
66
  return undefined;
@@ -90,19 +89,9 @@ const SelectItem = exports.SelectItem = /*#__PURE__*/React.memo(/*#__PURE__*/Rea
90
89
  }
91
90
  }
92
91
  }, [hasRegistered, index, multiple, isItemEqualToValue, store, itemValue, selectedItemTextRef]);
93
- const state = {
94
- disabled,
95
- selected,
96
- highlighted
97
- };
98
- const rootProps = getItemProps({
99
- active: highlighted,
100
- selected
101
- });
102
- rootProps.id = undefined;
103
92
  const lastKeyRef = React.useRef(null);
104
93
  const pointerTypeRef = React.useRef('mouse');
105
- const didPointerDownRef = React.useRef(false);
94
+ const allowMouseSelectionRef = React.useRef(false);
106
95
  const {
107
96
  getButtonProps,
108
97
  buttonRef
@@ -112,6 +101,11 @@ const SelectItem = exports.SelectItem = /*#__PURE__*/React.memo(/*#__PURE__*/Rea
112
101
  native: nativeButton,
113
102
  composite: true
114
103
  });
104
+ const state = {
105
+ disabled,
106
+ selected,
107
+ highlighted
108
+ };
115
109
  function commitSelection(event) {
116
110
  const selectedValue = store.state.value;
117
111
  if (multiple) {
@@ -123,16 +117,13 @@ const SelectItem = exports.SelectItem = /*#__PURE__*/React.memo(/*#__PURE__*/Rea
123
117
  setOpen(false, (0, _createBaseUIEventDetails.createChangeEventDetails)(_reasons.REASONS.itemPress, event));
124
118
  }
125
119
  }
120
+ function resetDragMovement() {
121
+ selectionRef.current.dragY = 0;
122
+ }
126
123
  const defaultProps = {
127
124
  role: 'option',
128
125
  'aria-selected': selected,
129
126
  tabIndex: highlighted ? 0 : -1,
130
- onTouchStart() {
131
- selectionRef.current = {
132
- allowSelectedMouseUp: false,
133
- allowUnselectedMouseUp: false
134
- };
135
- },
136
127
  onKeyDown(event) {
137
128
  lastKeyRef.current = event.key;
138
129
  store.set('activeIndex', index);
@@ -141,13 +132,24 @@ const SelectItem = exports.SelectItem = /*#__PURE__*/React.memo(/*#__PURE__*/Rea
141
132
  }
142
133
  },
143
134
  onClick(event) {
144
- didPointerDownRef.current = false;
135
+ const isMouseClick = event.type === 'click' && pointerTypeRef.current !== 'touch';
136
+ const clickPointerType = event.nativeEvent.pointerType;
137
+ const isVirtualMouseClick = isMouseClick && (0, _event.isVirtualClick)(event.nativeEvent) && (
138
+ // Generic no-pointer `detail === 0` clicks stay tied to highlight state. Virtual
139
+ // clicks that carry browser pointer data, including an empty string from assistive
140
+ // technology, can activate unhighlighted items.
141
+ clickPointerType !== undefined || highlighted);
142
+ // With alignItemWithTrigger, opening can place an item under the cursor. Real mouse
143
+ // clicks must start on the item, while virtual clicks represent explicit keyboard or
144
+ // assistive technology activation.
145
+ const isInvalidMouseClick = isMouseClick && !isVirtualMouseClick && !allowMouseSelectionRef.current;
146
+ allowMouseSelectionRef.current = false;
145
147
 
146
148
  // Prevent double commit on {Enter}
147
149
  if (event.type === 'keydown' && lastKeyRef.current === null) {
148
150
  return;
149
151
  }
150
- if (disabled || event.type === 'keydown' && lastKeyRef.current === ' ' && typingRef.current || pointerTypeRef.current !== 'touch' && !highlighted) {
152
+ if (disabled || event.type === 'keydown' && lastKeyRef.current === ' ' && typingRef.current || isInvalidMouseClick) {
151
153
  return;
152
154
  }
153
155
  lastKeyRef.current = null;
@@ -156,40 +158,52 @@ const SelectItem = exports.SelectItem = /*#__PURE__*/React.memo(/*#__PURE__*/Rea
156
158
  onPointerEnter(event) {
157
159
  pointerTypeRef.current = event.pointerType;
158
160
  },
161
+ onPointerMove(event) {
162
+ if (event.pointerType === 'mouse' && event.buttons === 1) {
163
+ const selection = selectionRef.current;
164
+ selection.dragY += event.movementY;
165
+ if (selection.dragY ** 2 >= 64) {
166
+ selection.allowUnselectedMouseUp = true;
167
+ }
168
+ }
169
+ },
159
170
  onPointerDown(event) {
160
171
  pointerTypeRef.current = event.pointerType;
161
- didPointerDownRef.current = true;
172
+ allowMouseSelectionRef.current = true;
173
+ resetDragMovement();
162
174
  },
163
175
  onMouseUp() {
164
- if (disabled) {
176
+ resetDragMovement();
177
+ if (disabled || pointerTypeRef.current === 'touch') {
165
178
  return;
166
179
  }
167
180
 
168
- // Regular click (pointerdown on this element) if didPointerDownRef is set, otherwise drag-to-select
169
- if (didPointerDownRef.current) {
170
- didPointerDownRef.current = false;
181
+ // Regular clicks are committed by the click event.
182
+ if (allowMouseSelectionRef.current) {
171
183
  return;
172
184
  }
173
185
  const disallowSelectedMouseUp = !selectionRef.current.allowSelectedMouseUp && selected;
174
186
  const disallowUnselectedMouseUp = !selectionRef.current.allowUnselectedMouseUp && !selected;
175
- if (disallowSelectedMouseUp || disallowUnselectedMouseUp || pointerTypeRef.current !== 'touch' && !highlighted) {
187
+ if (disallowSelectedMouseUp || disallowUnselectedMouseUp) {
176
188
  return;
177
189
  }
190
+ allowMouseSelectionRef.current = true;
178
191
  itemRef.current?.click();
192
+ allowMouseSelectionRef.current = false;
179
193
  }
180
194
  };
181
195
  const element = (0, _useRenderElement.useRenderElement)('div', componentProps, {
182
196
  ref: [buttonRef, forwardedRef, listItem.ref, itemRef],
183
197
  state,
184
- props: [rootProps, defaultProps, elementProps, getButtonProps]
198
+ props: [itemProps, defaultProps, elementProps, getButtonProps]
185
199
  });
186
200
  const contextValue = React.useMemo(() => ({
187
201
  selected,
188
- indexRef,
202
+ index,
189
203
  textRef,
190
204
  selectedByFocus,
191
205
  hasRegistered
192
- }), [selected, indexRef, textRef, selectedByFocus, hasRegistered]);
206
+ }), [selected, index, textRef, selectedByFocus, hasRegistered]);
193
207
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_SelectItemContext.SelectItemContext.Provider, {
194
208
  value: contextValue,
195
209
  children: element
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  export interface SelectItemContext {
3
3
  selected: boolean;
4
- indexRef: React.RefObject<number>;
4
+ index: number;
5
5
  textRef: React.RefObject<HTMLElement | null>;
6
6
  selectedByFocus: boolean;
7
7
  hasRegistered: boolean;
@@ -36,8 +36,7 @@ const SelectItemIndicator = exports.SelectItemIndicator = /*#__PURE__*/React.for
36
36
  });
37
37
  });
38
38
 
39
- /** The core implementation of the indicator is split here to avoid paying the hooks
40
- * costs unless the element needs to be mounted. */
39
+ // Split the core implementation to avoid paying the hook costs unless the element needs to mount.
41
40
  if (process.env.NODE_ENV !== "production") SelectItemIndicator.displayName = "SelectItemIndicator";
42
41
  const Inner = /*#__PURE__*/React.memo(/*#__PURE__*/React.forwardRef((componentProps, forwardedRef) => {
43
42
  const {
@@ -18,29 +18,32 @@ var _useRenderElement = require("../../internals/useRenderElement");
18
18
  */
19
19
  const SelectItemText = exports.SelectItemText = /*#__PURE__*/React.memo(/*#__PURE__*/React.forwardRef(function SelectItemText(componentProps, forwardedRef) {
20
20
  const {
21
- indexRef,
21
+ index,
22
22
  textRef,
23
23
  selectedByFocus,
24
24
  hasRegistered
25
25
  } = (0, _SelectItemContext.useSelectItemContext)();
26
26
  const {
27
+ firstItemTextRef,
27
28
  selectedItemTextRef
28
29
  } = (0, _SelectRootContext.useSelectRootContext)();
29
30
  const {
30
- className,
31
31
  render,
32
+ className,
32
33
  style,
33
34
  ...elementProps
34
35
  } = componentProps;
35
36
  const localRef = React.useCallback(node => {
36
- if (!node || !hasRegistered) {
37
+ if (!node) {
37
38
  return;
38
39
  }
39
- const hasNoSelectedItemText = selectedItemTextRef.current === null || !selectedItemTextRef.current.isConnected;
40
- if (selectedByFocus || hasNoSelectedItemText && indexRef.current === 0) {
40
+ if (hasRegistered && index === 0) {
41
+ firstItemTextRef.current = node;
42
+ }
43
+ if (hasRegistered && selectedByFocus) {
41
44
  selectedItemTextRef.current = node;
42
45
  }
43
- }, [selectedItemTextRef, indexRef, selectedByFocus, hasRegistered]);
46
+ }, [firstItemTextRef, selectedItemTextRef, index, selectedByFocus, hasRegistered]);
44
47
  const element = (0, _useRenderElement.useRenderElement)('div', componentProps, {
45
48
  ref: [localRef, forwardedRef, textRef],
46
49
  props: elementProps
@@ -23,8 +23,8 @@ var _store2 = require("../store");
23
23
  */
24
24
  const SelectList = exports.SelectList = /*#__PURE__*/React.forwardRef(function SelectList(componentProps, forwardedRef) {
25
25
  const {
26
- className,
27
26
  render,
27
+ className,
28
28
  style,
29
29
  ...elementProps
30
30
  } = componentProps;
@@ -32,7 +32,7 @@ var _composite = require("../../internals/composite/composite");
32
32
  var _getDisabledMountTransitionStyles = require("../../utils/getDisabledMountTransitionStyles");
33
33
  var _clamp = require("../../internals/clamp");
34
34
  var _scrollEdges = require("../../utils/scrollEdges");
35
- var _CSPContext = require("../../csp-provider/CSPContext");
35
+ var _CSPContext = require("../../internals/csp-context/CSPContext");
36
36
  var _DirectionContext = require("../../internals/direction-context/DirectionContext");
37
37
  var _jsxRuntime = require("react/jsx-runtime");
38
38
  const stateAttributesMapping = {
@@ -60,6 +60,7 @@ const SelectPopup = exports.SelectPopup = /*#__PURE__*/React.forwardRef(function
60
60
  onOpenChangeComplete,
61
61
  setOpen,
62
62
  valueRef,
63
+ firstItemTextRef,
63
64
  selectedItemTextRef,
64
65
  keyboardActiveRef,
65
66
  multiple,
@@ -239,7 +240,11 @@ const SelectPopup = exports.SelectPopup = /*#__PURE__*/React.forwardRef(function
239
240
  const restoreTransformStyles = unsetTransformStyles(popupElement);
240
241
  popupElement.style.removeProperty('--transform-origin');
241
242
  try {
242
- const textElement = selectedItemTextRef.current;
243
+ let textElement = selectedItemTextRef.current;
244
+ if (!textElement?.isConnected) {
245
+ const hasSelectedValue = _store2.selectors.hasSelectedValue(store.state);
246
+ textElement = !hasSelectedValue && firstItemTextRef.current?.isConnected ? firstItemTextRef.current : null;
247
+ }
243
248
  const valueElement = valueRef.current;
244
249
  const positionerStyles = getComputedStyle(positionerElement);
245
250
  const popupStyles = getComputedStyle(popupElement);
@@ -331,7 +336,7 @@ const SelectPopup = exports.SelectPopup = /*#__PURE__*/React.forwardRef(function
331
336
  } finally {
332
337
  restoreTransformStyles();
333
338
  }
334
- }, [store, open, positionerElement, triggerElement, valueRef, selectedItemTextRef, popupRef, handleScrollArrowVisibility, alignItemWithTriggerActive, setControlledAlignItemWithTrigger, scrollArrowFrame, scrollDownArrowRef, scrollUpArrowRef, listElement, listRef, highlightItemOnHover, direction, isPositioned]);
339
+ }, [store, open, positionerElement, triggerElement, valueRef, firstItemTextRef, selectedItemTextRef, popupRef, handleScrollArrowVisibility, alignItemWithTriggerActive, setControlledAlignItemWithTrigger, scrollArrowFrame, scrollDownArrowRef, scrollUpArrowRef, listElement, listRef, highlightItemOnHover, direction, isPositioned]);
335
340
  React.useEffect(() => {
336
341
  if (!alignItemWithTriggerActive || !positionerElement || !open) {
337
342
  return undefined;
@@ -120,6 +120,9 @@ const SelectPositioner = exports.SelectPositioner = /*#__PURE__*/React.forwardRe
120
120
  align: positioning.align,
121
121
  anchorHidden: positioning.anchorHidden
122
122
  };
123
+ (0, _useIsoLayoutEffect.useIsoLayoutEffect)(() => {
124
+ store.set('popupSide', positioning.side);
125
+ }, [store, positioning.side]);
123
126
  const setPositionerElement = (0, _useStableCallback.useStableCallback)(element => {
124
127
  store.set('positionerElement', element);
125
128
  });
@@ -34,6 +34,7 @@ var _itemEquality = require("../../internals/itemEquality");
34
34
  var _useValueChanged = require("../../internals/useValueChanged");
35
35
  var _useOpenInteractionType = require("../../utils/useOpenInteractionType");
36
36
  var _scrollEdges = require("../../utils/scrollEdges");
37
+ var _popups = require("../../utils/popups");
37
38
  var _mergeProps = require("../../merge-props");
38
39
  var _jsxRuntime = require("react/jsx-runtime");
39
40
  /**
@@ -110,10 +111,12 @@ function SelectRoot(props) {
110
111
  const valuesRef = React.useRef([]);
111
112
  const typingRef = React.useRef(false);
112
113
  const keyboardActiveRef = React.useRef(false);
114
+ const firstItemTextRef = React.useRef(null);
113
115
  const selectedItemTextRef = React.useRef(null);
114
116
  const selectionRef = React.useRef({
115
117
  allowSelectedMouseUp: false,
116
- allowUnselectedMouseUp: false
118
+ allowUnselectedMouseUp: false,
119
+ dragY: 0
117
120
  });
118
121
  const alignItemWithTriggerActiveRef = React.useRef(false);
119
122
  const {
@@ -147,6 +150,7 @@ function SelectRoot(props) {
147
150
  triggerElement: null,
148
151
  positionerElement: null,
149
152
  listElement: null,
153
+ popupSide: null,
150
154
  scrollUpArrowVisible: false,
151
155
  scrollDownArrowVisible: false,
152
156
  hasScrollArrows: false
@@ -170,13 +174,10 @@ function SelectRoot(props) {
170
174
  return (0, _resolveValueLabel.stringifyAsValue)(value, itemToStringValue);
171
175
  }, [multiple, value, itemToStringValue]);
172
176
  const controlRef = (0, _useValueAsRef.useValueAsRef)(store.state.triggerElement);
173
- const getFieldValue = (0, _useStableCallback.useStableCallback)(() => fieldStringValue);
174
- (0, _useRegisterFieldControl.useRegisterFieldControl)(controlRef, {
175
- id: generatedId,
176
- value,
177
- getValue: getFieldValue
178
- });
177
+ const getStringifiedValueForForm = (0, _useStableCallback.useStableCallback)(() => fieldStringValue);
178
+ (0, _useRegisterFieldControl.useRegisterFieldControl)(controlRef, generatedId, value, getStringifiedValueForForm);
179
179
  const initialValueRef = React.useRef(value);
180
+ const hasSelectedValue = multiple ? Array.isArray(value) && value.length > 0 : value != null;
180
181
  (0, _useIsoLayoutEffect.useIsoLayoutEffect)(() => {
181
182
  // Ensure the values and labels are registered for programmatic value changes.
182
183
  if (value !== initialValueRef.current) {
@@ -184,27 +185,32 @@ function SelectRoot(props) {
184
185
  }
185
186
  }, [store, value]);
186
187
  (0, _useIsoLayoutEffect.useIsoLayoutEffect)(() => {
187
- setFilled(multiple ? Array.isArray(value) && value.length > 0 : value != null);
188
- }, [multiple, value, setFilled]);
188
+ setFilled(hasSelectedValue);
189
+ }, [hasSelectedValue, setFilled]);
189
190
  (0, _useIsoLayoutEffect.useIsoLayoutEffect)(function syncSelectedIndex() {
190
- if (open) {
191
- return;
192
- }
193
191
  const registry = valuesRef.current;
192
+ let nextIndex;
194
193
  if (multiple) {
195
194
  const currentValue = Array.isArray(value) ? value : [];
196
195
  if (currentValue.length === 0) {
197
- store.set('selectedIndex', null);
198
- return;
196
+ nextIndex = null;
197
+ } else {
198
+ const lastValue = currentValue[currentValue.length - 1];
199
+ const lastIndex = (0, _itemEquality.findItemIndex)(registry, lastValue, isItemEqualToValue);
200
+ nextIndex = lastIndex === -1 ? null : lastIndex;
199
201
  }
200
- const lastValue = currentValue[currentValue.length - 1];
201
- const lastIndex = (0, _itemEquality.findItemIndex)(registry, lastValue, isItemEqualToValue);
202
- store.set('selectedIndex', lastIndex === -1 ? null : lastIndex);
202
+ } else {
203
+ const index = (0, _itemEquality.findItemIndex)(registry, value, isItemEqualToValue);
204
+ nextIndex = index === -1 ? null : index;
205
+ }
206
+ if (nextIndex === null) {
207
+ selectedItemTextRef.current = null;
208
+ }
209
+ if (open) {
203
210
  return;
204
211
  }
205
- const index = (0, _itemEquality.findItemIndex)(registry, value, isItemEqualToValue);
206
- store.set('selectedIndex', index === -1 ? null : index);
207
- }, [multiple, open, value, valuesRef, isItemEqualToValue, store]);
212
+ store.set('selectedIndex', nextIndex);
213
+ }, [hasSelectedValue, multiple, open, value, valuesRef, isItemEqualToValue, store, selectedItemTextRef]);
208
214
  (0, _useValueChanged.useValueChanged)(value, () => {
209
215
  clearErrors(name);
210
216
  setDirty(value !== validityData.initialValue);
@@ -298,9 +304,7 @@ function SelectRoot(props) {
298
304
  enabled: !readOnly && !disabled,
299
305
  event: 'mousedown'
300
306
  });
301
- const dismiss = (0, _floatingUiReact.useDismiss)(floatingContext, {
302
- bubbles: false
303
- });
307
+ const dismiss = (0, _floatingUiReact.useDismiss)(floatingContext);
304
308
  const listNavigation = (0, _floatingUiReact.useListNavigation)(floatingContext, {
305
309
  enabled: !readOnly && !disabled,
306
310
  listRef,
@@ -328,23 +332,22 @@ function SelectRoot(props) {
328
332
  setValue(valuesRef.current[index], (0, _createBaseUIEventDetails.createChangeEventDetails)('none'));
329
333
  }
330
334
  },
331
- onTypingChange(typing) {
335
+ onTyping(typing) {
332
336
  typingRef.current = typing;
333
337
  }
334
338
  });
335
- const {
336
- getReferenceProps,
337
- getFloatingProps,
338
- getItemProps
339
- } = (0, _floatingUiReact.useInteractions)([click, dismiss, listNavigation, typeahead]);
340
339
  const mergedTriggerProps = React.useMemo(() => {
341
- return (0, _mergeProps.mergeProps)(getReferenceProps(), interactionTypeProps, generatedId ? {
342
- id: generatedId
343
- } : _empty.EMPTY_OBJECT);
344
- }, [getReferenceProps, interactionTypeProps, generatedId]);
340
+ const triggerInteractionProps = (0, _mergeProps.mergeProps)(typeahead.reference, listNavigation.reference, dismiss.reference, click.reference, interactionTypeProps);
341
+ if (generatedId) {
342
+ triggerInteractionProps.id = generatedId;
343
+ }
344
+ return triggerInteractionProps;
345
+ }, [click.reference, typeahead.reference, listNavigation.reference, dismiss.reference, interactionTypeProps, generatedId]);
346
+ const popupProps = React.useMemo(() => (0, _mergeProps.mergeProps)(_popups.FOCUSABLE_POPUP_PROPS, typeahead.floating, listNavigation.floating, dismiss.floating), [typeahead.floating, listNavigation.floating, dismiss.floating]);
347
+ const itemProps = listNavigation.item ?? _empty.EMPTY_OBJECT;
345
348
  (0, _useOnFirstRender.useOnFirstRender)(() => {
346
349
  store.update({
347
- popupProps: getFloatingProps(),
350
+ popupProps,
348
351
  triggerProps: mergedTriggerProps
349
352
  });
350
353
  });
@@ -357,7 +360,7 @@ function SelectRoot(props) {
357
360
  open,
358
361
  mounted,
359
362
  transitionStatus,
360
- popupProps: getFloatingProps(),
363
+ popupProps,
361
364
  triggerProps: mergedTriggerProps,
362
365
  items,
363
366
  itemToStringLabel,
@@ -365,7 +368,7 @@ function SelectRoot(props) {
365
368
  isItemEqualToValue,
366
369
  openMethod: renderedOpenMethod
367
370
  });
368
- }, [store, generatedId, modal, multiple, value, open, mounted, transitionStatus, getFloatingProps, mergedTriggerProps, items, itemToStringLabel, itemToStringValue, isItemEqualToValue, renderedOpenMethod]);
371
+ }, [store, generatedId, modal, multiple, value, open, mounted, transitionStatus, popupProps, mergedTriggerProps, items, itemToStringLabel, itemToStringValue, isItemEqualToValue, renderedOpenMethod]);
369
372
  const contextValue = React.useMemo(() => ({
370
373
  store,
371
374
  name,
@@ -381,20 +384,21 @@ function SelectRoot(props) {
381
384
  scrollHandlerRef,
382
385
  handleScrollArrowVisibility,
383
386
  scrollArrowsMountedCountRef,
384
- getItemProps,
387
+ itemProps,
385
388
  events: floatingContext.context.events,
386
389
  valueRef,
387
390
  valuesRef,
388
391
  labelsRef,
389
392
  typingRef,
390
393
  selectionRef,
394
+ firstItemTextRef,
391
395
  selectedItemTextRef,
392
396
  validation,
393
397
  onOpenChangeComplete,
394
398
  keyboardActiveRef,
395
399
  alignItemWithTriggerActiveRef,
396
400
  initialValueRef
397
- }), [store, name, required, disabled, readOnly, multiple, highlightItemOnHover, setValue, setOpen, getItemProps, floatingContext.context.events, validation, onOpenChangeComplete, handleScrollArrowVisibility]);
401
+ }), [store, name, required, disabled, readOnly, multiple, highlightItemOnHover, setValue, setOpen, itemProps, floatingContext.context.events, validation, onOpenChangeComplete, handleScrollArrowVisibility]);
398
402
  const ref = (0, _useMergedRefs.useMergedRefs)(inputRef, validation.inputRef);
399
403
  const hasMultipleSelection = multiple && Array.isArray(value) && value.length > 0;
400
404
  const hiddenInputName = multiple ? undefined : name;
@@ -428,7 +432,9 @@ function SelectRoot(props) {
428
432
  // Handle browser autofill.
429
433
  onChange(event) {
430
434
  // Workaround for https://github.com/facebook/react/issues/9023
431
- if (event.nativeEvent.defaultPrevented) {
435
+ if (event.nativeEvent.defaultPrevented || disabled || readOnly) {
436
+ // Outside Field.Root, the event is not wrapped by mergeProps.
437
+ event.preventBaseUIHandler?.();
432
438
  return;
433
439
  }
434
440
  const nextValue = event.currentTarget.value;
@@ -19,10 +19,7 @@ export interface SelectRootContext {
19
19
  scrollHandlerRef: React.RefObject<((el: HTMLDivElement) => void) | null>;
20
20
  handleScrollArrowVisibility: () => void;
21
21
  scrollArrowsMountedCountRef: React.RefObject<number>;
22
- getItemProps: (props?: HTMLProps & {
23
- active?: boolean | undefined;
24
- selected?: boolean | undefined;
25
- }) => Record<string, unknown>;
22
+ itemProps: HTMLProps;
26
23
  events: FloatingEvents;
27
24
  valueRef: React.RefObject<HTMLSpanElement | null>;
28
25
  valuesRef: React.RefObject<Array<any>>;
@@ -31,8 +28,10 @@ export interface SelectRootContext {
31
28
  selectionRef: React.RefObject<{
32
29
  allowUnselectedMouseUp: boolean;
33
30
  allowSelectedMouseUp: boolean;
31
+ dragY: number;
34
32
  }>;
35
- selectedItemTextRef: React.RefObject<HTMLSpanElement | null>;
33
+ firstItemTextRef: React.RefObject<HTMLElement | null>;
34
+ selectedItemTextRef: React.RefObject<HTMLElement | null>;
36
35
  validation: UseFieldValidationReturnValue;
37
36
  onOpenChangeComplete?: ((open: boolean) => void) | undefined;
38
37
  keyboardActiveRef: React.RefObject<boolean>;
package/select/store.d.ts CHANGED
@@ -2,6 +2,7 @@ import { Store } from '@base-ui/utils/store';
2
2
  import { type InteractionType } from '@base-ui/utils/useEnhancedClickHandler';
3
3
  import type { TransitionStatus } from "../internals/useTransitionStatus.js";
4
4
  import type { HTMLProps } from "../internals/types.js";
5
+ import type { Side } from "../utils/useAnchorPositioning.js";
5
6
  import { type Group } from "../internals/resolveValueLabel.js";
6
7
  export type State = {
7
8
  id: string | undefined;
@@ -28,6 +29,7 @@ export type State = {
28
29
  triggerElement: HTMLElement | null;
29
30
  positionerElement: HTMLElement | null;
30
31
  listElement: HTMLDivElement | null;
32
+ popupSide: Side | null;
31
33
  scrollUpArrowVisible: boolean;
32
34
  scrollDownArrowVisible: boolean;
33
35
  hasScrollArrows: boolean;
@@ -63,6 +65,7 @@ export declare const selectors: {
63
65
  triggerElement: (state: State) => HTMLElement | null;
64
66
  positionerElement: (state: State) => HTMLElement | null;
65
67
  listElement: (state: State) => HTMLDivElement | null;
68
+ popupSide: (state: State) => Side | null;
66
69
  scrollUpArrowVisible: (state: State) => boolean;
67
70
  scrollDownArrowVisible: (state: State) => boolean;
68
71
  hasScrollArrows: (state: State) => boolean;
package/select/store.js CHANGED
@@ -64,6 +64,7 @@ const selectors = exports.selectors = {
64
64
  triggerElement: (0, _store.createSelector)(state => state.triggerElement),
65
65
  positionerElement: (0, _store.createSelector)(state => state.positionerElement),
66
66
  listElement: (0, _store.createSelector)(state => state.listElement),
67
+ popupSide: (0, _store.createSelector)(state => state.popupSide),
67
68
  scrollUpArrowVisible: (0, _store.createSelector)(state => state.scrollUpArrowVisible),
68
69
  scrollDownArrowVisible: (0, _store.createSelector)(state => state.scrollDownArrowVisible),
69
70
  hasScrollArrows: (0, _store.createSelector)(state => state.hasScrollArrows)
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { BaseUIComponentProps, NativeButtonProps } from "../../internals/types.js";
3
3
  import type { FieldRootState } from "../../field/root/FieldRoot.js";
4
+ import type { Side } from "../../utils/useAnchorPositioning.js";
4
5
  /**
5
6
  * A button that opens the select popup.
6
7
  * Renders a `<button>` element.
@@ -17,6 +18,10 @@ export interface SelectTriggerState extends FieldRootState {
17
18
  * Whether the select popup is readonly.
18
19
  */
19
20
  readOnly: boolean;
21
+ /**
22
+ * Indicates which side the corresponding popup is positioned relative to its anchor.
23
+ */
24
+ popupSide: Side | null;
20
25
  /**
21
26
  * The value of the currently selected item.
22
27
  */