@astryxdesign/core 0.7.7 → 0.7.8-canary.0b39b51

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 (581) 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/PickerWheel.d.ts +19 -0
  50. package/dist/DateInput/PickerWheel.d.ts.map +1 -0
  51. package/dist/DateInput/PickerWheel.js +625 -0
  52. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  53. package/dist/DateInput/TouchDateField.js +1 -0
  54. package/dist/DateInput/Wheel.d.ts +18 -37
  55. package/dist/DateInput/Wheel.d.ts.map +1 -1
  56. package/dist/DateInput/Wheel.js +84 -113
  57. package/dist/DateInput/useOwnScrollGesture.d.ts +10 -0
  58. package/dist/DateInput/useOwnScrollGesture.d.ts.map +1 -1
  59. package/dist/DateInput/useOwnScrollGesture.js +16 -3
  60. package/dist/DateInput/usePointerDragScroll.d.ts.map +1 -1
  61. package/dist/DateInput/usePointerDragScroll.js +2 -0
  62. package/dist/DateInput/useScrollSettle.d.ts.map +1 -1
  63. package/dist/DateInput/useScrollSettle.js +3 -0
  64. package/dist/DateInput/useWheelListbox.d.ts +59 -0
  65. package/dist/DateInput/useWheelListbox.d.ts.map +1 -0
  66. package/dist/DateInput/useWheelListbox.js +88 -0
  67. package/dist/DateInput/wheelOptions.d.ts +74 -0
  68. package/dist/DateInput/wheelOptions.d.ts.map +1 -0
  69. package/dist/DateInput/wheelOptions.js +98 -0
  70. package/dist/DateInput/wheelPhysics.d.ts +127 -0
  71. package/dist/DateInput/wheelPhysics.d.ts.map +1 -0
  72. package/dist/DateInput/wheelPhysics.js +341 -0
  73. package/dist/DateInput/wheelStrip.d.ts +92 -0
  74. package/dist/DateInput/wheelStrip.d.ts.map +1 -0
  75. package/dist/DateInput/wheelStrip.js +258 -0
  76. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  77. package/dist/DateTimeInput/TouchDateTimeField.js +2 -0
  78. package/dist/Dialog/Dialog.d.ts.map +1 -1
  79. package/dist/Dialog/Dialog.js +9 -32
  80. package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -1
  81. package/dist/Drawer/useDrawerDialogPresence.js +3 -0
  82. package/dist/DropdownMenu/useMenuOverflow.d.ts.map +1 -1
  83. package/dist/DropdownMenu/useMenuOverflow.js +5 -0
  84. package/dist/Field/Field.js +2 -2
  85. package/dist/FieldStatus/useFieldStatusAnnouncement.d.ts.map +1 -1
  86. package/dist/FieldStatus/useFieldStatusAnnouncement.js +1 -0
  87. package/dist/FormLayout/FormLayout.d.ts +5 -1
  88. package/dist/FormLayout/FormLayout.d.ts.map +1 -1
  89. package/dist/HoverCard/HoverCard.d.ts +6 -4
  90. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  91. package/dist/HoverCard/HoverCard.js +48 -3
  92. package/dist/HoverCard/useHoverCard.d.ts +5 -4
  93. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  94. package/dist/HoverCard/useHoverCard.js +20 -33
  95. package/dist/Icon/Icon.d.ts +5 -1
  96. package/dist/Icon/Icon.d.ts.map +1 -1
  97. package/dist/Icon/Icon.js +5 -2
  98. package/dist/Item/useSwipeAction.d.ts.map +1 -1
  99. package/dist/Item/useSwipeAction.js +3 -0
  100. package/dist/Layer/modalOutlet.d.ts.map +1 -1
  101. package/dist/Layer/modalOutlet.js +2 -0
  102. package/dist/Layer/outsidePress.d.ts.map +1 -1
  103. package/dist/Layer/outsidePress.js +1 -0
  104. package/dist/Layer/useLayer.d.ts.map +1 -1
  105. package/dist/Layer/useLayer.js +3 -0
  106. package/dist/Layer/useLayerDismissal.d.ts.map +1 -1
  107. package/dist/Layer/useLayerDismissal.js +3 -0
  108. package/dist/Layer/usePressPin.d.ts +17 -5
  109. package/dist/Layer/usePressPin.d.ts.map +1 -1
  110. package/dist/Layer/usePressPin.js +62 -12
  111. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  112. package/dist/Layer/useTouchTrigger.js +3 -0
  113. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  114. package/dist/Lightbox/Lightbox.js +19 -0
  115. package/dist/MobileNav/MobileNav.d.ts +3 -2
  116. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  117. package/dist/MobileNav/MobileNav.js +9 -25
  118. package/dist/Outline/useOutlineFromDOM.d.ts.map +1 -1
  119. package/dist/Outline/useOutlineFromDOM.js +3 -0
  120. package/dist/Outline/useScrollSpy.d.ts.map +1 -1
  121. package/dist/Outline/useScrollSpy.js +3 -0
  122. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  123. package/dist/OverflowList/OverflowList.js +3 -0
  124. package/dist/Popover/Popover.d.ts.map +1 -1
  125. package/dist/Popover/Popover.js +6 -0
  126. package/dist/PowerSearch/PowerSearch.d.ts +43 -4
  127. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  128. package/dist/PowerSearch/PowerSearch.js +445 -134
  129. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts +102 -0
  130. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +1 -0
  131. package/dist/PowerSearch/PowerSearchBottomSheet.js +1919 -0
  132. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +35 -2
  133. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  134. package/dist/PowerSearch/PowerSearchEditPopover.js +25 -6
  135. package/dist/PowerSearch/PowerSearchFilterEditor.d.ts +1 -1
  136. package/dist/PowerSearch/PowerSearchFilterEditor.d.ts.map +1 -1
  137. package/dist/PowerSearch/PowerSearchFilterEditor.js +4 -2
  138. package/dist/PowerSearch/PowerSearchToken.d.ts +1 -1
  139. package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
  140. package/dist/PowerSearch/PowerSearchToken.js +7 -2
  141. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +38 -3
  142. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  143. package/dist/PowerSearch/PowerSearchValueEditor.js +193 -83
  144. package/dist/PowerSearch/formatFilterValue.d.ts +18 -6
  145. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  146. package/dist/PowerSearch/formatFilterValue.js +33 -12
  147. package/dist/PowerSearch/formatTokenValue.d.ts +28 -0
  148. package/dist/PowerSearch/formatTokenValue.d.ts.map +1 -0
  149. package/dist/PowerSearch/formatTokenValue.js +162 -0
  150. package/dist/PowerSearch/powerSearchDateZone.d.ts +21 -0
  151. package/dist/PowerSearch/powerSearchDateZone.d.ts.map +1 -0
  152. package/dist/PowerSearch/powerSearchDateZone.js +37 -0
  153. package/dist/PowerSearch/powerSearchSheetUtils.d.ts +65 -0
  154. package/dist/PowerSearch/powerSearchSheetUtils.d.ts.map +1 -0
  155. package/dist/PowerSearch/powerSearchSheetUtils.js +168 -0
  156. package/dist/PowerSearch/types.d.ts +2 -0
  157. package/dist/PowerSearch/types.d.ts.map +1 -1
  158. package/dist/ProgressBar/ProgressBarTouch.d.ts.map +1 -1
  159. package/dist/ProgressBar/ProgressBarTouch.js +2 -0
  160. package/dist/RadioList/RadioList.d.ts.map +1 -1
  161. package/dist/RadioList/RadioList.js +3 -2
  162. package/dist/RadioList/RadioListItem.d.ts +1 -1
  163. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  164. package/dist/RadioList/RadioListItem.js +5 -3
  165. package/dist/Resizable/ResizeHandle.d.ts +2 -1
  166. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  167. package/dist/Resizable/ResizeHandle.js +101 -77
  168. package/dist/Resizable/createResizable.d.ts +145 -0
  169. package/dist/Resizable/createResizable.d.ts.map +1 -0
  170. package/dist/Resizable/createResizable.js +575 -0
  171. package/dist/Resizable/useResizable.d.ts +3 -3
  172. package/dist/Resizable/useResizable.d.ts.map +1 -1
  173. package/dist/Resizable/useResizable.js +252 -459
  174. package/dist/SegmentedControl/useSegmentedSelectionMotion.d.ts.map +1 -1
  175. package/dist/SegmentedControl/useSegmentedSelectionMotion.js +3 -3
  176. package/dist/SelectableCard/SelectableCard.d.ts +2 -0
  177. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  178. package/dist/SelectableCard/SelectableCard.js +36 -11
  179. package/dist/SelectableCard/selectableCardInput.d.ts +12 -0
  180. package/dist/SelectableCard/selectableCardInput.d.ts.map +1 -0
  181. package/dist/SelectableCard/selectableCardInput.js +20 -0
  182. package/dist/Selector/Selector.d.ts.map +1 -1
  183. package/dist/Selector/Selector.js +5 -8
  184. package/dist/Slider/sliderTouchController.js +2 -2
  185. package/dist/Spinner/Spinner.d.ts +1 -1
  186. package/dist/Spinner/Spinner.d.ts.map +1 -1
  187. package/dist/Spinner/Spinner.js +60 -58
  188. package/dist/Switch/Switch.d.ts.map +1 -1
  189. package/dist/Switch/Switch.js +4 -10
  190. package/dist/Switch/useSwitchTouch.js +4 -4
  191. package/dist/Table/BaseTable.d.ts.map +1 -1
  192. package/dist/Table/BaseTable.js +29 -8
  193. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  194. package/dist/Table/plugins/columnResize/useTableColumnResize.js +3 -1
  195. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  196. package/dist/Table/plugins/filtering/useTableFiltering.js +2 -1
  197. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  198. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +4 -0
  199. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  200. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +2 -0
  201. package/dist/TextInput/TextInput.d.ts +2 -2
  202. package/dist/TextInput/TextInput.d.ts.map +1 -1
  203. package/dist/TextInput/TextInput.js +10 -7
  204. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  205. package/dist/TimeInput/TimeInput.js +2 -0
  206. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
  207. package/dist/TimeInput/TouchTimeField.js +2 -0
  208. package/dist/Timer/Timer.d.ts.map +1 -1
  209. package/dist/Timer/Timer.js +2 -0
  210. package/dist/Timestamp/Timestamp.js +1 -1
  211. package/dist/Toast/Toast.d.ts +11 -1
  212. package/dist/Toast/Toast.d.ts.map +1 -1
  213. package/dist/Toast/Toast.js +25 -15
  214. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  215. package/dist/Toast/ToastViewport.js +97 -34
  216. package/dist/Toast/types.d.ts +9 -3
  217. package/dist/Toast/types.d.ts.map +1 -1
  218. package/dist/Toast/useToast.d.ts.map +1 -1
  219. package/dist/Toast/useToast.js +1 -0
  220. package/dist/Tokenizer/Tokenizer.d.ts +49 -37
  221. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  222. package/dist/Tokenizer/Tokenizer.js +22 -19
  223. package/dist/Tokenizer/TokenizerBottomSheet.d.ts +1 -1
  224. package/dist/Tokenizer/TokenizerBottomSheet.js +1 -1
  225. package/dist/Tokenizer/index.d.ts +1 -1
  226. package/dist/Tokenizer/index.d.ts.map +1 -1
  227. package/dist/Tooltip/useTooltip.d.ts +19 -1
  228. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  229. package/dist/Tooltip/useTooltip.js +34 -53
  230. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  231. package/dist/Typeahead/BaseTypeahead.js +27 -18
  232. package/dist/Typeahead/TypeaheadItem.d.ts +2 -1
  233. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  234. package/dist/animator/createAnimator.d.ts +98 -0
  235. package/dist/animator/createAnimator.d.ts.map +1 -0
  236. package/dist/animator/createAnimator.js +259 -0
  237. package/dist/astryx.css +39 -6
  238. package/dist/gestures/GestureHost.d.ts +16 -1
  239. package/dist/gestures/GestureHost.d.ts.map +1 -1
  240. package/dist/gestures/GestureHost.js +1 -1
  241. package/dist/gestures/PressTracker.d.ts.map +1 -1
  242. package/dist/gestures/PressTracker.js +4 -3
  243. package/dist/hooks/ModalAnnounceProvider.d.ts.map +1 -1
  244. package/dist/hooks/ModalAnnounceProvider.js +1 -0
  245. package/dist/hooks/actionGroupTracker.d.ts +4 -1
  246. package/dist/hooks/actionGroupTracker.d.ts.map +1 -1
  247. package/dist/hooks/actionGroupTracker.js +13 -3
  248. package/dist/hooks/index.d.ts +1 -0
  249. package/dist/hooks/index.d.ts.map +1 -1
  250. package/dist/hooks/index.js +1 -0
  251. package/dist/hooks/longPressDetector.d.ts +66 -0
  252. package/dist/hooks/longPressDetector.d.ts.map +1 -0
  253. package/dist/hooks/longPressDetector.js +200 -0
  254. package/dist/hooks/pressGroupContext.d.ts +6 -0
  255. package/dist/hooks/pressGroupContext.d.ts.map +1 -0
  256. package/dist/hooks/pressGroupContext.js +20 -0
  257. package/dist/hooks/rootScrollStyles.d.ts +48 -0
  258. package/dist/hooks/rootScrollStyles.d.ts.map +1 -0
  259. package/dist/hooks/rootScrollStyles.js +207 -0
  260. package/dist/hooks/scrollLockTouchGuard.d.ts +13 -0
  261. package/dist/hooks/scrollLockTouchGuard.d.ts.map +1 -0
  262. package/dist/hooks/scrollLockTouchGuard.js +134 -0
  263. package/dist/hooks/scrollbarGutter.d.ts +4 -4
  264. package/dist/hooks/scrollbarGutter.d.ts.map +1 -1
  265. package/dist/hooks/scrollbarGutter.js +36 -23
  266. package/dist/hooks/useActionGroupTracking.d.ts +53 -0
  267. package/dist/hooks/useActionGroupTracking.d.ts.map +1 -0
  268. package/dist/hooks/useActionGroupTracking.js +174 -0
  269. package/dist/hooks/useAnimator.d.ts +41 -0
  270. package/dist/hooks/useAnimator.d.ts.map +1 -0
  271. package/dist/hooks/useAnimator.js +70 -0
  272. package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
  273. package/dist/hooks/useAnnounceRenderedText.js +1 -0
  274. package/dist/hooks/useAttachment.d.ts +1 -1
  275. package/dist/hooks/useAttachment.js +1 -1
  276. package/dist/hooks/useAutoMediaMode.d.ts.map +1 -1
  277. package/dist/hooks/useAutoMediaMode.js +1 -0
  278. package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
  279. package/dist/hooks/useBusyAnnouncement.js +2 -0
  280. package/dist/hooks/useDevWarning.d.ts.map +1 -1
  281. package/dist/hooks/useDevWarning.js +2 -0
  282. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  283. package/dist/hooks/useFocusTrap.js +2 -0
  284. package/dist/hooks/useGridFocus.d.ts +8 -5
  285. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  286. package/dist/hooks/useGridFocus.js +4 -3
  287. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  288. package/dist/hooks/useHotkeys.js +3 -0
  289. package/dist/hooks/useImageMode.d.ts.map +1 -1
  290. package/dist/hooks/useImageMode.js +3 -0
  291. package/dist/hooks/useInputStatusIcon.d.ts +1 -1
  292. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  293. package/dist/hooks/useInputStatusIcon.js +2 -2
  294. package/dist/hooks/useKeyboardHint.js +1 -1
  295. package/dist/hooks/useLongPress.d.ts +8 -9
  296. package/dist/hooks/useLongPress.d.ts.map +1 -1
  297. package/dist/hooks/useLongPress.js +23 -106
  298. package/dist/hooks/useMenuHover.d.ts.map +1 -1
  299. package/dist/hooks/useMenuHover.js +2 -0
  300. package/dist/hooks/useMenuPress.d.ts.map +1 -1
  301. package/dist/hooks/useMenuPress.js +3 -0
  302. package/dist/hooks/useOverflow.d.ts.map +1 -1
  303. package/dist/hooks/useOverflow.js +2 -1
  304. package/dist/hooks/usePressFeedback.d.ts.map +1 -1
  305. package/dist/hooks/usePressFeedback.js +1 -0
  306. package/dist/hooks/useResolvedRequired.d.ts +3 -0
  307. package/dist/hooks/useResolvedRequired.d.ts.map +1 -1
  308. package/dist/hooks/useResolvedRequired.js +3 -0
  309. package/dist/hooks/useScrollLock.d.ts +7 -9
  310. package/dist/hooks/useScrollLock.d.ts.map +1 -1
  311. package/dist/hooks/useScrollLock.js +55 -48
  312. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  313. package/dist/hooks/useScrollableArea.js +5 -0
  314. package/dist/hooks/useStreamingText.d.ts.map +1 -1
  315. package/dist/hooks/useStreamingText.js +3 -0
  316. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts +8 -0
  317. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts.map +1 -0
  318. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.js +42 -0
  319. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.d.ts.map +1 -1
  320. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.js +6 -0
  321. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts +8 -0
  322. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts.map +1 -0
  323. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.js +14 -0
  324. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  325. package/dist/i18n/generated-locales/en.generated.js +30 -0
  326. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  327. package/dist/i18n/generated-locales/pseudo.generated.js +30 -0
  328. package/dist/index.d.ts +1 -0
  329. package/dist/index.d.ts.map +1 -1
  330. package/dist/index.js +4 -0
  331. package/dist/internal/indicatorPress.stylex.d.ts +20 -0
  332. package/dist/internal/indicatorPress.stylex.d.ts.map +1 -0
  333. package/dist/internal/indicatorPress.stylex.js +26 -0
  334. package/dist/internal/selectable-card.d.ts +21 -0
  335. package/dist/internal/selectable-card.d.ts.map +1 -0
  336. package/dist/internal/selectable-card.js +20 -0
  337. package/dist/internal/sheetDraft.d.ts +2 -2
  338. package/dist/internal/sheetDraft.js +2 -2
  339. package/dist/motion/animatedLayout.d.ts.map +1 -1
  340. package/dist/motion/animatedLayout.js +7 -7
  341. package/dist/motion/animator.d.ts +14 -14
  342. package/dist/motion/animator.d.ts.map +1 -1
  343. package/dist/motion/animator.js +45 -20
  344. package/dist/motion/progress.d.ts +88 -0
  345. package/dist/motion/progress.d.ts.map +1 -0
  346. package/dist/motion/progress.js +128 -0
  347. package/dist/motion/reducedMotion.d.ts.map +1 -1
  348. package/dist/motion/reducedMotion.js +3 -1
  349. package/dist/motion/uikit/alert.d.ts +41 -0
  350. package/dist/motion/uikit/alert.d.ts.map +1 -0
  351. package/dist/motion/uikit/alert.js +43 -0
  352. package/dist/motion/uikit/index.d.ts +4 -3
  353. package/dist/motion/uikit/index.d.ts.map +1 -1
  354. package/dist/motion/uikit/index.js +4 -3
  355. package/dist/motion/uikit/picker.d.ts +96 -0
  356. package/dist/motion/uikit/picker.d.ts.map +1 -0
  357. package/dist/motion/uikit/picker.js +117 -0
  358. package/dist/privateAttributes/pressGroupItem.stylex.d.ts +22 -0
  359. package/dist/privateAttributes/pressGroupItem.stylex.d.ts.map +1 -0
  360. package/dist/privateAttributes/pressGroupItem.stylex.js +36 -0
  361. package/dist/privateAttributes/reducedMotion.stylex.d.ts +23 -0
  362. package/dist/privateAttributes/reducedMotion.stylex.d.ts.map +1 -0
  363. package/dist/privateAttributes/reducedMotion.stylex.js +40 -0
  364. package/dist/theme/Theme.d.ts.map +1 -1
  365. package/dist/theme/Theme.js +29 -4
  366. package/dist/theme/motionKnobs.d.ts +4 -3
  367. package/dist/theme/motionKnobs.d.ts.map +1 -1
  368. package/dist/theme/motionKnobs.js +3 -2
  369. package/dist/theme/themeMotion.d.ts +6 -0
  370. package/dist/theme/themeMotion.d.ts.map +1 -1
  371. package/dist/theme/themeMotion.js +7 -0
  372. package/dist/utils/dateParser.d.ts.map +1 -1
  373. package/dist/utils/dateParser.js +12 -0
  374. package/dist/utils/focusReturn.d.ts +15 -0
  375. package/dist/utils/focusReturn.d.ts.map +1 -1
  376. package/dist/utils/focusReturn.js +28 -0
  377. package/dist/utils/interactionModality.d.ts.map +1 -1
  378. package/dist/utils/interactionModality.js +4 -0
  379. package/dist/utils/interactionOverlay.stylex.d.ts +3 -2
  380. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  381. package/dist/utils/interactionOverlay.stylex.js +3 -2
  382. package/dist/utils/plainDate.d.ts +8 -0
  383. package/dist/utils/plainDate.d.ts.map +1 -1
  384. package/dist/utils/plainDate.js +19 -0
  385. package/dist/utils/pressFeedback.d.ts.map +1 -1
  386. package/dist/utils/pressFeedback.js +20 -6
  387. package/dist/utils/triggerFocus.d.ts +36 -0
  388. package/dist/utils/triggerFocus.d.ts.map +1 -0
  389. package/dist/utils/triggerFocus.js +65 -0
  390. package/locales/en.json +120 -0
  391. package/locales/pseudo.json +90 -0
  392. package/package.json +14 -9
  393. package/src/AlertDialog/AlertDialog.doc.mjs +2 -2
  394. package/src/AlertDialog/AlertDialog.tsx +46 -5
  395. package/src/AppShell/AppShell.tsx +4 -0
  396. package/src/BottomSheet/BottomSheet.tsx +1 -0
  397. package/src/BottomSheet/BottomSheetPanel.tsx +39 -3
  398. package/src/BottomSheet/BottomSheetSwitcher.tsx +5 -0
  399. package/src/BottomSheet/useMobileKeyboard.ts +4 -0
  400. package/src/BottomSheet/useSheetGestures.ts +10 -1
  401. package/src/Button/Button.tsx +26 -4
  402. package/src/Calendar/Calendar.tsx +36 -25
  403. package/src/Carousel/Carousel.tsx +1 -0
  404. package/src/Chat/ChatComposerInput.tsx +2 -0
  405. package/src/Chat/ChatMessageList.tsx +2 -1
  406. package/src/Chat/useChatDictation.ts +1 -0
  407. package/src/Chat/useChatNewMessages.ts +1 -1
  408. package/src/Chat/useChatStreamScroll.ts +2 -0
  409. package/src/Chat/useSpeechRecognition.ts +2 -0
  410. package/src/Chat/useTriggerMenu.tsx +1 -1
  411. package/src/CheckboxInput/CheckboxInput.doc.mjs +18 -0
  412. package/src/CheckboxInput/CheckboxInput.tsx +38 -15
  413. package/src/CodeBlock/CodeBlock.doc.mjs +9 -1
  414. package/src/CodeBlock/CodeBlock.tsx +41 -4
  415. package/src/CommandPalette/CommandPalette.tsx +1 -0
  416. package/src/CommandPalette/CommandPaletteItem.tsx +1 -0
  417. package/src/ComplexSelector/ComplexSelector.tsx +20 -5
  418. package/src/ContextMenu/ContextMenu.tsx +2 -2
  419. package/src/DateInput/MonthScroller.tsx +8 -2
  420. package/src/DateInput/PickerWheel.tsx +765 -0
  421. package/src/DateInput/TouchDateField.tsx +1 -0
  422. package/src/DateInput/Wheel.tsx +94 -150
  423. package/src/DateInput/useOwnScrollGesture.ts +25 -3
  424. package/src/DateInput/usePointerDragScroll.ts +1 -0
  425. package/src/DateInput/useScrollSettle.ts +2 -0
  426. package/src/DateInput/useWheelListbox.ts +112 -0
  427. package/src/DateInput/wheelOptions.ts +155 -0
  428. package/src/DateInput/wheelPhysics.ts +406 -0
  429. package/src/DateInput/wheelStrip.ts +341 -0
  430. package/src/DateTimeInput/TouchDateTimeField.tsx +2 -0
  431. package/src/Dialog/Dialog.tsx +12 -32
  432. package/src/Drawer/useDrawerDialogPresence.ts +2 -0
  433. package/src/DropdownMenu/useMenuOverflow.ts +3 -0
  434. package/src/Field/Field.tsx +2 -2
  435. package/src/FieldStatus/useFieldStatusAnnouncement.ts +1 -0
  436. package/src/FormLayout/FormLayout.doc.mjs +181 -46
  437. package/src/FormLayout/FormLayout.tsx +5 -1
  438. package/src/HoverCard/HoverCard.doc.mjs +10 -8
  439. package/src/HoverCard/HoverCard.tsx +58 -6
  440. package/src/HoverCard/useHoverCard.doc.mjs +178 -36
  441. package/src/HoverCard/useHoverCard.tsx +49 -54
  442. package/src/Icon/Icon.doc.mjs +49 -8
  443. package/src/Icon/Icon.tsx +15 -7
  444. package/src/IconButton/IconButton.doc.mjs +141 -21
  445. package/src/Item/useSwipeAction.ts +2 -0
  446. package/src/Layer/modalOutlet.ts +2 -0
  447. package/src/Layer/outsidePress.ts +1 -0
  448. package/src/Layer/useLayer.tsx +2 -0
  449. package/src/Layer/useLayerDismissal.ts +2 -0
  450. package/src/Layer/usePressPin.ts +81 -15
  451. package/src/Layer/useTouchTrigger.ts +2 -0
  452. package/src/Lightbox/Lightbox.tsx +19 -0
  453. package/src/MobileNav/MobileNav.tsx +9 -30
  454. package/src/Outline/useOutlineFromDOM.ts +2 -0
  455. package/src/Outline/useScrollSpy.ts +2 -0
  456. package/src/OverflowList/OverflowList.tsx +2 -0
  457. package/src/Popover/Popover.tsx +4 -0
  458. package/src/PowerSearch/PowerSearch.doc.mjs +60 -8
  459. package/src/PowerSearch/PowerSearch.tsx +627 -157
  460. package/src/PowerSearch/PowerSearchBottomSheet.tsx +2525 -0
  461. package/src/PowerSearch/PowerSearchEditPopover.tsx +39 -6
  462. package/src/PowerSearch/PowerSearchFilterEditor.tsx +2 -0
  463. package/src/PowerSearch/PowerSearchToken.tsx +7 -0
  464. package/src/PowerSearch/PowerSearchValueEditor.tsx +244 -58
  465. package/src/PowerSearch/formatFilterValue.ts +55 -17
  466. package/src/PowerSearch/formatTokenValue.ts +222 -0
  467. package/src/PowerSearch/powerSearchDateZone.ts +64 -0
  468. package/src/PowerSearch/powerSearchSheetUtils.ts +224 -0
  469. package/src/PowerSearch/types.ts +2 -0
  470. package/src/ProgressBar/ProgressBarTouch.ts +2 -0
  471. package/src/RadioList/RadioList.tsx +3 -2
  472. package/src/RadioList/RadioListItem.tsx +5 -3
  473. package/src/Resizable/Resizable.doc.mjs +5 -4
  474. package/src/Resizable/ResizeHandle.tsx +169 -109
  475. package/src/Resizable/createResizable.ts +831 -0
  476. package/src/Resizable/useResizable.ts +292 -623
  477. package/src/SegmentedControl/useSegmentedSelectionMotion.ts +6 -3
  478. package/src/SelectableCard/SelectableCard.tsx +39 -10
  479. package/src/SelectableCard/selectableCardInput.ts +30 -0
  480. package/src/Selector/Selector.tsx +5 -12
  481. package/src/Slider/sliderTouchController.ts +2 -2
  482. package/src/Spinner/Spinner.tsx +77 -63
  483. package/src/Switch/Switch.tsx +2 -6
  484. package/src/Switch/useSwitchTouch.ts +4 -4
  485. package/src/Table/BaseTable.tsx +46 -12
  486. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +2 -1
  487. package/src/Table/plugins/filtering/useTableFiltering.tsx +1 -0
  488. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +4 -0
  489. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +2 -0
  490. package/src/TextInput/TextInput.tsx +11 -10
  491. package/src/TimeInput/TimeInput.tsx +2 -0
  492. package/src/TimeInput/TouchTimeField.tsx +2 -0
  493. package/src/Timer/Timer.tsx +1 -0
  494. package/src/Timestamp/Timestamp.tsx +1 -1
  495. package/src/Toast/Toast.doc.mjs +4 -3
  496. package/src/Toast/Toast.tsx +52 -32
  497. package/src/Toast/ToastViewport.tsx +123 -35
  498. package/src/Toast/types.ts +9 -3
  499. package/src/Toast/useToast.tsx +1 -0
  500. package/src/Tokenizer/Tokenizer.doc.mjs +19 -3
  501. package/src/Tokenizer/Tokenizer.tsx +73 -51
  502. package/src/Tokenizer/TokenizerBottomSheet.tsx +1 -1
  503. package/src/Tokenizer/index.ts +1 -0
  504. package/src/Tooltip/useTooltip.doc.mjs +24 -0
  505. package/src/Tooltip/useTooltip.tsx +61 -56
  506. package/src/Typeahead/BaseTypeahead.tsx +27 -17
  507. package/src/Typeahead/TypeaheadItem.doc.mjs +6 -3
  508. package/src/Typeahead/TypeaheadItem.tsx +2 -1
  509. package/src/animator/createAnimator.doc.mjs +153 -0
  510. package/src/animator/createAnimator.ts +324 -0
  511. package/src/gestures/GestureHost.ts +1 -1
  512. package/src/gestures/PressTracker.ts +4 -3
  513. package/src/gestures/README.md +10 -4
  514. package/src/hooks/ModalAnnounceProvider.tsx +1 -0
  515. package/src/hooks/actionGroupTracker.ts +20 -5
  516. package/src/hooks/index.ts +2 -0
  517. package/src/hooks/longPressDetector.ts +273 -0
  518. package/src/hooks/pressGroupContext.ts +21 -0
  519. package/src/hooks/rootScrollStyles.ts +247 -0
  520. package/src/hooks/scrollLockTouchGuard.ts +182 -0
  521. package/src/hooks/scrollbarGutter.ts +41 -26
  522. package/src/hooks/useActionGroupTracking.ts +224 -0
  523. package/src/hooks/useAnimator.doc.mjs +109 -0
  524. package/src/hooks/useAnimator.ts +67 -0
  525. package/src/hooks/useAnnounceRenderedText.ts +1 -0
  526. package/src/hooks/useAttachment.ts +1 -1
  527. package/src/hooks/useAutoMediaMode.ts +1 -0
  528. package/src/hooks/useBusyAnnouncement.ts +2 -0
  529. package/src/hooks/useDevWarning.ts +2 -0
  530. package/src/hooks/useFocusTrap.ts +2 -0
  531. package/src/hooks/useGridFocus.doc.mjs +6 -6
  532. package/src/hooks/useGridFocus.ts +10 -7
  533. package/src/hooks/useHotkeys.ts +2 -0
  534. package/src/hooks/useImageMode.ts +2 -0
  535. package/src/hooks/useInputStatusIcon.tsx +3 -2
  536. package/src/hooks/useKeyboardHint.tsx +1 -1
  537. package/src/hooks/useLongPress.doc.mjs +2 -2
  538. package/src/hooks/useLongPress.ts +32 -122
  539. package/src/hooks/useMenuHover.ts +1 -0
  540. package/src/hooks/useMenuPress.ts +2 -0
  541. package/src/hooks/useOverflow.ts +2 -1
  542. package/src/hooks/usePressFeedback.ts +1 -0
  543. package/src/hooks/useResolvedRequired.ts +3 -0
  544. package/src/hooks/useScrollLock.doc.mjs +51 -12
  545. package/src/hooks/useScrollLock.ts +57 -60
  546. package/src/hooks/useScrollableArea.ts +4 -0
  547. package/src/hooks/useStreamingText.ts +2 -0
  548. package/src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts +43 -0
  549. package/src/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.ts +6 -0
  550. package/src/i18n/generated-english/PowerSearch/formatTokenValue.generated.ts +15 -0
  551. package/src/i18n/generated-locales/en.generated.ts +41 -0
  552. package/src/i18n/generated-locales/pseudo.generated.ts +42 -0
  553. package/src/index.ts +13 -0
  554. package/src/internal/indicatorPress.stylex.ts +24 -0
  555. package/src/internal/selectable-card.ts +21 -0
  556. package/src/internal/sheetDraft.ts +2 -2
  557. package/src/motion/MEASUREMENTS.md +18 -0
  558. package/src/motion/README.md +10 -5
  559. package/src/motion/animatedLayout.ts +10 -5
  560. package/src/motion/animator.ts +66 -31
  561. package/src/motion/progress.ts +155 -0
  562. package/src/motion/reducedMotion.ts +3 -1
  563. package/src/motion/uikit/alert.ts +43 -0
  564. package/src/motion/uikit/index.ts +4 -3
  565. package/src/motion/uikit/picker.ts +116 -0
  566. package/src/privateAttributes/pressGroupItem.stylex.ts +44 -0
  567. package/src/privateAttributes/reducedMotion.stylex.ts +45 -0
  568. package/src/theme/Theme.tsx +37 -3
  569. package/src/theme/motionKnobs.ts +4 -3
  570. package/src/theme/themeMotion.ts +7 -0
  571. package/src/utils/dateParser.ts +16 -0
  572. package/src/utils/focusReturn.ts +30 -0
  573. package/src/utils/interactionModality.ts +4 -0
  574. package/src/utils/interactionOverlay.stylex.ts +3 -2
  575. package/src/utils/plainDate.ts +21 -0
  576. package/src/utils/pressFeedback.ts +24 -6
  577. package/src/utils/triggerFocus.ts +80 -0
  578. package/dist/internal/touch-sheet.d.ts +0 -21
  579. package/dist/internal/touch-sheet.d.ts.map +0 -1
  580. package/dist/internal/touch-sheet.js +0 -19
  581. package/src/internal/touch-sheet.ts +0 -21
@@ -25,7 +25,7 @@ import {
25
25
  type RefObject,
26
26
  } from 'react';
27
27
  import {
28
- createAnimator,
28
+ createMotionAnimator,
29
29
  type AnimateOptions,
30
30
  type Animator,
31
31
  type MotionCurve,
@@ -539,7 +539,7 @@ export class SegmentedSelectionMotion {
539
539
  private readonly after: Animator;
540
540
 
541
541
  constructor(
542
- private readonly animator: Animator = createAnimator(null, {
542
+ private readonly animator: Animator = createMotionAnimator(null, {
543
543
  pseudoElement: '::before',
544
544
  }),
545
545
  options: SegmentedSelectionMotionOptions = {},
@@ -552,7 +552,10 @@ export class SegmentedSelectionMotion {
552
552
  this.now = options.now ?? defaultNow;
553
553
  this.after =
554
554
  options.afterAnimator ??
555
- createAnimator(null, {pseudoElement: '::after', initial: {opacity: 0}});
555
+ createMotionAnimator(null, {
556
+ pseudoElement: '::after',
557
+ initial: {opacity: 0},
558
+ });
556
559
  }
557
560
 
558
561
  /** Attaches the radiogroup whose pseudo-elements are the lens (null detaches). */
@@ -23,6 +23,8 @@
23
23
  * A hidden <input type="checkbox"> inside the card provides the accessible
24
24
  * role, label, and checked state — the card surface itself has no role/tabIndex.
25
25
  * Space toggles it natively; Enter is wired up as an additional toggle key.
26
+ * Inside a single-choice group (Lab's SelectableCardGroup, through an internal
27
+ * context) the input is a radio: the card selects and never deselects itself.
26
28
  *
27
29
  * For static display, use Card.
28
30
  * For navigation or action cards, use ClickableCard.
@@ -34,13 +36,14 @@ import {
34
36
  type KeyboardEvent,
35
37
  useRef,
36
38
  useCallback,
39
+ use,
37
40
  type Ref,
38
41
  } from 'react';
39
42
  import * as stylex from '@stylexjs/stylex';
40
43
  import type {StyleXStyles} from '@stylexjs/stylex';
41
44
  import {colorVars, durationVars, easeVars} from '../theme/tokens.stylex';
42
45
  import type {Elevation, SizeValue, SpacingStep} from '../utils/types';
43
- import {mergeProps} from '../utils';
46
+ import {isImeKeyEvent, mergeProps} from '../utils';
44
47
  import {Card} from '../Card/Card';
45
48
  import type {CardVariant} from '../Card/Card';
46
49
  import {useClickableContainer} from '../hooks/useClickableContainer';
@@ -52,6 +55,7 @@ import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
52
55
  import {usePressFeedback} from '../hooks/usePressFeedback';
53
56
 
54
57
  import {useMergedRefs} from '../hooks/useMergedRefs';
58
+ import {SelectableCardInputContext} from './selectableCardInput';
55
59
  // =============================================================================
56
60
  // Styles — selection + interaction; Card handles the rest
57
61
  // =============================================================================
@@ -412,20 +416,34 @@ export function SelectableCard({
412
416
  const containerRef = useRef<HTMLDivElement | null>(null);
413
417
  const interactiveRef = useRef<HTMLInputElement | null>(null);
414
418
 
419
+ // A group can make the input a radio. A radio only selects: a native radio
420
+ // stays checked when it is clicked again.
421
+ const groupInput = use(SelectableCardInputContext);
422
+ const isRadio = groupInput?.type === 'radio';
423
+ const requestChange = useCallback(() => {
424
+ if (!isRadio) {
425
+ onChange(!isSelected);
426
+ } else if (!isSelected) {
427
+ onChange(true);
428
+ }
429
+ }, [isRadio, isSelected, onChange]);
430
+
415
431
  const handleClick = useCallback(
416
432
  (_event: MouseEvent<HTMLElement>) => {
417
433
  if (!isDisabled) {
418
- onChange(!isSelected);
434
+ requestChange();
419
435
  }
420
436
  },
421
- [isDisabled, isSelected, onChange],
437
+ [isDisabled, requestChange],
422
438
  );
423
439
 
424
- // The focusable control is a native checkbox, which toggles on Space but
425
- // ignores Enter. Add Enter as an extra toggle key; Space keeps its native
426
- // handling, so we deliberately do not toggle on Space here (would double).
440
+ // A native checkbox or radio reacts to Space but not to Enter. This handler
441
+ // adds Enter. Space is not handled here, because it would act twice.
427
442
  const handleKeyDown = useCallback(
428
443
  (event: KeyboardEvent<HTMLInputElement>) => {
444
+ if (isImeKeyEvent(event.nativeEvent)) {
445
+ return;
446
+ }
429
447
  if (isDisabled) {
430
448
  if (event.key === ' ' || event.key === 'Enter') {
431
449
  event.preventDefault();
@@ -434,10 +452,10 @@ export function SelectableCard({
434
452
  }
435
453
  if (event.key === 'Enter') {
436
454
  event.preventDefault();
437
- onChange(!isSelected);
455
+ requestChange();
438
456
  }
439
457
  },
440
- [isDisabled, isSelected, onChange],
458
+ [isDisabled, requestChange],
441
459
  );
442
460
 
443
461
  const {onClick, onMouseUp} = useClickableContainer({
@@ -523,7 +541,18 @@ export function SelectableCard({
523
541
  }>
524
542
  <input
525
543
  ref={interactiveRef}
526
- type="checkbox"
544
+ type={isRadio ? 'radio' : 'checkbox'}
545
+ name={groupInput?.name}
546
+ value={groupInput?.value}
547
+ // Radios group by name and form owner, so every radio card leaves
548
+ // the form together and the group stays one tab stop. The group
549
+ // submits its choice itself. A disabled checkbox card submits
550
+ // nothing, so it leaves the form too.
551
+ form={
552
+ groupInput != null && (groupInput.type === 'radio' || isDisabled)
553
+ ? ''
554
+ : undefined
555
+ }
527
556
  checked={isSelected}
528
557
  aria-label={label}
529
558
  aria-disabled={isDisabled ? 'true' : undefined}
@@ -531,7 +560,7 @@ export function SelectableCard({
531
560
  if (isDisabled) {
532
561
  return;
533
562
  }
534
- onChange(!isSelected);
563
+ requestChange();
535
564
  }}
536
565
  onKeyDown={handleKeyDown}
537
566
  {...stylex.props(styles.srOnly)}
@@ -0,0 +1,30 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file selectableCardInput.ts
7
+ * @input A card group's choice of native input for each card it renders
8
+ * @output SelectableCardInputContext: the input type, name and value a group
9
+ * gives one SelectableCard
10
+ * @position Internal: Lab's SelectableCardGroup provides it through
11
+ * `@astryxdesign/core/internal/selectable-card`. It is not public API, so
12
+ * SelectableCard's public props do not change.
13
+ */
14
+
15
+ import {createContext} from 'react';
16
+
17
+ /** The native input a group gives one card. */
18
+ export interface SelectableCardInput {
19
+ /** `radio` makes the card one choice of a single-choice set. */
20
+ readonly type: 'checkbox' | 'radio';
21
+ /** The input's `name`. Radios that share it form one native group. */
22
+ readonly name: string;
23
+ /** The input's `value`. A checkbox card submits it when it is selected. */
24
+ readonly value: string;
25
+ }
26
+
27
+ /** Without a provider, a card renders its own checkbox. */
28
+ export const SelectableCardInputContext =
29
+ createContext<SelectableCardInput | null>(null);
30
+ SelectableCardInputContext.displayName = 'SelectableCardInputContext';
@@ -1907,7 +1907,7 @@ export function Selector<T extends SelectorOptionType>(
1907
1907
  ref={attachListbox}
1908
1908
  id={listboxId}
1909
1909
  role="listbox"
1910
- aria-labelledby={triggerId}
1910
+ aria-label={label}
1911
1911
  {...listboxPress.menuProps}
1912
1912
  {...stylex.props(
1913
1913
  styles.dropdown,
@@ -1927,17 +1927,10 @@ export function Selector<T extends SelectorOptionType>(
1927
1927
  id={listboxId}
1928
1928
  role="listbox"
1929
1929
  {...listboxPress.menuProps}
1930
- // The bottom sheet is a modal layer, so Chromium drops the trigger
1931
- // outside it from the accessibility tree and a reference to it yields
1932
- // no name. Name only this no-search sheet directly from the component's
1933
- // label; the searchable sheet and the popovers keep the trigger
1934
- // relationship.
1935
- aria-label={
1936
- surface.activePresentation === 'bottom-sheet' ? label : undefined
1937
- }
1938
- aria-labelledby={
1939
- surface.activePresentation === 'bottom-sheet' ? undefined : triggerId
1940
- }
1930
+ // The trigger shows the value, so it cannot name the list.
1931
+ // A modal sheet removes an outside label from the accessibility tree.
1932
+ // The label element also holds the required marker and the tooltip.
1933
+ aria-label={label}
1941
1934
  aria-activedescendant={
1942
1935
  surface.isOpen && highlightedIndex >= 0
1943
1936
  ? getItemId(highlightedIndex)
@@ -29,7 +29,7 @@ import {TapGestureRecognizer} from '../gestures/TapGestureRecognizer';
29
29
  import type {PointerKind} from '../gestures/types';
30
30
  import {isRtlElement} from '../hooks/isRtlElement';
31
31
  import {
32
- createAnimator,
32
+ createMotionAnimator,
33
33
  type Animator,
34
34
  type MotionCurve,
35
35
  type MotionHandle,
@@ -1186,7 +1186,7 @@ export class SliderTouchController {
1186
1186
  private animatorFor(element: HTMLElement): Animator {
1187
1187
  let animator = this.animators.get(element);
1188
1188
  if (animator == null) {
1189
- animator = createAnimator(element);
1189
+ animator = createMotionAnimator(element);
1190
1190
  this.animators.set(element, animator);
1191
1191
  }
1192
1192
  return animator;
@@ -10,7 +10,7 @@
10
10
  *
11
11
  * SYNC: When modified, update these files to stay in sync:
12
12
  * - /packages/core/src/Spinner/Spinner.doc.mjs
13
- * - /packages/core/src/Spinner/Spinner.test.tsx
13
+ * - /packages/core/src/Spinner/Spinner.test.tsx and __tests__/SpinnerMotion.a11y.chromium.spec.ts (rotor timing)
14
14
  * - /packages/core/src/Spinner/index.ts
15
15
  * - /apps/storybook/stories/Spinner.stories.tsx
16
16
  * - /packages/cli/assets/templates/blocks/components/Spinner/ (showcase blocks)
@@ -153,60 +153,57 @@ function registerSpinnerVars(): void {
153
153
  registerSpinnerVars();
154
154
 
155
155
  /**
156
- * Pin every ring's dash motion to the document timeline's origin instead of
157
- * its own start time, so spinners mounted seconds apart stay in phase.
156
+ * Pin every ring's rotation to the document timeline's origin instead of its
157
+ * own start time, so spinners mounted seconds apart stay in phase.
158
158
  *
159
- * Setting `startTime` is exact where arithmetic on a clock read is not: a
159
+ * Setting `startTime` is exact where arithmetic on a clock read is not. A
160
160
  * negative `animation-delay` computed at mount is only as good as the gap
161
- * between reading the clock and the frame the animation starts in, which at
162
- * 10x CPU throttling measured 116deg of drift (from when this animated a
163
- * literal rotation; the same drift risk applies to the dash offset now).
161
+ * between the clock read and the frame the animation starts in. At 10x CPU
162
+ * throttling that gap measured 116 degrees of drift.
164
163
  *
165
- * Rings are collected and pinned in one frame because `getAnimations()`
166
- * resolves style and `startTime` dirties it again, so pinning them one at a
167
- * time makes each mount re-force what the previous one invalidated — 53 style
168
- * recalcs for 38 spinners against 19 batched.
164
+ * Rotors are collected and pinned in one frame. `getAnimations()` resolves
165
+ * style, and `startTime` dirties it again. So pinning them one at a time makes
166
+ * each mount re-force what the previous one invalidated: 53 style recalcs for
167
+ * 38 spinners, against 19 batched.
169
168
  */
170
- const pendingRings = new Set<SVGSVGElement>();
169
+ const pendingRotors = new Set<HTMLSpanElement>();
171
170
  let flushScheduled = false;
172
171
 
173
- function pinRingsToTimelineOrigin(): void {
172
+ function pinRotorsToTimelineOrigin(): void {
174
173
  flushScheduled = false;
175
174
  const animations: Animation[] = [];
176
- for (const svg of pendingRings) {
177
- // The animation now runs on the arc <circle>, a descendant of the ring
178
- // this ref sits on (#6253), so it needs subtree:true to be found here.
179
- animations.push(...svg.getAnimations({subtree: true}));
175
+ for (const rotor of pendingRotors) {
176
+ animations.push(...rotor.getAnimations());
180
177
  }
181
- pendingRings.clear();
178
+ pendingRotors.clear();
182
179
  for (const animation of animations) {
183
180
  animation.startTime = 0;
184
181
  }
185
182
  }
186
183
 
187
184
  /**
188
- * Ref callback for the ring: the one place a mounted ring touches the DOM.
185
+ * Ref callback for the rotor: the one place a mounted ring touches the DOM.
189
186
  *
190
187
  * It reads nothing back — the geometry is resolved by the cascade, not in JS.
191
188
  */
192
189
  function syncRotationPhase(
193
- svg: SVGSVGElement | null,
190
+ rotor: HTMLSpanElement | null,
194
191
  ): (() => void) | undefined {
195
- if (svg == null) {
192
+ if (rotor == null) {
196
193
  return undefined;
197
194
  }
198
195
  // jsdom implements no Web Animations, and this runs in every consumer's
199
196
  // component tests.
200
- if (typeof svg.getAnimations !== 'function') {
197
+ if (typeof rotor.getAnimations !== 'function') {
201
198
  return undefined;
202
199
  }
203
- pendingRings.add(svg);
200
+ pendingRotors.add(rotor);
204
201
  if (!flushScheduled) {
205
202
  flushScheduled = true;
206
- requestAnimationFrame(pinRingsToTimelineOrigin);
203
+ requestAnimationFrame(pinRotorsToTimelineOrigin);
207
204
  }
208
205
  return () => {
209
- pendingRings.delete(svg);
206
+ pendingRotors.delete(rotor);
210
207
  };
211
208
  }
212
209
 
@@ -215,19 +212,13 @@ function syncRotationPhase(
215
212
  // =============================================================================
216
213
 
217
214
  /**
218
- * Moves the dash around a stationary circle instead of rotating the whole
219
- * ring. WebKit re-antialiases a rotating stroked shape's rounded cap
220
- * (`strokeLinecap: 'round'`, below) slightly differently at each intermediate
221
- * angle, which reads as a visible wobble on iOS Safari independent of
222
- * compositing (#6253) — confirmed by a real-device test against this exact
223
- * fix, since `willChange`/layer promotion alone (the earlier fix for #3617)
224
- * only smooths the rotation's motion, not the per-frame stroke rasterization.
225
- * A static circle with an animated `stroke-dashoffset` never rotates, so
226
- * WebKit never re-rasterizes the cap at an intermediate angle at all.
215
+ * A `transform` animation runs on the compositor, so the ring keeps turning
216
+ * while a script runs. A `stroke-dashoffset` animation would repaint the arc
217
+ * on the main thread every frame, so it would stop while a script runs.
227
218
  */
228
- const dashMotion = stylex.keyframes({
229
- '0%': {strokeDashoffset: '0px'},
230
- '100%': {strokeDashoffset: `calc(var(${RESOLVED_DIAMETER}) * -${PI})`},
219
+ const rotation = stylex.keyframes({
220
+ '0%': {transform: 'rotate(0deg)'},
221
+ '100%': {transform: 'rotate(360deg)'},
231
222
  });
232
223
 
233
224
  // =============================================================================
@@ -283,6 +274,8 @@ const styles = stylex.create({
283
274
  ring: {
284
275
  backfaceVisibility: 'hidden',
285
276
  display: 'block',
277
+ // The track and the rotor share the one grid cell, stacked and centred.
278
+ gridArea: '1 / 1',
286
279
  // The frame is the box, read from the same composed var the span is sized
287
280
  // from — not from the size constant, which a theme cannot reach, and not
288
281
  // from a percentage, which needs the grid area to be a definite size in
@@ -300,6 +293,27 @@ const styles = stylex.create({
300
293
  // which put the ring 1.5-3.3px off across the four sizes.
301
294
  overflow: 'visible',
302
295
  },
296
+ // The rotor is the frame's size, so it turns about the ring's centre.
297
+ rotor: {
298
+ display: 'block',
299
+ gridArea: '1 / 1',
300
+ width: `var(${BOX_SIZE})`,
301
+ height: `var(${BOX_SIZE})`,
302
+ // Mobile Safari keeps a re-timed animation off the main thread only on an
303
+ // element with its own layer. So the rotor declares one before the start
304
+ // time is set (see `pinRotorsToTimelineOrigin`).
305
+ willChange: 'transform',
306
+ // Reduced motion slows the turn but never stops it: a still ring reads as
307
+ // broken. The status role and its name still say that work is busy.
308
+ animationDuration: {
309
+ // The loop reads the duration before a theme's tempo scales it.
310
+ default: `var(--_astryx-pre-tempo-duration-slow-min, ${durationVars['--duration-slow-min']})`,
311
+ '@media (prefers-reduced-motion: reduce)': '3s',
312
+ },
313
+ animationIterationCount: 'infinite',
314
+ animationName: rotation,
315
+ animationTimingFunction: 'linear',
316
+ },
303
317
  circle: {
304
318
  fill: 'none',
305
319
  // The ring is centred on the box (cx/cy 50%), so the arc's start offset
@@ -336,18 +350,6 @@ const styles = stylex.create({
336
350
  // `0` the way the registered length pair guards against, so it needs no
337
351
  // registration.
338
352
  arc: {
339
- // Slow the motion dramatically under reduced-motion rather than freezing
340
- // it (a frozen spinner reads as broken), matching ProgressBar's approach.
341
- // The role="status" + "Loading" label still convey busy state (obs-6).
342
- animationDuration: {
343
- // The loop reads the duration before a theme's tempo scales it
344
- // (spec:AST-108 FR4).
345
- default: `var(--_astryx-pre-tempo-duration-slow-min, ${durationVars['--duration-slow-min']})`,
346
- '@media (prefers-reduced-motion: reduce)': '3s',
347
- },
348
- animationIterationCount: 'infinite',
349
- animationName: dashMotion,
350
- animationTimingFunction: 'linear',
351
353
  stroke: 'var(--spinner-color)',
352
354
  transform: 'rotate(-90deg)',
353
355
  strokeDasharray: `calc(var(${RESOLVED_DIAMETER}) * ${PI} * var(--spinner-arc-fraction)) calc(var(${RESOLVED_DIAMETER}) * ${PI} * (1 - var(--spinner-arc-fraction)))`,
@@ -569,10 +571,12 @@ export function Spinner({
569
571
  height: `var(${BOX_SIZE}, ${frameSize}px)`,
570
572
  },
571
573
  )}>
574
+ {/* The track is zero-sized by attribute. With no stylesheet, the
575
+ rotor's arc alone fills the box, instead of two discs side by side.
576
+ `ring` sizes both to the box. */}
572
577
  <svg
573
- ref={syncRotationPhase}
574
- width={frameSize}
575
- height={frameSize}
578
+ width={0}
579
+ height={0}
576
580
  aria-hidden="true"
577
581
  {...stylex.props(styles.ring)}>
578
582
  <circle
@@ -586,18 +590,28 @@ export function Spinner({
586
590
  trackOpacityStyles[shade],
587
591
  )}
588
592
  />
589
- <circle
590
- cx="50%"
591
- cy="50%"
592
- r={diameter / 2}
593
- strokeWidth={border}
594
- // The size's own dash, for the render with no stylesheet. The rule
595
- // above composes the same lengths from the resolved diameter, so a
596
- // themed ring keeps this fraction of arc rather than this length.
597
- strokeDasharray={`${arcLength} ${circumference - arcLength}`}
598
- {...stylex.props(styles.circle, styles.arc)}
599
- />
600
593
  </svg>
594
+ <span
595
+ ref={syncRotationPhase}
596
+ aria-hidden="true"
597
+ {...stylex.props(styles.rotor)}>
598
+ <svg
599
+ width={frameSize}
600
+ height={frameSize}
601
+ {...stylex.props(styles.ring)}>
602
+ <circle
603
+ cx="50%"
604
+ cy="50%"
605
+ r={diameter / 2}
606
+ strokeWidth={border}
607
+ // The size's own dash, for the render with no stylesheet. The rule
608
+ // above composes the same lengths from the resolved diameter, so a
609
+ // themed ring keeps this fraction of arc rather than this length.
610
+ strokeDasharray={`${arcLength} ${circumference - arcLength}`}
611
+ {...stylex.props(styles.circle, styles.arc)}
612
+ />
613
+ </svg>
614
+ </span>
601
615
  </span>
602
616
  );
603
617
 
@@ -52,7 +52,6 @@ import type {BaseProps} from '../BaseProps';
52
52
  import type {SizeValue} from '../utils/types';
53
53
  import {themeProps} from '../utils/themeProps';
54
54
  import {useAnnounce} from '../hooks/useAnnounce';
55
- import {useResolvedRequired} from '../hooks/useResolvedRequired';
56
55
 
57
56
  import {useMergedRefs} from '../hooks/useMergedRefs';
58
57
  import {usePressFeedback} from '../hooks/usePressFeedback';
@@ -867,10 +866,6 @@ export function Switch({
867
866
  const pressable = usePressFeedback();
868
867
  const descriptionID = useId();
869
868
  const statusMessageID = useId();
870
- // Announce the effective required state (form default included) while the
871
- // native `required` stays bound to the explicit `isRequired` so a layout
872
- // default never switches on browser validation.
873
- const isEffectivelyRequired = useResolvedRequired({isRequired, isOptional});
874
869
 
875
870
  const [, startTransition] = useTransition();
876
871
  const [optimisticValue, setOptimisticValue] = useOptimistic(value);
@@ -1003,7 +998,8 @@ export function Switch({
1003
998
  aria-disabled={isDisabled ? 'true' : undefined}
1004
999
  form={isDisabled ? '' : undefined}
1005
1000
  required={isRequired}
1006
- aria-required={isEffectivelyRequired ? 'true' : undefined}
1001
+ // A form's required default sets nothing here: an off switch is an answer.
1002
+ aria-required={isRequired ? 'true' : undefined}
1007
1003
  onChange={e => {
1008
1004
  if (isDisabled || isBusy) {
1009
1005
  return;
@@ -23,7 +23,7 @@ import type {GestureTouch} from '../gestures/types';
23
23
  import {isRtlElement} from '../hooks/isRtlElement';
24
24
  import {useIsomorphicLayoutEffect} from '../hooks/useIsomorphicLayoutEffect';
25
25
  import {
26
- createAnimator,
26
+ createMotionAnimator,
27
27
  type Animator,
28
28
  type MotionCurve,
29
29
  } from '../motion/animator';
@@ -282,15 +282,15 @@ export class SwitchTouchController {
282
282
  return;
283
283
  }
284
284
  registerSwitchTable();
285
- this.thumb = createAnimator(elements.thumb);
285
+ this.thumb = createMotionAnimator(elements.thumb);
286
286
  // The layer rests clear (its class's opacity 0) while the visuals show
287
287
  // the value; from here its opacity is the animator's.
288
- this.fade = createAnimator(elements.track, {
288
+ this.fade = createMotionAnimator(elements.track, {
289
289
  pseudoElement: '::after',
290
290
  initial: {opacity: 0},
291
291
  });
292
292
  this.fade.set({opacity: 0});
293
- this.shadow = createAnimator(elements.thumb, {
293
+ this.shadow = createMotionAnimator(elements.thumb, {
294
294
  pseudoElement: '::after',
295
295
  initial: {opacity: 0},
296
296
  });
@@ -14,7 +14,14 @@
14
14
  * - /packages/cli/assets/templates/blocks/components/Table/ (showcase blocks)
15
15
  */
16
16
 
17
- import {memo, useRef, type ReactElement, type ReactNode, type Ref} from 'react';
17
+ import {
18
+ memo,
19
+ useId,
20
+ useRef,
21
+ type ReactElement,
22
+ type ReactNode,
23
+ type Ref,
24
+ } from 'react';
18
25
  import {isRenderable} from '../utils/isRenderable';
19
26
  import * as stylex from '@stylexjs/stylex';
20
27
  import {spacingVars} from '../theme/tokens.stylex';
@@ -423,6 +430,7 @@ function BaseTableInner<T extends Record<string, unknown>>({
423
430
  } satisfies TableRenderProps);
424
431
 
425
432
  // --- Plugin pipeline: header cells ---
433
+ const headerLabelIdBase = useId();
426
434
  const headerCells = resolvedColumns.map((col, columnIndex) => {
427
435
  const headerContent = col.header ?? col.key;
428
436
 
@@ -477,28 +485,54 @@ function BaseTableInner<T extends Record<string, unknown>>({
477
485
  const hasSlots =
478
486
  before != null || after != null || overlay != null || below != null;
479
487
 
480
- const headerInner = hasSlots ? (
488
+ const labelRow = isRenderable(after) ? (
489
+ <div {...stylex.props(styles.headerLabelRow)}>
490
+ {resolvedContent}
491
+ {after}
492
+ </div>
493
+ ) : (
494
+ resolvedContent
495
+ );
496
+
497
+ // The overlay is a control of its own. Keep its name and value out of the
498
+ // header's name.
499
+ const namesOwnHeader =
500
+ isRenderable(overlay) &&
501
+ mergedHtmlProps['aria-label'] == null &&
502
+ mergedHtmlProps['aria-labelledby'] == null;
503
+ const labelId = `${headerLabelIdBase}-label-${columnIndex}`;
504
+ const belowId = `${headerLabelIdBase}-below-${columnIndex}`;
505
+ const hasBelow = isRenderable(below);
506
+
507
+ const headerInner = !hasSlots ? (
508
+ resolvedContent
509
+ ) : namesOwnHeader ? (
510
+ <>
511
+ {/* Inline, so the cell's text-overflow still reaches the label. */}
512
+ <span id={labelId}>
513
+ {before}
514
+ {labelRow}
515
+ </span>
516
+ {overlay}
517
+ {hasBelow && <div id={belowId}>{below}</div>}
518
+ </>
519
+ ) : (
481
520
  <>
482
521
  {before}
483
- {isRenderable(after) ? (
484
- <div {...stylex.props(styles.headerLabelRow)}>
485
- {resolvedContent}
486
- {after}
487
- </div>
488
- ) : (
489
- resolvedContent
490
- )}
522
+ {labelRow}
491
523
  {overlay}
492
524
  {below}
493
525
  </>
494
- ) : (
495
- resolvedContent
496
526
  );
527
+ const headerNameProps = namesOwnHeader
528
+ ? {'aria-labelledby': hasBelow ? `${labelId} ${belowId}` : labelId}
529
+ : {};
497
530
 
498
531
  return (
499
532
  <HeaderCellComponent
500
533
  key={col.key}
501
534
  {...mergedHtmlProps}
535
+ {...headerNameProps}
502
536
  {...headerTitleProp}
503
537
  contextMenuActions={cellRenderProps.contextMenuActions}
504
538
  xstyle={cellRenderProps.xstyle}>
@@ -865,7 +865,7 @@ export function useTableColumnResize<T extends Record<string, unknown>>(
865
865
  }
866
866
  }, []);
867
867
 
868
- // Clean up observer on unmount
868
+ // Releases the table resize observer on unmount.
869
869
  useEffect(() => {
870
870
  return () => {
871
871
  unobserveTableRef.current?.();
@@ -934,6 +934,7 @@ export function useTableColumnResize<T extends Record<string, unknown>>(
934
934
  };
935
935
  }, []);
936
936
 
937
+ // Releases the resize gate on unmount.
937
938
  useEffect(() => {
938
939
  return () => {
939
940
  gateCleanupRef.current?.();
@@ -820,6 +820,7 @@ function StringListFilterControl({
820
820
  }}
821
821
  size={size}
822
822
  hasClear={hasClear}
823
+ presentation="popover"
823
824
  />
824
825
  );
825
826
  }
@@ -439,6 +439,8 @@ function PanelDividerModeWatch({
439
439
  const {mode} = useTheme();
440
440
  const themeName = useThemeName();
441
441
  const lastRef = useRef({mode, themeName});
442
+ // Syncs the panel dividers with the computed theme CSS after a color mode or
443
+ // theme change.
442
444
  useLayoutEffect(() => {
443
445
  const last = lastRef.current;
444
446
  if (last.mode === mode && last.themeName === themeName) {
@@ -703,6 +705,8 @@ export function useTableRowExpansion<T extends Record<string, unknown>>(
703
705
  }
704
706
  }
705
707
  }, []);
708
+ // Syncs the chevron transitions with the `animatedLayout` handle. Without a
709
+ // handle, the chevrons use the theme's turn.
706
710
  useLayoutEffect(() => {
707
711
  if (animatedLayout == null) {
708
712
  resetChevrons();
@@ -432,6 +432,8 @@ function PinnedDividerModeWatch({
432
432
  const {mode} = useTheme();
433
433
  const themeName = useThemeName();
434
434
  const lastRef = useRef({mode, themeName});
435
+ // Syncs the pinned divider with the computed theme CSS after a color mode or
436
+ // theme change.
435
437
  useLayoutEffect(() => {
436
438
  const last = lastRef.current;
437
439
  if (last.mode !== mode || last.themeName !== themeName) {