@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
@@ -475,6 +475,16 @@ interface WheelFollow {
475
475
  /** The fingers' speed at that move, content px per ms. */
476
476
  speedX: number;
477
477
  speedY: number;
478
+ /**
479
+ * The reading behind that speed: the fingers' travel where it began, and
480
+ * its interval in ms.
481
+ */
482
+ readFromX: number;
483
+ readFromY: number;
484
+ readSpan: number;
485
+ /** The fingers' speed before that reading, content px per ms. */
486
+ priorSpeedX: number;
487
+ priorSpeedY: number;
478
488
  }
479
489
 
480
490
  /**
@@ -503,6 +513,39 @@ function absorbedDebt(debt: number, moved: number): number {
503
513
  return Math.sign(debt) * Math.max(0, Math.abs(debt) - Math.abs(moved) / 2);
504
514
  }
505
515
 
516
+ /**
517
+ * A stall held a bunched wheel's frames back, and the move just before it took
518
+ * their time. So the wheel joins that move's reading. It can restore what the
519
+ * late move lowered, but never passes the speed before it.
520
+ */
521
+ function joinReading(f: WheelFollow, trueX: number, trueY: number): void {
522
+ if (f.readSpan <= 0) {
523
+ return;
524
+ }
525
+ f.speedX = joinedSpeed(
526
+ f.speedX,
527
+ (trueX - f.readFromX) / f.readSpan,
528
+ f.priorSpeedX,
529
+ );
530
+ f.speedY = joinedSpeed(
531
+ f.speedY,
532
+ (trueY - f.readFromY) / f.readSpan,
533
+ f.priorSpeedY,
534
+ );
535
+ }
536
+
537
+ /**
538
+ * A joined reading, held to the speed before the late move. It only ever
539
+ * raises the current speed, in the current direction.
540
+ */
541
+ function joinedSpeed(current: number, reading: number, prior: number): number {
542
+ const held =
543
+ Math.sign(reading) * Math.min(Math.abs(reading), Math.abs(prior));
544
+ return held * current >= 0 && Math.abs(held) > Math.abs(current)
545
+ ? held
546
+ : current;
547
+ }
548
+
506
549
  /**
507
550
  * `target` where it is ahead of `shown` in the direction of `speed`, else
508
551
  * `shown`: a reconcile that never steps back.
@@ -688,6 +731,12 @@ export class GestureHost {
688
731
  * lift click (`spec:AST-094` FR28: nothing acts).
689
732
  */
690
733
  private readonly cancelledFingers = new Set<number>();
734
+ /**
735
+ * The pens and pointer-read fingers that the app's lost focus cancelled,
736
+ * by pointer id. Each is kept until its lift, which must not click either,
737
+ * or until a new press.
738
+ */
739
+ private readonly cancelledPointers = new Map<number, PointerKind>();
691
740
  /** Touch.identifier → the element the finger landed on. */
692
741
  private readonly touchTargets = new Map<number, EventTarget>();
693
742
  /**
@@ -712,6 +761,8 @@ export class GestureHost {
712
761
  private readonly processed = new WeakSet<Event>();
713
762
  /** pointerId → arena id, for live mouse and pen contacts. */
714
763
  private readonly pointerIds = new Map<number, number>();
764
+ /** Each contact's kind: a blur refuses a pen's or a pointer-read finger's lift, never a mouse's. */
765
+ private readonly pointerKinds = new Map<number, PointerKind>();
715
766
  /**
716
767
  * The boxes the host watches for screen-edge pans (syncLayoutWatch): each
717
768
  * element with an enabled one, and the root for one whose band moves with
@@ -1203,12 +1254,17 @@ export class GestureHost {
1203
1254
  * cancels it (or the click guard drops it, a late one included) and this one
1204
1255
  * is the tap's single activation.
1205
1256
  */
1206
- private clickRetargeted(target: EventTarget, x: number, y: number): void {
1257
+ private clickRetargeted(
1258
+ target: EventTarget,
1259
+ x: number,
1260
+ y: number,
1261
+ pointerType: string,
1262
+ ): void {
1207
1263
  const view = this.doc.defaultView;
1208
1264
  if (!(target instanceof Element) || !target.isConnected || view == null) {
1209
1265
  return;
1210
1266
  }
1211
- armClickGuard(this.doc);
1267
+ armClickGuard(this.doc, {takesLateMouse: pointerType === 'touch'});
1212
1268
  if (
1213
1269
  target instanceof view.HTMLElement &&
1214
1270
  target.matches('input, textarea, select, [contenteditable]')
@@ -1772,13 +1828,36 @@ export class GestureHost {
1772
1828
  }
1773
1829
  }
1774
1830
 
1775
- /** After a contact ends: an armed press that is over stops listening. */
1831
+ /**
1832
+ * A new press is a new gesture, as the click guard reads one, so the lifts
1833
+ * the blur cancelled owe nothing after it. A second finger keeps the other
1834
+ * fingers' refusals, since those fingers may still be down.
1835
+ */
1836
+ private dropCancelledLifts(event: PointerEvent): void {
1837
+ const isSecond = event.pointerType === 'touch' && event.isPrimary === false;
1838
+ for (const [pointerId, kind] of [...this.cancelledPointers]) {
1839
+ if (pointerId === event.pointerId || !(isSecond && kind === 'touch')) {
1840
+ this.cancelledPointers.delete(pointerId);
1841
+ }
1842
+ }
1843
+ }
1844
+
1845
+ /**
1846
+ * After a contact ends: an armed press that is over stops listening. A
1847
+ * contact the lost focus cancelled still owes its lift, so the press is
1848
+ * not over until that lift comes. A lift the page never hears ends it at
1849
+ * the next press, or at a cancel.
1850
+ */
1776
1851
  private releaseArmedPress(): void {
1777
1852
  if (!this.isArmedPress) {
1778
1853
  return;
1779
1854
  }
1780
1855
  queueMicrotask(() => {
1781
- if (this.isArmedPress && this.arena.touches.length === 0) {
1856
+ if (
1857
+ this.isArmedPress &&
1858
+ this.arena.touches.length === 0 &&
1859
+ this.cancelledPointers.size === 0
1860
+ ) {
1782
1861
  this.isArmedPress = false;
1783
1862
  this.syncKeptPresses();
1784
1863
  this.syncListeners();
@@ -1809,6 +1888,7 @@ export class GestureHost {
1809
1888
  return;
1810
1889
  }
1811
1890
  this.cancelledFingers.clear();
1891
+ this.cancelledPointers.clear();
1812
1892
  this.clearClaimedLifts();
1813
1893
  this.cancelCallerRead?.();
1814
1894
  this.cancelCallerRead = null;
@@ -2271,9 +2351,22 @@ export class GestureHost {
2271
2351
  }
2272
2352
  if (this.wheelSegment?.decaying === true) {
2273
2353
  // Undecided: the real deltas wait for the splitter while the
2274
- // fingers' last speed carries the pan on.
2354
+ // fingers' last speed carries the pan on. A held wheel with its own
2355
+ // frame ends the reading a stall's bunch joins.
2275
2356
  f.heldX += dx;
2276
2357
  f.heldY += dy;
2358
+ if (this.wheelSegment.bunched) {
2359
+ // A raised speed moves on from where the pan is shown, so the
2360
+ // position never jumps inside the bunch.
2361
+ const since = time - f.lastMove;
2362
+ const speedX = f.speedX;
2363
+ const speedY = f.speedY;
2364
+ joinReading(f, f.trueX - f.heldX, f.trueY - f.heldY);
2365
+ f.baseX += (speedX - f.speedX) * since;
2366
+ f.baseY += (speedY - f.speedY) * since;
2367
+ } else {
2368
+ f.readSpan = 0;
2369
+ }
2277
2370
  this.followProvisionally(gesture, f, time);
2278
2371
  return;
2279
2372
  }
@@ -2286,10 +2379,18 @@ export class GestureHost {
2286
2379
  const debtY = absorbedDebt(gesture.y - beforeY, dy);
2287
2380
  const trueX = beforeX - dx;
2288
2381
  const trueY = beforeY - dy;
2289
- // A wheel the splitter reads as one stall's merge sets no speed. Its
2290
- // speed is one the fingers never had.
2382
+ // A wheel the splitter reads as one stall's merge has no speed of its
2383
+ // own. It joins the reading of the move before its bunch, whose
2384
+ // interval holds its time.
2291
2385
  const elapsed = time - f.lastMove;
2292
- if (elapsed > 0 && this.wheelSegment?.bunched !== true) {
2386
+ if (this.wheelSegment?.bunched === true) {
2387
+ joinReading(f, trueX, trueY);
2388
+ } else if (elapsed > 0) {
2389
+ f.priorSpeedX = f.speedX;
2390
+ f.priorSpeedY = f.speedY;
2391
+ f.readFromX = f.trueX;
2392
+ f.readFromY = f.trueY;
2393
+ f.readSpan = elapsed;
2293
2394
  f.speedX = (trueX - f.trueX) / elapsed;
2294
2395
  f.speedY = (trueY - f.trueY) / elapsed;
2295
2396
  }
@@ -2440,6 +2541,11 @@ export class GestureHost {
2440
2541
  baseY: kept.y,
2441
2542
  speedX: 0,
2442
2543
  speedY: 0,
2544
+ readFromX: kept.x,
2545
+ readFromY: kept.y,
2546
+ readSpan: 0,
2547
+ priorSpeedX: 0,
2548
+ priorSpeedY: 0,
2443
2549
  };
2444
2550
  }
2445
2551
  this.arena.began(
@@ -2860,13 +2966,19 @@ export class GestureHost {
2860
2966
  if (locksSelectionFor('touch')) {
2861
2967
  toLock.push({id, target, consumerElement});
2862
2968
  }
2863
- // The finger's events keep going to what the engine hit.
2969
+ // The finger's events keep going to what the engine hit. A disabled
2970
+ // participant can never claim, so a scroll never waits on it.
2864
2971
  this.watchTarget(
2865
2972
  touch.identifier,
2866
2973
  native,
2867
- recognizers.some(claimsWhileMoving) || consumer?.keepsTouch != null,
2868
- consumer != null ||
2869
- recognizers.some(recognizer => recognizer.claimsTouches),
2974
+ recognizers.some(
2975
+ recognizer => recognizer.isEnabled && claimsWhileMoving(recognizer),
2976
+ ) ||
2977
+ (consumer?.keepsTouch != null && consumer.isEnabled?.() !== false),
2978
+ (consumer != null && consumer.isEnabled?.() !== false) ||
2979
+ recognizers.some(
2980
+ recognizer => recognizer.isEnabled && recognizer.claimsTouches,
2981
+ ),
2870
2982
  );
2871
2983
  this.lastFed.set(id, {x: touch.clientX, y: touch.clientY, time});
2872
2984
  this.pairTouch(id, {x: touch.clientX, y: touch.clientY, target: native});
@@ -2901,6 +3013,11 @@ export class GestureHost {
2901
3013
  for (const input of untracked) {
2902
3014
  this.arena.untrackedBegan(input);
2903
3015
  }
3016
+ // Again once the new fingers are delivered: a pinch's second finger may
3017
+ // have landed on another one-finger pan, the next row.
3018
+ if (this.fingerTargets.length > 1 && !this.isFingerClaimed()) {
3019
+ this.failUnclaimedLoneFingerPans();
3020
+ }
2904
3021
  // Stamped after the consumers judged the touch: the brake asks whether
2905
3022
  // an EARLIER finger is still driving a scroll.
2906
3023
  const landed = landedOn(event);
@@ -3146,7 +3263,14 @@ export class GestureHost {
3146
3263
  // A tap sent to what is drawn: the engine's click would hit the layout
3147
3264
  // position, so it is cancelled and the tap clicks what it touched.
3148
3265
  for (const end of retargetedEnds) {
3149
- if (this.clickRetargetedTap(end.landed, end, dispositions.get(end.id))) {
3266
+ if (
3267
+ this.clickRetargetedTap(
3268
+ end.landed,
3269
+ end,
3270
+ dispositions.get(end.id),
3271
+ 'touch',
3272
+ )
3273
+ ) {
3150
3274
  cancelsClick = true;
3151
3275
  }
3152
3276
  }
@@ -3154,7 +3278,7 @@ export class GestureHost {
3154
3278
  if (event.cancelable) {
3155
3279
  event.preventDefault();
3156
3280
  }
3157
- armClickGuard(this.doc);
3281
+ armClickGuard(this.doc, {takesLateMouse: true});
3158
3282
  }
3159
3283
  };
3160
3284
 
@@ -3168,6 +3292,7 @@ export class GestureHost {
3168
3292
  landed: {x: number; y: number; target: EventTarget} | undefined,
3169
3293
  end: {x: number; y: number},
3170
3294
  disposition: ClickDisposition | undefined,
3295
+ pointerType: string,
3171
3296
  ): boolean {
3172
3297
  if (landed == null || disposition !== 'allow') {
3173
3298
  return false;
@@ -3176,7 +3301,7 @@ export class GestureHost {
3176
3301
  if (moved > UIKIT_TAP.allowableMovement.value) {
3177
3302
  return false;
3178
3303
  }
3179
- this.clickRetargeted(landed.target, end.x, end.y);
3304
+ this.clickRetargeted(landed.target, end.x, end.y, pointerType);
3180
3305
  return true;
3181
3306
  }
3182
3307
 
@@ -3488,6 +3613,7 @@ export class GestureHost {
3488
3613
  if (!isPointerKind(event.pointerType)) {
3489
3614
  return;
3490
3615
  }
3616
+ this.dropCancelledLifts(event);
3491
3617
  if (event.pointerType === 'touch' && this.usesTouchEvents) {
3492
3618
  this.pairPointer(event.pointerId, {
3493
3619
  x: event.clientX,
@@ -3496,6 +3622,13 @@ export class GestureHost {
3496
3622
  });
3497
3623
  return;
3498
3624
  }
3625
+ if (event.pointerType === 'touch' && event.isPrimary === false) {
3626
+ // Fingers from pointer events: a second one, wherever either lands,
3627
+ // leaves the two to the page's pinch, as onTouchStart does. A finger
3628
+ // that is not the primary pointer is a second finger, even where the
3629
+ // host never heard the first.
3630
+ this.failUnclaimedLoneFingerPans();
3631
+ }
3499
3632
  // A right click, a pen's barrel button, or a ctrl-click on macOS (its
3500
3633
  // context click) starts no press (FR43).
3501
3634
  if (event.pointerType !== 'touch' && !isPrimaryClick(event)) {
@@ -3517,6 +3650,7 @@ export class GestureHost {
3517
3650
  }
3518
3651
  const id = this.nextId++;
3519
3652
  this.pointerIds.set(event.pointerId, id);
3653
+ this.pointerKinds.set(event.pointerId, event.pointerType);
3520
3654
  if (target !== landed && target != null) {
3521
3655
  this.retargeted.set(id, {x: event.clientX, y: event.clientY, target});
3522
3656
  }
@@ -3538,6 +3672,15 @@ export class GestureHost {
3538
3672
  consumer,
3539
3673
  },
3540
3674
  ]);
3675
+ if (
3676
+ event.pointerType === 'touch' &&
3677
+ event.isPrimary === false &&
3678
+ !this.isFingerClaimed()
3679
+ ) {
3680
+ // Again once this finger is delivered: it may have landed on another
3681
+ // one-finger pan.
3682
+ this.failUnclaimedLoneFingerPans();
3683
+ }
3541
3684
  if (locksSelectionFor(event.pointerType)) {
3542
3685
  // The presented target: what the pen is on, where the engine's own
3543
3686
  // hit test may still see the motion's start.
@@ -3596,9 +3739,14 @@ export class GestureHost {
3596
3739
  }
3597
3740
  const id = this.pointerIds.get(event.pointerId);
3598
3741
  if (id == null) {
3742
+ // A contact the lost focus cancelled: its lift clicks nothing.
3743
+ if (this.cancelledPointers.delete(event.pointerId)) {
3744
+ this.refuseCancelledLift(event);
3745
+ }
3599
3746
  return;
3600
3747
  }
3601
3748
  this.pointerIds.delete(event.pointerId);
3749
+ this.pointerKinds.delete(event.pointerId);
3602
3750
  this.unlockSelection(id);
3603
3751
  const dispositions = this.arena.ended([
3604
3752
  {id, x: event.clientX, y: event.clientY, time: eventTime(event)},
@@ -3610,9 +3758,10 @@ export class GestureHost {
3610
3758
  landed,
3611
3759
  {x: event.clientX, y: event.clientY},
3612
3760
  dispositions.get(id),
3761
+ event.pointerType,
3613
3762
  );
3614
3763
  if (!clicked && needsSuppression(dispositions)) {
3615
- armClickGuard(this.doc);
3764
+ armClickGuard(this.doc, {takesLateMouse: event.pointerType === 'touch'});
3616
3765
  }
3617
3766
  // A finger read from its pointer events: the touchend that follows the
3618
3767
  // lift is cancelled when a gesture took it, which the lift itself may
@@ -3701,9 +3850,12 @@ export class GestureHost {
3701
3850
  }
3702
3851
  return;
3703
3852
  }
3853
+ // A contact that ends in a cancel owes no refused lift.
3854
+ this.cancelledPointers.delete(event.pointerId);
3704
3855
  const id = this.pointerIds.get(event.pointerId);
3705
3856
  if (id != null) {
3706
3857
  this.pointerIds.delete(event.pointerId);
3858
+ this.pointerKinds.delete(event.pointerId);
3707
3859
  this.unlockSelection(id, true);
3708
3860
  this.retargeted.delete(id);
3709
3861
  this.arena.cancelled([id], eventTime(event));
@@ -3908,20 +4060,26 @@ export class GestureHost {
3908
4060
  }
3909
4061
  }
3910
4062
  }
4063
+ /** Whether a finger's drag is claimed: then two fingers make no pinch. */
4064
+ private isFingerClaimed(): boolean {
4065
+ return this.arena.touches.some(
4066
+ touch => touch.pointerType === 'touch' && this.arena.isClaimed(touch.id),
4067
+ );
4068
+ }
3911
4069
 
3912
4070
  private readonly onVisibilityChange = (): void => {
3913
4071
  if (this.doc.visibilityState === 'hidden') {
3914
4072
  this.cancelEverything(this.arena.now());
3915
- // As at a blur: the press sends no further pointer event, so an armed
3916
- // press's page listeners go now (FR24).
4073
+ // As at a blur: an armed press's page listeners go once nothing is left
4074
+ // to hear.
3917
4075
  this.releaseArmedPress();
3918
4076
  }
3919
4077
  };
3920
4078
 
3921
4079
  private readonly onBlur = (): void => {
3922
4080
  this.cancelEverything(this.arena.now());
3923
- // The press a blur ends sends no further pointer event: an armed press's
3924
- // page listeners go now, as at its lift (FR24).
4081
+ // An armed press's page listeners go once nothing is left to hear. A pen
4082
+ // or a pointer-read finger the blur cancelled still owes its lift.
3925
4083
  this.releaseArmedPress();
3926
4084
  };
3927
4085
 
@@ -3944,8 +4102,27 @@ export class GestureHost {
3944
4102
  );
3945
4103
  }
3946
4104
 
4105
+ /**
4106
+ * The lift of a contact the lost focus cancelled: its click is refused,
4107
+ * and a finger's touchend after it is cancelled.
4108
+ */
4109
+ private refuseCancelledLift(event: PointerEvent): void {
4110
+ armClickGuard(this.doc, {takesLateMouse: event.pointerType === 'touch'});
4111
+ if (event.pointerType === 'touch') {
4112
+ // Noted as a claimed lift is: capped, and gone after its time.
4113
+ this.noteClaimedLift(event);
4114
+ }
4115
+ }
4116
+
3947
4117
  /** The app lost focus: UIKit cancels every touch in flight. */
3948
4118
  private cancelEverything(time: number): void {
4119
+ // The browser may keep a pen or a pointer-read finger down: its lift must
4120
+ // not click. A mouse button held through the blur keeps its click.
4121
+ for (const [pointerId, kind] of this.pointerKinds) {
4122
+ if (kind !== 'mouse') {
4123
+ this.cancelledPointers.set(pointerId, kind);
4124
+ }
4125
+ }
3949
4126
  const ids = [...this.pointerIds.values()];
3950
4127
  for (const id of ids) {
3951
4128
  this.unlockSelection(id, true);
@@ -3959,6 +4136,7 @@ export class GestureHost {
3959
4136
  }
3960
4137
  }
3961
4138
  this.pointerIds.clear();
4139
+ this.pointerKinds.clear();
3962
4140
  this.retargeted.clear();
3963
4141
  this.fingerPointers.clear();
3964
4142
  this.pendingPointers.clear();
@@ -47,7 +47,8 @@
47
47
  */
48
48
 
49
49
  import {UIKIT_CONTROL, UIKIT_PAN, UIKIT_PRESS} from '../motion/uikit/gestures';
50
- import {timing} from '../motion/uikit/timing';
50
+ // Importing the whole table bundles its curves into each press-tracking control.
51
+ import {press as pressClocks} from '../motion/uikit/timing';
51
52
  import {travel} from './geometry';
52
53
  import type {GestureRecognizer, SelectionLock} from './GestureRecognizer';
53
54
  import type {TapGestureRecognizer} from './TapGestureRecognizer';
@@ -154,7 +155,7 @@ export const PRESS_PROFILES = {
154
155
  // The shared press styles release every surface on the deselect clock
155
156
  // until a control runs its own release (UIButton's 250 ms), so a
156
157
  // painter's `fading` never outlasts the fade it shows.
157
- releaseMs: timing.press.highlightOutMs,
158
+ releaseMs: pressClocks.highlightOutMs,
158
159
  },
159
160
  /**
160
161
  * A table or collection cell: inside a scroll view it highlights after the
@@ -165,7 +166,7 @@ export const PRESS_PROFILES = {
165
166
  highlightDelay: 'inScrollers',
166
167
  cancelTravel: UIKIT_PAN.hysteresis.value,
167
168
  quickTapFlash: 0,
168
- releaseMs: timing.press.highlightOutMs,
169
+ releaseMs: pressClocks.highlightOutMs,
169
170
  },
170
171
  } as const satisfies Record<string, PressProfile>;
171
172
 
@@ -96,6 +96,10 @@ Once a drag has claimed its finger, a second finger never breaks it.
96
96
  | `PinchGestureRecognizer` | `UIPinchGestureRecognizer` | continuous | `scale` (settable, to re-base it), `velocity` in scale per second, `focalPoint()` |
97
97
  | `ScreenEdgePanGestureRecognizer` | `UIScreenEdgePanGestureRecognizer` | continuous | `edges`: `leading` / `trailing`, resolved against the view's writing direction; attached to an edge zone the view lies within; fails as soon as the touch lands outside every requested edge band; a finger's only |
98
98
 
99
+ Each recognizer reports what it is in `kind` (`'tap'`, `'longPress'`,
100
+ `'pan'`, `'screenEdgePan'`, `'swipe'`, `'pinch'`): code tells the family apart by it, never by `instanceof`
101
+ (`architecture:react-component-runtime` INV13).
102
+
99
103
  A recognizer created with `claimsTouches: false` is a watcher (a tab bar
100
104
  that minimizes while the page scrolls): it never claims, so its element gets
101
105
  only passive listeners and a scroll never waits for it; it prevents no other
@@ -174,7 +178,9 @@ innerPan.requireToFail(edgePan);
174
178
  ## Touches in the view: `createPressTracker`
175
179
 
176
180
  A pressable control's view-level touch handling, with `UIControl`
177
- semantics:
181
+ semantics, built by `createPressTracker(options)`: a factory, as
182
+ `architecture:react-component-runtime` INV13 asks of the touch modules outside
183
+ the recognizer family (`VelocityTracker` is still a class, its one listed gap):
178
184
 
179
185
  - `touchDown`, `touchDragInside` / `touchDragOutside`, `touchDragEnter` /
180
186
  `touchDragExit`, `touchUpInside` / `touchUpOutside`, `touchCancel`.
@@ -12,6 +12,8 @@
12
12
  * SYNC: When modified, update actionGroupTracker.test.ts
13
13
  */
14
14
 
15
+ import {clickAndReport, clickForLift} from '../utils/browserClickWait';
16
+ import {armClickGuard} from '../utils/clickGuard';
15
17
  import {PRESSED_ATTRIBUTE} from '../utils/pressFeedback';
16
18
  import {PRESS_FADE_MS} from '../utils/pressGesture';
17
19
 
@@ -55,7 +57,8 @@ export interface ActionGroupTrackerOptions {
55
57
  * target past the group's ends commits the lift there wherever the finger
56
58
  * lifts.
57
59
  * @default the target whose rect, grown by `highlightExpansion`, holds the
58
- * point; none between or outside them
60
+ * point, the one the press landed on where several do; none between or
61
+ * outside them
59
62
  */
60
63
  resolveTarget?: (
61
64
  x: number,
@@ -70,9 +73,9 @@ export interface ActionGroupTrackerOptions {
70
73
  */
71
74
  onActivated?: (item: HTMLElement, cancelled: boolean) => void;
72
75
  /**
73
- * After the lift ran an action, take the browser's own click for that
74
- * touch (left to it by a recognizer that did not claim the touch), so the
75
- * action runs once. @default false
76
+ * After the lift ran an action, the shared click guard takes the browser's
77
+ * own click for that touch, so the action runs once. A recognizer that did
78
+ * not claim the touch leaves that click to the browser. @default false
76
79
  */
77
80
  swallowsNativeClick?: boolean;
78
81
  }
@@ -81,8 +84,13 @@ export interface ActionGroupTracker {
81
84
  /**
82
85
  * A press began at viewport (x, y): read the actions' rects once and
83
86
  * highlight the one under it. An inert press is taken but tracks nothing.
87
+ * `landed` is the node the press landed on.
84
88
  */
85
- begin(x: number, y: number, options?: {inert?: boolean}): void;
89
+ begin(
90
+ x: number,
91
+ y: number,
92
+ options?: {inert?: boolean; landed?: Node | null},
93
+ ): void;
86
94
  /** The finger moved to viewport (x, y). */
87
95
  move(x: number, y: number): void;
88
96
  /**
@@ -126,54 +134,6 @@ interface TrackedAction {
126
134
  bottom: number;
127
135
  }
128
136
 
129
- /**
130
- * Swallow the browser's own click for a touch that the lift already acted
131
- * on. The listeners exist only from that lift until the click, the next
132
- * press, or the next key. An activation with `detail === 0` (a key or
133
- * assistive technology) always passes, and the swallower keeps waiting
134
- * (`AST-094`).
135
- */
136
- function swallowNextClick(view: Window): void {
137
- const disarm = () => {
138
- view.removeEventListener('click', onClick, true);
139
- view.removeEventListener('pointerdown', disarm, true);
140
- view.removeEventListener('keydown', disarm, true);
141
- };
142
- const onClick = (event: MouseEvent) => {
143
- if (!event.isTrusted || event.detail === 0) {
144
- return;
145
- }
146
- disarm();
147
- event.preventDefault();
148
- event.stopImmediatePropagation();
149
- };
150
- view.addEventListener('click', onClick, true);
151
- view.addEventListener('pointerdown', disarm, true);
152
- view.addEventListener('keydown', disarm, true);
153
- }
154
-
155
- /**
156
- * Click `element` (its own `click()`, so its activation behavior and every
157
- * handler run as for any click) and report whether a handler cancelled it.
158
- * The event is read from a capture listener that exists only for the call.
159
- */
160
- function clickAndReport(element: HTMLElement): boolean {
161
- const view = element.ownerDocument.defaultView;
162
- let clicked: Event | null = null;
163
- const grab = (event: Event) => {
164
- if (clicked == null && event.target === element) {
165
- clicked = event;
166
- }
167
- };
168
- view?.addEventListener('click', grab, true);
169
- try {
170
- element.click();
171
- } finally {
172
- view?.removeEventListener('click', grab, true);
173
- }
174
- return (clicked as Event | null)?.defaultPrevented === true;
175
- }
176
-
177
137
  /**
178
138
  * Create a tracker. `getOptions` is read on every call, so a hook can pass
179
139
  * the latest props without recreating it.
@@ -196,6 +156,7 @@ export function createActionGroupTracker(
196
156
  let actions: TrackedAction[] = [];
197
157
  let highlighted: HTMLElement | null = null;
198
158
  let beganOn: HTMLElement | null = null;
159
+ let landedOn: Node | null = null;
199
160
  let isTracking = false;
200
161
  let isInert = false;
201
162
  // The finger's last position: `remeasure` resolves it again.
@@ -287,6 +248,9 @@ export function createActionGroupTracker(
287
248
  if (resolveTarget != null) {
288
249
  return actions.length === 0 ? null : resolveTarget(x, y, actions);
289
250
  }
251
+ // Rects that share an edge, or that have no layout (a test renderer), can
252
+ // both hold the point: the one the press landed on wins.
253
+ let first: HTMLElement | null = null;
290
254
  for (const action of actions) {
291
255
  if (
292
256
  x >= action.left - margin &&
@@ -294,22 +258,26 @@ export function createActionGroupTracker(
294
258
  y >= action.top - margin &&
295
259
  y <= action.bottom + margin
296
260
  ) {
297
- return action.element;
261
+ if (landedOn != null && action.element.contains(landedOn)) {
262
+ return action.element;
263
+ }
264
+ first ??= action.element;
298
265
  }
299
266
  }
300
- return null;
267
+ return first;
301
268
  };
302
269
 
303
270
  const reset = () => {
304
271
  actions = [];
305
272
  highlighted = null;
306
273
  beganOn = null;
274
+ landedOn = null;
307
275
  isTracking = false;
308
276
  isInert = false;
309
277
  };
310
278
 
311
279
  return {
312
- begin(x, y, {inert = false} = {}) {
280
+ begin(x, y, {inert = false, landed = null} = {}) {
313
281
  // A press can begin while another is tracked, when a second recognizer
314
282
  // takes over the finger (a trigger's held press, then the menu's): the
315
283
  // action the first one lit loses its paint.
@@ -322,6 +290,7 @@ export function createActionGroupTracker(
322
290
  highlighted = null;
323
291
  isTracking = true;
324
292
  isInert = inert;
293
+ landedOn = landed;
325
294
  lastX = x;
326
295
  lastY = y;
327
296
  getOptions().onMove?.(x, y);
@@ -358,14 +327,16 @@ export function createActionGroupTracker(
358
327
  const {onActivate, onActivated, swallowsNativeClick} = getOptions();
359
328
  if (onActivate != null) {
360
329
  onActivate(lifted);
330
+ if (swallowsNativeClick === true) {
331
+ armClickGuard(lifted.ownerDocument);
332
+ }
361
333
  } else {
362
- const cancelled = clickAndReport(lifted);
334
+ const cancelled =
335
+ swallowsNativeClick === true
336
+ ? clickForLift(lifted)
337
+ : clickAndReport(lifted);
363
338
  onActivated?.(lifted, cancelled);
364
339
  }
365
- const view = lifted.ownerDocument.defaultView;
366
- if (swallowsNativeClick === true && view != null) {
367
- swallowNextClick(view);
368
- }
369
340
  return lifted;
370
341
  },
371
342
  cancel() {
@@ -133,6 +133,8 @@ export type {
133
133
  UseInteractiveRoleOptions,
134
134
  } from './useInteractiveRole';
135
135
 
136
+ export {useAnimator} from './useAnimator';
137
+
136
138
  export {useLongPress} from './useLongPress';
137
139
  export type {UseLongPressOptions, UseLongPressHandlers} from './useLongPress';
138
140
 
@@ -0,0 +1,21 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file pressGroupContext.ts
7
+ * @input Nothing
8
+ * @output PressGroupContext: true inside a group whose own tracker paints
9
+ * its actions' press
10
+ * @position Internal; not exported from the hooks entry. AlertDialog
11
+ * provides it around its tracked actions, and Button reads it.
12
+ */
13
+
14
+ import {createContext} from 'react';
15
+
16
+ /**
17
+ * True inside a group whose tracker paints a pointer's press on its actions.
18
+ * Those actions take no `:active` paint, so one press never lights two.
19
+ */
20
+ export const PressGroupContext = createContext(false);
21
+ PressGroupContext.displayName = 'PressGroupContext';