@astryxdesign/core 0.7.7-canary.c0929c8 → 0.7.7-canary.c19ca12

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 (472) 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 +36 -6
  4. package/dist/AppShell/useCloseMobileDrawerOnActivate.d.ts +13 -0
  5. package/dist/AppShell/useCloseMobileDrawerOnActivate.d.ts.map +1 -0
  6. package/dist/AppShell/useCloseMobileDrawerOnActivate.js +45 -0
  7. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  8. package/dist/BottomSheet/BottomSheet.js +79 -9
  9. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  10. package/dist/BottomSheet/BottomSheetPanel.js +23 -4
  11. package/dist/BottomSheet/bottomSheetStack.d.ts.map +1 -1
  12. package/dist/BottomSheet/bottomSheetStack.js +5 -4
  13. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  14. package/dist/BottomSheet/useSheetGestures.js +3 -1
  15. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +2 -1
  16. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  17. package/dist/Breadcrumbs/BreadcrumbItem.js +7 -3
  18. package/dist/Button/Button.d.ts.map +1 -1
  19. package/dist/Button/Button.js +47 -3
  20. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  21. package/dist/CheckboxInput/CheckboxInput.js +13 -2
  22. package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
  23. package/dist/CheckboxList/CheckboxList.js +7 -1
  24. package/dist/CheckboxList/CheckboxListContext.d.ts +6 -0
  25. package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
  26. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  27. package/dist/CheckboxList/CheckboxListItem.js +10 -2
  28. package/dist/ComplexSelector/ComplexSelector.d.ts +4 -1
  29. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  30. package/dist/ComplexSelector/ComplexSelector.js +14 -4
  31. package/dist/ContextMenu/ContextMenu.js +2 -2
  32. package/dist/DateInput/DateInput.d.ts.map +1 -1
  33. package/dist/DateInput/DateInput.js +5 -2
  34. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  35. package/dist/DateInput/MonthScroller.js +13 -27
  36. package/dist/DateInput/Wheel.d.ts.map +1 -1
  37. package/dist/DateInput/Wheel.js +22 -41
  38. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  39. package/dist/DateTimeInput/DateTimeInput.js +5 -2
  40. package/dist/Dialog/Dialog.d.ts.map +1 -1
  41. package/dist/Dialog/Dialog.js +23 -45
  42. package/dist/Drawer/Drawer.d.ts.map +1 -1
  43. package/dist/Drawer/Drawer.js +15 -11
  44. package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -1
  45. package/dist/Drawer/useDrawerDialogPresence.js +5 -1
  46. package/dist/Field/Field.js +2 -2
  47. package/dist/Field/PanelSearchInput.d.ts +9 -1
  48. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  49. package/dist/Field/PanelSearchInput.js +3 -1
  50. package/dist/HoverCard/HoverCard.d.ts +4 -3
  51. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  52. package/dist/HoverCard/HoverCard.js +27 -2
  53. package/dist/HoverCard/useHoverCard.d.ts +5 -4
  54. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  55. package/dist/HoverCard/useHoverCard.js +17 -31
  56. package/dist/Icon/Icon.d.ts +5 -1
  57. package/dist/Icon/Icon.d.ts.map +1 -1
  58. package/dist/Icon/Icon.js +5 -2
  59. package/dist/InfoTip/InfoTip.d.ts +63 -0
  60. package/dist/InfoTip/InfoTip.d.ts.map +1 -0
  61. package/dist/InfoTip/InfoTip.js +126 -0
  62. package/dist/InfoTip/index.d.ts +10 -0
  63. package/dist/InfoTip/index.d.ts.map +1 -0
  64. package/dist/InfoTip/index.js +12 -0
  65. package/dist/Layer/layerAnimations.stylex.d.ts +7 -8
  66. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  67. package/dist/Layer/layerAnimations.stylex.js +25 -20
  68. package/dist/Layer/useBackdropPress.d.ts +27 -0
  69. package/dist/Layer/useBackdropPress.d.ts.map +1 -0
  70. package/dist/Layer/useBackdropPress.js +53 -0
  71. package/dist/Layer/usePressPin.d.ts +20 -10
  72. package/dist/Layer/usePressPin.d.ts.map +1 -1
  73. package/dist/Layer/usePressPin.js +66 -18
  74. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  75. package/dist/Lightbox/Lightbox.js +18 -0
  76. package/dist/MobileNav/MobileNav.js +0 -1
  77. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  78. package/dist/MultiSelector/hooks.js +2 -4
  79. package/dist/Outline/Outline.d.ts +2 -4
  80. package/dist/Outline/Outline.d.ts.map +1 -1
  81. package/dist/Outline/Outline.js +4 -52
  82. package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
  83. package/dist/Outline/useOutlineFromMarkdown.js +1 -0
  84. package/dist/Outline/useScrollSpy.js +3 -3
  85. package/dist/PowerSearch/PowerSearch.d.ts +36 -3
  86. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  87. package/dist/PowerSearch/PowerSearch.js +571 -302
  88. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts +100 -0
  89. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +1 -0
  90. package/dist/PowerSearch/PowerSearchBottomSheet.js +1913 -0
  91. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +32 -1
  92. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  93. package/dist/PowerSearch/PowerSearchEditPopover.js +17 -6
  94. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +38 -3
  95. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  96. package/dist/PowerSearch/PowerSearchValueEditor.js +170 -61
  97. package/dist/PowerSearch/formatFilterValue.d.ts +7 -0
  98. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  99. package/dist/PowerSearch/formatFilterValue.js +11 -1
  100. package/dist/PowerSearch/formatTokenValue.d.ts +28 -0
  101. package/dist/PowerSearch/formatTokenValue.d.ts.map +1 -0
  102. package/dist/PowerSearch/formatTokenValue.js +160 -0
  103. package/dist/PowerSearch/powerSearchSheetUtils.d.ts +65 -0
  104. package/dist/PowerSearch/powerSearchSheetUtils.d.ts.map +1 -0
  105. package/dist/PowerSearch/powerSearchSheetUtils.js +168 -0
  106. package/dist/RadioList/RadioList.d.ts.map +1 -1
  107. package/dist/RadioList/RadioList.js +8 -2
  108. package/dist/RadioList/RadioListItem.d.ts +1 -1
  109. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  110. package/dist/RadioList/RadioListItem.js +5 -3
  111. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  112. package/dist/Resizable/ResizeHandle.js +118 -260
  113. package/dist/Resizable/resizeGesture.d.ts +91 -0
  114. package/dist/Resizable/resizeGesture.d.ts.map +1 -0
  115. package/dist/Resizable/resizeGesture.js +251 -0
  116. package/dist/SegmentedControl/SegmentedControl.d.ts +3 -1
  117. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  118. package/dist/SegmentedControl/SegmentedControl.js +115 -8
  119. package/dist/SegmentedControl/SegmentedControlContext.d.ts +6 -0
  120. package/dist/SegmentedControl/SegmentedControlContext.d.ts.map +1 -1
  121. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -0
  122. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  123. package/dist/SegmentedControl/SegmentedControlItem.js +8 -1
  124. package/dist/SegmentedControl/useSegmentedSelectionMotion.d.ts +357 -0
  125. package/dist/SegmentedControl/useSegmentedSelectionMotion.d.ts.map +1 -0
  126. package/dist/SegmentedControl/useSegmentedSelectionMotion.js +1349 -0
  127. package/dist/SegmentedControl/useSegmentedTouchTracking.d.ts +70 -0
  128. package/dist/SegmentedControl/useSegmentedTouchTracking.d.ts.map +1 -0
  129. package/dist/SegmentedControl/useSegmentedTouchTracking.js +264 -0
  130. package/dist/Selector/Selector.d.ts.map +1 -1
  131. package/dist/Selector/Selector.js +96 -67
  132. package/dist/Selector/optionShape.d.ts +24 -0
  133. package/dist/Selector/optionShape.d.ts.map +1 -0
  134. package/dist/Selector/optionShape.js +48 -0
  135. package/dist/Selector/selectableOptionEntries.d.ts +20 -0
  136. package/dist/Selector/selectableOptionEntries.d.ts.map +1 -0
  137. package/dist/Selector/selectableOptionEntries.js +38 -0
  138. package/dist/Selector/utils.d.ts +2 -17
  139. package/dist/Selector/utils.d.ts.map +1 -1
  140. package/dist/Selector/utils.js +3 -51
  141. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  142. package/dist/SideNav/SideNavItem.js +3 -9
  143. package/dist/Slider/sliderTouchController.js +2 -2
  144. package/dist/Spinner/Spinner.d.ts +1 -1
  145. package/dist/Spinner/Spinner.d.ts.map +1 -1
  146. package/dist/Spinner/Spinner.js +60 -58
  147. package/dist/Switch/switchTouch.d.ts +0 -7
  148. package/dist/Switch/switchTouch.d.ts.map +1 -1
  149. package/dist/Switch/switchTouch.js +2 -10
  150. package/dist/Switch/useSwitchTouch.d.ts +2 -11
  151. package/dist/Switch/useSwitchTouch.d.ts.map +1 -1
  152. package/dist/Switch/useSwitchTouch.js +35 -93
  153. package/dist/Table/BaseTable.d.ts.map +1 -1
  154. package/dist/Table/BaseTable.js +29 -8
  155. package/dist/TextInput/TextInput.d.ts +2 -2
  156. package/dist/TextInput/TextInput.d.ts.map +1 -1
  157. package/dist/TextInput/TextInput.js +10 -7
  158. package/dist/Toast/Toast.d.ts +11 -1
  159. package/dist/Toast/Toast.d.ts.map +1 -1
  160. package/dist/Toast/Toast.js +30 -15
  161. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  162. package/dist/Toast/ToastViewport.js +94 -34
  163. package/dist/Toast/types.d.ts +9 -3
  164. package/dist/Toast/types.d.ts.map +1 -1
  165. package/dist/Token/Token.d.ts +2 -2
  166. package/dist/Token/Token.d.ts.map +1 -1
  167. package/dist/Token/Token.js +13 -4
  168. package/dist/Token/TokenNamingContext.d.ts +14 -0
  169. package/dist/Token/TokenNamingContext.d.ts.map +1 -0
  170. package/dist/Token/TokenNamingContext.js +23 -0
  171. package/dist/Tokenizer/Tokenizer.d.ts +46 -59
  172. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  173. package/dist/Tokenizer/Tokenizer.js +40 -57
  174. package/dist/Tokenizer/TokenizerBottomSheet.d.ts +25 -28
  175. package/dist/Tokenizer/TokenizerBottomSheet.d.ts.map +1 -1
  176. package/dist/Tokenizer/TokenizerBottomSheet.js +157 -54
  177. package/dist/Tokenizer/TokenizerItemRemovableContext.d.ts +3 -0
  178. package/dist/Tokenizer/TokenizerItemRemovableContext.d.ts.map +1 -0
  179. package/dist/Tokenizer/TokenizerItemRemovableContext.js +19 -0
  180. package/dist/Tooltip/Tooltip.d.ts +25 -30
  181. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  182. package/dist/Tooltip/Tooltip.js +24 -5
  183. package/dist/Tooltip/index.d.ts +1 -1
  184. package/dist/Tooltip/index.d.ts.map +1 -1
  185. package/dist/Tooltip/useTooltip.d.ts +45 -28
  186. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  187. package/dist/Tooltip/useTooltip.js +52 -59
  188. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  189. package/dist/TopNav/TopNavItem.js +4 -7
  190. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  191. package/dist/TopNav/TopNavMegaMenuItem.js +4 -7
  192. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  193. package/dist/TopNav/TopNavMenu.js +4 -7
  194. package/dist/Typeahead/TypeaheadItem.d.ts +2 -1
  195. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  196. package/dist/animator/createAnimator.d.ts +98 -0
  197. package/dist/animator/createAnimator.d.ts.map +1 -0
  198. package/dist/animator/createAnimator.js +259 -0
  199. package/dist/astryx.css +96 -7
  200. package/dist/gestures/GestureHost.d.ts +27 -1
  201. package/dist/gestures/GestureHost.d.ts.map +1 -1
  202. package/dist/gestures/GestureHost.js +157 -21
  203. package/dist/gestures/PressTracker.d.ts.map +1 -1
  204. package/dist/gestures/PressTracker.js +4 -3
  205. package/dist/hooks/actionGroupTracker.d.ts +7 -4
  206. package/dist/hooks/actionGroupTracker.d.ts.map +1 -1
  207. package/dist/hooks/actionGroupTracker.js +19 -56
  208. package/dist/hooks/index.d.ts +1 -0
  209. package/dist/hooks/index.d.ts.map +1 -1
  210. package/dist/hooks/index.js +1 -0
  211. package/dist/hooks/pressGroupContext.d.ts +6 -0
  212. package/dist/hooks/pressGroupContext.d.ts.map +1 -0
  213. package/dist/hooks/pressGroupContext.js +20 -0
  214. package/dist/hooks/useActionGroupTracking.d.ts +53 -0
  215. package/dist/hooks/useActionGroupTracking.d.ts.map +1 -0
  216. package/dist/hooks/useActionGroupTracking.js +174 -0
  217. package/dist/hooks/useAnimator.d.ts +41 -0
  218. package/dist/hooks/useAnimator.d.ts.map +1 -0
  219. package/dist/hooks/useAnimator.js +70 -0
  220. package/dist/hooks/useAttachment.d.ts +1 -1
  221. package/dist/hooks/useAttachment.js +1 -1
  222. package/dist/hooks/useHighlightedOptionScroll.d.ts +11 -1
  223. package/dist/hooks/useHighlightedOptionScroll.d.ts.map +1 -1
  224. package/dist/hooks/useHighlightedOptionScroll.js +112 -11
  225. package/dist/hooks/useInputStatusIcon.d.ts +1 -1
  226. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  227. package/dist/hooks/useInputStatusIcon.js +2 -2
  228. package/dist/hooks/useLongPress.d.ts +6 -2
  229. package/dist/hooks/useLongPress.d.ts.map +1 -1
  230. package/dist/hooks/useLongPress.js +95 -15
  231. package/dist/hooks/useMediaQuery.d.ts +2 -1
  232. package/dist/hooks/useMediaQuery.d.ts.map +1 -1
  233. package/dist/hooks/useMediaQuery.js +7 -4
  234. package/dist/hooks/useMenuPress.d.ts.map +1 -1
  235. package/dist/hooks/useMenuPress.js +4 -2
  236. package/dist/i18n/generated-english/InfoTip/InfoTip.generated.d.ts +8 -0
  237. package/dist/i18n/generated-english/InfoTip/InfoTip.generated.d.ts.map +1 -0
  238. package/dist/i18n/generated-english/InfoTip/InfoTip.generated.js +12 -0
  239. package/dist/i18n/generated-english/PowerSearch/PowerSearch.generated.d.ts.map +1 -1
  240. package/dist/i18n/generated-english/PowerSearch/PowerSearch.generated.js +1 -0
  241. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts +8 -0
  242. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts.map +1 -0
  243. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.js +42 -0
  244. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.d.ts.map +1 -1
  245. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.js +6 -0
  246. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts +8 -0
  247. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts.map +1 -0
  248. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.js +14 -0
  249. package/dist/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.d.ts.map +1 -1
  250. package/dist/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.js +7 -1
  251. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  252. package/dist/i18n/generated-locales/en.generated.js +33 -1
  253. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  254. package/dist/i18n/generated-locales/pseudo.generated.js +33 -1
  255. package/dist/index.d.ts +2 -0
  256. package/dist/index.d.ts.map +1 -1
  257. package/dist/index.js +5 -0
  258. package/dist/internal/SheetConfirmation.d.ts +11 -0
  259. package/dist/internal/SheetConfirmation.d.ts.map +1 -0
  260. package/dist/internal/SheetConfirmation.js +92 -0
  261. package/dist/internal/indicatorPress.stylex.d.ts +20 -0
  262. package/dist/internal/indicatorPress.stylex.d.ts.map +1 -0
  263. package/dist/internal/indicatorPress.stylex.js +26 -0
  264. package/dist/internal/sheetDraft.d.ts +35 -0
  265. package/dist/internal/sheetDraft.d.ts.map +1 -0
  266. package/dist/internal/sheetDraft.js +65 -0
  267. package/dist/internal/touch-sheet.d.ts +21 -0
  268. package/dist/internal/touch-sheet.d.ts.map +1 -0
  269. package/dist/internal/touch-sheet.js +19 -0
  270. package/dist/internal/useDismissSearchOnTouchDrag.d.ts +24 -0
  271. package/dist/internal/useDismissSearchOnTouchDrag.d.ts.map +1 -0
  272. package/dist/internal/useDismissSearchOnTouchDrag.js +56 -0
  273. package/dist/motion/animator.d.ts +14 -14
  274. package/dist/motion/animator.d.ts.map +1 -1
  275. package/dist/motion/animator.js +41 -18
  276. package/dist/motion/reducedMotion.d.ts +24 -0
  277. package/dist/motion/reducedMotion.d.ts.map +1 -1
  278. package/dist/motion/reducedMotion.js +78 -1
  279. package/dist/motion/roles.d.ts +7 -1
  280. package/dist/motion/roles.d.ts.map +1 -1
  281. package/dist/motion/roles.js +20 -1
  282. package/dist/motion/uikit/alert.d.ts +41 -0
  283. package/dist/motion/uikit/alert.d.ts.map +1 -0
  284. package/dist/motion/uikit/alert.js +43 -0
  285. package/dist/motion/uikit/index.d.ts +6 -5
  286. package/dist/motion/uikit/index.d.ts.map +1 -1
  287. package/dist/motion/uikit/index.js +6 -5
  288. package/dist/motion/uikit/segmented.d.ts +55 -0
  289. package/dist/motion/uikit/segmented.d.ts.map +1 -0
  290. package/dist/motion/uikit/segmented.js +77 -0
  291. package/dist/motion/uikit/springs.d.ts +0 -18
  292. package/dist/motion/uikit/springs.d.ts.map +1 -1
  293. package/dist/motion/uikit/springs.js +5 -21
  294. package/dist/privateAttributes/pressGroupItem.stylex.d.ts +15 -0
  295. package/dist/privateAttributes/pressGroupItem.stylex.d.ts.map +1 -0
  296. package/dist/privateAttributes/pressGroupItem.stylex.js +23 -0
  297. package/dist/privateAttributes/segmentTitle.stylex.d.ts +5 -0
  298. package/dist/privateAttributes/segmentTitle.stylex.d.ts.map +1 -0
  299. package/dist/privateAttributes/segmentTitle.stylex.js +22 -0
  300. package/dist/utils/browserClickWait.d.ts +35 -0
  301. package/dist/utils/browserClickWait.d.ts.map +1 -0
  302. package/dist/utils/browserClickWait.js +123 -0
  303. package/dist/utils/clickGuard.d.ts +14 -1
  304. package/dist/utils/clickGuard.d.ts.map +1 -1
  305. package/dist/utils/clickGuard.js +46 -1
  306. package/dist/utils/dateParser.d.ts.map +1 -1
  307. package/dist/utils/dateParser.js +12 -0
  308. package/dist/utils/focusReturn.d.ts +15 -0
  309. package/dist/utils/focusReturn.d.ts.map +1 -1
  310. package/dist/utils/focusReturn.js +28 -0
  311. package/dist/utils/interactionOverlay.stylex.d.ts +3 -2
  312. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  313. package/dist/utils/interactionOverlay.stylex.js +3 -2
  314. package/dist/utils/pressFeedback.d.ts.map +1 -1
  315. package/dist/utils/pressFeedback.js +19 -6
  316. package/dist/utils/triggerFocus.d.ts +36 -0
  317. package/dist/utils/triggerFocus.d.ts.map +1 -0
  318. package/dist/utils/triggerFocus.js +65 -0
  319. package/locales/en.json +128 -0
  320. package/locales/pseudo.json +96 -0
  321. package/package.json +18 -8
  322. package/src/AlertDialog/AlertDialog.doc.mjs +2 -2
  323. package/src/AlertDialog/AlertDialog.tsx +37 -5
  324. package/src/AppShell/useCloseMobileDrawerOnActivate.ts +52 -0
  325. package/src/BottomSheet/BottomSheet.tsx +95 -10
  326. package/src/BottomSheet/BottomSheetPanel.tsx +40 -5
  327. package/src/BottomSheet/bottomSheetStack.ts +8 -4
  328. package/src/BottomSheet/useSheetGestures.ts +3 -1
  329. package/src/Breadcrumbs/BreadcrumbItem.tsx +13 -3
  330. package/src/Button/Button.tsx +63 -5
  331. package/src/CheckboxInput/CheckboxInput.doc.mjs +18 -0
  332. package/src/CheckboxInput/CheckboxInput.tsx +36 -9
  333. package/src/CheckboxList/CheckboxList.doc.mjs +4 -2
  334. package/src/CheckboxList/CheckboxList.tsx +6 -0
  335. package/src/CheckboxList/CheckboxListContext.tsx +6 -0
  336. package/src/CheckboxList/CheckboxListItem.tsx +11 -2
  337. package/src/ComplexSelector/ComplexSelector.tsx +20 -5
  338. package/src/ContextMenu/ContextMenu.tsx +2 -2
  339. package/src/DateInput/DateInput.tsx +8 -2
  340. package/src/DateInput/MonthScroller.tsx +18 -22
  341. package/src/DateInput/Wheel.tsx +30 -32
  342. package/src/DateTimeInput/DateTimeInput.tsx +8 -2
  343. package/src/Dialog/Dialog.tsx +54 -45
  344. package/src/Drawer/Drawer.tsx +28 -11
  345. package/src/Drawer/useDrawerDialogPresence.ts +5 -1
  346. package/src/Field/Field.tsx +2 -2
  347. package/src/Field/PanelSearchInput.tsx +11 -0
  348. package/src/HoverCard/HoverCard.doc.mjs +4 -2
  349. package/src/HoverCard/HoverCard.tsx +35 -4
  350. package/src/HoverCard/useHoverCard.doc.mjs +178 -36
  351. package/src/HoverCard/useHoverCard.tsx +46 -52
  352. package/src/Icon/Icon.doc.mjs +49 -8
  353. package/src/Icon/Icon.tsx +15 -7
  354. package/src/InfoTip/InfoTip.doc.mjs +192 -0
  355. package/src/InfoTip/InfoTip.tsx +186 -0
  356. package/src/InfoTip/index.ts +14 -0
  357. package/src/Layer/layerAnimations.stylex.ts +24 -16
  358. package/src/Layer/useBackdropPress.ts +81 -0
  359. package/src/Layer/usePressPin.ts +86 -26
  360. package/src/Lightbox/Lightbox.tsx +18 -0
  361. package/src/MobileNav/MobileNav.tsx +1 -1
  362. package/src/MultiSelector/hooks.ts +2 -4
  363. package/src/Outline/Outline.doc.mjs +177 -51
  364. package/src/Outline/Outline.tsx +5 -57
  365. package/src/Outline/useOutlineFromMarkdown.doc.mjs +157 -0
  366. package/src/Outline/useOutlineFromMarkdown.ts +1 -0
  367. package/src/Outline/useScrollSpy.ts +3 -3
  368. package/src/PowerSearch/PowerSearch.doc.mjs +55 -6
  369. package/src/PowerSearch/PowerSearch.tsx +798 -324
  370. package/src/PowerSearch/PowerSearchBottomSheet.tsx +2515 -0
  371. package/src/PowerSearch/PowerSearchEditPopover.tsx +28 -6
  372. package/src/PowerSearch/PowerSearchValueEditor.tsx +203 -38
  373. package/src/PowerSearch/formatFilterValue.ts +18 -1
  374. package/src/PowerSearch/formatTokenValue.ts +215 -0
  375. package/src/PowerSearch/powerSearchSheetUtils.ts +224 -0
  376. package/src/RadioList/RadioList.doc.mjs +4 -2
  377. package/src/RadioList/RadioList.tsx +7 -2
  378. package/src/RadioList/RadioListItem.tsx +5 -3
  379. package/src/Resizable/ResizeHandle.tsx +133 -328
  380. package/src/Resizable/resizeGesture.ts +368 -0
  381. package/src/SegmentedControl/SegmentedControl.doc.mjs +3 -3
  382. package/src/SegmentedControl/SegmentedControl.tsx +179 -5
  383. package/src/SegmentedControl/SegmentedControlContext.ts +6 -0
  384. package/src/SegmentedControl/SegmentedControlItem.tsx +12 -1
  385. package/src/SegmentedControl/useSegmentedSelectionMotion.ts +1640 -0
  386. package/src/SegmentedControl/useSegmentedTouchTracking.ts +308 -0
  387. package/src/Selector/Selector.tsx +136 -89
  388. package/src/Selector/optionShape.ts +64 -0
  389. package/src/Selector/selectableOptionEntries.ts +39 -0
  390. package/src/Selector/utils.ts +9 -68
  391. package/src/SideNav/SideNavItem.tsx +3 -7
  392. package/src/Slider/sliderTouchController.ts +2 -2
  393. package/src/Spinner/Spinner.tsx +77 -63
  394. package/src/Switch/switchTouch.ts +2 -10
  395. package/src/Switch/useSwitchTouch.ts +38 -104
  396. package/src/Table/BaseTable.tsx +46 -12
  397. package/src/TextInput/TextInput.tsx +11 -10
  398. package/src/Toast/Toast.doc.mjs +4 -3
  399. package/src/Toast/Toast.tsx +57 -32
  400. package/src/Toast/ToastViewport.tsx +121 -35
  401. package/src/Toast/types.ts +9 -3
  402. package/src/Token/Token.tsx +15 -4
  403. package/src/Token/TokenNamingContext.ts +28 -0
  404. package/src/Tokenizer/Tokenizer.doc.mjs +16 -0
  405. package/src/Tokenizer/Tokenizer.tsx +89 -85
  406. package/src/Tokenizer/TokenizerBottomSheet.tsx +219 -93
  407. package/src/Tokenizer/TokenizerItemRemovableContext.ts +24 -0
  408. package/src/Tooltip/Tooltip.doc.mjs +123 -54
  409. package/src/Tooltip/Tooltip.tsx +36 -39
  410. package/src/Tooltip/index.ts +0 -1
  411. package/src/Tooltip/useTooltip.doc.mjs +171 -33
  412. package/src/Tooltip/useTooltip.tsx +98 -86
  413. package/src/TopNav/TopNavItem.tsx +6 -5
  414. package/src/TopNav/TopNavMegaMenuItem.tsx +6 -5
  415. package/src/TopNav/TopNavMenu.tsx +6 -5
  416. package/src/Typeahead/TypeaheadItem.doc.mjs +6 -3
  417. package/src/Typeahead/TypeaheadItem.tsx +2 -1
  418. package/src/animator/createAnimator.doc.mjs +153 -0
  419. package/src/animator/createAnimator.ts +324 -0
  420. package/src/gestures/GestureHost.ts +198 -20
  421. package/src/gestures/PressTracker.ts +4 -3
  422. package/src/gestures/README.md +7 -1
  423. package/src/hooks/actionGroupTracker.ts +32 -61
  424. package/src/hooks/index.ts +2 -0
  425. package/src/hooks/pressGroupContext.ts +21 -0
  426. package/src/hooks/useActionGroupTracking.ts +224 -0
  427. package/src/hooks/useAnimator.doc.mjs +109 -0
  428. package/src/hooks/useAnimator.ts +67 -0
  429. package/src/hooks/useAttachment.ts +1 -1
  430. package/src/hooks/useHighlightedOptionScroll.ts +123 -15
  431. package/src/hooks/useInputStatusIcon.tsx +3 -2
  432. package/src/hooks/useLongPress.doc.mjs +2 -2
  433. package/src/hooks/useLongPress.ts +136 -15
  434. package/src/hooks/useMediaQuery.doc.mjs +2 -2
  435. package/src/hooks/useMediaQuery.ts +13 -4
  436. package/src/hooks/useMenuPress.ts +8 -2
  437. package/src/i18n/generated-english/InfoTip/InfoTip.generated.ts +13 -0
  438. package/src/i18n/generated-english/PowerSearch/PowerSearch.generated.ts +1 -0
  439. package/src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts +43 -0
  440. package/src/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.ts +6 -0
  441. package/src/i18n/generated-english/PowerSearch/formatTokenValue.generated.ts +15 -0
  442. package/src/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.ts +7 -1
  443. package/src/i18n/generated-locales/en.generated.ts +43 -0
  444. package/src/i18n/generated-locales/pseudo.generated.ts +44 -0
  445. package/src/index.ts +14 -0
  446. package/src/internal/SheetConfirmation.tsx +101 -0
  447. package/src/internal/indicatorPress.stylex.ts +24 -0
  448. package/src/internal/sheetDraft.ts +80 -0
  449. package/src/internal/touch-sheet.ts +21 -0
  450. package/src/internal/useDismissSearchOnTouchDrag.ts +69 -0
  451. package/src/motion/MEASUREMENTS.md +7 -0
  452. package/src/motion/README.md +9 -5
  453. package/src/motion/animator.ts +61 -29
  454. package/src/motion/reducedMotion.ts +79 -1
  455. package/src/motion/roles.ts +20 -1
  456. package/src/motion/uikit/alert.ts +43 -0
  457. package/src/motion/uikit/index.ts +5 -5
  458. package/src/motion/uikit/segmented.ts +74 -0
  459. package/src/motion/uikit/springs.ts +5 -21
  460. package/src/privateAttributes/pressGroupItem.stylex.ts +23 -0
  461. package/src/privateAttributes/segmentTitle.stylex.ts +22 -0
  462. package/src/utils/browserClickWait.ts +133 -0
  463. package/src/utils/clickGuard.ts +64 -1
  464. package/src/utils/dateParser.ts +16 -0
  465. package/src/utils/focusReturn.ts +30 -0
  466. package/src/utils/interactionOverlay.stylex.ts +3 -2
  467. package/src/utils/pressFeedback.ts +19 -6
  468. package/src/utils/triggerFocus.ts +80 -0
  469. package/dist/internal/tokenizer-presentation.d.ts +0 -21
  470. package/dist/internal/tokenizer-presentation.d.ts.map +0 -1
  471. package/dist/internal/tokenizer-presentation.js +0 -21
  472. package/src/internal/tokenizer-presentation.ts +0 -25
@@ -6,61 +6,15 @@
6
6
  * @position Utilities; used by Selector.tsx
7
7
  */
8
8
 
9
- import type {
10
- SelectorOptionType,
11
- SelectorOptionData,
12
- SelectorDivider,
13
- SelectorSection,
14
- } from './types';
9
+ import type {SelectorOptionType, SelectorOptionData} from './types';
10
+ import {getSelectableOptionEntries} from './selectableOptionEntries';
15
11
 
16
- /**
17
- * Type guard: check if option is a selectable option (string or OptionData)
18
- */
19
- export function isOptionData(
20
- option: SelectorOptionType,
21
- ): option is SelectorOptionData | string {
22
- if (typeof option === 'string') {
23
- return true;
24
- }
25
- return !('type' in option);
26
- }
27
-
28
- /**
29
- * Type guard: check if option is a divider
30
- */
31
- export function isDivider(
32
- option: SelectorOptionType,
33
- ): option is SelectorDivider {
34
- return (
35
- typeof option === 'object' && 'type' in option && option.type === 'divider'
36
- );
37
- }
38
-
39
- /**
40
- * Type guard: check if option is a section
41
- */
42
- export function isSection(
43
- option: SelectorOptionType,
44
- ): option is SelectorSection {
45
- return (
46
- typeof option === 'object' && 'type' in option && option.type === 'section'
47
- );
48
- }
49
-
50
- /**
51
- * Normalize string or option to consistent shape
52
- */
53
- export function normalizeOption(
54
- option: string | SelectorOptionData,
55
- ): SelectorOptionData {
56
- if (typeof option === 'string') {
57
- return {value: option, label: option};
58
- }
59
- return {
60
- ...option,
61
- label: option.label ?? option.value,
62
- };
63
- }
12
+ export {
13
+ isOptionData,
14
+ isDivider,
15
+ isSection,
16
+ normalizeOption,
17
+ } from './optionShape';
64
18
 
65
19
  /**
66
20
  * Get all selectable options (flattening sections)
@@ -68,18 +22,5 @@ export function normalizeOption(
68
22
  export function getSelectableOptions(
69
23
  options: SelectorOptionType[],
70
24
  ): SelectorOptionData[] {
71
- const result: SelectorOptionData[] = [];
72
-
73
- for (const option of options) {
74
- if (isOptionData(option)) {
75
- result.push(normalizeOption(option));
76
- } else if (isSection(option)) {
77
- for (const opt of option.options) {
78
- result.push(normalizeOption(opt));
79
- }
80
- }
81
- // Skip dividers
82
- }
83
-
84
- return result;
25
+ return getSelectableOptionEntries(options).map(entry => entry.item);
85
26
  }
@@ -72,7 +72,7 @@ import {
72
72
  SideNavCollapseContext,
73
73
  } from './SideNavCollapseContext';
74
74
  import {useSideNavRenderMode} from './SideNavRenderContext';
75
- import {useAppShellMobile} from '../AppShell/AppShellMobileContext';
75
+ import {useCloseMobileDrawerOnActivate} from '../AppShell/useCloseMobileDrawerOnActivate';
76
76
  import {themeProps} from '../utils/themeProps';
77
77
  import {disabledInteractionProps} from '../utils/disabledInteraction';
78
78
 
@@ -535,8 +535,8 @@ export function SideNavItem({
535
535
  const t = useComponentTranslator();
536
536
  const {isCollapsed} = useSideNavCollapse();
537
537
  const renderMode = useSideNavRenderMode();
538
- const {closeMobileNav} = useAppShellMobile();
539
538
  const isInDrawer = renderMode === 'drawer' || renderMode === 'drawer-content';
539
+ const closeDrawerAfter = useCloseMobileDrawerOnActivate(isInDrawer);
540
540
  const id = useId();
541
541
  const hasChildren = !!children;
542
542
  const depth = use(SideNavItemDepthContext);
@@ -625,11 +625,7 @@ export function SideNavItem({
625
625
  toggleItemCollapse();
626
626
  return;
627
627
  }
628
- onClick?.(e);
629
- // Close the mobile nav when a nav item is activated inside the drawer
630
- if (isInDrawer) {
631
- closeMobileNav();
632
- }
628
+ closeDrawerAfter(onClick)?.(e);
633
629
  };
634
630
 
635
631
  const handleToggleClick = (e: React.MouseEvent) => {
@@ -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
 
@@ -4,8 +4,8 @@
4
4
  * @file switchTouch.ts
5
5
  * @input The UIKit switch constants (motion/uikit/switch.ts) and a track size
6
6
  * @output The pure model of Switch's touch presentation: thumb geometry, the
7
- * drag's target, the flip rule, the commit on release and its click wait,
8
- * and when the lifted thumb may settle
7
+ * drag's target, the flip rule, the commit on release, and when the lifted
8
+ * thumb may settle
9
9
  * @position Pure half of Switch's touch presentation; driven by
10
10
  * useSwitchTouch.ts, tested by switchTouch.test.ts without a browser
11
11
  *
@@ -158,14 +158,6 @@ export function stepFlip(
158
158
  return isPast === flip.isArmed ? flip : {...flip, isArmed: isPast};
159
159
  }
160
160
 
161
- /**
162
- * Passive: how long a lift waits for the browser's own click before the
163
- * switch clicks its input itself, ms. The browser sends that click with the
164
- * lift's `touchend`. The surface's `touch-action` leaves no double-tap delay.
165
- * So this only runs out for a lift the browser does not count as a click.
166
- */
167
- export const BROWSER_CLICK_WAIT_MS = 300;
168
-
169
161
  /**
170
162
  * What a release commits: the side a drag flipped to; when nothing flipped,
171
163
  * the other side of the value, wherever the finger lifts. A press slid off
@@ -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';
@@ -31,9 +31,9 @@ import {solveSpring, toSpring, type SpringDescription} from '../motion/spring';
31
31
  import {UIKIT_GESTURES} from '../motion/uikit/gestures';
32
32
  import {registerSwitchTable, switchControl} from '../motion/uikit/switch';
33
33
  import {useTouchPresentation} from '../utils/touchPresentation';
34
- import {armClickGuard, withoutClickGuard} from '../utils/clickGuard';
34
+ import {awaitBrowserClick, clickForLift} from '../utils/browserClickWait';
35
+ import {armClickGuard} from '../utils/clickGuard';
35
36
  import {
36
- BROWSER_CLICK_WAIT_MS,
37
37
  commitOnRelease,
38
38
  dragTarget,
39
39
  settleTime,
@@ -253,11 +253,8 @@ export class SwitchTouchController {
253
253
  private isTracking = false;
254
254
  /** Which presentation the switch has: the touch one, or its own. */
255
255
  private presentation: SwitchPresentation = 'touch';
256
- /** The press-time listeners under a fine pointer, while armed. */
257
- private pressListeners: (() => void) | null = null;
258
- private pressListenersTimer: ReturnType<typeof setTimeout> | null = null;
259
- /** Passive: a lift is waiting for the browser's own click. */
260
- private browserClickTimer: ReturnType<typeof setTimeout> | null = null;
256
+ /** Passive: a lift is waiting for the browser's own click; this ends it. */
257
+ private endBrowserClickWait: (() => void) | null = null;
261
258
  private reconcileTimer: ReturnType<typeof setTimeout> | null = null;
262
259
 
263
260
  constructor(isOn: boolean, geometry: SwitchTouchGeometry) {
@@ -285,15 +282,15 @@ export class SwitchTouchController {
285
282
  return;
286
283
  }
287
284
  registerSwitchTable();
288
- this.thumb = createAnimator(elements.thumb);
285
+ this.thumb = createMotionAnimator(elements.thumb);
289
286
  // The layer rests clear (its class's opacity 0) while the visuals show
290
287
  // the value; from here its opacity is the animator's.
291
- this.fade = createAnimator(elements.track, {
288
+ this.fade = createMotionAnimator(elements.track, {
292
289
  pseudoElement: '::after',
293
290
  initial: {opacity: 0},
294
291
  });
295
292
  this.fade.set({opacity: 0});
296
- this.shadow = createAnimator(elements.thumb, {
293
+ this.shadow = createMotionAnimator(elements.thumb, {
297
294
  pseudoElement: '::after',
298
295
  initial: {opacity: 0},
299
296
  });
@@ -328,73 +325,7 @@ export class SwitchTouchController {
328
325
  }
329
326
  },
330
327
  });
331
- // The lift's own click activates the input natively: the switch then
332
- // clicks nothing itself.
333
- const onClick = (event: MouseEvent) => {
334
- if (event.isTrusted && this.browserClickTimer != null) {
335
- clearTimeout(this.browserClickTimer);
336
- this.browserClickTimer = null;
337
- this.scheduleReconcile();
338
- }
339
- };
340
- const listen = (): (() => void) => {
341
- surface.addEventListener('click', onClick, true);
342
- return () => {
343
- surface.removeEventListener('click', onClick, true);
344
- };
345
- };
346
- if (this.presentation === 'pointer') {
347
- // Under a fine pointer only the press the host arms listens at rest.
348
- // The switch's click listener comes with a press and goes after its
349
- // click wait.
350
- this.listenForPress = listen;
351
- return [
352
- host.attachConsumer(surface, tracker),
353
- () => tracker.dispose(),
354
- () => this.stopPressListeners(),
355
- ];
356
- }
357
- return [
358
- host.attachConsumer(surface, tracker),
359
- () => tracker.dispose(),
360
- listen(),
361
- ];
362
- }
363
-
364
- /** Under a fine pointer: adds the switch's own listeners for a press. */
365
- private listenForPress: (() => () => void) | null = null;
366
-
367
- private startPressListeners(): void {
368
- if (this.pressListenersTimer != null) {
369
- clearTimeout(this.pressListenersTimer);
370
- this.pressListenersTimer = null;
371
- }
372
- if (this.pressListeners == null && this.listenForPress != null) {
373
- this.pressListeners = this.listenForPress();
374
- }
375
- }
376
-
377
- /** The press's click window is over: its listeners go. */
378
- private endPressListeners(afterMs: number): void {
379
- if (this.pressListeners == null) {
380
- return;
381
- }
382
- if (this.pressListenersTimer != null) {
383
- clearTimeout(this.pressListenersTimer);
384
- }
385
- this.pressListenersTimer = setTimeout(() => {
386
- this.pressListenersTimer = null;
387
- this.stopPressListeners();
388
- }, afterMs);
389
- }
390
-
391
- private stopPressListeners(): void {
392
- if (this.pressListenersTimer != null) {
393
- clearTimeout(this.pressListenersTimer);
394
- this.pressListenersTimer = null;
395
- }
396
- this.pressListeners?.();
397
- this.pressListeners = null;
328
+ return [host.attachConsumer(surface, tracker), () => tracker.dispose()];
398
329
  }
399
330
 
400
331
  /** Undo everything: listeners, timers, animations and inline styles. */
@@ -403,7 +334,6 @@ export class SwitchTouchController {
403
334
  detach();
404
335
  }
405
336
  this.detachers = [];
406
- this.listenForPress = null;
407
337
  this.clearTimers();
408
338
  for (const animator of [this.thumb, this.fade, this.shadow]) {
409
339
  const element = animator?.element;
@@ -576,7 +506,6 @@ export class SwitchTouchController {
576
506
  switch (event) {
577
507
  case 'touchDown':
578
508
  this.isTracking = true;
579
- this.startPressListeners();
580
509
  this.touchDown(time);
581
510
  return;
582
511
  case 'touchDragInside':
@@ -612,16 +541,18 @@ export class SwitchTouchController {
612
541
  byBrowserClick: true,
613
542
  clicksIfNoBrowserClick: touch.pointerType === 'touch',
614
543
  });
615
- this.endPressListeners(BROWSER_CLICK_WAIT_MS);
616
544
  return;
617
545
  }
618
- if (this.drag?.flip.didFlip !== true && touch.pointerType !== 'touch') {
619
- // A mouse or a pen slid off and released outside, with no flip:
620
- // the switch is left alone, as the native checkbox is. Only a
621
- // finger's press slid off toggles.
546
+ if (
547
+ touch.pointerType !== 'touch' &&
548
+ (event === 'touchUpOutside' || this.drag?.flip.didFlip !== true)
549
+ ) {
550
+ // A mouse or a pen released outside the tracking bounds, flipped or
551
+ // not, leaves the switch alone, as the native checkbox does. So the
552
+ // press can be taken back (WCAG 2.5.2). Only a finger's press slid
553
+ // off toggles.
622
554
  this.released = true;
623
555
  this.abandon(time);
624
- this.endPressListeners(0);
625
556
  return;
626
557
  }
627
558
  // A drag that flipped, or a press slid off and lifted outside, which
@@ -633,7 +564,6 @@ export class SwitchTouchController {
633
564
  armClickGuard(this.elements.input.ownerDocument);
634
565
  }
635
566
  this.release(time);
636
- this.endPressListeners(0);
637
567
  return;
638
568
  case 'touchCancel':
639
569
  // The browser took the touch for its scroll, or a recognizer above
@@ -643,7 +573,6 @@ export class SwitchTouchController {
643
573
  this.released = true;
644
574
  this.abandon(time);
645
575
  }
646
- this.endPressListeners(0);
647
576
  return;
648
577
  case 'touchDragEnter':
649
578
  case 'touchDragExit':
@@ -725,14 +654,23 @@ export class SwitchTouchController {
725
654
  this.showSide(commit, time, undefined, true);
726
655
  }
727
656
  this.pressEnded(time, true);
728
- if (byBrowserClick) {
729
- this.browserClickTimer = setTimeout(() => {
730
- this.browserClickTimer = null;
731
- if (clicksIfNoBrowserClick && commit !== this.isOn) {
732
- this.clickInput();
733
- }
734
- this.scheduleReconcile();
735
- }, BROWSER_CLICK_WAIT_MS);
657
+ const surface = this.elements?.surface;
658
+ if (byBrowserClick && surface != null) {
659
+ // The lift's own click activates the input natively: the switch then
660
+ // clicks nothing itself.
661
+ this.endBrowserClickWait = awaitBrowserClick(surface, {
662
+ onClicked: () => {
663
+ this.endBrowserClickWait = null;
664
+ this.scheduleReconcile();
665
+ },
666
+ onNoClick: () => {
667
+ this.endBrowserClickWait = null;
668
+ if (clicksIfNoBrowserClick && commit !== this.isOn) {
669
+ this.clickInput();
670
+ }
671
+ this.scheduleReconcile();
672
+ },
673
+ });
736
674
  return;
737
675
  }
738
676
  if (commit !== this.isOn) {
@@ -749,11 +687,9 @@ export class SwitchTouchController {
749
687
  */
750
688
  private clickInput(): void {
751
689
  const input = this.elements?.input;
752
- if (input == null) {
753
- return;
690
+ if (input != null) {
691
+ clickForLift(input);
754
692
  }
755
- armClickGuard(input.ownerDocument);
756
- withoutClickGuard(() => input.click());
757
693
  }
758
694
 
759
695
  /** If the owner kept the old value, the visuals go back to it. */
@@ -1034,10 +970,8 @@ export class SwitchTouchController {
1034
970
  }
1035
971
 
1036
972
  private clearTimers(): void {
1037
- if (this.browserClickTimer != null) {
1038
- clearTimeout(this.browserClickTimer);
1039
- this.browserClickTimer = null;
1040
- }
973
+ this.endBrowserClickWait?.();
974
+ this.endBrowserClickWait = null;
1041
975
  if (this.reconcileTimer != null) {
1042
976
  clearTimeout(this.reconcileTimer);
1043
977
  this.reconcileTimer = null;