@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
@@ -0,0 +1,43 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file alert.ts
5
+ * @input Nothing; data only
6
+ * @output Exports `alertController`: how UIAlertController (`.alert`) tracks
7
+ * a finger across its actions
8
+ * @position The alert domain of the UIKit constants table (motion/uikit);
9
+ * its springs are `springs.alertPresent` and `springs.alertDismiss`
10
+ *
11
+ * Every value was read from UIKit on the iOS 26.2 simulator. A host app
12
+ * presented `UIAlertController(.alert)` with two and with three actions.
13
+ * Real HID touches drove it, and the action views' highlight was sampled
14
+ * every frame. Lengths are in pt (CSS px), durations in ms.
15
+ *
16
+ * Every leaf carries one or more `@source`; GUESS values also carry the
17
+ * `@measure` task that will confirm or replace them. uikit.test.ts enforces
18
+ * both.
19
+ *
20
+ * SYNC: When modified, update /packages/core/src/motion/MEASUREMENTS.md
21
+ */
22
+
23
+ export const alertController = {
24
+ actions: {
25
+ /**
26
+ * How long after touch-down the touched action highlights: none, it is
27
+ * highlighted in the touch-down frame (a tap and a 300 ms hold alike).
28
+ * @source measured: UIKit lab (injected host app), iOS 26.2 simulator,
29
+ * iPhone 17 Pro, per-frame highlight of the action views under real HID
30
+ * touches, Oct 23 2026
31
+ */
32
+ highlightOnsetMs: 0,
33
+ /**
34
+ * How far outside an action the finger may go and keep it highlighted:
35
+ * none. The highlight cleared 1 pt below the action, and a lift there ran
36
+ * nothing. UIButton keeps 70 pt; an alert action does not.
37
+ * @source measured: UIKit lab (injected host app), iOS 26.2 simulator,
38
+ * iPhone 17 Pro, per-frame highlight of the action views under real HID
39
+ * touches, Oct 23 2026
40
+ */
41
+ highlightExpansion: 0,
42
+ },
43
+ } as const;
@@ -4,10 +4,10 @@
4
4
  * @file index.ts
5
5
  * @input The domain files of the UIKit constants table
6
6
  * @output Re-exports `springs` and one constant per spring (`SHEET_PRESENT_SPRING`,
7
- * …), `scroll`, `timing`, `navigation`, `progressBar`, the `slider` and
8
- * switch (`switchControl`) domains, and the gesture thresholds (one
9
- * `UIKIT_*` group per recognizer, their union `UIKIT_GESTURES`, and the
10
- * haptic tables)
7
+ * …), `scroll`, `timing`, `navigation`, `progressBar`, `segmentedControl`,
8
+ * the `slider` and switch (`switchControl`) domains, and the gesture
9
+ * thresholds (one `UIKIT_*` group per recognizer, their union
10
+ * `UIKIT_GESTURES`, and the haptic tables)
11
11
  * @position Entry of the UIKit constants table (motion/uikit). Internal to
12
12
  * core: not exported from the package entry point
13
13
  *
@@ -42,6 +42,7 @@ export {
42
42
  export {navigation, registerNavigationTable} from './navigation';
43
43
  export {progressBar, registerProgressBarTable} from './progressBar';
44
44
  export {registerScrollTable, scroll} from './scroll';
45
+ export {segmentedControl} from './segmented';
45
46
  export {slider} from './slider';
46
47
  export {
47
48
  ACTION_SHEET_DISMISS_SPRING,
@@ -64,7 +65,6 @@ export {
64
65
  NAVIGATION_POP_SPRING,
65
66
  NAVIGATION_PUSH_SPRING,
66
67
  QUICK_CHANGE_SPRING,
67
- SEGMENTED_THUMB_SPRING,
68
68
  SETTLE_SPRING,
69
69
  SHEET_DETENT_SPRING,
70
70
  SHEET_DISMISS_SPRING,
@@ -0,0 +1,74 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file segmented.ts
5
+ * @input Nothing; data only
6
+ * @output Exports `segmentedControl`, UISegmentedControl's selection slide
7
+ * spring and its drag overshoot; and `registerSegmentedTable`, which
8
+ * registers the spring as an internal motion role
9
+ * @position The segmented-control domain of the UIKit constants table
10
+ * (motion/uikit); read by SegmentedControl's touch presentation
11
+ *
12
+ * SYNC: When modified, update:
13
+ * - /packages/core/src/SegmentedControl/useSegmentedSelectionMotion.ts
14
+ * - /packages/core/src/motion/README.md (domain list)
15
+ */
16
+
17
+ import {registerMotionTable} from '../roles';
18
+
19
+ /**
20
+ * UIKit's own UISegmentedControl, measured with three text segments in a
21
+ * 300 × 31 pt control. A tap and a programmatic change follow the same
22
+ * spring. Every leaf carries a `@source`, and uikit.test.ts checks it.
23
+ *
24
+ * Some UIKit motion is left out on purpose. UIKit cross-fades the two titles
25
+ * that change, over 0.2 s. Astryx switches them at once, because a
26
+ * cross-fade needs a second copy of each title. Under Reduce Motion, UIKit's
27
+ * lens fades in at the new segment and scales from 0.88. Astryx allows no
28
+ * scaling there, so the animator's Reduce Motion cross-fade replaces it.
29
+ * UIKit's lens also lifts and stretches under a finger. A theme role owns
30
+ * the lift, and the stretch is not modeled. The lens chases a dragging
31
+ * finger on the shared `springs.fingerTracking` role, which matches the
32
+ * values UIKit reports for this control.
33
+ */
34
+ export const segmentedControl = {
35
+ /**
36
+ * The selection indicator's slide from the old segment to the new one,
37
+ * after a tap or a programmatic change. Its response is 0.40 s and its
38
+ * damping ratio 0.85. That gives about 1.25 pt of overshoot on a 200 pt
39
+ * move, settled by about 0.6 s. The width follows the same spring when the
40
+ * segments differ in width.
41
+ * @source measured: UIKit lab (injected host app), iOS 26.2 simulator,
42
+ * iPhone 17 Pro, UIViewSpringAnimationBehavior read on the lens position
43
+ * for a tap and a programmatic set (dampingRatio 0.85, response 0.40,
44
+ * tracking off), Oct 23 2026
45
+ * @source measured: UIKit lab (injected host app), iOS 26.2 simulator,
46
+ * iPhone 17 Pro, per-frame log of the lens's presentation position and
47
+ * velocity (method C) for a tap, a programmatic set and an animated set,
48
+ * least-squares spring fit (response 0.395 / 0.405 / 0.400 s, damping
49
+ * ratio 0.855 / 0.845 / 0.850, rms at most 0.65 pt over 200 pt),
50
+ * Oct 23 2026
51
+ */
52
+ selectionSpring: {response: 0.4, dampingRatio: 0.85},
53
+ /**
54
+ * How far past the first or last segment's center the lens follows a
55
+ * dragging finger, in pt. Beyond that, the lens stays put while the finger
56
+ * goes on.
57
+ * @source measured: UIKit lab (injected host app), iOS 26.2 simulator,
58
+ * iPhone 17 Pro, a drag 60 pt past the last segment: the lens stops about
59
+ * 11 pt past its center (312 vs 301), Oct 23 2026
60
+ */
61
+ dragOvershoot: 11,
62
+ } as const;
63
+
64
+ /**
65
+ * Registers this table with the motion registry (motion/roles.ts). The
66
+ * slide's spring becomes an internal motion role. The drag overshoot is not
67
+ * motion, so it stays an internal constant. Nothing registers on import, and
68
+ * a second call does nothing.
69
+ */
70
+ export function registerSegmentedTable(): void {
71
+ registerMotionTable('segmented', segmentedControl, {
72
+ roles: ['selectionSpring'],
73
+ });
74
+ }
@@ -15,11 +15,11 @@
15
15
  * that will confirm or replace them (MEASUREMENTS.md lists them all).
16
16
  * uikit.test.ts enforces both.
17
17
  *
18
- * Most springs are measured on iOS 26.2 or documented by Apple; two are still
19
- * GUESSES (`segmentedThumb`, `banner`). `switchThumbMove` is the switch's
20
- * measured travel, which uikit/switch.ts reads. A guess starts from the
21
- * nearest sourced spring and names it. A component built on the table gets
22
- * the measured value the moment it lands, without changing.
18
+ * Most springs are measured on iOS 26.2 or documented by Apple; one is still
19
+ * a GUESS (`banner`). `switchThumbMove` is the switch's measured travel,
20
+ * which uikit/switch.ts reads. A guess starts from the nearest sourced
21
+ * spring and names it. A component built on the table gets the measured
22
+ * value the moment it lands, without changing.
23
23
  *
24
24
  * Press highlight in/out are fades, not springs: see timing.ts.
25
25
  *
@@ -400,21 +400,6 @@ export const SWITCH_THUMB_MOVE_SPRING = {
400
400
  dampingRatio: 1,
401
401
  } as const;
402
402
 
403
- /**
404
- * UISegmentedControl selection thumb sliding to a new segment.
405
- * @source GUESS — WebKit's UIKit-matched switch thumb spring
406
- * (RenderThemeCocoa.mm `thumbMoveSpring`: response 0.30 s, ratio 0.75),
407
- * kept only until UISegmentedControl's measured spring replaces it;
408
- * UISwitch's measured travel (`SWITCH_THUMB_MOVE_SPRING`)
409
- * belongs to another control
410
- * @measure M-SG02
411
- * @measure M-SG03
412
- */
413
- export const SEGMENTED_THUMB_SPRING = {
414
- response: 0.3,
415
- dampingRatio: 0.75,
416
- } as const;
417
-
418
403
  // ---------------------------------------------------------------------
419
404
  // System
420
405
  // ---------------------------------------------------------------------
@@ -504,7 +489,6 @@ export const springs = {
504
489
  contextMenuMorph: CONTEXT_MENU_MORPH_SPRING,
505
490
  menuReducedMotion: MENU_REDUCED_MOTION_SPRING,
506
491
  switchThumbMove: SWITCH_THUMB_MOVE_SPRING,
507
- segmentedThumb: SEGMENTED_THUMB_SPRING,
508
492
  keyboard: KEYBOARD_SPRING,
509
493
  banner: BANNER_SPRING,
510
494
  sliderRelease: SLIDER_RELEASE_SPRING,
@@ -0,0 +1,23 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ /**
3
+ * @file privateAttributes/pressGroupItem.stylex.ts
4
+ * @input Nothing: the private press-group-item attribute
5
+ * @output pressGroupItemProps, which marks an action a group's tracker
6
+ * follows, and isTrackedByGroup, which reads the mark
7
+ * @position Owner module of the private press-group-item attribute: the only
8
+ * file that writes its name. AlertDialog marks its actions, and the press
9
+ * controller (utils/pressFeedback.ts) leaves their press to the group's
10
+ * tracker. No package entry exports it.
11
+ */
12
+
13
+ const PRESS_GROUP_ITEM = 'data-astryx-press-group-item';
14
+
15
+ /** Spread on each action that a group's tracker follows. */
16
+ export const pressGroupItemProps: Readonly<Record<string, string>> = {
17
+ [PRESS_GROUP_ITEM]: '',
18
+ };
19
+
20
+ /** Whether a group's tracker paints the press on `element` or an ancestor. */
21
+ export function isTrackedByGroup(element: Element): boolean {
22
+ return element.closest(`[${PRESS_GROUP_ITEM}]`) != null;
23
+ }
@@ -0,0 +1,22 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file privateAttributes/segmentTitle.stylex.ts
5
+ * @input Nothing
6
+ * @output segmentTitleProps, which marks a SegmentedControl segment's title,
7
+ * and titleOfSegment, which finds that title in a segment
8
+ * @position Owner module of the private segment-title attribute: the only
9
+ * file that writes its name. No package entry exports it.
10
+ */
11
+
12
+ const SEGMENT_TITLE = 'data-astryx-segment-title';
13
+
14
+ /** Spread on a segment's title: marks it for the touch layer. */
15
+ export const segmentTitleProps: Readonly<Record<string, string>> = {
16
+ [SEGMENT_TITLE]: '',
17
+ };
18
+
19
+ /** The title inside `segment`, or null when the label is hidden. */
20
+ export function titleOfSegment(segment: Element): HTMLElement | null {
21
+ return segment.querySelector<HTMLElement>(`[${SEGMENT_TITLE}]`);
22
+ }
@@ -0,0 +1,133 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file browserClickWait.ts
5
+ * @input An element a tap's lift released on, and the control that acts on
6
+ * its click
7
+ * @output BROWSER_CLICK_WAIT_MS, awaitBrowserClick, clickForLift and
8
+ * clickAndReport
9
+ * @position The one wait for the browser's click after a tap, shared by
10
+ * Switch/useSwitchTouch.ts and SegmentedControl/useSegmentedTouchTracking.ts.
11
+ * It swallows nothing: utils/clickGuard.ts is the one guard for a late click.
12
+ *
13
+ * SYNC: When modified, update browserClickWait.test.ts.
14
+ */
15
+
16
+ import {armClickGuard, withoutClickGuard} from './clickGuard';
17
+ import {subscribeInput} from './inputStream';
18
+
19
+ /**
20
+ * How long a tap's lift waits for the browser's own click, ms. The browser
21
+ * sends that click with the lift when the page has no double-tap delay. The
22
+ * wait runs out for a lift that the browser does not count as a click, such
23
+ * as a hold. It also runs out when a busy main thread holds the click back.
24
+ */
25
+ export const BROWSER_CLICK_WAIT_MS = 300;
26
+
27
+ /** What a control does when the browser's click comes, or does not. */
28
+ export interface BrowserClickWaitHandlers {
29
+ /** The browser's click ran its handlers. `isCancelled`: one cancelled it. */
30
+ readonly onClicked: (isCancelled: boolean) => void;
31
+ /** No browser click came in time. */
32
+ readonly onNoClick: () => void;
33
+ }
34
+
35
+ /**
36
+ * Waits for the browser's own click inside `target` after a tap's lift. That
37
+ * click is the activation: `onClicked` runs once its handlers have run. With
38
+ * no click in time, `onNoClick` runs. The returned call ends the wait at once
39
+ * and leaves no listener or timer behind.
40
+ */
41
+ export function awaitBrowserClick(
42
+ target: Element,
43
+ {onClicked, onNoClick}: BrowserClickWaitHandlers,
44
+ ): () => void {
45
+ const view = target.ownerDocument.defaultView;
46
+ if (view == null) {
47
+ // A document with no window gets no click: the wait runs out at once.
48
+ let isEnded = false;
49
+ queueMicrotask(() => {
50
+ if (!isEnded) {
51
+ onNoClick();
52
+ }
53
+ });
54
+ return () => {
55
+ isEnded = true;
56
+ };
57
+ }
58
+ let isDone = false;
59
+ let report: number | null = null;
60
+ let timer: number | null = null;
61
+ let stopListening: (() => void) | null = null;
62
+ const stop = () => {
63
+ isDone = true;
64
+ stopListening?.();
65
+ stopListening = null;
66
+ if (timer != null) {
67
+ view.clearTimeout(timer);
68
+ timer = null;
69
+ }
70
+ };
71
+ stopListening = subscribeInput(view, 'click', event => {
72
+ if (
73
+ isDone ||
74
+ !event.isTrusted ||
75
+ !target.contains(event.target as Node | null)
76
+ ) {
77
+ return;
78
+ }
79
+ stop();
80
+ // After every handler has run: was it cancelled?
81
+ report = view.setTimeout(() => {
82
+ report = null;
83
+ onClicked(event.defaultPrevented);
84
+ }, 0);
85
+ });
86
+ timer = view.setTimeout(() => {
87
+ if (isDone) {
88
+ return;
89
+ }
90
+ stop();
91
+ onNoClick();
92
+ }, BROWSER_CLICK_WAIT_MS);
93
+ return () => {
94
+ stop();
95
+ if (report != null) {
96
+ view.clearTimeout(report);
97
+ report = null;
98
+ }
99
+ };
100
+ }
101
+
102
+ /**
103
+ * Click `element` (its own `click()`, so its activation behavior and every
104
+ * handler run as for any click) and report whether a handler cancelled it.
105
+ * The event is read from a capture listener that exists only for the call.
106
+ */
107
+ export function clickAndReport(element: HTMLElement): boolean {
108
+ const view = element.ownerDocument.defaultView;
109
+ let clicked: Event | null = null;
110
+ const grab = (event: Event) => {
111
+ if (clicked == null && event.target === element) {
112
+ clicked = event;
113
+ }
114
+ };
115
+ view?.addEventListener('click', grab, true);
116
+ try {
117
+ element.click();
118
+ } finally {
119
+ view?.removeEventListener('click', grab, true);
120
+ }
121
+ return (clicked as Event | null)?.defaultPrevented === true;
122
+ }
123
+
124
+ /**
125
+ * Clicks `element` for a lift the control decided itself, and reports
126
+ * whether a handler cancelled the click. The shared click guard swallows the
127
+ * browser's own click for the same lift, if it comes later, so the lift
128
+ * activates once.
129
+ */
130
+ export function clickForLift(element: HTMLElement): boolean {
131
+ armClickGuard(element.ownerDocument);
132
+ return withoutClickGuard(() => clickAndReport(element));
133
+ }
@@ -21,6 +21,16 @@
21
21
  // page adds later (AST-057, AST-094). If only the gesture host arms it, the
22
22
  // click listener stays only while the guard is armed.
23
23
  //
24
+ // An arm at a claimed touch's lift also takes that touch's late `mousedown`
25
+ // and `mouseup`. WebKit sends them a few ms after a held tap's cancelled
26
+ // `touchend`, aimed at whatever is under the finger by then. They go with
27
+ // the click, the next `pointerdown` or the window, as the guard does.
28
+ //
29
+ // The menu press model's arm at a finger's release also cancels that touch's
30
+ // `touchend`, so the browser creates no click and no compatibility mouse
31
+ // events. A busy main thread can otherwise hold that click past the window,
32
+ // when a drill-in has put another row under the finger.
33
+ //
24
34
  // Some clicks always pass:
25
35
  // - a click with `detail` 0: a keyboard's, a screen reader's, or one that the
26
36
  // page dispatches;
@@ -45,6 +55,19 @@ export interface ClickGuardOptions {
45
55
  * @default false
46
56
  */
47
57
  readonly staysInstalled?: boolean;
58
+ /**
59
+ * The gesture host's arm at a claimed touch's lift: the guard also takes
60
+ * that touch's late `mousedown` and `mouseup` while it is armed.
61
+ * @default false
62
+ */
63
+ readonly takesLateMouse?: boolean;
64
+ /**
65
+ * The menu press model's arm at a finger's release: the guard also cancels
66
+ * that touch's `touchend`, so the browser creates no click for it. A
67
+ * cancelled `touchend` disarms the guard.
68
+ * @default false
69
+ */
70
+ readonly cancelsTouchEnd?: boolean;
48
71
  }
49
72
 
50
73
  interface Guard {
@@ -78,7 +101,11 @@ function listenForClicks(view: Window): () => void {
78
101
  /** Swallow the browser's next click on `doc` (see the file header). */
79
102
  export function armClickGuard(
80
103
  doc: Document,
81
- {staysInstalled = false}: ClickGuardOptions = {},
104
+ {
105
+ staysInstalled = false,
106
+ takesLateMouse = false,
107
+ cancelsTouchEnd = false,
108
+ }: ClickGuardOptions = {},
82
109
  ): void {
83
110
  const view = doc.defaultView;
84
111
  if (view == null) {
@@ -98,6 +125,33 @@ export function armClickGuard(
98
125
  // The next press is a new gesture: its click must never be eaten.
99
126
  subscribeInput(view, 'pointerdown', () => disarmClickGuard(doc)),
100
127
  );
128
+ if (takesLateMouse) {
129
+ for (const type of ['mousedown', 'mouseup'] as const) {
130
+ guard.unsubscribers.push(
131
+ subscribeInput(view, type, swallowLateMouse, {cancels: true}),
132
+ );
133
+ }
134
+ }
135
+ if (cancelsTouchEnd) {
136
+ // A touch sends its pointerup before its touchend, so the next touchend is
137
+ // that touch's own. The next pointerdown disarms the guard first.
138
+ const stopTouchEnd = subscribeInput(
139
+ view,
140
+ 'touchend',
141
+ event => {
142
+ stopTouchEnd();
143
+ // A touchend that the browser took for a scroll is not cancelable.
144
+ // The guard stays armed for a click that may follow it.
145
+ if (event.cancelable) {
146
+ event.preventDefault();
147
+ // No click follows a cancelled touchend.
148
+ disarmClickGuard(doc);
149
+ }
150
+ },
151
+ {cancels: true},
152
+ );
153
+ guard.unsubscribers.push(stopTouchEnd);
154
+ }
101
155
  guard.timer = setTimeout(() => disarmClickGuard(doc), CLICK_GUARD_WINDOW_MS);
102
156
  }
103
157
 
@@ -149,6 +203,15 @@ export function __resetClickGuardForTest(): void {
149
203
  }
150
204
  }
151
205
 
206
+ /** Swallows a claimed touch's late `mousedown` or `mouseup`. */
207
+ function swallowLateMouse(event: MouseEvent): void {
208
+ if (isExempt(event)) {
209
+ return;
210
+ }
211
+ event.preventDefault();
212
+ event.stopImmediatePropagation();
213
+ }
214
+
152
215
  function isExempt(event: MouseEvent): boolean {
153
216
  if (event.detail === 0 || unguardedDepth > 0) {
154
217
  return true;
@@ -32,6 +32,11 @@ export function isLocaleDayFirst(locale: Locale = 'en'): boolean {
32
32
  return dayIndex < monthIndex;
33
33
  }
34
34
 
35
+ // Built at run time: a Unicode property escape in a literal fails a source
36
+ // build whose Babel lacks the Unicode data.
37
+ const LETTER_FREE = new RegExp('^[^\\p{L}]+$', 'u');
38
+ const YEAR_FIRST = new RegExp('^\\d{4}[^\\p{L}\\d]', 'u');
39
+
35
40
  /**
36
41
  * Parses user input into a PlainDate.
37
42
  *
@@ -138,6 +143,17 @@ export function parseDateInput(
138
143
  if (/^\d+$/.test(trimmed)) {
139
144
  return null;
140
145
  }
146
+ // In a day-first locale, letter-free text that no form above matched is not
147
+ // a date. Native `Date` reads `a/b/c` month first. It also takes a year of
148
+ // one to three digits. So "12/01/2" gives a wrong date. A four-digit year
149
+ // written first is not ambiguous.
150
+ if (
151
+ isLocaleDayFirst(locale) &&
152
+ LETTER_FREE.test(trimmed) &&
153
+ !YEAR_FIRST.test(trimmed)
154
+ ) {
155
+ return null;
156
+ }
141
157
 
142
158
  const parsed = new Date(trimmed);
143
159
  if (!isNaN(parsed.getTime())) {
@@ -151,3 +151,33 @@ export function focusForLastInput(
151
151
  }
152
152
  element.focus({...options, focusVisible: false});
153
153
  }
154
+
155
+ /**
156
+ * Prepares the focus return for an open surface that may be removed while
157
+ * open (rendered only while open, or removed with its view). Removing a
158
+ * `<dialog>` runs no close and no browser focus return. Call this while the
159
+ * surface is mounted: it reads the frame that hosts the surface now, because a
160
+ * removed frame's document has no window. Call the returned function from the
161
+ * effect cleanup with the opener.
162
+ *
163
+ * Once the commit has finished, focus moves to the opener only when the
164
+ * surface really left the document (StrictMode's simulated unmount keeps it),
165
+ * the opener is still on the page, and the removal lost focus, both in the
166
+ * surface's document and in the document that hosts its frame. A control the
167
+ * user pressed outside the surface, or outside its frame, keeps its focus.
168
+ */
169
+ export function prepareFocusReturnOnRemoval(
170
+ surface: Element,
171
+ ): (opener: Element | null) => void {
172
+ const host = surface.ownerDocument.defaultView?.frameElement ?? null;
173
+ return opener => {
174
+ queueMicrotask(() => {
175
+ if (surface.isConnected || opener == null || !opener.isConnected) {
176
+ return;
177
+ }
178
+ if (isFocusLost(surface) && (host == null || isFocusLost(host))) {
179
+ focusForLastInput(opener as HTMLElement);
180
+ }
181
+ });
182
+ };
183
+ }
@@ -15,8 +15,9 @@
15
15
  * SYNC: When modified, update pressFeedback.ts, pressGesture.ts (the fade
16
16
  * clock), hooks/usePressFeedback.doc.mjs, the components that paint the touch
17
17
  * press off an ancestor scope or a pseudo-element (Switch, Tab,
18
- * CheckboxInput, RadioListItem, ClickableCard, SelectableCard, Thumbnail)
19
- * and scripts/build-css.test.mjs.
18
+ * CheckboxInput, RadioListItem, ClickableCard, SelectableCard, Thumbnail),
19
+ * Button (a tracked action sizes its `:active` image to zero) and
20
+ * scripts/build-css.test.mjs.
20
21
  */
21
22
 
22
23
  // Every surface that paints a press uses one of these styles, so a change to
@@ -2,8 +2,8 @@
2
2
 
3
3
  /**
4
4
  * @file pressFeedback.ts
5
- * @input The press state machine (pressGesture.ts), the menu-press marker
6
- * (hooks/menuPressMarker.ts) and the document's pointer, keyboard, scroll and
5
+ * @input The press state machine (pressGesture.ts), the menu-press and
6
+ * press-group markers and the document's pointer, keyboard, scroll and
7
7
  * visibility events
8
8
  * @output PRESSABLE_ATTRIBUTE, PRESSED_ATTRIBUTE, pressableProps and
9
9
  * installPressFeedback
@@ -46,6 +46,7 @@ import {isCoarsePointer, watchCoarsePointer} from './coarsePointer';
46
46
  import {subscribeInput} from './inputStream';
47
47
  import {TOUCH_QUERY} from './touchPresentation';
48
48
  import {holdsPressThroughDrag} from '../privateAttributes/pressHoldsDrag.stylex';
49
+ import {isTrackedByGroup} from '../privateAttributes/pressGroupItem.stylex';
49
50
 
50
51
  /**
51
52
  * The marker the controller finds with `closest()`. Every Astryx component
@@ -325,8 +326,9 @@ function stylesheetDroppedActive(): boolean {
325
326
 
326
327
  /**
327
328
  * The surface a mouse button's or the Space key's press paints, if any: the
328
- * innermost marked surface, outside a menu. A key's press paints only a
329
- * focused element that is itself the surface, as `:active` does.
329
+ * innermost marked surface, outside a menu and off a tracked action. A key's
330
+ * press paints only a focused element that is itself the surface, as
331
+ * `:active` does.
330
332
  */
331
333
  function buttonSurfaceAt(
332
334
  target: EventTarget | null,
@@ -336,6 +338,10 @@ function buttonSurfaceAt(
336
338
  if (element == null || element.closest(MENU_PRESS_ROOT) != null) {
337
339
  return null;
338
340
  }
341
+ // A group's tracker follows pointers only, so a key's press stays here.
342
+ if (pointerId != null && isTrackedByGroup(element)) {
343
+ return null;
344
+ }
339
345
  if (pointerId == null && element !== target) {
340
346
  return null;
341
347
  }
@@ -414,7 +420,9 @@ function onPointerDown(event: PointerEvent): void {
414
420
  const braking = element != null && scrollerIsBraking(element);
415
421
  lastTouchAt = Date.now();
416
422
  lastTouchTarget = event.target instanceof Node ? event.target : null;
417
- if (element == null || braking) {
423
+ // A group's tracker paints a tracked action, so two writers would erase each
424
+ // other's paint. The touch still counts for the brake above.
425
+ if (element == null || braking || isTrackedByGroup(element)) {
418
426
  return;
419
427
  }
420
428
  takeOver(button, element);
@@ -560,6 +568,11 @@ function activatesOnSpace(target: EventTarget | null): boolean {
560
568
  );
561
569
  }
562
570
 
571
+ /** A tracked action takes no `:active` paint, so a key's press paints here. */
572
+ function isTrackedAction(target: EventTarget | null): boolean {
573
+ return target instanceof Element && isTrackedByGroup(target);
574
+ }
575
+
563
576
  /**
564
577
  * Space went down on a focused button that is itself a pressable surface.
565
578
  * Heard in the BUBBLE phase, after the page's own handlers, so a press the
@@ -573,7 +586,7 @@ function onKeyDown(event: KeyboardEvent): void {
573
586
  event.isComposing ||
574
587
  event.defaultPrevented ||
575
588
  !activatesOnSpace(event.target) ||
576
- !stylesheetDroppedActive()
589
+ !(stylesheetDroppedActive() || isTrackedAction(event.target))
577
590
  ) {
578
591
  return;
579
592
  }