@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
@@ -75,6 +75,7 @@ import {
75
75
  import {useDevWarning} from '../hooks/useDevWarning';
76
76
  import {useScrollLock} from '../hooks/useScrollLock';
77
77
  import {useMergedRefs} from '../hooks/useMergedRefs';
78
+ import {observeMutations} from '../utils/sharedMutationObserver';
78
79
  import {mergeProps} from '../utils/mergeProps';
79
80
  import {LayerDepthProvider} from '../Layer/LayerDepthContext';
80
81
  import {ModalAnnounceProvider} from '../hooks/ModalAnnounceProvider';
@@ -147,12 +148,17 @@ const styles = stylex.create({
147
148
  },
148
149
  // An open standalone dialog positions its panel: the panel sits at its
149
150
  // block end, centred, with no wrapper. A tap beside a narrower panel lands
150
- // on the dialog, which light dismiss reads. The stack's recede applies to
151
- // this dialog too, so a covered sheet shrinks and lifts as one.
151
+ // on the dialog, which light dismiss reads. A flex row, not a grid: WebKit
152
+ // lays a grid host out again on each render inside the sheet, which makes
153
+ // each update slower. Not a column: WebKit then drops the content's
154
+ // block-end padding from the scroll range. In a row the panel's height is
155
+ // its own cross size, so a sheet taller than the viewport runs past the top
156
+ // edge, as in a grid. The stack's recede applies to this dialog too, so a
157
+ // covered sheet shrinks and lifts as one.
152
158
  dialogPanelHost: {
153
- display: 'grid',
154
- alignContent: 'end',
155
- justifyItems: 'center',
159
+ display: 'flex',
160
+ justifyContent: 'center',
161
+ alignItems: 'flex-end',
156
162
  },
157
163
  // A non-modal sheet is in the top layer as a manual popover, so it has no
158
164
  // page z-index (AST-027). Below the Popover API floor, `show()` leaves it
@@ -207,6 +213,10 @@ const styles = stylex.create({
207
213
  transitionTimingFunction: 'linear',
208
214
  },
209
215
  },
216
+ // A closing sheet that keeps focus takes no pointer input during its exit.
217
+ exitHoldingFocus: {
218
+ pointerEvents: 'none',
219
+ },
210
220
  positioner: {
211
221
  position: 'absolute',
212
222
  insetInline: 0,
@@ -255,6 +265,24 @@ function stackPositionerStyles(view: BottomSheetStackView) {
255
265
  }
256
266
 
257
267
  /** The `data-sheet-stack` value for a host: only set while sheets stack. */
268
+ /** Stops a click, from any input, before it reaches its target. */
269
+ function ignoreActivation(event: React.MouseEvent): void {
270
+ event.preventDefault();
271
+ event.stopPropagation();
272
+ }
273
+
274
+ /**
275
+ * Stops every key except Tab before it reaches the focused control, so no
276
+ * key handler runs and no text changes (a search field's Enter, a typed
277
+ * letter, Backspace, an arrow that reopens a list). Tab still moves focus.
278
+ */
279
+ function ignoreKeyDuringExit(event: React.KeyboardEvent): void {
280
+ if (event.key !== 'Tab') {
281
+ event.preventDefault();
282
+ event.stopPropagation();
283
+ }
284
+ }
285
+
258
286
  function stackStateAttribute(
259
287
  view: BottomSheetStackView,
260
288
  isOpen: boolean,
@@ -445,10 +473,14 @@ function StandaloneBottomSheet({
445
473
  // `isOpen` restarts the flag during render, and the layout effect below
446
474
  // settles a close.
447
475
  const [isCloseSettled, setIsCloseSettled] = useState(false);
476
+ // Whether focus was inside the sheet when it closed. Such a sheet stays out
477
+ // of `inert` and `aria-hidden` until its exit ends and focus has left.
478
+ const [isExitFocusHeld, setIsExitFocusHeld] = useState(false);
448
479
  const [settledIsOpen, setSettledIsOpen] = useState(isOpen);
449
480
  if (settledIsOpen !== isOpen) {
450
481
  setSettledIsOpen(isOpen);
451
482
  setIsCloseSettled(false);
483
+ setIsExitFocusHeld(false);
452
484
  }
453
485
  const panelState: BottomSheetPanelState = isOpen
454
486
  ? {kind: 'open', entering: stackView.isReplacing}
@@ -576,9 +608,8 @@ function StandaloneBottomSheet({
576
608
  }, [hasScrim, shouldPresent, writeScrim]);
577
609
  useLayoutEffect(() => {
578
610
  if (!isOpen) {
579
- // Read before the browser's focus fixup for the exiting sheet's
580
- // `inert` runs (at the next rendering opportunity), so this is where
581
- // focus was when the person closed the sheet.
611
+ // Where focus was when the person closed the sheet. The closing sheet
612
+ // is not inert yet, so focus has not moved.
582
613
  const dialog = dialogRef.current;
583
614
  hadFocusAtCloseRef.current =
584
615
  dialog != null && dialog.contains(dialog.ownerDocument.activeElement);
@@ -591,6 +622,8 @@ function StandaloneBottomSheet({
591
622
  // that was not paired as a replace is an exit from here on.
592
623
  // eslint-disable-next-line @eslint-react/set-state-in-effect -- settles the close once the registry has answered
593
624
  setIsCloseSettled(true);
625
+ // Read with the close, before the sheet can go inert.
626
+ setIsExitFocusHeld(hadFocusAtCloseRef.current);
594
627
  }
595
628
  }, [hasScrim, isOpen, shouldPresent]);
596
629
 
@@ -694,7 +727,44 @@ function StandaloneBottomSheet({
694
727
  );
695
728
 
696
729
  const {ref: modalityRef} = useInteractionModalityTracking();
697
- const dialogComposedRef = useMergedRefs(dialogRef, modalityRef);
730
+ // Ends the exit hold once focus has left the sheet: moved elsewhere, or
731
+ // dropped to the page because the focused control was removed or disabled.
732
+ // Native listeners, because React drops the `focusout` a browser sends while
733
+ // React removes the focused element, and Firefox and WebKit send no
734
+ // `focusout` for a removed element at all, so a subtree change is read too.
735
+ // Each reads the focus after the event. They attach only while a closing
736
+ // sheet holds focus, so a closed or open sheet observes nothing.
737
+ const isWatchingExitFocus =
738
+ !isOpen && isPresented && !isReplaced && isExitFocusHeld;
739
+ const exitFocusRef = useCallback(
740
+ (dialog: HTMLDialogElement | null) => {
741
+ if (dialog == null || !isWatchingExitFocus) {
742
+ return;
743
+ }
744
+ const releaseIfFocusLeft = () => {
745
+ if (!dialog.contains(dialog.ownerDocument.activeElement)) {
746
+ setIsExitFocusHeld(false);
747
+ }
748
+ };
749
+ const onFocusOut = () => queueMicrotask(releaseIfFocusLeft);
750
+ dialog.addEventListener('focusout', onFocusOut);
751
+ const unobserve = observeMutations(
752
+ dialog,
753
+ {
754
+ childList: true,
755
+ subtree: true,
756
+ attributeFilter: ['disabled', 'hidden', 'inert'],
757
+ },
758
+ releaseIfFocusLeft,
759
+ );
760
+ return () => {
761
+ dialog.removeEventListener('focusout', onFocusOut);
762
+ unobserve();
763
+ };
764
+ },
765
+ [isWatchingExitFocus],
766
+ );
767
+ const dialogComposedRef = useMergedRefs(dialogRef, modalityRef, exitFocusRef);
698
768
  useScrollLock(shouldPresent && hasScrim);
699
769
  useDevWarning(
700
770
  'BottomSheet',
@@ -764,7 +834,16 @@ function StandaloneBottomSheet({
764
834
  // that contains no presented sheet is marked inert and hidden as well, so
765
835
  // the state is explicit; one that does contain the top sheet is left alone,
766
836
  // because inert on it would reach the top sheet too.
767
- const isInert = isExiting || stackView.isBlocked;
837
+ // A sheet that closes with focus inside it is neither inert nor hidden
838
+ // while that focus stays: `inert` would drop the focus to the page, and
839
+ // `aria-hidden` would hide the focused control. When the exit ends, the
840
+ // dialog closes and focus returns in the same task. When focus leaves the
841
+ // sheet first (into a sheet opened above it, for example), the sheet goes
842
+ // inert at once. Until the close settles, no closing sheet is inert, so the
843
+ // first commit of a close never hides focus.
844
+ const isExitHoldingFocus =
845
+ isExiting && !isReplaced && (!isCloseSettled || isExitFocusHeld);
846
+ const isInert = (isExiting && !isExitHoldingFocus) || stackView.isBlocked;
768
847
 
769
848
  return (
770
849
  <dialog
@@ -779,6 +858,7 @@ function StandaloneBottomSheet({
779
858
  hasScrim && styles.scrim,
780
859
  hasScrim && isEntrySettled && styles.scrimSettled,
781
860
  hasScrim && isExiting && styles.scrimClosing,
861
+ isExitHoldingFocus && styles.exitHoldingFocus,
782
862
  !hasScrim && styles.dialogNonModal,
783
863
  )}
784
864
  ref={dialogComposedRef}
@@ -800,6 +880,11 @@ function StandaloneBottomSheet({
800
880
  hasScrim && stackView.depth > 0 ? stackView.depth : undefined
801
881
  }
802
882
  onCancel={handleCancel}
883
+ // A closing sheet that keeps focus takes no activation during its
884
+ // exit: no click and no key but Tab reaches the control that has focus.
885
+ onClickCapture={isExitHoldingFocus ? ignoreActivation : undefined}
886
+ onKeyDownCapture={isExitHoldingFocus ? ignoreKeyDuringExit : undefined}
887
+ onKeyUpCapture={isExitHoldingFocus ? ignoreKeyDuringExit : undefined}
803
888
  // Presses inside the sheet do not reach handlers around where it is
804
889
  // written. The dialog, not the panel, is the root, as in a switcher.
805
890
  {...layerClickBoundary({onClick: handleClick})}>
@@ -296,14 +296,19 @@ const styles = stylex.create({
296
296
  },
297
297
  content: {
298
298
  // Preserve the body's block formatting (including margin/float isolation)
299
- // and its definite percentage-height basis. min-content lets this real
299
+ // and its definite percentage-height basis. fit-content lets this real
300
300
  // observed box grow with async content beyond a fixed-height viewport.
301
301
  // This box is also the sheet's container: it carries the padding and
302
302
  // publishes it, so a lone Section child escapes it exactly as in Dialog.
303
303
  display: 'flow-root',
304
304
  boxSizing: 'border-box',
305
305
  height: '100%',
306
- minHeight: 'min-content',
306
+ // fit-content, not min-content: they are one size in the block axis, but
307
+ // WebKit ignores min-content on a block's min-height. There the box keeps
308
+ // its body's height on a budget-height sheet. Content placed directly in
309
+ // it then overflows the box, and its block-end padding leaves the scroll
310
+ // range.
311
+ minHeight: 'fit-content',
307
312
  },
308
313
  tallKeyboardBody: {
309
314
  scrollPaddingBlockEnd: MOBILE_KEYBOARD_BOTTOM_CLEARANCE,
@@ -413,6 +418,7 @@ function waitForTransition(
413
418
 
414
419
  let done = false;
415
420
  let timer: ReturnType<typeof setTimeout> | null = null;
421
+ let backstopMs = 0;
416
422
  const finish = () => {
417
423
  if (done) {
418
424
  return;
@@ -426,9 +432,24 @@ function waitForTransition(
426
432
  complete();
427
433
  };
428
434
  const handleTransitionEnd = (event: TransitionEvent) => {
429
- if (event.target === element && event.propertyName === propertyName) {
430
- finish();
435
+ if (event.target !== element || event.propertyName !== propertyName) {
436
+ return;
437
+ }
438
+ // The engine cancels a transition whose end value changes mid-flight. A
439
+ // percentage transform does when the closing frame moves the height by a
440
+ // fraction of a pixel. A replacement runs on from where it was. That one
441
+ // ends the motion, not the cancel.
442
+ if (
443
+ event.type === 'transitioncancel' &&
444
+ hasRunningTransition(element, propertyName)
445
+ ) {
446
+ if (timer != null) {
447
+ clearTimeout(timer);
448
+ timer = setTimeout(finish, backstopMs);
449
+ }
450
+ return;
431
451
  }
452
+ finish();
432
453
  };
433
454
  element.addEventListener('transitionend', handleTransitionEnd);
434
455
  element.addEventListener('transitioncancel', handleTransitionEnd);
@@ -479,7 +500,8 @@ function waitForTransition(
479
500
  return () => {};
480
501
  }
481
502
 
482
- timer = setTimeout(finish, transitionMs + TRANSITION_BACKSTOP_BUFFER_MS);
503
+ backstopMs = transitionMs + TRANSITION_BACKSTOP_BUFFER_MS;
504
+ timer = setTimeout(finish, backstopMs);
483
505
  return () => {
484
506
  if (timer != null) {
485
507
  clearTimeout(timer);
@@ -489,6 +511,19 @@ function waitForTransition(
489
511
  };
490
512
  }
491
513
 
514
+ // Whether a CSS transition of `propertyName` still runs on `element`.
515
+ function hasRunningTransition(
516
+ element: HTMLElement,
517
+ propertyName: string,
518
+ ): boolean {
519
+ return (element.getAnimations?.() ?? []).some(
520
+ animation =>
521
+ (animation as Animation & {transitionProperty?: string})
522
+ .transitionProperty === propertyName &&
523
+ (animation.playState === 'running' || animation.playState === 'paused'),
524
+ );
525
+ }
526
+
492
527
  function parseTransitionTime(value: string): number | null {
493
528
  const normalizedValue = value.trim();
494
529
  if (!/^-?(?:\d+|\d*\.\d+)(?:ms|s)$/.test(normalizedValue)) {
@@ -866,12 +866,16 @@ function openModalsOutside(element: Element): HTMLDialogElement[] {
866
866
  if (dialog === element || dialog.contains(element)) {
867
867
  continue;
868
868
  }
869
- // A modal on its way out (a closing sheet keeps its dialog modal through
870
- // the exit animation, inert and hidden) blocks nothing any more: it is
871
- // gone for this decision.
869
+ // A modal on its way out blocks nothing any more: it is gone for this
870
+ // decision. A closing sheet keeps its dialog modal through the exit
871
+ // animation; it is inert and hidden then, unless focus was inside it at
872
+ // the close, so the registry's own record of the close counts too.
872
873
  if (
873
874
  dialog.hasAttribute('inert') ||
874
- dialog.getAttribute('aria-hidden') === 'true'
875
+ dialog.getAttribute('aria-hidden') === 'true' ||
876
+ state.entries.some(
877
+ entry => !entry.isOpen && entry.getElement() === dialog,
878
+ )
875
879
  ) {
876
880
  continue;
877
881
  }
@@ -738,7 +738,9 @@ export function useSheetGestures({
738
738
  }
739
739
  return;
740
740
  }
741
- recordSheetHeight(node.getBoundingClientRect().height);
741
+ // No measure here: reading the height while the sheet mounts forces a
742
+ // layout in the middle of the open. The observer's first report comes
743
+ // after the browser's own layout, before the first paint.
742
744
  const ro = new ResizeObserver(entries => {
743
745
  const entry = entries[0];
744
746
  if (entry) {
@@ -7,7 +7,8 @@
7
7
  * @input Uses React use/useRef/useEffect, stylex, theme tokens, BreadcrumbContext,
8
8
  * rtlStyles for the contextual default slash, and (for the menu trigger)
9
9
  * usePopover + the shared DropdownMenu item API (renderDropdownItems,
10
- * DropdownMenuContext, MENU_ITEM_SELECTOR, useListFocus)
10
+ * DropdownMenuContext, MENU_ITEM_SELECTOR, useListFocus), and
11
+ * the AppShell mobile drawer helpers
11
12
  * @output Exports BreadcrumbItem component and BreadcrumbItemProps
12
13
  * @position Individual breadcrumb item; used inside Breadcrumbs
13
14
  *
@@ -72,6 +73,10 @@ import {
72
73
  import type {DropdownMenuOption} from '../DropdownMenu/DropdownMenu';
73
74
 
74
75
  import {useMergedRefs} from '../hooks/useMergedRefs';
76
+ import {
77
+ useCloseMobileDrawerOnActivate,
78
+ useIsInAppShellMobileDrawer,
79
+ } from '../AppShell/useCloseMobileDrawerOnActivate';
75
80
  import {useInteractionModalityTracking} from '../utils/interactionModality';
76
81
  import {isRenderable} from '../utils/isRenderable';
77
82
  // =============================================================================
@@ -306,6 +311,11 @@ export function BreadcrumbItem({
306
311
  // aria-current on this instead of guessing the <li>'s last child.
307
312
  const contentRef = useRef<HTMLElement>(null);
308
313
 
314
+ const closeDrawerAfter = useCloseMobileDrawerOnActivate(
315
+ useIsInAppShellMobileDrawer(),
316
+ );
317
+ const handleActivate = closeDrawerAfter(onClick);
318
+
309
319
  const isCurrent = isCurrentProp === true;
310
320
  const isAutoCandidate = isCurrentProp == null;
311
321
  const hasMenu = menu != null;
@@ -456,7 +466,7 @@ export function BreadcrumbItem({
456
466
  <LinkComponent
457
467
  ref={contentRef}
458
468
  href={href}
459
- onClick={onClick}
469
+ onClick={handleActivate}
460
470
  {...focusOutlineProps.focusVisible(
461
471
  itemStyles.link,
462
472
  isSupporting ? itemStyles.supportingLink : itemStyles.defaultLink,
@@ -467,7 +477,7 @@ export function BreadcrumbItem({
467
477
  <button
468
478
  ref={contentRef as React.RefObject<HTMLButtonElement | null>}
469
479
  type="button"
470
- onClick={onClick}
480
+ onClick={handleActivate}
471
481
  {...focusOutlineProps.focusVisible(
472
482
  itemStyles.link,
473
483
  itemStyles.buttonReset,
@@ -19,6 +19,7 @@
19
19
  */
20
20
 
21
21
  import {
22
+ isValidElement,
22
23
  use,
23
24
  useEffect,
24
25
  useRef,
@@ -44,6 +45,7 @@ import {
44
45
  focusVars,
45
46
  } from '../theme/tokens.stylex';
46
47
  import {Spinner} from '../Spinner/Spinner';
48
+ import {Icon} from '../Icon/Icon';
47
49
  import {VisuallyHidden} from '../VisuallyHidden/VisuallyHidden';
48
50
  import {IconDefaultSizeProvider} from '../Icon/IconDefaultSizeContext';
49
51
  import {iconBoxSizeStyles, type IconSize} from '../Icon/IconSize.stylex';
@@ -51,6 +53,7 @@ import {iconBoxSizeStyles, type IconSize} from '../Icon/IconSize.stylex';
51
53
  import {EDGE_COMP_ATTR} from '../Layout/edgeCompensation.stylex';
52
54
  import {useSize} from '../SizeContext/SizeContext';
53
55
  import {useButtonGroup} from '../ButtonGroup/ButtonGroupContext';
56
+ import {PressGroupContext} from '../hooks/pressGroupContext';
54
57
  import {useInputGroup} from '../InputGroup/InputGroupContext';
55
58
  import {InputGroupInternalContext} from '../InputGroup/InputGroupInternalContext';
56
59
  import {
@@ -75,6 +78,12 @@ import {isRenderable} from '../utils/isRenderable';
75
78
 
76
79
  registerEnglishFallback(english);
77
80
 
81
+ /**
82
+ * Written by the press controller or a group's tracker while a press is
83
+ * believed. Typed `string`, so StyleX reads it as a computed key.
84
+ */
85
+ const PRESSED_ON: string = '[data-astryx-press="on"]';
86
+
78
87
  /**
79
88
  * Base button styles
80
89
  * Pseudo-classes are nested within properties per StyleX recommendation:
@@ -136,7 +145,19 @@ const styles = stylex.create({
136
145
  default: 'scale(0.98)',
137
146
  '@media (pointer: coarse)': 'scale(1)',
138
147
  },
139
- '[data-astryx-press="on"]': 'scale(0.98)',
148
+ [PRESSED_ON]: 'scale(0.98)',
149
+ },
150
+ },
151
+ // A tracked action's own `:active` image paints nothing: the tracker paints
152
+ // the action under the pointer, which need not be the one pressed first.
153
+ trackedOverlay: {
154
+ backgroundSize: {default: null, [`:active:not(${PRESSED_ON})`]: '0 0'},
155
+ },
156
+ // A tracked action's press is painted by its group's tracker alone.
157
+ pressableTracked: {
158
+ transform: {
159
+ default: 'scale(1)',
160
+ [PRESSED_ON]: 'scale(0.98)',
140
161
  },
141
162
  },
142
163
  inactive: {
@@ -145,7 +166,7 @@ const styles = stylex.create({
145
166
  transform: {
146
167
  default: 'none',
147
168
  ':active': 'none',
148
- '[data-astryx-press="on"]': 'none',
169
+ [PRESSED_ON]: 'none',
149
170
  },
150
171
  },
151
172
  disabled: {
@@ -158,7 +179,7 @@ const styles = stylex.create({
158
179
  backgroundImage: {
159
180
  default: 'none',
160
181
  ':active': 'none',
161
- '[data-astryx-press="on"]': 'none',
182
+ [PRESSED_ON]: 'none',
162
183
  },
163
184
  },
164
185
  iconOnly: {
@@ -559,6 +580,21 @@ const groupStyles = stylex.create({
559
580
  },
560
581
  });
561
582
 
583
+ /**
584
+ * Whether `node` adds nothing to a content name: nothing renders, or an Icon
585
+ * with no label. Any other node can add text.
586
+ */
587
+ function addsNoName(node: ReactNode): boolean {
588
+ if (!isRenderable(node)) {
589
+ return true;
590
+ }
591
+ if (!isValidElement<{label?: unknown}>(node) || node.type !== Icon) {
592
+ return false;
593
+ }
594
+ const {label} = node.props;
595
+ return typeof label !== 'string' || label.trim() === '';
596
+ }
597
+
562
598
  /**
563
599
  * A versatile button component with multiple variants.
564
600
  *
@@ -615,6 +651,7 @@ export function Button({
615
651
  const t = useComponentTranslator();
616
652
  const size = useSize(sizeProp, 'md');
617
653
  const buttonGroup = useButtonGroup();
654
+ const isGroupTracked = use(PressGroupContext);
618
655
  const inputGroup = useInputGroup();
619
656
 
620
657
  const [isPending, startTransition] = useTransition();
@@ -743,11 +780,13 @@ export function Button({
743
780
  sizeStyles[size],
744
781
  isIconOnly && styles.iconOnly,
745
782
  interactionOverlayStyles.backgroundImage,
783
+ isGroupTracked && styles.trackedOverlay,
746
784
  buttonDisabled && styles.inactive,
747
785
  isTrueDisabled && styles.disabled,
748
786
  useAriaDisabled && styles.ariaDisabled,
749
787
  renderAsLink && styles.link,
750
- !buttonGroup && styles.pressable,
788
+ !buttonGroup &&
789
+ (isGroupTracked ? styles.pressableTracked : styles.pressable),
751
790
  buttonGroup &&
752
791
  (buttonGroup.orientation === 'horizontal'
753
792
  ? groupStyles.horizontal
@@ -836,10 +875,29 @@ export function Button({
836
875
  (children != null && children !== label);
837
876
  const ariaLabelProp = needsAriaLabel ? {'aria-label': label} : null;
838
877
 
878
+ // The Button's accessible name when props decide it: the derived
879
+ // aria-label, else a caller aria-label, else the label text alone. It is
880
+ // not known here when a caller aria-labelledby names the Button from other
881
+ // elements, or when `icon` or `endContent` can add text to its content
882
+ // name (a count, for example). A decorative Icon in either slot adds none.
883
+ const accessibleName =
884
+ props['aria-labelledby'] != null
885
+ ? undefined
886
+ : needsAriaLabel
887
+ ? label
888
+ : (props['aria-label'] ??
889
+ (addsNoName(icon) && addsNoName(endContent) ? label : undefined));
890
+ // A tooltip that repeats the name adds nothing to the description, so a
891
+ // screen reader does not read the same words twice.
892
+ const isTooltipName =
893
+ tooltip != null &&
894
+ accessibleName != null &&
895
+ tooltip.trim() === accessibleName.trim();
896
+
839
897
  // When a tooltip is attached via the hook, point aria-describedby at the
840
898
  // tooltip content (composing with any consumer-provided value).
841
899
  const describedByProp =
842
- tooltip != null
900
+ tooltip != null && !isTooltipName
843
901
  ? {
844
902
  'aria-describedby':
845
903
  [props['aria-describedby'], tooltipHook.describedBy]
@@ -151,6 +151,15 @@ export const docs = {
151
151
  },
152
152
  {className: 'astryx-checkbox-label'},
153
153
  ],
154
+ vars: [
155
+ {
156
+ name: '--_indicator-press-image',
157
+ description:
158
+ "The row's touch press image, handed down to a first-party indicator that paints its own press. Set from the press paint only while the row itself is pressed; only this row declares it.",
159
+ default: 'none',
160
+ private: true,
161
+ },
162
+ ],
154
163
  },
155
164
  usage: {
156
165
  accessibility: [
@@ -390,6 +399,15 @@ export const docsZh = {
390
399
  },
391
400
  {className: 'astryx-checkbox-label'},
392
401
  ],
402
+ vars: [
403
+ {
404
+ name: '--_indicator-press-image',
405
+ description:
406
+ '复选框行的触摸按下图像,传递给自行绘制按下效果的第一方指示器。仅在该行自身被按下时根据按下涂层设置,只有该行声明它。',
407
+ default: 'none',
408
+ private: true,
409
+ },
410
+ ],
393
411
  },
394
412
  };
395
413
 
@@ -46,6 +46,7 @@ import {useTooltip} from '../Tooltip/useTooltip';
46
46
  import {mergeProps} from '../utils/mergeProps';
47
47
  import {rtlStyles} from '../utils/rtlStyles';
48
48
  import {indicatorScope} from '../Indicator/indicator.markers.stylex';
49
+ import {indicatorPressScope} from '../internal/indicatorPress.stylex';
49
50
  import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
50
51
  import {useIndicatorFocusRing} from '../hooks/useIndicatorFocusRing';
51
52
  import {useBusyAnnouncement} from '../hooks/useBusyAnnouncement';
@@ -63,6 +64,11 @@ import english from '../i18n/generated-english/CheckboxInput/CheckboxInput.gener
63
64
 
64
65
  registerEnglishFallback(english);
65
66
 
67
+ /** Written by the touch press controller while the row is pressed. */
68
+ const PRESSED_ON = '[data-astryx-press="on"]';
69
+ /** Written by the touch press controller for the press's release. */
70
+ const PRESSED_FADING = '[data-astryx-press="fading"]';
71
+
66
72
  // The touch press's paint, declared by the shared overlay styles on the
67
73
  // element the controller writes to (`pressedAlpha`) at the press's strength,
68
74
  // 1 while on and 1 → 0 over the release, and inherited resolved by the layer
@@ -78,6 +84,20 @@ const styles = stylex.create({
78
84
  containerLabelHidden: {
79
85
  gap: 0,
80
86
  },
87
+ // An indicator in another package may not name this row's private press
88
+ // attribute. So the row hands its touch press image down to an indicator
89
+ // that paints its own press, but only in its own press states. A pressed
90
+ // ancestor row reaches it no more than it reaches the built-in box. The
91
+ // property has no default: a layered stylesheet ranks a default above the
92
+ // arms. Only this row declares it. A menu item paints its own press, so a
93
+ // mapped indicator there paints none.
94
+ indicatorPressImage: {
95
+ '--_indicator-press-image': {
96
+ default: null,
97
+ [PRESSED_ON]: 'var(--_press-paint-image)',
98
+ [PRESSED_FADING]: 'var(--_press-paint-image)',
99
+ },
100
+ },
81
101
  checkboxWrapper: {
82
102
  position: 'relative',
83
103
  display: 'flex',
@@ -86,15 +106,22 @@ const styles = stylex.create({
86
106
  flexShrink: 0,
87
107
  isolation: 'isolate',
88
108
  },
89
- // The owner paints this layer over the resolved indicator, so a theme
90
- // replacement cannot accidentally drop the component's pressed contract.
109
+ // The owner paints this layer over the resolved indicator, so a plain theme
110
+ // replacement keeps the pressed feedback. An indicator with
111
+ // `indicatorPressScope` paints its own press from what the row hands down,
112
+ // so this layer stays off over it.
91
113
  // Two pointers, two press models (see interactionOverlay.stylex.ts): a
92
114
  // mouse keeps `:active`; under a coarse pointer that arm is dropped and the
93
115
  // touch press controller writes `data-astryx-press` on the row, which this layer
94
116
  // reads off the same scope marker as the hover tint.
95
117
  indicatorPressOverlay: {
96
118
  '::after': {
97
- content: '""',
119
+ // `when.descendant` takes a pseudo-class; `:is(*)` matches any marked
120
+ // indicator.
121
+ content: {
122
+ default: '""',
123
+ [stylex.when.descendant(':is(*)', indicatorPressScope)]: 'none',
124
+ },
98
125
  position: 'absolute',
99
126
  inset: 0,
100
127
  borderRadius: radiusVars['--radius-inner'],
@@ -112,15 +139,14 @@ const styles = stylex.create({
112
139
  // what moves. Coarse pointers only, like the drop above.
113
140
  backgroundImage: {
114
141
  default: null,
115
- [stylex.when.ancestor('[data-astryx-press="on"]', indicatorScope)]: {
142
+ [stylex.when.ancestor(PRESSED_ON, indicatorScope)]: {
143
+ default: null,
144
+ '@media (pointer: coarse)': pressedOverlayImage,
145
+ },
146
+ [stylex.when.ancestor(PRESSED_FADING, indicatorScope)]: {
116
147
  default: null,
117
148
  '@media (pointer: coarse)': pressedOverlayImage,
118
149
  },
119
- [stylex.when.ancestor('[data-astryx-press="fading"]', indicatorScope)]:
120
- {
121
- default: null,
122
- '@media (pointer: coarse)': pressedOverlayImage,
123
- },
124
150
  },
125
151
  },
126
152
  },
@@ -450,6 +476,7 @@ export function CheckboxInput({
450
476
  // Hover and focus reach the checkbox visual through this ancestor
451
477
  // marker rather than props, so the whole row drives it.
452
478
  !isDisabled && indicatorScope,
479
+ !isDisabled && styles.indicatorPressImage,
453
480
  // The touch press's strength and release live on the row the
454
481
  // controller writes to; the layer over the checkbox box inherits
455
482
  // and paints it.
@@ -178,12 +178,14 @@ export const docs = {
178
178
  {
179
179
  name: 'containerClassName',
180
180
  type: 'string',
181
- description: 'Class name for the field container. Same targeting as `containerXstyle`.',
181
+ description:
182
+ 'Class name for the field container. Same targeting as `containerXstyle`.',
182
183
  },
183
184
  {
184
185
  name: 'containerStyle',
185
186
  type: 'CSSProperties',
186
- description: 'Inline styles for the field container. Same targeting as `containerXstyle`.',
187
+ description:
188
+ 'Inline styles for the field container. Same targeting as `containerXstyle`.',
187
189
  },
188
190
  {
189
191
  name: 'controlXstyle',
@@ -246,6 +246,7 @@ export function CheckboxList({
246
246
  ? disabledMessageTooltip.describedBy
247
247
  : undefined,
248
248
  isReadOnly,
249
+ isInvalid: status?.type === 'error',
249
250
  loadingValues,
250
251
  }),
251
252
  [
@@ -256,6 +257,7 @@ export function CheckboxList({
256
257
  showsDisabledMessage,
257
258
  disabledMessageTooltip.describedBy,
258
259
  isReadOnly,
260
+ status?.type,
259
261
  loadingValues,
260
262
  ],
261
263
  );
@@ -298,6 +300,10 @@ export function CheckboxList({
298
300
  controlStyle,
299
301
  )}
300
302
  role="group"
303
+ // Screen readers announce the whole group as unavailable. Its dimmed
304
+ // label then labels a disabled control. An enabled list keeps a
305
+ // caller's own value.
306
+ aria-disabled={isDisabled || rest['aria-disabled']}
301
307
  // A caller aria-labelledby names the group together with its label.
302
308
  aria-labelledby={joinAriaIDs(labelID, ariaLabelledByProp)}
303
309
  aria-describedby={