@astryxdesign/core 0.7.7 → 0.7.8-canary.30b1896

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 (540) hide show
  1. package/dist/AlertDialog/AlertDialog.d.ts +4 -1
  2. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  3. package/dist/AlertDialog/AlertDialog.js +46 -6
  4. package/dist/AppShell/AppShell.d.ts.map +1 -1
  5. package/dist/AppShell/AppShell.js +5 -0
  6. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  7. package/dist/BottomSheet/BottomSheet.js +1 -0
  8. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  9. package/dist/BottomSheet/BottomSheetPanel.js +25 -4
  10. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  11. package/dist/BottomSheet/BottomSheetSwitcher.js +5 -0
  12. package/dist/BottomSheet/useMobileKeyboard.d.ts.map +1 -1
  13. package/dist/BottomSheet/useMobileKeyboard.js +6 -0
  14. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  15. package/dist/BottomSheet/useSheetGestures.js +12 -1
  16. package/dist/Button/Button.d.ts.map +1 -1
  17. package/dist/Button/Button.js +17 -1
  18. package/dist/Calendar/Calendar.d.ts.map +1 -1
  19. package/dist/Calendar/Calendar.js +15 -16
  20. package/dist/Carousel/Carousel.d.ts.map +1 -1
  21. package/dist/Carousel/Carousel.js +2 -0
  22. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  23. package/dist/Chat/ChatComposerInput.js +4 -0
  24. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  25. package/dist/Chat/ChatMessageList.js +2 -1
  26. package/dist/Chat/useChatDictation.d.ts.map +1 -1
  27. package/dist/Chat/useChatDictation.js +2 -0
  28. package/dist/Chat/useChatNewMessages.js +1 -1
  29. package/dist/Chat/useChatStreamScroll.d.ts.map +1 -1
  30. package/dist/Chat/useChatStreamScroll.js +2 -0
  31. package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
  32. package/dist/Chat/useSpeechRecognition.js +3 -0
  33. package/dist/Chat/useTriggerMenu.js +1 -1
  34. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  35. package/dist/CheckboxInput/CheckboxInput.js +17 -12
  36. package/dist/CodeBlock/CodeBlock.d.ts +10 -1
  37. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  38. package/dist/CodeBlock/CodeBlock.js +28 -11
  39. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  40. package/dist/CommandPalette/CommandPalette.js +2 -0
  41. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  42. package/dist/CommandPalette/CommandPaletteItem.js +2 -0
  43. package/dist/ComplexSelector/ComplexSelector.d.ts +4 -1
  44. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  45. package/dist/ComplexSelector/ComplexSelector.js +14 -4
  46. package/dist/ContextMenu/ContextMenu.js +2 -2
  47. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  48. package/dist/DateInput/MonthScroller.js +5 -2
  49. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  50. package/dist/DateInput/TouchDateField.js +1 -0
  51. package/dist/DateInput/Wheel.d.ts.map +1 -1
  52. package/dist/DateInput/Wheel.js +4 -0
  53. package/dist/DateInput/useOwnScrollGesture.d.ts.map +1 -1
  54. package/dist/DateInput/useOwnScrollGesture.js +3 -0
  55. package/dist/DateInput/usePointerDragScroll.d.ts.map +1 -1
  56. package/dist/DateInput/usePointerDragScroll.js +2 -0
  57. package/dist/DateInput/useScrollSettle.d.ts.map +1 -1
  58. package/dist/DateInput/useScrollSettle.js +3 -0
  59. package/dist/Dialog/Dialog.d.ts.map +1 -1
  60. package/dist/Dialog/Dialog.js +9 -32
  61. package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -1
  62. package/dist/Drawer/useDrawerDialogPresence.js +3 -0
  63. package/dist/DropdownMenu/useMenuOverflow.d.ts.map +1 -1
  64. package/dist/DropdownMenu/useMenuOverflow.js +5 -0
  65. package/dist/Field/Field.js +2 -2
  66. package/dist/FieldStatus/useFieldStatusAnnouncement.d.ts.map +1 -1
  67. package/dist/FieldStatus/useFieldStatusAnnouncement.js +1 -0
  68. package/dist/FormLayout/FormLayout.d.ts +5 -1
  69. package/dist/FormLayout/FormLayout.d.ts.map +1 -1
  70. package/dist/HoverCard/HoverCard.d.ts +6 -4
  71. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  72. package/dist/HoverCard/HoverCard.js +48 -3
  73. package/dist/HoverCard/useHoverCard.d.ts +5 -4
  74. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  75. package/dist/HoverCard/useHoverCard.js +20 -33
  76. package/dist/Icon/Icon.d.ts +5 -1
  77. package/dist/Icon/Icon.d.ts.map +1 -1
  78. package/dist/Icon/Icon.js +5 -2
  79. package/dist/Item/useSwipeAction.d.ts.map +1 -1
  80. package/dist/Item/useSwipeAction.js +3 -0
  81. package/dist/Layer/modalOutlet.d.ts.map +1 -1
  82. package/dist/Layer/modalOutlet.js +2 -0
  83. package/dist/Layer/outsidePress.d.ts.map +1 -1
  84. package/dist/Layer/outsidePress.js +1 -0
  85. package/dist/Layer/useLayer.d.ts.map +1 -1
  86. package/dist/Layer/useLayer.js +3 -0
  87. package/dist/Layer/useLayerDismissal.d.ts.map +1 -1
  88. package/dist/Layer/useLayerDismissal.js +3 -0
  89. package/dist/Layer/usePressPin.d.ts +17 -5
  90. package/dist/Layer/usePressPin.d.ts.map +1 -1
  91. package/dist/Layer/usePressPin.js +62 -12
  92. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  93. package/dist/Layer/useTouchTrigger.js +3 -0
  94. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  95. package/dist/Lightbox/Lightbox.js +19 -0
  96. package/dist/MobileNav/MobileNav.d.ts +3 -2
  97. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  98. package/dist/MobileNav/MobileNav.js +9 -25
  99. package/dist/Outline/useOutlineFromDOM.d.ts.map +1 -1
  100. package/dist/Outline/useOutlineFromDOM.js +3 -0
  101. package/dist/Outline/useScrollSpy.d.ts.map +1 -1
  102. package/dist/Outline/useScrollSpy.js +3 -0
  103. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  104. package/dist/OverflowList/OverflowList.js +3 -0
  105. package/dist/Popover/Popover.d.ts.map +1 -1
  106. package/dist/Popover/Popover.js +6 -0
  107. package/dist/PowerSearch/PowerSearch.d.ts +43 -4
  108. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  109. package/dist/PowerSearch/PowerSearch.js +445 -134
  110. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts +102 -0
  111. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +1 -0
  112. package/dist/PowerSearch/PowerSearchBottomSheet.js +1919 -0
  113. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +35 -2
  114. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  115. package/dist/PowerSearch/PowerSearchEditPopover.js +25 -6
  116. package/dist/PowerSearch/PowerSearchFilterEditor.d.ts +1 -1
  117. package/dist/PowerSearch/PowerSearchFilterEditor.d.ts.map +1 -1
  118. package/dist/PowerSearch/PowerSearchFilterEditor.js +4 -2
  119. package/dist/PowerSearch/PowerSearchToken.d.ts +1 -1
  120. package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
  121. package/dist/PowerSearch/PowerSearchToken.js +7 -2
  122. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +38 -3
  123. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  124. package/dist/PowerSearch/PowerSearchValueEditor.js +193 -83
  125. package/dist/PowerSearch/formatFilterValue.d.ts +18 -6
  126. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  127. package/dist/PowerSearch/formatFilterValue.js +33 -12
  128. package/dist/PowerSearch/formatTokenValue.d.ts +28 -0
  129. package/dist/PowerSearch/formatTokenValue.d.ts.map +1 -0
  130. package/dist/PowerSearch/formatTokenValue.js +162 -0
  131. package/dist/PowerSearch/powerSearchDateZone.d.ts +21 -0
  132. package/dist/PowerSearch/powerSearchDateZone.d.ts.map +1 -0
  133. package/dist/PowerSearch/powerSearchDateZone.js +37 -0
  134. package/dist/PowerSearch/powerSearchSheetUtils.d.ts +65 -0
  135. package/dist/PowerSearch/powerSearchSheetUtils.d.ts.map +1 -0
  136. package/dist/PowerSearch/powerSearchSheetUtils.js +168 -0
  137. package/dist/PowerSearch/types.d.ts +2 -0
  138. package/dist/PowerSearch/types.d.ts.map +1 -1
  139. package/dist/ProgressBar/ProgressBarTouch.d.ts.map +1 -1
  140. package/dist/ProgressBar/ProgressBarTouch.js +2 -0
  141. package/dist/RadioList/RadioList.d.ts.map +1 -1
  142. package/dist/RadioList/RadioList.js +3 -2
  143. package/dist/RadioList/RadioListItem.d.ts +1 -1
  144. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  145. package/dist/RadioList/RadioListItem.js +5 -3
  146. package/dist/Resizable/ResizeHandle.d.ts +2 -1
  147. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  148. package/dist/Resizable/ResizeHandle.js +101 -77
  149. package/dist/Resizable/createResizable.d.ts +145 -0
  150. package/dist/Resizable/createResizable.d.ts.map +1 -0
  151. package/dist/Resizable/createResizable.js +575 -0
  152. package/dist/Resizable/useResizable.d.ts +3 -3
  153. package/dist/Resizable/useResizable.d.ts.map +1 -1
  154. package/dist/Resizable/useResizable.js +252 -459
  155. package/dist/SegmentedControl/useSegmentedSelectionMotion.d.ts.map +1 -1
  156. package/dist/SegmentedControl/useSegmentedSelectionMotion.js +3 -3
  157. package/dist/SelectableCard/SelectableCard.d.ts +2 -0
  158. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  159. package/dist/SelectableCard/SelectableCard.js +36 -11
  160. package/dist/SelectableCard/selectableCardInput.d.ts +12 -0
  161. package/dist/SelectableCard/selectableCardInput.d.ts.map +1 -0
  162. package/dist/SelectableCard/selectableCardInput.js +20 -0
  163. package/dist/Selector/Selector.d.ts.map +1 -1
  164. package/dist/Selector/Selector.js +5 -8
  165. package/dist/Slider/sliderTouchController.js +2 -2
  166. package/dist/Spinner/Spinner.d.ts +1 -1
  167. package/dist/Spinner/Spinner.d.ts.map +1 -1
  168. package/dist/Spinner/Spinner.js +60 -58
  169. package/dist/Switch/Switch.d.ts.map +1 -1
  170. package/dist/Switch/Switch.js +4 -10
  171. package/dist/Switch/useSwitchTouch.js +4 -4
  172. package/dist/Table/BaseTable.d.ts.map +1 -1
  173. package/dist/Table/BaseTable.js +29 -8
  174. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  175. package/dist/Table/plugins/columnResize/useTableColumnResize.js +3 -1
  176. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  177. package/dist/Table/plugins/filtering/useTableFiltering.js +2 -1
  178. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  179. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +4 -0
  180. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  181. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +2 -0
  182. package/dist/TextInput/TextInput.d.ts +2 -2
  183. package/dist/TextInput/TextInput.d.ts.map +1 -1
  184. package/dist/TextInput/TextInput.js +10 -7
  185. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  186. package/dist/TimeInput/TimeInput.js +2 -0
  187. package/dist/Timer/Timer.d.ts.map +1 -1
  188. package/dist/Timer/Timer.js +2 -0
  189. package/dist/Timestamp/Timestamp.js +1 -1
  190. package/dist/Toast/Toast.d.ts +11 -1
  191. package/dist/Toast/Toast.d.ts.map +1 -1
  192. package/dist/Toast/Toast.js +25 -15
  193. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  194. package/dist/Toast/ToastViewport.js +97 -34
  195. package/dist/Toast/types.d.ts +9 -3
  196. package/dist/Toast/types.d.ts.map +1 -1
  197. package/dist/Toast/useToast.d.ts.map +1 -1
  198. package/dist/Toast/useToast.js +1 -0
  199. package/dist/Tokenizer/Tokenizer.d.ts +49 -37
  200. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  201. package/dist/Tokenizer/Tokenizer.js +22 -19
  202. package/dist/Tokenizer/TokenizerBottomSheet.d.ts +1 -1
  203. package/dist/Tokenizer/TokenizerBottomSheet.js +1 -1
  204. package/dist/Tokenizer/index.d.ts +1 -1
  205. package/dist/Tokenizer/index.d.ts.map +1 -1
  206. package/dist/Tooltip/useTooltip.d.ts +19 -1
  207. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  208. package/dist/Tooltip/useTooltip.js +34 -53
  209. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  210. package/dist/Typeahead/BaseTypeahead.js +27 -18
  211. package/dist/Typeahead/TypeaheadItem.d.ts +2 -1
  212. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  213. package/dist/animator/createAnimator.d.ts +98 -0
  214. package/dist/animator/createAnimator.d.ts.map +1 -0
  215. package/dist/animator/createAnimator.js +259 -0
  216. package/dist/astryx.css +36 -6
  217. package/dist/gestures/PressTracker.d.ts.map +1 -1
  218. package/dist/gestures/PressTracker.js +4 -3
  219. package/dist/hooks/ModalAnnounceProvider.d.ts.map +1 -1
  220. package/dist/hooks/ModalAnnounceProvider.js +1 -0
  221. package/dist/hooks/actionGroupTracker.d.ts +4 -1
  222. package/dist/hooks/actionGroupTracker.d.ts.map +1 -1
  223. package/dist/hooks/actionGroupTracker.js +13 -3
  224. package/dist/hooks/index.d.ts +1 -0
  225. package/dist/hooks/index.d.ts.map +1 -1
  226. package/dist/hooks/index.js +1 -0
  227. package/dist/hooks/longPressDetector.d.ts +66 -0
  228. package/dist/hooks/longPressDetector.d.ts.map +1 -0
  229. package/dist/hooks/longPressDetector.js +200 -0
  230. package/dist/hooks/pressGroupContext.d.ts +6 -0
  231. package/dist/hooks/pressGroupContext.d.ts.map +1 -0
  232. package/dist/hooks/pressGroupContext.js +20 -0
  233. package/dist/hooks/rootScrollStyles.d.ts +48 -0
  234. package/dist/hooks/rootScrollStyles.d.ts.map +1 -0
  235. package/dist/hooks/rootScrollStyles.js +207 -0
  236. package/dist/hooks/scrollLockTouchGuard.d.ts +13 -0
  237. package/dist/hooks/scrollLockTouchGuard.d.ts.map +1 -0
  238. package/dist/hooks/scrollLockTouchGuard.js +134 -0
  239. package/dist/hooks/scrollbarGutter.d.ts +4 -4
  240. package/dist/hooks/scrollbarGutter.d.ts.map +1 -1
  241. package/dist/hooks/scrollbarGutter.js +36 -23
  242. package/dist/hooks/useActionGroupTracking.d.ts +53 -0
  243. package/dist/hooks/useActionGroupTracking.d.ts.map +1 -0
  244. package/dist/hooks/useActionGroupTracking.js +174 -0
  245. package/dist/hooks/useAnimator.d.ts +41 -0
  246. package/dist/hooks/useAnimator.d.ts.map +1 -0
  247. package/dist/hooks/useAnimator.js +70 -0
  248. package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
  249. package/dist/hooks/useAnnounceRenderedText.js +1 -0
  250. package/dist/hooks/useAttachment.d.ts +1 -1
  251. package/dist/hooks/useAttachment.js +1 -1
  252. package/dist/hooks/useAutoMediaMode.d.ts.map +1 -1
  253. package/dist/hooks/useAutoMediaMode.js +1 -0
  254. package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
  255. package/dist/hooks/useBusyAnnouncement.js +2 -0
  256. package/dist/hooks/useDevWarning.d.ts.map +1 -1
  257. package/dist/hooks/useDevWarning.js +2 -0
  258. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  259. package/dist/hooks/useFocusTrap.js +2 -0
  260. package/dist/hooks/useGridFocus.d.ts +8 -5
  261. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  262. package/dist/hooks/useGridFocus.js +4 -3
  263. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  264. package/dist/hooks/useHotkeys.js +3 -0
  265. package/dist/hooks/useImageMode.d.ts.map +1 -1
  266. package/dist/hooks/useImageMode.js +3 -0
  267. package/dist/hooks/useInputStatusIcon.d.ts +1 -1
  268. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  269. package/dist/hooks/useInputStatusIcon.js +2 -2
  270. package/dist/hooks/useKeyboardHint.js +1 -1
  271. package/dist/hooks/useLongPress.d.ts +8 -9
  272. package/dist/hooks/useLongPress.d.ts.map +1 -1
  273. package/dist/hooks/useLongPress.js +23 -106
  274. package/dist/hooks/useMenuHover.d.ts.map +1 -1
  275. package/dist/hooks/useMenuHover.js +2 -0
  276. package/dist/hooks/useMenuPress.d.ts.map +1 -1
  277. package/dist/hooks/useMenuPress.js +3 -0
  278. package/dist/hooks/useOverflow.d.ts.map +1 -1
  279. package/dist/hooks/useOverflow.js +2 -1
  280. package/dist/hooks/usePressFeedback.d.ts.map +1 -1
  281. package/dist/hooks/usePressFeedback.js +1 -0
  282. package/dist/hooks/useResolvedRequired.d.ts +3 -0
  283. package/dist/hooks/useResolvedRequired.d.ts.map +1 -1
  284. package/dist/hooks/useResolvedRequired.js +3 -0
  285. package/dist/hooks/useScrollLock.d.ts +7 -9
  286. package/dist/hooks/useScrollLock.d.ts.map +1 -1
  287. package/dist/hooks/useScrollLock.js +55 -48
  288. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  289. package/dist/hooks/useScrollableArea.js +5 -0
  290. package/dist/hooks/useStreamingText.d.ts.map +1 -1
  291. package/dist/hooks/useStreamingText.js +3 -0
  292. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts +8 -0
  293. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts.map +1 -0
  294. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.js +42 -0
  295. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.d.ts.map +1 -1
  296. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.js +6 -0
  297. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts +8 -0
  298. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts.map +1 -0
  299. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.js +14 -0
  300. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  301. package/dist/i18n/generated-locales/en.generated.js +30 -0
  302. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  303. package/dist/i18n/generated-locales/pseudo.generated.js +30 -0
  304. package/dist/index.d.ts +1 -0
  305. package/dist/index.d.ts.map +1 -1
  306. package/dist/index.js +4 -0
  307. package/dist/internal/indicatorPress.stylex.d.ts +20 -0
  308. package/dist/internal/indicatorPress.stylex.d.ts.map +1 -0
  309. package/dist/internal/indicatorPress.stylex.js +26 -0
  310. package/dist/internal/selectable-card.d.ts +21 -0
  311. package/dist/internal/selectable-card.d.ts.map +1 -0
  312. package/dist/internal/selectable-card.js +20 -0
  313. package/dist/internal/sheetDraft.d.ts +2 -2
  314. package/dist/internal/sheetDraft.js +2 -2
  315. package/dist/motion/animatedLayout.d.ts.map +1 -1
  316. package/dist/motion/animatedLayout.js +7 -7
  317. package/dist/motion/animator.d.ts +14 -14
  318. package/dist/motion/animator.d.ts.map +1 -1
  319. package/dist/motion/animator.js +45 -20
  320. package/dist/motion/progress.d.ts +88 -0
  321. package/dist/motion/progress.d.ts.map +1 -0
  322. package/dist/motion/progress.js +128 -0
  323. package/dist/motion/reducedMotion.d.ts.map +1 -1
  324. package/dist/motion/reducedMotion.js +3 -1
  325. package/dist/motion/uikit/alert.d.ts +41 -0
  326. package/dist/motion/uikit/alert.d.ts.map +1 -0
  327. package/dist/motion/uikit/alert.js +43 -0
  328. package/dist/privateAttributes/pressGroupItem.stylex.d.ts +22 -0
  329. package/dist/privateAttributes/pressGroupItem.stylex.d.ts.map +1 -0
  330. package/dist/privateAttributes/pressGroupItem.stylex.js +36 -0
  331. package/dist/privateAttributes/reducedMotion.stylex.d.ts +23 -0
  332. package/dist/privateAttributes/reducedMotion.stylex.d.ts.map +1 -0
  333. package/dist/privateAttributes/reducedMotion.stylex.js +40 -0
  334. package/dist/theme/Theme.d.ts.map +1 -1
  335. package/dist/theme/Theme.js +29 -4
  336. package/dist/theme/motionKnobs.d.ts +4 -3
  337. package/dist/theme/motionKnobs.d.ts.map +1 -1
  338. package/dist/theme/motionKnobs.js +3 -2
  339. package/dist/theme/themeMotion.d.ts +6 -0
  340. package/dist/theme/themeMotion.d.ts.map +1 -1
  341. package/dist/theme/themeMotion.js +7 -0
  342. package/dist/utils/dateParser.d.ts.map +1 -1
  343. package/dist/utils/dateParser.js +12 -0
  344. package/dist/utils/focusReturn.d.ts +15 -0
  345. package/dist/utils/focusReturn.d.ts.map +1 -1
  346. package/dist/utils/focusReturn.js +28 -0
  347. package/dist/utils/interactionModality.d.ts.map +1 -1
  348. package/dist/utils/interactionModality.js +4 -0
  349. package/dist/utils/interactionOverlay.stylex.d.ts +3 -2
  350. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  351. package/dist/utils/interactionOverlay.stylex.js +3 -2
  352. package/dist/utils/plainDate.d.ts +8 -0
  353. package/dist/utils/plainDate.d.ts.map +1 -1
  354. package/dist/utils/plainDate.js +19 -0
  355. package/dist/utils/pressFeedback.d.ts.map +1 -1
  356. package/dist/utils/pressFeedback.js +20 -6
  357. package/dist/utils/triggerFocus.d.ts +36 -0
  358. package/dist/utils/triggerFocus.d.ts.map +1 -0
  359. package/dist/utils/triggerFocus.js +65 -0
  360. package/locales/en.json +120 -0
  361. package/locales/pseudo.json +90 -0
  362. package/package.json +14 -9
  363. package/src/AlertDialog/AlertDialog.doc.mjs +2 -2
  364. package/src/AlertDialog/AlertDialog.tsx +46 -5
  365. package/src/AppShell/AppShell.tsx +4 -0
  366. package/src/BottomSheet/BottomSheet.tsx +1 -0
  367. package/src/BottomSheet/BottomSheetPanel.tsx +39 -3
  368. package/src/BottomSheet/BottomSheetSwitcher.tsx +5 -0
  369. package/src/BottomSheet/useMobileKeyboard.ts +4 -0
  370. package/src/BottomSheet/useSheetGestures.ts +10 -1
  371. package/src/Button/Button.tsx +26 -4
  372. package/src/Calendar/Calendar.tsx +36 -25
  373. package/src/Carousel/Carousel.tsx +1 -0
  374. package/src/Chat/ChatComposerInput.tsx +2 -0
  375. package/src/Chat/ChatMessageList.tsx +2 -1
  376. package/src/Chat/useChatDictation.ts +1 -0
  377. package/src/Chat/useChatNewMessages.ts +1 -1
  378. package/src/Chat/useChatStreamScroll.ts +2 -0
  379. package/src/Chat/useSpeechRecognition.ts +2 -0
  380. package/src/Chat/useTriggerMenu.tsx +1 -1
  381. package/src/CheckboxInput/CheckboxInput.doc.mjs +18 -0
  382. package/src/CheckboxInput/CheckboxInput.tsx +38 -15
  383. package/src/CodeBlock/CodeBlock.doc.mjs +9 -1
  384. package/src/CodeBlock/CodeBlock.tsx +41 -4
  385. package/src/CommandPalette/CommandPalette.tsx +1 -0
  386. package/src/CommandPalette/CommandPaletteItem.tsx +1 -0
  387. package/src/ComplexSelector/ComplexSelector.tsx +20 -5
  388. package/src/ContextMenu/ContextMenu.tsx +2 -2
  389. package/src/DateInput/MonthScroller.tsx +8 -2
  390. package/src/DateInput/TouchDateField.tsx +1 -0
  391. package/src/DateInput/Wheel.tsx +4 -0
  392. package/src/DateInput/useOwnScrollGesture.ts +2 -0
  393. package/src/DateInput/usePointerDragScroll.ts +1 -0
  394. package/src/DateInput/useScrollSettle.ts +2 -0
  395. package/src/Dialog/Dialog.tsx +12 -32
  396. package/src/Drawer/useDrawerDialogPresence.ts +2 -0
  397. package/src/DropdownMenu/useMenuOverflow.ts +3 -0
  398. package/src/Field/Field.tsx +2 -2
  399. package/src/FieldStatus/useFieldStatusAnnouncement.ts +1 -0
  400. package/src/FormLayout/FormLayout.doc.mjs +181 -46
  401. package/src/FormLayout/FormLayout.tsx +5 -1
  402. package/src/HoverCard/HoverCard.doc.mjs +10 -8
  403. package/src/HoverCard/HoverCard.tsx +58 -6
  404. package/src/HoverCard/useHoverCard.doc.mjs +178 -36
  405. package/src/HoverCard/useHoverCard.tsx +49 -54
  406. package/src/Icon/Icon.doc.mjs +49 -8
  407. package/src/Icon/Icon.tsx +15 -7
  408. package/src/IconButton/IconButton.doc.mjs +141 -21
  409. package/src/Item/useSwipeAction.ts +2 -0
  410. package/src/Layer/modalOutlet.ts +2 -0
  411. package/src/Layer/outsidePress.ts +1 -0
  412. package/src/Layer/useLayer.tsx +2 -0
  413. package/src/Layer/useLayerDismissal.ts +2 -0
  414. package/src/Layer/usePressPin.ts +81 -15
  415. package/src/Layer/useTouchTrigger.ts +2 -0
  416. package/src/Lightbox/Lightbox.tsx +19 -0
  417. package/src/MobileNav/MobileNav.tsx +9 -30
  418. package/src/Outline/useOutlineFromDOM.ts +2 -0
  419. package/src/Outline/useScrollSpy.ts +2 -0
  420. package/src/OverflowList/OverflowList.tsx +2 -0
  421. package/src/Popover/Popover.tsx +4 -0
  422. package/src/PowerSearch/PowerSearch.doc.mjs +60 -8
  423. package/src/PowerSearch/PowerSearch.tsx +627 -157
  424. package/src/PowerSearch/PowerSearchBottomSheet.tsx +2525 -0
  425. package/src/PowerSearch/PowerSearchEditPopover.tsx +39 -6
  426. package/src/PowerSearch/PowerSearchFilterEditor.tsx +2 -0
  427. package/src/PowerSearch/PowerSearchToken.tsx +7 -0
  428. package/src/PowerSearch/PowerSearchValueEditor.tsx +244 -58
  429. package/src/PowerSearch/formatFilterValue.ts +55 -17
  430. package/src/PowerSearch/formatTokenValue.ts +222 -0
  431. package/src/PowerSearch/powerSearchDateZone.ts +64 -0
  432. package/src/PowerSearch/powerSearchSheetUtils.ts +224 -0
  433. package/src/PowerSearch/types.ts +2 -0
  434. package/src/ProgressBar/ProgressBarTouch.ts +2 -0
  435. package/src/RadioList/RadioList.tsx +3 -2
  436. package/src/RadioList/RadioListItem.tsx +5 -3
  437. package/src/Resizable/Resizable.doc.mjs +5 -4
  438. package/src/Resizable/ResizeHandle.tsx +169 -109
  439. package/src/Resizable/createResizable.ts +831 -0
  440. package/src/Resizable/useResizable.ts +292 -623
  441. package/src/SegmentedControl/useSegmentedSelectionMotion.ts +6 -3
  442. package/src/SelectableCard/SelectableCard.tsx +39 -10
  443. package/src/SelectableCard/selectableCardInput.ts +30 -0
  444. package/src/Selector/Selector.tsx +5 -12
  445. package/src/Slider/sliderTouchController.ts +2 -2
  446. package/src/Spinner/Spinner.tsx +77 -63
  447. package/src/Switch/Switch.tsx +2 -6
  448. package/src/Switch/useSwitchTouch.ts +4 -4
  449. package/src/Table/BaseTable.tsx +46 -12
  450. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +2 -1
  451. package/src/Table/plugins/filtering/useTableFiltering.tsx +1 -0
  452. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +4 -0
  453. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +2 -0
  454. package/src/TextInput/TextInput.tsx +11 -10
  455. package/src/TimeInput/TimeInput.tsx +2 -0
  456. package/src/Timer/Timer.tsx +1 -0
  457. package/src/Timestamp/Timestamp.tsx +1 -1
  458. package/src/Toast/Toast.doc.mjs +4 -3
  459. package/src/Toast/Toast.tsx +52 -32
  460. package/src/Toast/ToastViewport.tsx +123 -35
  461. package/src/Toast/types.ts +9 -3
  462. package/src/Toast/useToast.tsx +1 -0
  463. package/src/Tokenizer/Tokenizer.doc.mjs +19 -3
  464. package/src/Tokenizer/Tokenizer.tsx +73 -51
  465. package/src/Tokenizer/TokenizerBottomSheet.tsx +1 -1
  466. package/src/Tokenizer/index.ts +1 -0
  467. package/src/Tooltip/useTooltip.doc.mjs +24 -0
  468. package/src/Tooltip/useTooltip.tsx +61 -56
  469. package/src/Typeahead/BaseTypeahead.tsx +27 -17
  470. package/src/Typeahead/TypeaheadItem.doc.mjs +6 -3
  471. package/src/Typeahead/TypeaheadItem.tsx +2 -1
  472. package/src/animator/createAnimator.doc.mjs +153 -0
  473. package/src/animator/createAnimator.ts +324 -0
  474. package/src/gestures/PressTracker.ts +4 -3
  475. package/src/gestures/README.md +10 -4
  476. package/src/hooks/ModalAnnounceProvider.tsx +1 -0
  477. package/src/hooks/actionGroupTracker.ts +20 -5
  478. package/src/hooks/index.ts +2 -0
  479. package/src/hooks/longPressDetector.ts +273 -0
  480. package/src/hooks/pressGroupContext.ts +21 -0
  481. package/src/hooks/rootScrollStyles.ts +247 -0
  482. package/src/hooks/scrollLockTouchGuard.ts +182 -0
  483. package/src/hooks/scrollbarGutter.ts +41 -26
  484. package/src/hooks/useActionGroupTracking.ts +224 -0
  485. package/src/hooks/useAnimator.doc.mjs +109 -0
  486. package/src/hooks/useAnimator.ts +67 -0
  487. package/src/hooks/useAnnounceRenderedText.ts +1 -0
  488. package/src/hooks/useAttachment.ts +1 -1
  489. package/src/hooks/useAutoMediaMode.ts +1 -0
  490. package/src/hooks/useBusyAnnouncement.ts +2 -0
  491. package/src/hooks/useDevWarning.ts +2 -0
  492. package/src/hooks/useFocusTrap.ts +2 -0
  493. package/src/hooks/useGridFocus.doc.mjs +6 -6
  494. package/src/hooks/useGridFocus.ts +10 -7
  495. package/src/hooks/useHotkeys.ts +2 -0
  496. package/src/hooks/useImageMode.ts +2 -0
  497. package/src/hooks/useInputStatusIcon.tsx +3 -2
  498. package/src/hooks/useKeyboardHint.tsx +1 -1
  499. package/src/hooks/useLongPress.doc.mjs +2 -2
  500. package/src/hooks/useLongPress.ts +32 -122
  501. package/src/hooks/useMenuHover.ts +1 -0
  502. package/src/hooks/useMenuPress.ts +2 -0
  503. package/src/hooks/useOverflow.ts +2 -1
  504. package/src/hooks/usePressFeedback.ts +1 -0
  505. package/src/hooks/useResolvedRequired.ts +3 -0
  506. package/src/hooks/useScrollLock.doc.mjs +51 -12
  507. package/src/hooks/useScrollLock.ts +57 -60
  508. package/src/hooks/useScrollableArea.ts +4 -0
  509. package/src/hooks/useStreamingText.ts +2 -0
  510. package/src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts +43 -0
  511. package/src/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.ts +6 -0
  512. package/src/i18n/generated-english/PowerSearch/formatTokenValue.generated.ts +15 -0
  513. package/src/i18n/generated-locales/en.generated.ts +41 -0
  514. package/src/i18n/generated-locales/pseudo.generated.ts +42 -0
  515. package/src/index.ts +13 -0
  516. package/src/internal/indicatorPress.stylex.ts +24 -0
  517. package/src/internal/selectable-card.ts +21 -0
  518. package/src/internal/sheetDraft.ts +2 -2
  519. package/src/motion/README.md +9 -5
  520. package/src/motion/animatedLayout.ts +10 -5
  521. package/src/motion/animator.ts +66 -31
  522. package/src/motion/progress.ts +155 -0
  523. package/src/motion/reducedMotion.ts +3 -1
  524. package/src/motion/uikit/alert.ts +43 -0
  525. package/src/privateAttributes/pressGroupItem.stylex.ts +44 -0
  526. package/src/privateAttributes/reducedMotion.stylex.ts +45 -0
  527. package/src/theme/Theme.tsx +37 -3
  528. package/src/theme/motionKnobs.ts +4 -3
  529. package/src/theme/themeMotion.ts +7 -0
  530. package/src/utils/dateParser.ts +16 -0
  531. package/src/utils/focusReturn.ts +30 -0
  532. package/src/utils/interactionModality.ts +4 -0
  533. package/src/utils/interactionOverlay.stylex.ts +3 -2
  534. package/src/utils/plainDate.ts +21 -0
  535. package/src/utils/pressFeedback.ts +24 -6
  536. package/src/utils/triggerFocus.ts +80 -0
  537. package/dist/internal/touch-sheet.d.ts +0 -21
  538. package/dist/internal/touch-sheet.d.ts.map +0 -1
  539. package/dist/internal/touch-sheet.js +0 -19
  540. package/src/internal/touch-sheet.ts +0 -21
@@ -35,6 +35,7 @@ import {
35
35
  } from '../Field/fieldParts';
36
36
  import {useDevWarning} from '../hooks/useDevWarning';
37
37
  import {mergeRefs} from '../utils/mergeRefs';
38
+ import {isFocusLost} from '../utils/focusReturn';
38
39
  import {useMergedRefs} from '../hooks/useMergedRefs';
39
40
  import {useBusyAnnouncement} from '../hooks/useBusyAnnouncement';
40
41
  import {Field, inputWrapperStyles} from '../Field';
@@ -347,7 +348,10 @@ export interface ComplexSelectorRenderState {
347
348
  export interface ComplexSelectorHandle {
348
349
  /** Open the selector surface. No-op when disabled or already open. */
349
350
  open(): void;
350
- /** Close the selector surface. Restores focus to the trigger. */
351
+ /**
352
+ * Close the selector surface. Focus returns to the trigger only when it
353
+ * would otherwise be lost; a caller-rendered trigger always gets it back.
354
+ */
351
355
  close(): void;
352
356
  /** Toggle the selector surface open or closed. */
353
357
  toggle(): void;
@@ -630,12 +634,22 @@ export function ComplexSelector<Value>({
630
634
  onOpenChange?.(true);
631
635
  }, [onOpenChange]);
632
636
 
637
+ // The popup's content element, read when it closes.
638
+ const popupContentRef = useRef<HTMLElement | null>(null);
639
+ const hasCallerTrigger = renderTrigger != null;
633
640
  const handlePopoverHide = useCallback(() => {
634
- // Focus is restored first so a consumer that moves focus elsewhere from
635
- // the callback wins, instead of being overwritten a line later.
636
- triggerRef.current?.focus();
641
+ const trigger = triggerRef.current;
642
+ // A press that moved focus to another control keeps it there. A caller's
643
+ // control always gets focus back. Focus moves before the callback, so a
644
+ // consumer that moves it from the callback wins.
645
+ if (
646
+ hasCallerTrigger ||
647
+ isFocusLost(popupContentRef.current, trigger?.ownerDocument)
648
+ ) {
649
+ trigger?.focus();
650
+ }
637
651
  onOpenChange?.(false);
638
- }, [onOpenChange]);
652
+ }, [hasCallerTrigger, onOpenChange]);
639
653
 
640
654
  const popover = usePopover({
641
655
  dialogLabel: label,
@@ -645,6 +659,7 @@ export function ComplexSelector<Value>({
645
659
  onShow: handlePopoverShow,
646
660
  onHide: handlePopoverHide,
647
661
  });
662
+ popupContentRef.current = popover.contentRef.current;
648
663
 
649
664
  const isOpen = popover.isOpen;
650
665
 
@@ -712,14 +712,14 @@ export function ContextMenu({
712
712
  );
713
713
  const handleTriggerTouchEnd = useCallback(
714
714
  (event: React.TouchEvent<HTMLElement>) => {
715
- handleLongPressTouchEnd();
715
+ handleLongPressTouchEnd(event);
716
716
  onTouchEndProp?.(event);
717
717
  },
718
718
  [handleLongPressTouchEnd, onTouchEndProp],
719
719
  );
720
720
  const handleTriggerTouchCancel = useCallback(
721
721
  (event: React.TouchEvent<HTMLElement>) => {
722
- handleLongPressTouchCancel();
722
+ handleLongPressTouchCancel(event);
723
723
  onTouchCancelProp?.(event);
724
724
  },
725
725
  [handleLongPressTouchCancel, onTouchCancelProp],
@@ -51,7 +51,10 @@ import {
51
51
  borderVars,
52
52
  } from '../theme/tokens.stylex';
53
53
  import {focusOutlineStyles} from '../utils';
54
- import {plainDateFormatStandaloneMonthYear} from '../utils/plainDate';
54
+ import {
55
+ plainDateFormatDayNumber,
56
+ plainDateFormatStandaloneMonthYear,
57
+ } from '../utils/plainDate';
55
58
  import {
56
59
  type DayOfWeek,
57
60
  type ISODateString,
@@ -591,6 +594,7 @@ export function MonthScroller({
591
594
  * it cannot oscillate.
592
595
  */
593
596
  const settleFrameRef = useRef<number | undefined>(undefined);
597
+ // Releases the settle frame on unmount.
594
598
  useEffect(
595
599
  () => () => {
596
600
  if (settleFrameRef.current != null) {
@@ -663,6 +667,8 @@ export function MonthScroller({
663
667
  // rAF-throttled: a touch scroll fires far more scroll events than frames,
664
668
  // and all this does is move a label and widen a window.
665
669
  const frameRef = useRef<number | undefined>(undefined);
670
+ // Syncs scroll, touch and wheel listeners on the scroller with its measured
671
+ // height.
666
672
  useEffect(() => {
667
673
  const scroller = scrollerRef.current;
668
674
  // Not before the height is known. A listener attached while it was zero
@@ -1012,7 +1018,7 @@ function MonthPane({
1012
1018
  isToday && styles.puckToday,
1013
1019
  isSelected && styles.puckSelected,
1014
1020
  )}>
1015
- {day.dayNumber}
1021
+ {plainDateFormatDayNumber(day.dayNumber, locale)}
1016
1022
  </span>
1017
1023
  </button>
1018
1024
  </div>
@@ -676,6 +676,7 @@ export function TouchDateField({
676
676
  const scrollerHandleRef = useRef<MonthScrollerHandle | null>(null);
677
677
  // Pending focus handoff from the clear button; see handleClear.
678
678
  const clearFocusTimerRef = useRef<number | null>(null);
679
+ // Releases the focus timer on unmount.
679
680
  useEffect(
680
681
  () => () => {
681
682
  if (clearFocusTimerRef.current != null) {
@@ -462,6 +462,8 @@ export function Wheel({
462
462
  // useScrollSettle. The settle handler re-checks the position afterwards, so
463
463
  // a correction that is genuinely needed still happens, just at rest.
464
464
  const parkedRef = useRef(false);
465
+ // Syncs the wheel's scroll position with the selected index while the wheel
466
+ // is active.
465
467
  useEffect(() => {
466
468
  if (!isActive) {
467
469
  parkedRef.current = false;
@@ -492,6 +494,8 @@ export function Wheel({
492
494
  // Highlight follows the finger. rAF-throttled: a scroll can fire far more
493
495
  // often than the display refreshes, and this only feeds a repaint.
494
496
  const frameRef = useRef<number | undefined>(undefined);
497
+ // Syncs a scroll listener with the active wheel. It updates the highlighted
498
+ // row.
495
499
  useEffect(() => {
496
500
  const scroller = scrollerRef.current;
497
501
  if (scroller == null || !isActive) {
@@ -137,6 +137,8 @@ export function useOwnScrollGesture(
137
137
  const onSwipeRef = useRef(onSwipe);
138
138
  onSwipeRef.current = onSwipe;
139
139
 
140
+ // Syncs touch listeners on the element with `isEnabled`. They decide which
141
+ // gesture owns a horizontal scroll.
140
142
  useEffect(() => {
141
143
  const element = ref.current;
142
144
  if (element == null || !isEnabled) {
@@ -87,6 +87,7 @@ export function usePointerDragScroll(
87
87
  ): PointerDragScrollState {
88
88
  const isDraggingRef = useRef(false);
89
89
 
90
+ // Syncs pointer listeners with `isEnabled`. A mouse drag scrolls the element.
90
91
  useEffect(() => {
91
92
  const element = ref.current;
92
93
  if (element == null || !isEnabled) {
@@ -98,6 +98,8 @@ export function useScrollSettle(
98
98
 
99
99
  const isAtRestRef = useRef(true);
100
100
 
101
+ // Syncs scroll, touch and pointer listeners with `isEnabled`. They find when
102
+ // scrolling stops.
101
103
  useEffect(() => {
102
104
  const element = ref.current;
103
105
  if (element == null || !isEnabled) {
@@ -81,7 +81,10 @@ import {themeProps} from '../utils/themeProps';
81
81
  import type {DialogVariantMap} from './index';
82
82
  import {focusOutlineProps} from '../utils/focusOutline.stylex';
83
83
  import {useInteractionModalityTracking} from '../utils/interactionModality';
84
- import {focusForLastInput, isFocusLost} from '../utils/focusReturn';
84
+ import {
85
+ focusForLastInput,
86
+ prepareFocusReturnOnRemoval,
87
+ } from '../utils/focusReturn';
85
88
  import {ModalAnnounceProvider} from '../hooks/ModalAnnounceProvider';
86
89
 
87
90
  import {useMergedRefs} from '../hooks/useMergedRefs';
@@ -603,7 +606,8 @@ export function Dialog({
603
606
  const allowEscape = purpose !== 'required';
604
607
  const allowBackdropClick = purpose === 'info';
605
608
 
606
- // Handle open/close state — skip for inline rendering
609
+ // Syncs the native dialog with `isOpen` through `showModal()` and `close()`.
610
+ // An inline dialog is not in the top layer, so it skips this.
607
611
  useEffect(() => {
608
612
  if (isInline) {
609
613
  return;
@@ -653,39 +657,15 @@ export function Dialog({
653
657
  }, [isOpen, isInline]);
654
658
 
655
659
  // A dialog that unmounts while open (rendered only while open, or removed
656
- // with the rest of a view) never runs the close branch above, and removing a
657
- // <dialog> does not run the browser's own focus return. Focus left inside
658
- // it, or dropped to the body by the removal, goes back to the opener.
660
+ // with the rest of a view) never runs the close branch above. Focus the
661
+ // removal lost goes back to the opener.
659
662
  useEffect(() => {
660
- if (isInline) {
663
+ const dialog = dialogRef.current;
664
+ if (isInline || dialog == null) {
661
665
  return;
662
666
  }
663
- const dialog = dialogRef.current;
664
- // Read now: a removed iframe's document has no window, so its frame
665
- // element can no longer be found once the dialog is gone.
666
- const host = dialog?.ownerDocument.defaultView?.frameElement ?? null;
667
- return () => {
668
- const trigger = triggerElementRef.current;
669
- if (dialog == null || trigger == null) {
670
- return;
671
- }
672
- // Checked once the commit has finished: StrictMode's simulated unmount
673
- // leaves the dialog in the document, and only a real removal returns
674
- // focus.
675
- queueMicrotask(() => {
676
- if (dialog.isConnected || !trigger.isConnected) {
677
- return;
678
- }
679
- // isFocusLost reads the dialog's own document. For a dialog in an
680
- // iframe, the document that hosts the frame must also have lost focus
681
- // or keep it on that frame, wherever the opener is: a control the
682
- // user pressed outside the frame to remove the dialog, or the frame
683
- // itself, keeps its focus.
684
- if (isFocusLost(dialog) && (host == null || isFocusLost(host))) {
685
- focusForLastInput(trigger);
686
- }
687
- });
688
- };
667
+ const returnFocusOnRemoval = prepareFocusReturnOnRemoval(dialog);
668
+ return () => returnFocusOnRemoval(triggerElementRef.current);
689
669
  }, [isInline]);
690
670
 
691
671
  // Host app-global surfaces (toasts) inside this modal while it is open, so
@@ -131,6 +131,8 @@ export function useDrawerDialogPresence({
131
131
  // Element focused when the drawer opened — restored on close.
132
132
  const triggerElementRef = useRef<HTMLElement | null>(null);
133
133
 
134
+ // Syncs the drawer's native host with `isOpen`. It shows or hides the
135
+ // top-layer host, keeps the opener, waits for the exit, and returns focus.
134
136
  useEffect(() => {
135
137
  const dialog = dialogRef.current;
136
138
  if (!dialog) {
@@ -63,6 +63,8 @@ export function useMenuOverflow(
63
63
  );
64
64
  }, [menuRef]);
65
65
 
66
+ // Syncs the overflow measurement with the open menu. It measures, then
67
+ // observes resize, DOM changes and window resize.
66
68
  useIsomorphicLayoutEffect(() => {
67
69
  if (!isOpen) {
68
70
  return;
@@ -98,6 +100,7 @@ export function useMenuOverflow(
98
100
  };
99
101
  }, [isOpen, measureOverflow, menuRef]);
100
102
 
103
+ // Measures overflow again after the content changes while the menu is open.
101
104
  useIsomorphicLayoutEffect(() => {
102
105
  if (isOpen) {
103
106
  measureOverflow();
@@ -25,11 +25,11 @@ import {FieldStatus} from '../FieldStatus/FieldStatus';
25
25
  import {useFieldStatusAnnouncement} from '../FieldStatus/useFieldStatusAnnouncement';
26
26
  import {spacingVars, borderVars, sizeVars} from '../theme/tokens.stylex';
27
27
  import type {IconType} from '../Icon';
28
- import {mergeProps} from '../utils';
28
+ import {mergeProps} from '../utils/mergeProps';
29
29
  import {useDevWarning} from '../hooks/useDevWarning';
30
30
  import {FormLayoutContext} from '../FormLayout/FormLayoutContext';
31
31
  import {Text} from '../Text/Text';
32
- import {VisuallyHidden} from '../VisuallyHidden';
32
+ import {VisuallyHidden} from '../VisuallyHidden/VisuallyHidden';
33
33
  import {themeProps} from '../utils/themeProps';
34
34
  import type {FieldStatusPlacement} from './fieldStatusPlacement';
35
35
 
@@ -36,6 +36,7 @@ export function useFieldStatusAnnouncement(
36
36
  type: InputStatusType | undefined,
37
37
  ): void {
38
38
  const announce = useAnnounce();
39
+ // Syncs the live region with the status message.
39
40
  useEffect(() => {
40
41
  if (message) {
41
42
  announce(message, type === 'error' ? 'assertive' : 'polite');
@@ -7,7 +7,16 @@ export const docs = {
7
7
  displayName: 'Form Layout',
8
8
  group: 'Layout',
9
9
  category: 'Layout',
10
- keywords: ["formlayout","form","fieldset","formgroup","formcontainer","fields","vertical","horizontal"],
10
+ keywords: [
11
+ 'formlayout',
12
+ 'form',
13
+ 'fieldset',
14
+ 'formgroup',
15
+ 'formcontainer',
16
+ 'fields',
17
+ 'vertical',
18
+ 'horizontal',
19
+ ],
11
20
  props: [
12
21
  {
13
22
  name: 'direction',
@@ -20,7 +29,7 @@ export const docs = {
20
29
  name: 'defaultOptionality',
21
30
  type: "'optional' | 'required'",
22
31
  description:
23
- 'The state the form treats as its default, so only the exception shows an optional/required indicator. With "optional", only fields marked isRequired show an indicator; with "required", only fields marked isOptional do. A field that restates the default shows nothing. Under "required" the unmarked fields also expose aria-required so screen readers match the visual default; aria-required only, never the native required attribute. Leave unset for today\'s per-field behavior.',
32
+ 'The state the form treats as its default, so only the exception shows an optional/required indicator. With "optional", only fields marked isRequired show an indicator; with "required", only fields marked isOptional do. A field that restates the default shows nothing. Under "required" the unmarked fields also expose aria-required so screen readers match the visual default; aria-required only, never the native required attribute. CheckboxInput, Switch and CheckboxList are the exception: an unchecked box, an off switch or an empty group is an answer, so they take no required state from the default. A CheckboxInput or Switch is required only through its own isRequired. Leave unset for today\'s per-field behavior.',
24
33
  },
25
34
  {
26
35
  name: 'children',
@@ -36,25 +45,65 @@ export const docs = {
36
45
  },
37
46
  ],
38
47
  theming: {
39
- targets: [
40
- {className: 'astryx-form-layout', visualProps: ['direction']},
41
- ],
48
+ targets: [{className: 'astryx-form-layout', visualProps: ['direction']}],
42
49
  },
43
50
  usage: {
44
- description: 'A layout container that arranges form fields with consistent spacing and direction. FormLayout handles where fields go, not state or submission. Wrap it in a <form> for that. Supports vertical (default), horizontal, and horizontal-labels directions, and can be nested to mix them.',
51
+ description:
52
+ 'A layout container that arranges form fields with consistent spacing and direction. FormLayout handles where fields go, not state or submission. Wrap it in a <form> for that. Supports vertical (default), horizontal, and horizontal-labels directions, and can be nested to mix them.',
45
53
  bestPractices: [
46
- { guidance: true, description: 'Stack fields vertically for most forms. It\'s the easiest to scan top to bottom.' },
47
- { guidance: true, description: 'Nest a horizontal FormLayout inside a vertical one when fields naturally pair up, like First Name + Last Name or City + State + ZIP.' },
48
- { guidance: true, description: 'Use horizontal-labels for settings pages where labels sit beside their inputs.' },
49
- { guidance: false, description: 'Use FormLayout for form state or submission. It\'s just layout. Wrap it in a <form> for that.' },
50
- { guidance: false, description: 'Put unrelated fields side by side in a horizontal layout. Save it for fields that belong together.' },
51
- { guidance: false, description: 'Nest horizontal-labels inside another FormLayout. It uses CSS Grid and needs to be the outermost container.' },
54
+ {
55
+ guidance: true,
56
+ description:
57
+ "Stack fields vertically for most forms. It's the easiest to scan top to bottom.",
58
+ },
59
+ {
60
+ guidance: true,
61
+ description:
62
+ 'Nest a horizontal FormLayout inside a vertical one when fields naturally pair up, like First Name + Last Name or City + State + ZIP.',
63
+ },
64
+ {
65
+ guidance: true,
66
+ description:
67
+ 'Use horizontal-labels for settings pages where labels sit beside their inputs.',
68
+ },
69
+ {
70
+ guidance: false,
71
+ description:
72
+ "Use FormLayout for form state or submission. It's just layout. Wrap it in a <form> for that.",
73
+ },
74
+ {
75
+ guidance: false,
76
+ description:
77
+ 'Put unrelated fields side by side in a horizontal layout. Save it for fields that belong together.',
78
+ },
79
+ {
80
+ guidance: false,
81
+ description:
82
+ 'Nest horizontal-labels inside another FormLayout. It uses CSS Grid and needs to be the outermost container.',
83
+ },
52
84
  ],
53
85
  anatomy: [
54
- {name: 'Layout container', required: true, description: 'Owns field arrangement, spacing, direction, and form-level optionality.'},
55
- {name: 'Form title', required: false, description: 'Heading that describes the purpose of the form.'},
56
- {name: 'Fields', required: true, description: 'Input components with labels for collecting user data.'},
57
- {name: 'Footer', required: false, description: 'Contains confirmation buttons such as Submit or Cancel.'},
86
+ {
87
+ name: 'Layout container',
88
+ required: true,
89
+ description:
90
+ 'Owns field arrangement, spacing, direction, and form-level optionality.',
91
+ },
92
+ {
93
+ name: 'Form title',
94
+ required: false,
95
+ description: 'Heading that describes the purpose of the form.',
96
+ },
97
+ {
98
+ name: 'Fields',
99
+ required: true,
100
+ description: 'Input components with labels for collecting user data.',
101
+ },
102
+ {
103
+ name: 'Footer',
104
+ required: false,
105
+ description: 'Contains confirmation buttons such as Submit or Cancel.',
106
+ },
58
107
  ],
59
108
  },
60
109
  };
@@ -75,7 +124,7 @@ export const docsZh = {
75
124
  name: 'defaultOptionality',
76
125
  type: "'optional' | 'required'",
77
126
  description:
78
- '表单视为默认的状态,因此仅例外字段显示可选/必填指示器。设为 "optional" 时,仅标记 isRequired 的字段显示指示器;设为 "required" 时,仅标记 isOptional 的字段显示。与默认一致的字段不显示任何内容。设为 "required" 时,未标记的字段仍会暴露 aria-required,使屏幕阅读器与视觉默认一致——仅作用于 aria-required,不改变原生 required 属性。不设置则保持当前逐字段行为。',
127
+ '表单视为默认的状态,因此仅例外字段显示可选/必填指示器。设为 "optional" 时,仅标记 isRequired 的字段显示指示器;设为 "required" 时,仅标记 isOptional 的字段显示。与默认一致的字段不显示任何内容。设为 "required" 时,未标记的字段仍会暴露 aria-required,使屏幕阅读器与视觉默认一致——仅作用于 aria-required,不改变原生 required 属性。CheckboxInput、Switch 和 CheckboxList 例外:未勾选的复选框、关闭的开关或空的复选框组本身就是一个回答,因此默认值不会赋予它们必填状态。CheckboxInput 或 Switch 只有通过自身的 isRequired 才会成为必填。不设置则保持当前逐字段行为。',
79
128
  },
80
129
  {
81
130
  name: 'children',
@@ -91,25 +140,65 @@ export const docsZh = {
91
140
  },
92
141
  ],
93
142
  theming: {
94
- targets: [
95
- {className: 'astryx-form-layout', visualProps: ['direction']},
96
- ],
143
+ targets: [{className: 'astryx-form-layout', visualProps: ['direction']}],
97
144
  },
98
145
  usage: {
99
- description: 'A layout container that arranges form fields with consistent spacing and direction. FormLayout handles where fields go, not state or submission. Wrap it in a <form> for that. Supports vertical (default), horizontal, and horizontal-labels directions, and can be nested to mix them.',
146
+ description:
147
+ 'A layout container that arranges form fields with consistent spacing and direction. FormLayout handles where fields go, not state or submission. Wrap it in a <form> for that. Supports vertical (default), horizontal, and horizontal-labels directions, and can be nested to mix them.',
100
148
  bestPractices: [
101
- { guidance: true, description: 'Stack fields vertically for most forms. It\'s the easiest to scan top to bottom.' },
102
- { guidance: true, description: 'Nest a horizontal FormLayout inside a vertical one when fields naturally pair up, like First Name + Last Name or City + State + ZIP.' },
103
- { guidance: true, description: 'Use horizontal-labels for settings pages where labels sit beside their inputs.' },
104
- { guidance: false, description: 'Use FormLayout for form state or submission. It\'s just layout. Wrap it in a <form> for that.' },
105
- { guidance: false, description: 'Put unrelated fields side by side in a horizontal layout. Save it for fields that belong together.' },
106
- { guidance: false, description: 'Nest horizontal-labels inside another FormLayout. It uses CSS Grid and needs to be the outermost container.' },
149
+ {
150
+ guidance: true,
151
+ description:
152
+ "Stack fields vertically for most forms. It's the easiest to scan top to bottom.",
153
+ },
154
+ {
155
+ guidance: true,
156
+ description:
157
+ 'Nest a horizontal FormLayout inside a vertical one when fields naturally pair up, like First Name + Last Name or City + State + ZIP.',
158
+ },
159
+ {
160
+ guidance: true,
161
+ description:
162
+ 'Use horizontal-labels for settings pages where labels sit beside their inputs.',
163
+ },
164
+ {
165
+ guidance: false,
166
+ description:
167
+ "Use FormLayout for form state or submission. It's just layout. Wrap it in a <form> for that.",
168
+ },
169
+ {
170
+ guidance: false,
171
+ description:
172
+ 'Put unrelated fields side by side in a horizontal layout. Save it for fields that belong together.',
173
+ },
174
+ {
175
+ guidance: false,
176
+ description:
177
+ 'Nest horizontal-labels inside another FormLayout. It uses CSS Grid and needs to be the outermost container.',
178
+ },
107
179
  ],
108
180
  anatomy: [
109
- {name: 'Layout container', required: true, description: 'Owns field arrangement, spacing, direction, and form-level optionality.'},
110
- {name: 'Form title', required: false, description: 'Heading that describes the purpose of the form.'},
111
- {name: 'Fields', required: true, description: 'Input components with labels for collecting user data.'},
112
- {name: 'Footer', required: false, description: 'Contains confirmation buttons such as Submit or Cancel.'},
181
+ {
182
+ name: 'Layout container',
183
+ required: true,
184
+ description:
185
+ 'Owns field arrangement, spacing, direction, and form-level optionality.',
186
+ },
187
+ {
188
+ name: 'Form title',
189
+ required: false,
190
+ description: 'Heading that describes the purpose of the form.',
191
+ },
192
+ {
193
+ name: 'Fields',
194
+ required: true,
195
+ description: 'Input components with labels for collecting user data.',
196
+ },
197
+ {
198
+ name: 'Footer',
199
+ required: false,
200
+ description: 'Contains confirmation buttons such as Submit or Cancel.',
201
+ },
113
202
  ],
114
203
  },
115
204
  };
@@ -119,26 +208,72 @@ export const docsDense = {
119
208
  description:
120
209
  'Layout container for form fields w/ consistent spacing + direction.',
121
210
  usage: {
122
- description: 'A layout container that arranges form fields with consistent spacing and direction. FormLayout handles where fields go, not state or submission. Wrap it in a <form> for that. Supports vertical (default), horizontal, and horizontal-labels directions, and can be nested to mix them.',
211
+ description:
212
+ 'A layout container that arranges form fields with consistent spacing and direction. FormLayout handles where fields go, not state or submission. Wrap it in a <form> for that. Supports vertical (default), horizontal, and horizontal-labels directions, and can be nested to mix them.',
123
213
  bestPractices: [
124
- { guidance: true, description: 'Stack fields vertically for most forms. It\'s the easiest to scan top to bottom.' },
125
- { guidance: true, description: 'Nest a horizontal FormLayout inside a vertical one when fields naturally pair up, like First Name + Last Name or City + State + ZIP.' },
126
- { guidance: true, description: 'Use horizontal-labels for settings pages where labels sit beside their inputs.' },
127
- { guidance: false, description: 'Use FormLayout for form state or submission. It\'s just layout. Wrap it in a <form> for that.' },
128
- { guidance: false, description: 'Put unrelated fields side by side in a horizontal layout. Save it for fields that belong together.' },
129
- { guidance: false, description: 'Nest horizontal-labels inside another FormLayout. It uses CSS Grid and needs to be the outermost container.' },
214
+ {
215
+ guidance: true,
216
+ description:
217
+ "Stack fields vertically for most forms. It's the easiest to scan top to bottom.",
218
+ },
219
+ {
220
+ guidance: true,
221
+ description:
222
+ 'Nest a horizontal FormLayout inside a vertical one when fields naturally pair up, like First Name + Last Name or City + State + ZIP.',
223
+ },
224
+ {
225
+ guidance: true,
226
+ description:
227
+ 'Use horizontal-labels for settings pages where labels sit beside their inputs.',
228
+ },
229
+ {
230
+ guidance: false,
231
+ description:
232
+ "Use FormLayout for form state or submission. It's just layout. Wrap it in a <form> for that.",
233
+ },
234
+ {
235
+ guidance: false,
236
+ description:
237
+ 'Put unrelated fields side by side in a horizontal layout. Save it for fields that belong together.',
238
+ },
239
+ {
240
+ guidance: false,
241
+ description:
242
+ 'Nest horizontal-labels inside another FormLayout. It uses CSS Grid and needs to be the outermost container.',
243
+ },
130
244
  ],
131
245
  anatomy: [
132
- {name: 'Layout container', required: true, description: 'Owns field arrangement, spacing, direction, and form-level optionality.'},
133
- {name: 'Form title', required: false, description: 'Heading that describes the purpose of the form.'},
134
- {name: 'Fields', required: true, description: 'Input components with labels for collecting user data.'},
135
- {name: 'Footer', required: false, description: 'Contains confirmation buttons such as Submit or Cancel.'},
246
+ {
247
+ name: 'Layout container',
248
+ required: true,
249
+ description:
250
+ 'Owns field arrangement, spacing, direction, and form-level optionality.',
251
+ },
252
+ {
253
+ name: 'Form title',
254
+ required: false,
255
+ description: 'Heading that describes the purpose of the form.',
256
+ },
257
+ {
258
+ name: 'Fields',
259
+ required: true,
260
+ description: 'Input components with labels for collecting user data.',
261
+ },
262
+ {
263
+ name: 'Footer',
264
+ required: false,
265
+ description: 'Contains confirmation buttons such as Submit or Cancel.',
266
+ },
136
267
  ],
137
268
  },
138
269
  propDescriptions: {
139
- direction: 'Field arrangement. Vertical stacks top-to-bottom; horizontal uses one fractional grid track per field in logical inline order; horizontal-labels places labels on the inline-start side and collapses when the viewport is <=480px.',
140
- defaultOptionality: 'State the form treats as default, so only the exception is marked. "optional" → only isRequired fields show an indicator; "required" → only isOptional fields do. Under "required" unmarked fields also expose aria-required (aria only, not native required). Unset = per-field behavior.',
141
- children: 'Form fields to arrange. Accepts Astryx inputs + Field-wrapped custom controls.',
142
- xstyle: 'StyleX styles for layout customization. Must be stylex.create() value.',
270
+ direction:
271
+ 'Field arrangement. Vertical stacks top-to-bottom; horizontal uses one fractional grid track per field in logical inline order; horizontal-labels places labels on the inline-start side and collapses when the viewport is <=480px.',
272
+ defaultOptionality:
273
+ 'State the form treats as default, so only the exception is marked. "optional" → only isRequired fields show an indicator; "required" → only isOptional fields do. Under "required" unmarked fields also expose aria-required (aria only, not native required), except CheckboxInput, Switch and CheckboxList, which take no required state from it (CheckboxInput and Switch are required only through their own isRequired). Unset = per-field behavior.',
274
+ children:
275
+ 'Form fields to arrange. Accepts Astryx inputs + Field-wrapped custom controls.',
276
+ xstyle:
277
+ 'StyleX styles for layout customization. Must be stylex.create() value.',
143
278
  },
144
279
  };
@@ -103,7 +103,11 @@ export interface FormLayoutProps extends BaseProps<HTMLDivElement> {
103
103
  * shows an indicator (the "required" one).
104
104
  * - `'required'` — fields read as required; only a field with `isOptional`
105
105
  * shows an indicator (the "optional" one). Fields without `isOptional`
106
- * expose `aria-required` even though they show no indicator.
106
+ * expose `aria-required` even though they show no indicator. Checkboxes,
107
+ * switches and checkbox groups are the exception: an unchecked box, an off
108
+ * switch or an empty group is an answer, so they take no required state
109
+ * from the default. A checkbox or switch is required only through its own
110
+ * `isRequired`.
107
111
  * - unset — today's behavior: `isRequired` and `isOptional` each show their
108
112
  * own indicator independently.
109
113
  *