@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
@@ -7,33 +7,146 @@ export const docs = {
7
7
  group: 'Tooltip',
8
8
  keywords: ['tooltip', 'hint', 'label', 'hover', 'info', 'title', 'floating'],
9
9
  params: [
10
- {name: 'placement', type: "'above' | 'below' | 'start' | 'end'", description: "Position relative to the trigger. Logical: start/end resolve against the popover\'s own inherited direction (RTL mirrors in pure CSS).", default: "'above'"},
11
- {name: 'alignment', type: "'start' | 'center' | 'end'", description: "Alignment along the placement axis. Logical: start/end resolve against the popover\'s own inherited direction (RTL mirrors in pure CSS).", default: "'center'"},
12
- {name: 'delay', type: 'number', description: 'Delay before showing on hover, in milliseconds.', default: '200'},
13
- {name: 'hideDelay', type: 'number', description: 'Delay before hiding after mouse or focus leaves, in milliseconds.', default: '0'},
14
- {name: 'focusTrigger', type: "'auto' | 'always' | 'never'", description: 'When focus should open the tooltip. auto opens when the trigger itself takes focus, or focus lands inside a trigger that is focusable at that moment, so a roving-tabindex member opens when the arrow keys reach it.', default: "'auto'"},
15
- {name: 'touchTrigger', type: "'auto' | 'tap' | 'none'", description: 'What a tap does where there is no hover. auto opens on tap unless the trigger performs an action of its own (an aria-disabled control performs none); tap always opens; none never opens on touch. It decides only under triggerBehavior="adaptive", the default.', default: "'auto'"},
16
- {name: 'triggerBehavior', type: "'adaptive' | 'hover' | 'toggle'", description: 'How the trigger opens the tooltip. adaptive (the default) previews on hover and focus and opens on a tap unless the trigger acts (touchTrigger decides while it remains); hover previews on hover and focus, and no touch or pen tap opens it; toggle, on a button trigger, pins on a click, a tap, Enter, or Space and closes on the same press, Escape, a press outside, or focus leaving. The trigger carries aria-expanded and aria-controls, the tooltip is announced once when it pins. Astryx clickable rows and cards ignore the pinning press, except an Item row on a trigger that is not a native button; a plain onClick ancestor still receives it from the hook (the Tooltip component stops it at a child trigger).', default: "'adaptive'"},
17
- {name: 'isEnabled', type: 'boolean', description: 'Whether hover and focus triggers are enabled.', default: 'true'},
18
- {name: 'isOpen', type: 'boolean', description: 'Controlled open state. true force-shows, false force-hides, undefined lets hover/focus manage visibility.'},
19
- {name: 'isDefaultOpen', type: 'boolean', description: 'Whether the tooltip should be shown on mount.', default: 'false'},
20
- {name: 'onShow', type: '() => void', description: 'Callback fired when the tooltip becomes visible.'},
21
- {name: 'onHide', type: '() => void', description: 'Callback fired when the tooltip is hidden.'},
10
+ {
11
+ name: 'placement',
12
+ type: "'above' | 'below' | 'start' | 'end'",
13
+ description:
14
+ "Position relative to the trigger. Logical: start/end resolve against the popover\'s own inherited direction (RTL mirrors in pure CSS).",
15
+ default: "'above'",
16
+ },
17
+ {
18
+ name: 'alignment',
19
+ type: "'start' | 'center' | 'end'",
20
+ description:
21
+ "Alignment along the placement axis. Logical: start/end resolve against the popover\'s own inherited direction (RTL mirrors in pure CSS).",
22
+ default: "'center'",
23
+ },
24
+ {
25
+ name: 'delay',
26
+ type: 'number',
27
+ description: 'Delay before showing on hover, in milliseconds.',
28
+ default: '200',
29
+ },
30
+ {
31
+ name: 'hideDelay',
32
+ type: 'number',
33
+ description:
34
+ 'Delay before hiding after mouse or focus leaves, in milliseconds.',
35
+ default: '0',
36
+ },
37
+ {
38
+ name: 'focusTrigger',
39
+ type: "'auto' | 'always' | 'never'",
40
+ description:
41
+ 'When focus should open the tooltip. auto opens when the trigger itself takes focus, or focus lands inside a trigger that is focusable at that moment, so a roving-tabindex member opens when the arrow keys reach it.',
42
+ default: "'auto'",
43
+ },
44
+ {
45
+ name: 'touchTrigger',
46
+ type: "'auto' | 'tap' | 'none'",
47
+ description:
48
+ 'What a tap does where there is no hover. auto opens on tap unless the trigger performs an action of its own (an aria-disabled control performs none); tap always opens (a button whose only job is revealing the tooltip); none never opens on touch.',
49
+ default: "'auto'",
50
+ },
51
+ {
52
+ name: 'isEnabled',
53
+ type: 'boolean',
54
+ description: 'Whether hover and focus triggers are enabled.',
55
+ default: 'true',
56
+ },
57
+ {
58
+ name: 'isOpen',
59
+ type: 'boolean',
60
+ description:
61
+ 'Controlled open state. true force-shows, false force-hides, undefined lets hover/focus manage visibility.',
62
+ },
63
+ {
64
+ name: 'isDefaultOpen',
65
+ type: 'boolean',
66
+ description: 'Whether the tooltip should be shown on mount.',
67
+ default: 'false',
68
+ },
69
+ {
70
+ name: 'onShow',
71
+ type: '() => void',
72
+ description: 'Callback fired when the tooltip becomes visible.',
73
+ },
74
+ {
75
+ name: 'onHide',
76
+ type: '() => void',
77
+ description: 'Callback fired when the tooltip is hidden.',
78
+ },
22
79
  ],
23
80
  returns: [
24
- {name: 'ref', type: 'RefCallback<HTMLElement>', description: 'Combined ref that sets both position and interaction on the same trigger element.'},
25
- {name: 'positionRef', type: 'RefCallback<HTMLElement>', description: 'Ref for the positioning anchor element.'},
26
- {name: 'interactionRef', type: 'RefCallback<HTMLElement>', description: 'Ref for the hover/focus interaction element.'},
27
- {name: 'anchorId', type: 'string', description: 'CSS anchor name for advanced positioning cases.'},
28
- {name: 'describedBy', type: 'string', description: 'ID to compose into aria-describedby on the trigger.'},
29
- {name: 'renderTooltip', type: "(children: ReactNode, props?: Omit<ContextRenderProps, 'positioning'>) => ReactNode", description: 'Render function for the anchor-positioned tooltip content. The positioning opt-out is excluded: the tooltip always derives its position from placement/alignment.'},
81
+ {
82
+ name: 'ref',
83
+ type: 'RefCallback<HTMLElement>',
84
+ description:
85
+ 'Combined ref that sets both position and interaction on the same trigger element.',
86
+ },
87
+ {
88
+ name: 'positionRef',
89
+ type: 'RefCallback<HTMLElement>',
90
+ description: 'Ref for the positioning anchor element.',
91
+ },
92
+ {
93
+ name: 'interactionRef',
94
+ type: 'RefCallback<HTMLElement>',
95
+ description: 'Ref for the hover/focus interaction element.',
96
+ },
97
+ {
98
+ name: 'anchorId',
99
+ type: 'string',
100
+ description: 'CSS anchor name for advanced positioning cases.',
101
+ },
102
+ {
103
+ name: 'describedBy',
104
+ type: 'string',
105
+ description: 'ID to compose into aria-describedby on the trigger.',
106
+ },
107
+ {
108
+ name: 'renderTooltip',
109
+ type: "(children: ReactNode, props?: Omit<ContextRenderProps, 'positioning'>) => ReactNode",
110
+ description:
111
+ 'Render function for the anchor-positioned tooltip content. The positioning opt-out is excluded: the tooltip always derives its position from placement/alignment.',
112
+ },
113
+ {
114
+ name: 'show',
115
+ type: '() => void',
116
+ description:
117
+ 'Opens the tooltip now and keeps it open until hide(), Escape, a press outside, or focus leaving its trigger. Its text is announced once, and onShow fires. Under a controlled isOpen it only calls onShow. Does nothing while isEnabled is false.',
118
+ },
119
+ {
120
+ name: 'hide',
121
+ type: '() => void',
122
+ description:
123
+ 'Closes the tooltip now, and onHide fires. Under a controlled isOpen it only calls onHide.',
124
+ },
30
125
  ],
31
126
  usage: {
32
- description: 'Headless hook for hover/focus-triggered tooltips. Builds on useLayer with hover intent, keyboard focus handling, and accessible aria-describedby linking. Use for custom trigger elements that need tooltip behavior without the wrapper component.',
127
+ description:
128
+ 'Headless hook for hover/focus-triggered tooltips. Builds on useLayer with hover intent, keyboard focus handling, and accessible aria-describedby linking. Use for custom trigger elements that need tooltip behavior without the wrapper component.',
33
129
  bestPractices: [
34
- {guidance: true, description: 'Use for brief text labels that describe icon buttons, truncated text, abbreviations, or compact controls.'},
35
- {guidance: true, description: 'Prefer the Tooltip component for standard wrapping; use the hook when the trigger is not a simple child.'},
36
- {guidance: false, description: 'Put interactive content inside tooltips: use Popover or HoverCard instead.'},
130
+ {
131
+ guidance: true,
132
+ description:
133
+ 'Use for brief text labels that describe icon buttons, truncated text, abbreviations, or compact controls.',
134
+ },
135
+ {
136
+ guidance: true,
137
+ description:
138
+ 'Prefer the Tooltip component for standard wrapping; use the hook when the trigger is not a simple child.',
139
+ },
140
+ {
141
+ guidance: true,
142
+ description:
143
+ 'For a toggle-style trigger, have your own button call show() and hide() on each press. Give it aria-describedby and aria-controls set to describedBy, and aria-expanded (true while show() holds the tooltip, false after hide() or onHide), and keep its own accessible name. For an info icon, use InfoTip instead.',
144
+ },
145
+ {
146
+ guidance: false,
147
+ description:
148
+ 'Put interactive content inside tooltips: use Popover or HoverCard instead.',
149
+ },
37
150
  ],
38
151
  },
39
152
  relatedComponents: ['Tooltip', 'HoverCard', 'Popover'],
@@ -44,17 +157,22 @@ export const docs = {
44
157
 
45
158
  /** @type {import('@astryxdesign/cli/authoring').HookTranslationDoc} */
46
159
  export const docsDense = {
47
- description: 'Headless hover/focus tooltip hook. Builds on useLayer w/ hover intent, keyboard focus handling, aria-describedby. Use for custom triggers without wrapper component.',
160
+ description:
161
+ 'Headless hover/focus tooltip hook. Builds on useLayer w/ hover intent, keyboard focus handling, aria-describedby. Use for custom triggers without wrapper component.',
48
162
  paramDescriptions: {
49
- placement: 'position relative to trigger. logical: start/end follow the popover\'s inherited direction (RTL mirrors).',
50
- alignment: 'alignment along placement axis. logical: start/end follow the popover\'s inherited direction (RTL mirrors).',
163
+ placement:
164
+ "position relative to trigger. logical: start/end follow the popover's inherited direction (RTL mirrors).",
165
+ alignment:
166
+ "alignment along placement axis. logical: start/end follow the popover's inherited direction (RTL mirrors).",
51
167
  delay: 'show delay in ms.',
52
168
  hideDelay: 'hide delay after mouse/focus leave in ms.',
53
- focusTrigger: 'when focus opens tooltip; auto = focus on the trigger, or inside a trigger focusable when focus arrives.',
54
- touchTrigger: 'tap behavior with no hover, under triggerBehavior adaptive only; auto = tap unless trigger acts, tap = always, none = never.',
55
- triggerBehavior: 'adaptive (default) = hover/focus preview, tap opens unless the trigger acts; hover = no touch/pen tap opens; toggle = a press on a button trigger pins and closes; clickable rows and cards ignore it (an Item row only on a native-button trigger), and the Tooltip component also stops it at a child trigger.',
169
+ focusTrigger:
170
+ 'when focus opens tooltip; auto = focus on the trigger, or inside a trigger focusable when focus arrives.',
171
+ touchTrigger:
172
+ 'tap behavior with no hover; auto = tap unless trigger acts, tap = always, none = never.',
56
173
  isEnabled: 'whether hover/focus triggers are enabled.',
57
- isOpen: 'controlled open state: true force-show, false force-hide, undefined unmanaged.',
174
+ isOpen:
175
+ 'controlled open state: true force-show, false force-hide, undefined unmanaged.',
58
176
  isDefaultOpen: 'show on mount.',
59
177
  onShow: 'fires when tooltip becomes visible.',
60
178
  onHide: 'fires when tooltip hides.',
@@ -66,13 +184,33 @@ export const docsDense = {
66
184
  anchorId: 'CSS anchor name.',
67
185
  describedBy: 'ID for aria-describedby.',
68
186
  renderTooltip: 'renders anchor-positioned tooltip content.',
187
+ show: 'opens + holds until hide()/Escape/outside press/focus leave; announces once; onShow. Controlled: onShow only. No-op when disabled.',
188
+ hide: 'closes; onHide. Controlled: onHide only.',
69
189
  },
70
190
  usage: {
71
- description: 'Headless hover/focus tooltip hook. Builds on useLayer w/ hover intent, keyboard focus handling, aria-describedby. Use for custom triggers without wrapper component.',
191
+ description:
192
+ 'Headless hover/focus tooltip hook. Builds on useLayer w/ hover intent, keyboard focus handling, aria-describedby. Use for custom triggers without wrapper component.',
72
193
  bestPractices: [
73
- {guidance: true, description: 'Use for brief text labels describing icon buttons, truncated text, abbreviations, compact controls.'},
74
- {guidance: true, description: 'Prefer Tooltip for standard wrapping; use hook when trigger is not simple child.'},
75
- {guidance: false, description: 'Put interactive content in tooltips: use Popover / HoverCard instead.'},
194
+ {
195
+ guidance: true,
196
+ description:
197
+ 'Use for brief text labels describing icon buttons, truncated text, abbreviations, compact controls.',
198
+ },
199
+ {
200
+ guidance: true,
201
+ description:
202
+ 'Prefer Tooltip for standard wrapping; use hook when trigger is not simple child.',
203
+ },
204
+ {
205
+ guidance: true,
206
+ description:
207
+ 'Toggle-style trigger: own button calls show()/hide() per press, sets aria-describedby + aria-controls={describedBy}, aria-expanded (true while held), keeps its own name. Info icon: use InfoTip.',
208
+ },
209
+ {
210
+ guidance: false,
211
+ description:
212
+ 'Put interactive content in tooltips: use Popover / HoverCard instead.',
213
+ },
76
214
  ],
77
215
  },
78
216
  };
@@ -6,6 +6,8 @@
6
6
  * @file useTooltip.tsx
7
7
  * @input Uses useLayer, usePressPin, React hooks
8
8
  * @output Exports useTooltip hook with stable trigger refs for hover/focus/tap tooltips
9
+ * and imperative show() and hide() for an app-built toggle trigger,
10
+ * and the module-only useTooltipWithTriggerBehavior that InfoTip's press-to-pin uses
9
11
  * @position Layer hook; builds on useLayer for tooltip behavior
10
12
  *
11
13
  * SYNC: When modified, update:
@@ -16,9 +18,11 @@ import {
16
18
  useCallback,
17
19
  useEffect,
18
20
  useRef,
21
+ useState,
19
22
  type ReactNode,
20
23
  type RefCallback,
21
24
  } from 'react';
25
+ import {createTriggerFocusGate} from '../utils/triggerFocus';
22
26
  import * as stylex from '@stylexjs/stylex';
23
27
  import {
24
28
  useLayerInternal,
@@ -31,7 +35,7 @@ import {useAnnounceRenderedText} from '../hooks/useAnnounceRenderedText';
31
35
  import {useMergedRefs} from '../hooks/useMergedRefs';
32
36
  import {layerAnimations} from '../Layer/layerAnimations.stylex';
33
37
  import {registerLayerSurface} from '../Layer/layerSurfacePress';
34
- import {usePressPin} from '../Layer/usePressPin';
38
+ import {usePressPin, type LayerTriggerBehavior} from '../Layer/usePressPin';
35
39
  import {useLayerDismissal} from '../Layer/useLayerDismissal';
36
40
  import {themeProps} from '../utils/themeProps';
37
41
  import {
@@ -83,14 +87,6 @@ export type TooltipFocusTrigger = 'auto' | 'always' | 'never';
83
87
  */
84
88
  export type TooltipTouchTrigger = LayerTouchTrigger;
85
89
 
86
- /**
87
- * How the trigger opens the tooltip. `adaptive`, the default, previews it on
88
- * hover and focus, and a tap opens it unless the trigger acts. `hover`
89
- * previews it on hover and focus, and no touch or pen tap opens it. `toggle`
90
- * pins it on a click, tap, Enter, or Space on a button trigger.
91
- */
92
- export type TooltipTriggerBehavior = 'adaptive' | 'hover' | 'toggle';
93
-
94
90
  export interface TooltipOptions {
95
91
  /**
96
92
  * Position placement relative to anchor
@@ -135,32 +131,10 @@ export interface TooltipOptions {
135
131
  * - `tap`: tap always opens the tooltip, even on a trigger that acts
136
132
  * - `none`: touch never opens the tooltip
137
133
  *
138
- * It decides only under `triggerBehavior="adaptive"`, the default.
139
- *
140
134
  * @default 'auto'
141
135
  */
142
136
  touchTrigger?: TooltipTouchTrigger;
143
137
 
144
- /**
145
- * How the trigger opens the tooltip:
146
- * - `adaptive` (the default): hover and focus preview it. A tap opens it
147
- * unless the trigger performs an action of its own. While `touchTrigger`
148
- * remains, it decides those taps.
149
- * - `hover`: hover and focus preview it; no touch or pen tap opens it.
150
- * - `toggle`: on a button trigger, a click, a tap, Enter, or Space pins the
151
- * tooltip open, and the same press closes it. Hover and keyboard focus
152
- * still preview it. A pinned tooltip stays until Escape, a second press,
153
- * a press outside, or focus leaving. Astryx clickable rows and cards
154
- * ignore the pinning press, except an Item row on a trigger that is not
155
- * a native button. The `Tooltip` component also stops it at a child
156
- * trigger. A hook caller stops a plain `onClick` ancestor itself. The
157
- * trigger reports `aria-expanded` and `aria-controls`, and the tooltip's
158
- * text is announced once when it pins. `touchTrigger` is ignored.
159
- *
160
- * @default 'adaptive'
161
- */
162
- triggerBehavior?: TooltipTriggerBehavior;
163
-
164
138
  /**
165
139
  * Whether the tooltip is enabled.
166
140
  * When false, hover/focus triggers are disabled.
@@ -245,29 +219,25 @@ export interface TooltipReturn {
245
219
  children: ReactNode,
246
220
  props?: Omit<ContextRenderProps, 'positioning'>,
247
221
  ) => ReactNode;
248
- }
249
222
 
250
- /**
251
- * Check if an element is naturally focusable
252
- */
253
- function isFocusable(element: HTMLElement): boolean {
254
- // Elements with explicit tabindex
255
- if (element.hasAttribute('tabindex')) {
256
- return element.tabIndex >= 0;
257
- }
258
-
259
- // Naturally focusable elements
260
- const focusableTags = ['A', 'BUTTON', 'INPUT', 'SELECT', 'TEXTAREA'];
261
- if (focusableTags.includes(element.tagName)) {
262
- return !(element as HTMLButtonElement).disabled;
263
- }
264
-
265
- // Elements with contenteditable
266
- if (element.isContentEditable) {
267
- return true;
268
- }
269
-
270
- return false;
223
+ /**
224
+ * Opens the tooltip now and keeps it open until `hide()`, Escape, a press
225
+ * outside, or focus leaving its trigger, as a pinned tooltip does. Its text
226
+ * is announced once. Reports through `onShow`. Under a controlled `isOpen`,
227
+ * it calls `onShow` and does not change `isOpen`. Does nothing while
228
+ * `isEnabled` is false.
229
+ *
230
+ * Use `show()` and `hide()` to build a toggle-style trigger: your own button
231
+ * calls them, sets `aria-describedby` and `aria-controls` to `describedBy`
232
+ * and `aria-expanded` (true while shown), and keeps its own accessible name.
233
+ */
234
+ show: () => void;
235
+
236
+ /**
237
+ * Closes the tooltip now. Reports through `onHide`. Under a controlled
238
+ * `isOpen`, it calls `onHide` and does not change `isOpen`.
239
+ */
240
+ hide: () => void;
271
241
  }
272
242
 
273
243
  /**
@@ -296,6 +266,42 @@ function isFocusable(element: HTMLElement): boolean {
296
266
  */
297
267
 
298
268
  export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
269
+ // The option is fixed to `adaptive`, so an options object that carries it at
270
+ // runtime cannot reach the press-to-pin path.
271
+ return useTooltipWithTriggerBehavior({
272
+ ...options,
273
+ triggerBehavior: 'adaptive',
274
+ });
275
+ }
276
+
277
+ /**
278
+ * Module-only options for `useTooltipWithTriggerBehavior`. Not exported from
279
+ * the package.
280
+ */
281
+ export interface TooltipWithTriggerBehaviorOptions extends TooltipOptions {
282
+ /**
283
+ * How the trigger opens the tooltip:
284
+ * - `adaptive` (the default): hover and focus preview it. `touchTrigger`
285
+ * decides taps.
286
+ * - `toggle`: on a button trigger, a click, a tap, Enter, or Space pins the
287
+ * tooltip open, and the same press closes it. Hover and keyboard focus
288
+ * still preview it. A pinned tooltip stays until Escape, a second press,
289
+ * a press outside, or focus leaving. The trigger reports `aria-expanded`
290
+ * and `aria-controls`, and the tooltip's text is announced once when it
291
+ * pins. `touchTrigger` is ignored. InfoTip uses it.
292
+ *
293
+ * @default 'adaptive'
294
+ */
295
+ triggerBehavior?: LayerTriggerBehavior;
296
+ }
297
+
298
+ /**
299
+ * `useTooltip` with a trigger behavior. Module-only: InfoTip's press-to-pin
300
+ * goes through it, and the package does not export it.
301
+ */
302
+ export function useTooltipWithTriggerBehavior(
303
+ options: TooltipWithTriggerBehaviorOptions = {},
304
+ ): TooltipReturn {
299
305
  const {
300
306
  placement = 'above',
301
307
  alignment = 'center',
@@ -368,6 +374,9 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
368
374
  isHeldOpen: isPressHeldOpen,
369
375
  attach: attachPressPin,
370
376
  unpin: unpinPress,
377
+ hold: holdPress,
378
+ release: releasePress,
379
+ isAppHeld,
371
380
  isPinShown,
372
381
  touch: {
373
382
  isTouchPointerRef,
@@ -478,32 +487,13 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
478
487
  [isTouchPointerRef, layerId, scheduleHide],
479
488
  );
480
489
 
481
- // Under `auto`, whether focus counts is decided when it arrives, not when
482
- // the listeners attach: a roving-tabindex member that was `tabindex="-1"`
483
- // then can be the tab stop now. A trigger that receives focus is focusable
484
- // by definition; focus inside it counts only while the trigger is
485
- // focusable too, so a plain wrapper still ignores its children's focus.
486
- const isFocusForTrigger = useCallback(
487
- (e: Event): boolean => {
488
- if (focusTrigger === 'always') {
489
- return true;
490
- }
491
- const triggerEl = e.currentTarget as HTMLElement | null;
492
- return (
493
- triggerEl != null && (e.target === triggerEl || isFocusable(triggerEl))
494
- );
495
- },
496
- [focusTrigger],
497
- );
498
-
499
- // Whether the trigger's current focus counted when it arrived, so its blur
500
- // hides the tooltip even if the trigger has since left the tab order.
501
- const focusCountedRef = useRef(false);
490
+ // Under `auto`, whether focus counts is decided when it arrives, and a
491
+ // focus that counted still hides on blur (utils/triggerFocus.ts).
492
+ const [focusGate] = useState(createTriggerFocusGate);
502
493
 
503
494
  const handleFocusIn = useCallback(
504
495
  (e: Event) => {
505
- focusCountedRef.current = isFocusForTrigger(e);
506
- if (!isEnabled || !focusCountedRef.current) {
496
+ if (!focusGate.focusIn(e, focusTrigger) || !isEnabled) {
507
497
  return;
508
498
  }
509
499
  // A tap focuses the trigger it activates, and `:focus-visible` does not
@@ -524,8 +514,9 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
524
514
  showLayer();
525
515
  },
526
516
  [
517
+ focusGate,
518
+ focusTrigger,
527
519
  isEnabled,
528
- isFocusForTrigger,
529
520
  isTouchInteraction,
530
521
  clearTimeouts,
531
522
  showLayer,
@@ -537,13 +528,12 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
537
528
  // which a held tooltip skips.
538
529
  const handleFocusOut = useCallback(
539
530
  (e: Event) => {
540
- if (!focusCountedRef.current && !isFocusForTrigger(e)) {
531
+ if (!focusGate.focusOut(e, focusTrigger)) {
541
532
  return;
542
533
  }
543
- focusCountedRef.current = false;
544
534
  scheduleHide();
545
535
  },
546
- [isFocusForTrigger, scheduleHide],
536
+ [focusGate, focusTrigger, scheduleHide],
547
537
  );
548
538
 
549
539
  // Pressing the trigger hides its own tooltip: once the control is activated
@@ -555,9 +545,10 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
555
545
  // tooltip at all), so the touch path answers it first.
556
546
  const handlePointerDown = useCallback(
557
547
  (event: PointerEvent) => {
558
- // A press on a toggle trigger pins or closes through its click. It
559
- // neither hides the preview here nor waits for a tap verdict.
560
- if (isToggleTrigger(triggerRef.current)) {
548
+ // A toggle trigger's press pins or closes through its click. The app's
549
+ // hide() closes a held tooltip. Neither path hides here or waits for a
550
+ // tap verdict.
551
+ if (isToggleTrigger(triggerRef.current) || isAppHeld()) {
561
552
  return;
562
553
  }
563
554
  if (handleTouchPointerDown(event)) {
@@ -569,7 +560,14 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
569
560
  clearTimeouts();
570
561
  hideLayer();
571
562
  },
572
- [isToggleTrigger, handleTouchPointerDown, isOpen, clearTimeouts, hideLayer],
563
+ [
564
+ isToggleTrigger,
565
+ isAppHeld,
566
+ handleTouchPointerDown,
567
+ isOpen,
568
+ clearTimeouts,
569
+ hideLayer,
570
+ ],
573
571
  );
574
572
 
575
573
  // Interaction ref that handles event listeners only
@@ -602,7 +600,7 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
602
600
  el.addEventListener('pointerdown', handlePointerDown);
603
601
 
604
602
  // Focus listeners unless focus never opens the tooltip; `auto` decides
605
- // per event (isFocusForTrigger).
603
+ // per event (utils/triggerFocus.ts).
606
604
  if (focusTrigger !== 'never') {
607
605
  el.addEventListener('focusin', handleFocusIn);
608
606
  el.addEventListener('focusout', handleFocusOut);
@@ -658,9 +656,11 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
658
656
  showLayer();
659
657
  } else {
660
658
  clearTimeouts();
659
+ // A pin or app hold ends when the consumer closes the tooltip.
660
+ unpinPress();
661
661
  hideLayer();
662
662
  }
663
- }, [isOpen, clearTimeouts, showLayer, hideLayer]);
663
+ }, [isOpen, clearTimeouts, showLayer, hideLayer, unpinPress]);
664
664
 
665
665
  // Dismiss on Escape (WCAG 1.4.13 — dismissible) through the shared layer
666
666
  // stack. A visible tip is the top-most layer, so it takes the press and
@@ -756,6 +756,16 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
756
756
  ],
757
757
  );
758
758
 
759
+ const show = useCallback(() => {
760
+ clearTimeouts();
761
+ holdPress();
762
+ }, [clearTimeouts, holdPress]);
763
+
764
+ const hide = useCallback(() => {
765
+ clearTimeouts();
766
+ releasePress();
767
+ }, [clearTimeouts, releasePress]);
768
+
759
769
  return {
760
770
  ref,
761
771
  positionRef: layerRef,
@@ -763,5 +773,7 @@ export function useTooltip(options: TooltipOptions = {}): TooltipReturn {
763
773
  anchorId: layerAnchorId,
764
774
  describedBy: layerId,
765
775
  renderTooltip,
776
+ show,
777
+ hide,
766
778
  };
767
779
  }
@@ -33,7 +33,7 @@ import type {LinkComponentType} from '../Link/types';
33
33
  import {useTopNavRenderMode} from './TopNavRenderContext';
34
34
  import {navItemStyles, type NavItemSize} from '../NavItem/navItemStyles.stylex';
35
35
  import {mergeProps} from '../utils';
36
- import {useAppShellMobile} from '../AppShell/AppShellMobileContext';
36
+ import {useCloseMobileDrawerOnActivate} from '../AppShell/useCloseMobileDrawerOnActivate';
37
37
  import {themeProps} from '../utils/themeProps';
38
38
  import {focusOutlineProps} from '../utils/focusOutline.stylex';
39
39
  import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
@@ -199,7 +199,9 @@ export function TopNavItem({
199
199
  const pressable = usePressFeedback();
200
200
  const LinkComponent = useLinkComponent(as);
201
201
  const renderMode = useTopNavRenderMode();
202
- const {closeMobileNav} = useAppShellMobile();
202
+ const closeDrawerAfter = useCloseMobileDrawerOnActivate(
203
+ renderMode === 'drawer',
204
+ );
203
205
 
204
206
  // A disabled item renders as a plain <a> with no href: an href-less anchor
205
207
  // is not focusable and exposes no link affordance, so programmatic focus +
@@ -214,14 +216,13 @@ export function TopNavItem({
214
216
  // Drawer mode — render as a SideNavItem-style vertical list element
215
217
  // =========================================================================
216
218
  if (renderMode === 'drawer') {
219
+ const activate = closeDrawerAfter(onClick);
217
220
  const handleDrawerClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
218
221
  if (isDisabled) {
219
222
  preventDefaultClick(e);
220
223
  return;
221
224
  }
222
- // Forward the original onClick if present
223
- onClick?.(e);
224
- closeMobileNav();
225
+ activate?.(e);
225
226
  };
226
227
 
227
228
  return (
@@ -32,7 +32,7 @@ import type {LinkComponentType} from '../Link/types';
32
32
  import {useTopNavRenderMode} from './TopNavRenderContext';
33
33
  import {mergeProps} from '../utils';
34
34
  import type {BaseProps} from '../BaseProps';
35
- import {useAppShellMobile} from '../AppShell/AppShellMobileContext';
35
+ import {useCloseMobileDrawerOnActivate} from '../AppShell/useCloseMobileDrawerOnActivate';
36
36
  import {themeProps} from '../utils/themeProps';
37
37
  import {focusOutlineProps} from '../utils/focusOutline.stylex';
38
38
  import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
@@ -200,7 +200,9 @@ export function TopNavMegaMenuItem({
200
200
  const pressable = usePressFeedback();
201
201
  const renderMode = useTopNavRenderMode();
202
202
  const LinkComponent = useLinkComponent(as);
203
- const {closeMobileNav} = useAppShellMobile();
203
+ const closeDrawerAfter = useCloseMobileDrawerOnActivate(
204
+ renderMode === 'drawer',
205
+ );
204
206
 
205
207
  // =========================================================================
206
208
  // Drawer mode — matches SideNavItem / TopNavMenu drawer appearance
@@ -208,10 +210,9 @@ export function TopNavMegaMenuItem({
208
210
  if (renderMode === 'drawer') {
209
211
  const Element = href ? LinkComponent : 'button';
210
212
  const elementProps = Element === 'button' ? {type: 'button' as const} : {};
211
- const handleDrawerClick = () => {
213
+ const handleDrawerClick = closeDrawerAfter(() => {
212
214
  onClick?.();
213
- closeMobileNav();
214
- };
215
+ });
215
216
  return (
216
217
  <Element
217
218
  {...restProps}
@@ -39,7 +39,7 @@ import type {BaseProps} from '../BaseProps';
39
39
  import {navItemStyles} from '../NavItem/navItemStyles.stylex';
40
40
  import {useTopNavSlot} from './TopNavContext';
41
41
  import {useTopNavRenderMode} from './TopNavRenderContext';
42
- import {useAppShellMobile} from '../AppShell/AppShellMobileContext';
42
+ import {useCloseMobileDrawerOnActivate} from '../AppShell/useCloseMobileDrawerOnActivate';
43
43
  import {useLinkComponent} from '../Link/useLinkComponent';
44
44
  import {isSafeUrl} from '../utils/safeUrl';
45
45
  import {themeProps} from '../utils/themeProps';
@@ -363,7 +363,9 @@ export function TopNavMenu({
363
363
  }: TopNavMenuProps) {
364
364
  const pressable = usePressFeedback();
365
365
  const renderMode = useTopNavRenderMode();
366
- const {closeMobileNav} = useAppShellMobile();
366
+ const closeDrawerAfter = useCloseMobileDrawerOnActivate(
367
+ renderMode === 'drawer',
368
+ );
367
369
  const LinkComponent = useLinkComponent();
368
370
  const [drawerExpanded, setDrawerExpanded] = useState(false);
369
371
  const menuId = useId();
@@ -524,10 +526,9 @@ export function TopNavMenu({
524
526
  key={getMenuItemKey(item)}
525
527
  href={item.href}
526
528
  {...pressable}
527
- onClick={(_e: React.MouseEvent) => {
529
+ onClick={closeDrawerAfter((_e: React.MouseEvent) => {
528
530
  item.onClick?.();
529
- closeMobileNav();
530
- }}
531
+ })}
531
532
  {...focusOutlineProps.focusVisible(
532
533
  navItemStyles.item,
533
534
  interactionOverlayStyles.backgroundColor,