@astryxdesign/core 0.7.7-canary.550ff21 → 0.7.7-canary.58c5b8a

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 (504) 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/Avatar/Avatar.d.ts.map +1 -1
  8. package/dist/Avatar/Avatar.js +1 -1
  9. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  10. package/dist/BottomSheet/BottomSheet.js +79 -9
  11. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  12. package/dist/BottomSheet/BottomSheetPanel.js +23 -4
  13. package/dist/BottomSheet/bottomSheetStack.d.ts.map +1 -1
  14. package/dist/BottomSheet/bottomSheetStack.js +5 -4
  15. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  16. package/dist/BottomSheet/useSheetGestures.js +3 -1
  17. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +2 -1
  18. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  19. package/dist/Breadcrumbs/BreadcrumbItem.js +9 -4
  20. package/dist/Button/Button.d.ts.map +1 -1
  21. package/dist/Button/Button.js +50 -5
  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/DateInput/DateInput.d.ts.map +1 -1
  32. package/dist/DateInput/DateInput.js +5 -2
  33. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  34. package/dist/DateInput/MonthScroller.js +13 -27
  35. package/dist/DateInput/Wheel.d.ts +17 -1
  36. package/dist/DateInput/Wheel.d.ts.map +1 -1
  37. package/dist/DateInput/Wheel.js +161 -20
  38. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  39. package/dist/DateRangeInput/DateRangeInput.js +63 -49
  40. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  41. package/dist/DateTimeInput/DateTimeInput.js +5 -2
  42. package/dist/Dialog/Dialog.d.ts.map +1 -1
  43. package/dist/Dialog/Dialog.js +53 -15
  44. package/dist/Drawer/Drawer.d.ts.map +1 -1
  45. package/dist/Drawer/Drawer.js +15 -11
  46. package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -1
  47. package/dist/Drawer/useDrawerDialogPresence.js +9 -1
  48. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  49. package/dist/DropdownMenu/DropdownMenu.js +20 -4
  50. package/dist/Field/Field.js +2 -2
  51. package/dist/Field/PanelSearchInput.d.ts +9 -1
  52. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  53. package/dist/Field/PanelSearchInput.js +3 -1
  54. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  55. package/dist/HoverCard/HoverCard.js +27 -2
  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/layerClickBoundary.d.ts +7 -1
  69. package/dist/Layer/layerClickBoundary.d.ts.map +1 -1
  70. package/dist/Layer/layerClickBoundary.js +2 -2
  71. package/dist/Layer/useBackdropPress.d.ts +27 -0
  72. package/dist/Layer/useBackdropPress.d.ts.map +1 -0
  73. package/dist/Layer/useBackdropPress.js +53 -0
  74. package/dist/Layer/usePressPin.d.ts +105 -0
  75. package/dist/Layer/usePressPin.d.ts.map +1 -0
  76. package/dist/Layer/usePressPin.js +413 -0
  77. package/dist/Layer/useTouchTrigger.d.ts +23 -1
  78. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  79. package/dist/Layer/useTouchTrigger.js +45 -7
  80. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  81. package/dist/Lightbox/Lightbox.js +2 -1
  82. package/dist/MobileNav/MobileNav.js +0 -1
  83. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  84. package/dist/MultiSelector/hooks.js +2 -4
  85. package/dist/Outline/Outline.d.ts +2 -4
  86. package/dist/Outline/Outline.d.ts.map +1 -1
  87. package/dist/Outline/Outline.js +4 -52
  88. package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
  89. package/dist/Outline/useOutlineFromMarkdown.js +1 -0
  90. package/dist/Outline/useScrollSpy.js +3 -3
  91. package/dist/Popover/usePopover.d.ts.map +1 -1
  92. package/dist/Popover/usePopover.js +56 -7
  93. package/dist/PowerSearch/PowerSearch.d.ts +36 -3
  94. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  95. package/dist/PowerSearch/PowerSearch.js +571 -302
  96. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts +100 -0
  97. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +1 -0
  98. package/dist/PowerSearch/PowerSearchBottomSheet.js +1913 -0
  99. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +32 -1
  100. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  101. package/dist/PowerSearch/PowerSearchEditPopover.js +17 -6
  102. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +38 -3
  103. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  104. package/dist/PowerSearch/PowerSearchValueEditor.js +170 -61
  105. package/dist/PowerSearch/formatFilterValue.d.ts +7 -0
  106. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  107. package/dist/PowerSearch/formatFilterValue.js +11 -1
  108. package/dist/PowerSearch/formatTokenValue.d.ts +28 -0
  109. package/dist/PowerSearch/formatTokenValue.d.ts.map +1 -0
  110. package/dist/PowerSearch/formatTokenValue.js +160 -0
  111. package/dist/PowerSearch/powerSearchSheetUtils.d.ts +65 -0
  112. package/dist/PowerSearch/powerSearchSheetUtils.d.ts.map +1 -0
  113. package/dist/PowerSearch/powerSearchSheetUtils.js +168 -0
  114. package/dist/ProgressBar/ProgressBar.d.ts +1 -1
  115. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  116. package/dist/ProgressBar/ProgressBar.js +33 -6
  117. package/dist/RadioList/RadioList.d.ts.map +1 -1
  118. package/dist/RadioList/RadioList.js +8 -2
  119. package/dist/RadioList/RadioListItem.d.ts +1 -1
  120. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  121. package/dist/RadioList/RadioListItem.js +5 -3
  122. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  123. package/dist/Resizable/ResizeHandle.js +118 -260
  124. package/dist/Resizable/resizeGesture.d.ts +91 -0
  125. package/dist/Resizable/resizeGesture.d.ts.map +1 -0
  126. package/dist/Resizable/resizeGesture.js +251 -0
  127. package/dist/SegmentedControl/SegmentedControl.d.ts +3 -1
  128. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  129. package/dist/SegmentedControl/SegmentedControl.js +115 -8
  130. package/dist/SegmentedControl/SegmentedControlContext.d.ts +6 -0
  131. package/dist/SegmentedControl/SegmentedControlContext.d.ts.map +1 -1
  132. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -0
  133. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  134. package/dist/SegmentedControl/SegmentedControlItem.js +10 -2
  135. package/dist/SegmentedControl/useSegmentedSelectionMotion.d.ts +357 -0
  136. package/dist/SegmentedControl/useSegmentedSelectionMotion.d.ts.map +1 -0
  137. package/dist/SegmentedControl/useSegmentedSelectionMotion.js +1349 -0
  138. package/dist/SegmentedControl/useSegmentedTouchTracking.d.ts +70 -0
  139. package/dist/SegmentedControl/useSegmentedTouchTracking.d.ts.map +1 -0
  140. package/dist/SegmentedControl/useSegmentedTouchTracking.js +264 -0
  141. package/dist/Selector/Selector.d.ts.map +1 -1
  142. package/dist/Selector/Selector.js +96 -67
  143. package/dist/Selector/optionShape.d.ts +24 -0
  144. package/dist/Selector/optionShape.d.ts.map +1 -0
  145. package/dist/Selector/optionShape.js +48 -0
  146. package/dist/Selector/selectableOptionEntries.d.ts +20 -0
  147. package/dist/Selector/selectableOptionEntries.d.ts.map +1 -0
  148. package/dist/Selector/selectableOptionEntries.js +38 -0
  149. package/dist/Selector/utils.d.ts +2 -17
  150. package/dist/Selector/utils.d.ts.map +1 -1
  151. package/dist/Selector/utils.js +3 -51
  152. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  153. package/dist/SideNav/SideNavItem.js +3 -9
  154. package/dist/Slider/sliderTouchController.js +2 -2
  155. package/dist/Switch/Switch.d.ts +1 -1
  156. package/dist/Switch/Switch.d.ts.map +1 -1
  157. package/dist/Switch/Switch.js +200 -46
  158. package/dist/Switch/switchFill.d.ts +31 -0
  159. package/dist/Switch/switchFill.d.ts.map +1 -0
  160. package/dist/Switch/switchFill.js +88 -0
  161. package/dist/Switch/switchTouch.d.ts +74 -0
  162. package/dist/Switch/switchTouch.d.ts.map +1 -0
  163. package/dist/Switch/switchTouch.js +125 -0
  164. package/dist/Switch/useSwitchTouch.d.ts +276 -0
  165. package/dist/Switch/useSwitchTouch.d.ts.map +1 -0
  166. package/dist/Switch/useSwitchTouch.js +939 -0
  167. package/dist/TabList/Tab.d.ts.map +1 -1
  168. package/dist/TabList/Tab.js +4 -3
  169. package/dist/Table/BaseTable.d.ts.map +1 -1
  170. package/dist/Table/BaseTable.js +29 -8
  171. package/dist/TextInput/TextInput.d.ts +2 -2
  172. package/dist/TextInput/TextInput.d.ts.map +1 -1
  173. package/dist/TextInput/TextInput.js +10 -7
  174. package/dist/Toast/Toast.d.ts.map +1 -1
  175. package/dist/Toast/Toast.js +5 -0
  176. package/dist/Token/Token.d.ts +2 -2
  177. package/dist/Token/Token.d.ts.map +1 -1
  178. package/dist/Token/Token.js +13 -4
  179. package/dist/Token/TokenNamingContext.d.ts +14 -0
  180. package/dist/Token/TokenNamingContext.d.ts.map +1 -0
  181. package/dist/Token/TokenNamingContext.js +23 -0
  182. package/dist/Tokenizer/Tokenizer.d.ts +46 -59
  183. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  184. package/dist/Tokenizer/Tokenizer.js +44 -60
  185. package/dist/Tokenizer/TokenizerBottomSheet.d.ts +25 -28
  186. package/dist/Tokenizer/TokenizerBottomSheet.d.ts.map +1 -1
  187. package/dist/Tokenizer/TokenizerBottomSheet.js +157 -54
  188. package/dist/Tokenizer/TokenizerItemRemovableContext.d.ts +3 -0
  189. package/dist/Tokenizer/TokenizerItemRemovableContext.d.ts.map +1 -0
  190. package/dist/Tokenizer/TokenizerItemRemovableContext.js +19 -0
  191. package/dist/Tooltip/Tooltip.d.ts +24 -5
  192. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  193. package/dist/Tooltip/Tooltip.js +29 -5
  194. package/dist/Tooltip/useTooltip.d.ts +48 -5
  195. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  196. package/dist/Tooltip/useTooltip.js +90 -20
  197. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  198. package/dist/TopNav/TopNavItem.js +4 -7
  199. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  200. package/dist/TopNav/TopNavMegaMenuItem.js +4 -7
  201. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  202. package/dist/TopNav/TopNavMenu.js +4 -7
  203. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  204. package/dist/Typeahead/Typeahead.js +26 -15
  205. package/dist/animator/createAnimator.d.ts +98 -0
  206. package/dist/animator/createAnimator.d.ts.map +1 -0
  207. package/dist/animator/createAnimator.js +259 -0
  208. package/dist/astryx.css +142 -7
  209. package/dist/gestures/GestureHost.d.ts +27 -1
  210. package/dist/gestures/GestureHost.d.ts.map +1 -1
  211. package/dist/gestures/GestureHost.js +161 -22
  212. package/dist/gestures/PressTracker.d.ts +6 -0
  213. package/dist/gestures/PressTracker.d.ts.map +1 -1
  214. package/dist/gestures/PressTracker.js +3 -0
  215. package/dist/gestures/types.d.ts +6 -0
  216. package/dist/gestures/types.d.ts.map +1 -1
  217. package/dist/gestures/usePressTracker.d.ts.map +1 -1
  218. package/dist/gestures/usePressTracker.js +1 -0
  219. package/dist/gestures/wheelSegmenter.d.ts +14 -3
  220. package/dist/gestures/wheelSegmenter.d.ts.map +1 -1
  221. package/dist/gestures/wheelSegmenter.js +32 -8
  222. package/dist/hooks/actionGroupTracker.d.ts +7 -4
  223. package/dist/hooks/actionGroupTracker.d.ts.map +1 -1
  224. package/dist/hooks/actionGroupTracker.js +19 -56
  225. package/dist/hooks/index.d.ts +1 -0
  226. package/dist/hooks/index.d.ts.map +1 -1
  227. package/dist/hooks/index.js +1 -0
  228. package/dist/hooks/pressGroupContext.d.ts +6 -0
  229. package/dist/hooks/pressGroupContext.d.ts.map +1 -0
  230. package/dist/hooks/pressGroupContext.js +20 -0
  231. package/dist/hooks/useActionGroupTracking.d.ts +53 -0
  232. package/dist/hooks/useActionGroupTracking.d.ts.map +1 -0
  233. package/dist/hooks/useActionGroupTracking.js +174 -0
  234. package/dist/hooks/useAnimator.d.ts +41 -0
  235. package/dist/hooks/useAnimator.d.ts.map +1 -0
  236. package/dist/hooks/useAnimator.js +70 -0
  237. package/dist/hooks/useAttachment.d.ts +16 -8
  238. package/dist/hooks/useAttachment.d.ts.map +1 -1
  239. package/dist/hooks/useAttachment.js +35 -15
  240. package/dist/hooks/useFocusTrap.d.ts +15 -0
  241. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  242. package/dist/hooks/useFocusTrap.js +13 -2
  243. package/dist/hooks/useHighlightedOptionScroll.d.ts +11 -1
  244. package/dist/hooks/useHighlightedOptionScroll.d.ts.map +1 -1
  245. package/dist/hooks/useHighlightedOptionScroll.js +112 -11
  246. package/dist/hooks/useInputStatusIcon.d.ts +1 -1
  247. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  248. package/dist/hooks/useInputStatusIcon.js +2 -2
  249. package/dist/hooks/useMediaQuery.d.ts +2 -1
  250. package/dist/hooks/useMediaQuery.d.ts.map +1 -1
  251. package/dist/hooks/useMediaQuery.js +7 -4
  252. package/dist/hooks/useMenuPress.d.ts.map +1 -1
  253. package/dist/hooks/useMenuPress.js +4 -2
  254. package/dist/hooks/usePager.d.ts +261 -0
  255. package/dist/hooks/usePager.d.ts.map +1 -0
  256. package/dist/hooks/usePager.js +1169 -0
  257. package/dist/i18n/generated-english/InfoTip/InfoTip.generated.d.ts +8 -0
  258. package/dist/i18n/generated-english/InfoTip/InfoTip.generated.d.ts.map +1 -0
  259. package/dist/i18n/generated-english/InfoTip/InfoTip.generated.js +12 -0
  260. package/dist/i18n/generated-english/PowerSearch/PowerSearch.generated.d.ts.map +1 -1
  261. package/dist/i18n/generated-english/PowerSearch/PowerSearch.generated.js +1 -0
  262. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts +8 -0
  263. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts.map +1 -0
  264. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.js +42 -0
  265. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.d.ts.map +1 -1
  266. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.js +6 -0
  267. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts +8 -0
  268. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts.map +1 -0
  269. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.js +14 -0
  270. package/dist/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.d.ts.map +1 -1
  271. package/dist/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.js +7 -1
  272. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  273. package/dist/i18n/generated-locales/en.generated.js +33 -1
  274. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  275. package/dist/i18n/generated-locales/pseudo.generated.js +33 -1
  276. package/dist/index.d.ts +2 -0
  277. package/dist/index.d.ts.map +1 -1
  278. package/dist/index.js +5 -0
  279. package/dist/internal/SheetConfirmation.d.ts +11 -0
  280. package/dist/internal/SheetConfirmation.d.ts.map +1 -0
  281. package/dist/internal/SheetConfirmation.js +92 -0
  282. package/dist/internal/sheetDraft.d.ts +35 -0
  283. package/dist/internal/sheetDraft.d.ts.map +1 -0
  284. package/dist/internal/sheetDraft.js +65 -0
  285. package/dist/internal/touch-sheet.d.ts +21 -0
  286. package/dist/internal/touch-sheet.d.ts.map +1 -0
  287. package/dist/internal/touch-sheet.js +19 -0
  288. package/dist/internal/useDismissSearchOnTouchDrag.d.ts +24 -0
  289. package/dist/internal/useDismissSearchOnTouchDrag.d.ts.map +1 -0
  290. package/dist/internal/useDismissSearchOnTouchDrag.js +56 -0
  291. package/dist/motion/animator.d.ts +14 -14
  292. package/dist/motion/animator.d.ts.map +1 -1
  293. package/dist/motion/animator.js +41 -18
  294. package/dist/motion/paging.d.ts +16 -5
  295. package/dist/motion/paging.d.ts.map +1 -1
  296. package/dist/motion/paging.js +34 -14
  297. package/dist/motion/reducedMotion.d.ts +24 -0
  298. package/dist/motion/reducedMotion.d.ts.map +1 -1
  299. package/dist/motion/reducedMotion.js +78 -1
  300. package/dist/motion/roles.d.ts +7 -1
  301. package/dist/motion/roles.d.ts.map +1 -1
  302. package/dist/motion/roles.js +20 -1
  303. package/dist/motion/uikit/alert.d.ts +41 -0
  304. package/dist/motion/uikit/alert.d.ts.map +1 -0
  305. package/dist/motion/uikit/alert.js +43 -0
  306. package/dist/motion/uikit/index.d.ts +7 -4
  307. package/dist/motion/uikit/index.d.ts.map +1 -1
  308. package/dist/motion/uikit/index.js +7 -4
  309. package/dist/motion/uikit/paging.d.ts +31 -20
  310. package/dist/motion/uikit/paging.d.ts.map +1 -1
  311. package/dist/motion/uikit/paging.js +41 -11
  312. package/dist/motion/uikit/progressBar.d.ts +27 -7
  313. package/dist/motion/uikit/progressBar.d.ts.map +1 -1
  314. package/dist/motion/uikit/progressBar.js +31 -11
  315. package/dist/motion/uikit/segmented.d.ts +55 -0
  316. package/dist/motion/uikit/segmented.d.ts.map +1 -0
  317. package/dist/motion/uikit/segmented.js +77 -0
  318. package/dist/motion/uikit/springs.d.ts +8 -42
  319. package/dist/motion/uikit/springs.d.ts.map +1 -1
  320. package/dist/motion/uikit/springs.js +12 -42
  321. package/dist/motion/uikit/switch.d.ts +166 -0
  322. package/dist/motion/uikit/switch.d.ts.map +1 -0
  323. package/dist/motion/uikit/switch.js +186 -0
  324. package/dist/privateAttributes/pressGroupItem.stylex.d.ts +15 -0
  325. package/dist/privateAttributes/pressGroupItem.stylex.d.ts.map +1 -0
  326. package/dist/privateAttributes/pressGroupItem.stylex.js +23 -0
  327. package/dist/privateAttributes/pressHoldsDrag.stylex.d.ts +18 -0
  328. package/dist/privateAttributes/pressHoldsDrag.stylex.d.ts.map +1 -0
  329. package/dist/privateAttributes/pressHoldsDrag.stylex.js +28 -0
  330. package/dist/privateAttributes/segmentTitle.stylex.d.ts +5 -0
  331. package/dist/privateAttributes/segmentTitle.stylex.d.ts.map +1 -0
  332. package/dist/privateAttributes/segmentTitle.stylex.js +22 -0
  333. package/dist/utils/browserClickWait.d.ts +35 -0
  334. package/dist/utils/browserClickWait.d.ts.map +1 -0
  335. package/dist/utils/browserClickWait.js +123 -0
  336. package/dist/utils/clickGuard.d.ts +14 -1
  337. package/dist/utils/clickGuard.d.ts.map +1 -1
  338. package/dist/utils/clickGuard.js +46 -1
  339. package/dist/utils/dateParser.d.ts.map +1 -1
  340. package/dist/utils/dateParser.js +12 -0
  341. package/dist/utils/interactionOverlay.stylex.d.ts +3 -2
  342. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  343. package/dist/utils/interactionOverlay.stylex.js +3 -2
  344. package/dist/utils/pressFeedback.d.ts.map +1 -1
  345. package/dist/utils/pressFeedback.js +24 -6
  346. package/locales/en.json +128 -0
  347. package/locales/pseudo.json +96 -0
  348. package/package.json +13 -8
  349. package/src/AlertDialog/AlertDialog.doc.mjs +2 -2
  350. package/src/AlertDialog/AlertDialog.tsx +37 -5
  351. package/src/AppShell/useCloseMobileDrawerOnActivate.ts +52 -0
  352. package/src/Avatar/Avatar.tsx +3 -1
  353. package/src/BottomSheet/BottomSheet.tsx +95 -10
  354. package/src/BottomSheet/BottomSheetPanel.tsx +40 -5
  355. package/src/BottomSheet/bottomSheetStack.ts +8 -4
  356. package/src/BottomSheet/useSheetGestures.ts +3 -1
  357. package/src/Breadcrumbs/BreadcrumbItem.tsx +17 -4
  358. package/src/Button/Button.tsx +66 -7
  359. package/src/CheckboxList/CheckboxList.doc.mjs +4 -2
  360. package/src/CheckboxList/CheckboxList.tsx +6 -0
  361. package/src/CheckboxList/CheckboxListContext.tsx +6 -0
  362. package/src/CheckboxList/CheckboxListItem.tsx +11 -2
  363. package/src/ComplexSelector/ComplexSelector.tsx +20 -5
  364. package/src/DateInput/DateInput.tsx +8 -2
  365. package/src/DateInput/MonthScroller.tsx +18 -22
  366. package/src/DateInput/Wheel.tsx +172 -14
  367. package/src/DateRangeInput/DateRangeInput.doc.mjs +3 -2
  368. package/src/DateRangeInput/DateRangeInput.tsx +117 -71
  369. package/src/DateTimeInput/DateTimeInput.tsx +8 -2
  370. package/src/Dialog/Dialog.tsx +81 -15
  371. package/src/Drawer/Drawer.tsx +28 -11
  372. package/src/Drawer/useDrawerDialogPresence.ts +9 -1
  373. package/src/DropdownMenu/DropdownMenu.tsx +28 -6
  374. package/src/Field/Field.tsx +2 -2
  375. package/src/Field/PanelSearchInput.tsx +11 -0
  376. package/src/HoverCard/HoverCard.tsx +31 -1
  377. package/src/Icon/Icon.doc.mjs +49 -8
  378. package/src/Icon/Icon.tsx +15 -7
  379. package/src/InfoTip/InfoTip.doc.mjs +192 -0
  380. package/src/InfoTip/InfoTip.tsx +186 -0
  381. package/src/InfoTip/index.ts +14 -0
  382. package/src/Layer/layerAnimations.stylex.ts +24 -16
  383. package/src/Layer/layerClickBoundary.ts +2 -2
  384. package/src/Layer/useBackdropPress.ts +81 -0
  385. package/src/Layer/usePressPin.ts +576 -0
  386. package/src/Layer/useTouchTrigger.ts +56 -6
  387. package/src/Lightbox/Lightbox.tsx +2 -1
  388. package/src/MobileNav/MobileNav.tsx +1 -1
  389. package/src/MultiSelector/hooks.ts +2 -4
  390. package/src/Outline/Outline.doc.mjs +177 -51
  391. package/src/Outline/Outline.tsx +5 -57
  392. package/src/Outline/useOutlineFromMarkdown.doc.mjs +157 -0
  393. package/src/Outline/useOutlineFromMarkdown.ts +1 -0
  394. package/src/Outline/useScrollSpy.ts +3 -3
  395. package/src/Popover/usePopover.tsx +71 -9
  396. package/src/PowerSearch/PowerSearch.doc.mjs +55 -6
  397. package/src/PowerSearch/PowerSearch.tsx +798 -324
  398. package/src/PowerSearch/PowerSearchBottomSheet.tsx +2515 -0
  399. package/src/PowerSearch/PowerSearchEditPopover.tsx +28 -6
  400. package/src/PowerSearch/PowerSearchValueEditor.tsx +203 -38
  401. package/src/PowerSearch/formatFilterValue.ts +18 -1
  402. package/src/PowerSearch/formatTokenValue.ts +215 -0
  403. package/src/PowerSearch/powerSearchSheetUtils.ts +224 -0
  404. package/src/ProgressBar/ProgressBar.doc.mjs +4 -2
  405. package/src/ProgressBar/ProgressBar.tsx +67 -7
  406. package/src/RadioList/RadioList.doc.mjs +4 -2
  407. package/src/RadioList/RadioList.tsx +7 -2
  408. package/src/RadioList/RadioListItem.tsx +5 -3
  409. package/src/Resizable/ResizeHandle.tsx +133 -328
  410. package/src/Resizable/resizeGesture.ts +368 -0
  411. package/src/SegmentedControl/SegmentedControl.doc.mjs +3 -3
  412. package/src/SegmentedControl/SegmentedControl.tsx +179 -5
  413. package/src/SegmentedControl/SegmentedControlContext.ts +6 -0
  414. package/src/SegmentedControl/SegmentedControlItem.tsx +14 -2
  415. package/src/SegmentedControl/useSegmentedSelectionMotion.ts +1640 -0
  416. package/src/SegmentedControl/useSegmentedTouchTracking.ts +308 -0
  417. package/src/Selector/Selector.tsx +136 -89
  418. package/src/Selector/optionShape.ts +64 -0
  419. package/src/Selector/selectableOptionEntries.ts +39 -0
  420. package/src/Selector/utils.ts +9 -68
  421. package/src/SideNav/SideNavItem.tsx +3 -7
  422. package/src/Slider/sliderTouchController.ts +2 -2
  423. package/src/Switch/Switch.doc.mjs +3 -3
  424. package/src/Switch/Switch.tsx +412 -86
  425. package/src/Switch/switchFill.ts +106 -0
  426. package/src/Switch/switchTouch.ts +186 -0
  427. package/src/Switch/useSwitchTouch.ts +1051 -0
  428. package/src/TabList/Tab.tsx +5 -3
  429. package/src/Table/BaseTable.tsx +46 -12
  430. package/src/TextInput/TextInput.tsx +11 -10
  431. package/src/Toast/Toast.tsx +5 -0
  432. package/src/Token/Token.tsx +15 -4
  433. package/src/Token/TokenNamingContext.ts +28 -0
  434. package/src/Tokenizer/Tokenizer.doc.mjs +16 -0
  435. package/src/Tokenizer/Tokenizer.tsx +93 -88
  436. package/src/Tokenizer/TokenizerBottomSheet.tsx +219 -93
  437. package/src/Tokenizer/TokenizerItemRemovableContext.ts +24 -0
  438. package/src/Tooltip/Tooltip.doc.mjs +123 -39
  439. package/src/Tooltip/Tooltip.tsx +43 -9
  440. package/src/Tooltip/useTooltip.doc.mjs +171 -31
  441. package/src/Tooltip/useTooltip.tsx +137 -22
  442. package/src/TopNav/TopNavItem.tsx +6 -5
  443. package/src/TopNav/TopNavMegaMenuItem.tsx +6 -5
  444. package/src/TopNav/TopNavMenu.tsx +6 -5
  445. package/src/Typeahead/Typeahead.tsx +29 -15
  446. package/src/animator/createAnimator.doc.mjs +153 -0
  447. package/src/animator/createAnimator.ts +324 -0
  448. package/src/gestures/GestureHost.ts +205 -21
  449. package/src/gestures/PressTracker.ts +10 -0
  450. package/src/gestures/types.ts +6 -0
  451. package/src/gestures/usePressTracker.ts +2 -0
  452. package/src/gestures/wheelSegmenter.ts +36 -7
  453. package/src/hooks/actionGroupTracker.ts +32 -61
  454. package/src/hooks/index.ts +2 -0
  455. package/src/hooks/pressGroupContext.ts +21 -0
  456. package/src/hooks/useActionGroupTracking.ts +224 -0
  457. package/src/hooks/useAnimator.doc.mjs +109 -0
  458. package/src/hooks/useAnimator.ts +67 -0
  459. package/src/hooks/useAttachment.ts +56 -14
  460. package/src/hooks/useFocusTrap.ts +26 -2
  461. package/src/hooks/useHighlightedOptionScroll.ts +123 -15
  462. package/src/hooks/useInputStatusIcon.tsx +3 -2
  463. package/src/hooks/useMediaQuery.doc.mjs +2 -2
  464. package/src/hooks/useMediaQuery.ts +13 -4
  465. package/src/hooks/useMenuPress.ts +8 -2
  466. package/src/hooks/usePager.ts +1446 -0
  467. package/src/i18n/generated-english/InfoTip/InfoTip.generated.ts +13 -0
  468. package/src/i18n/generated-english/PowerSearch/PowerSearch.generated.ts +1 -0
  469. package/src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts +43 -0
  470. package/src/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.ts +6 -0
  471. package/src/i18n/generated-english/PowerSearch/formatTokenValue.generated.ts +15 -0
  472. package/src/i18n/generated-english/Tokenizer/TokenizerBottomSheet.generated.ts +7 -1
  473. package/src/i18n/generated-locales/en.generated.ts +43 -0
  474. package/src/i18n/generated-locales/pseudo.generated.ts +44 -0
  475. package/src/index.ts +14 -0
  476. package/src/internal/SheetConfirmation.tsx +101 -0
  477. package/src/internal/sheetDraft.ts +80 -0
  478. package/src/internal/touch-sheet.ts +21 -0
  479. package/src/internal/useDismissSearchOnTouchDrag.ts +69 -0
  480. package/src/motion/MEASUREMENTS.md +36 -27
  481. package/src/motion/README.md +11 -6
  482. package/src/motion/animator.ts +61 -29
  483. package/src/motion/paging.ts +37 -14
  484. package/src/motion/reducedMotion.ts +79 -1
  485. package/src/motion/roles.ts +20 -1
  486. package/src/motion/uikit/alert.ts +43 -0
  487. package/src/motion/uikit/index.ts +6 -5
  488. package/src/motion/uikit/paging.ts +41 -10
  489. package/src/motion/uikit/progressBar.ts +31 -11
  490. package/src/motion/uikit/segmented.ts +74 -0
  491. package/src/motion/uikit/springs.ts +12 -42
  492. package/src/motion/uikit/switch.ts +174 -0
  493. package/src/privateAttributes/pressGroupItem.stylex.ts +23 -0
  494. package/src/privateAttributes/pressHoldsDrag.stylex.ts +28 -0
  495. package/src/privateAttributes/segmentTitle.stylex.ts +22 -0
  496. package/src/utils/browserClickWait.ts +133 -0
  497. package/src/utils/clickGuard.ts +64 -1
  498. package/src/utils/dateParser.ts +16 -0
  499. package/src/utils/interactionOverlay.stylex.ts +3 -2
  500. package/src/utils/pressFeedback.ts +24 -6
  501. package/dist/internal/tokenizer-presentation.d.ts +0 -21
  502. package/dist/internal/tokenizer-presentation.d.ts.map +0 -1
  503. package/dist/internal/tokenizer-presentation.js +0 -21
  504. package/src/internal/tokenizer-presentation.ts +0 -25
@@ -191,6 +191,96 @@
191
191
  "@astryx.powersearch.resultCount": {
192
192
  "defaultMessage": "⟦{count, number} {count, plural, one {result} other {results}}⟧"
193
193
  },
194
+ "@astryx.powersearch.sheet.filtersTitle": {
195
+ "defaultMessage": "⟦Ƒíłţéřš⟧"
196
+ },
197
+ "@astryx.powersearch.sheet.addFilter": {
198
+ "defaultMessage": "⟦Àðð ƒíłţéř⟧"
199
+ },
200
+ "@astryx.powersearch.sheet.noFilters": {
201
+ "defaultMessage": "⟦Ñó ƒíłţéřš àþþłíéð⟧"
202
+ },
203
+ "@astryx.powersearch.sheet.noFiltersDescription": {
204
+ "defaultMessage": "⟦Àðð à ƒíłţéř ţó ñàřřóŵ ýóúř řéšúłţš àñð ƒíñð ŵĥàţ ýóú ñééð ƒàšţéř.⟧"
205
+ },
206
+ "@astryx.powersearch.sheet.clearAll": {
207
+ "defaultMessage": "⟦Çłéàř àłł⟧"
208
+ },
209
+ "@astryx.powersearch.sheet.clearAllTitle": {
210
+ "defaultMessage": "⟦Çłéàř àłł ƒíłţéřš?⟧"
211
+ },
212
+ "@astryx.powersearch.sheet.clearAllDescription": {
213
+ "defaultMessage": "⟦Ţĥíš řéɱóṽéš àłł éðíţàƀłé ƒíłţéřš ƒřóɱ ţĥíš šéàřçĥ.⟧"
214
+ },
215
+ "@astryx.powersearch.sheet.clearAllConfirm": {
216
+ "defaultMessage": "⟦Çłéàř ƒíłţéřš⟧"
217
+ },
218
+ "@astryx.powersearch.sheet.clearAllCancel": {
219
+ "defaultMessage": "⟦Ķééþ ƒíłţéřš⟧"
220
+ },
221
+ "@astryx.powersearch.sheet.done": {
222
+ "defaultMessage": "⟦Ðóñé⟧"
223
+ },
224
+ "@astryx.powersearch.sheet.search": {
225
+ "defaultMessage": "⟦Šéàřçĥ⟧"
226
+ },
227
+ "@astryx.powersearch.sheet.searchResults": {
228
+ "defaultMessage": "⟦Šéàřçĥ řéšúłţš⟧"
229
+ },
230
+ "@astryx.powersearch.sheet.searchFields": {
231
+ "defaultMessage": "⟦Šéàřçĥ ƒíłţéřš⟧"
232
+ },
233
+ "@astryx.powersearch.sheet.searchFieldsPlaceholder": {
234
+ "defaultMessage": "⟦Šéàřçĥ ƒíłţéřš…⟧"
235
+ },
236
+ "@astryx.powersearch.sheet.ungroupedFields": {
237
+ "defaultMessage": "⟦Ĝéñéřàł⟧"
238
+ },
239
+ "@astryx.powersearch.sheet.noMatchingFields": {
240
+ "defaultMessage": "⟦Ñó ƒíłţéřš ɱàţçĥ ýóúř šéàřçĥ⟧"
241
+ },
242
+ "@astryx.powersearch.sheet.tryDifferentSearch": {
243
+ "defaultMessage": "⟦Ţřý à ð탃éřéñţ šéàřçĥ.⟧"
244
+ },
245
+ "@astryx.powersearch.sheet.noResults": {
246
+ "defaultMessage": "⟦Ñó řéšúłţš ƒóúñð⟧"
247
+ },
248
+ "@astryx.powersearch.sheet.filterUnavailable": {
249
+ "defaultMessage": "⟦Ţĥíš ƒíłţéř íš ñó łóñĝéř àṽàíłàƀłé⟧"
250
+ },
251
+ "@astryx.powersearch.sheet.removeFilter": {
252
+ "defaultMessage": "⟦Řéɱóṽé {field} ƒíłţéř⟧"
253
+ },
254
+ "@astryx.powersearch.sheet.relativeDaysAgo": {
255
+ "defaultMessage": "⟦{count, number} {count, plural, one {day} other {days}} àĝó⟧"
256
+ },
257
+ "@astryx.powersearch.sheet.relativeDaysFromNow": {
258
+ "defaultMessage": "⟦{count, number} {count, plural, one {day} other {days}} ƒřóɱ ñóŵ⟧"
259
+ },
260
+ "@astryx.powersearch.sheet.relativeWeeksAgo": {
261
+ "defaultMessage": "⟦{count, number} {count, plural, one {week} other {weeks}} àĝó⟧"
262
+ },
263
+ "@astryx.powersearch.sheet.relativeWeeksFromNow": {
264
+ "defaultMessage": "⟦{count, number} {count, plural, one {week} other {weeks}} ƒřóɱ ñóŵ⟧"
265
+ },
266
+ "@astryx.powersearch.sheet.relativeMonthsAgo": {
267
+ "defaultMessage": "⟦{count, number} {count, plural, one {month} other {months}} àĝó⟧"
268
+ },
269
+ "@astryx.powersearch.sheet.relativeMonthsFromNow": {
270
+ "defaultMessage": "⟦{count, number} {count, plural, one {month} other {months}} ƒřóɱ ñóŵ⟧"
271
+ },
272
+ "@astryx.powersearch.sheet.fieldOperator": {
273
+ "defaultMessage": "⟦{field} {operator}⟧"
274
+ },
275
+ "@astryx.powersearch.sheet.labelValue": {
276
+ "defaultMessage": "⟦{label} {value}⟧"
277
+ },
278
+ "@astryx.powersearch.sheet.filtersClearedWithCount": {
279
+ "defaultMessage": "⟦Àłł ƒíłţéřš řéɱóṽéð. {resultCount}⟧"
280
+ },
281
+ "@astryx.powersearch.sheet.editableFiltersClearedWithCount": {
282
+ "defaultMessage": "⟦Éðíţàƀłé ƒíłţéřš řéɱóṽéð. {resultCount}⟧"
283
+ },
194
284
  "@astryx.alertDialog.cancel": {
195
285
  "defaultMessage": "⟦Çàñçéł⟧"
196
286
  },
@@ -842,6 +932,9 @@
842
932
  "@astryx.powersearch.allFiltersRemoved": {
843
933
  "defaultMessage": "⟦Àłł ƒíłţéřš řéɱóṽéð⟧"
844
934
  },
935
+ "@astryx.powersearch.editableFiltersRemoved": {
936
+ "defaultMessage": "⟦Éðíţàƀłé ƒíłţéřš řéɱóṽéð⟧"
937
+ },
845
938
  "@astryx.resizable.collapsed": {
846
939
  "defaultMessage": "⟦Çółłàþšéð⟧"
847
940
  },
@@ -1702,5 +1795,8 @@
1702
1795
  },
1703
1796
  "@astryx.comments.postFailed": {
1704
1797
  "defaultMessage": "⟦Ýóúř çóɱɱéñţ çóúłðñ'ţ ƀé þóšţéð.⟧"
1798
+ },
1799
+ "@astryx.infoTip.label": {
1800
+ "defaultMessage": "⟦Ṁóřé íñƒóřɱàţíóñ⟧"
1705
1801
  }
1706
1802
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/core",
3
- "version": "0.7.7-canary.550ff21",
3
+ "version": "0.7.7-canary.58c5b8a",
4
4
  "displayName": "Astryx Core",
5
5
  "description": "The component library. Accessible, themeable React components with built-in spacing, dark mode, and StyleX styling.",
6
6
  "author": "Meta Open Source",
@@ -399,6 +399,11 @@
399
399
  "types": "./dist/Indicator/index.d.ts",
400
400
  "default": "./dist/Indicator/index.js"
401
401
  },
402
+ "./InfoTip": {
403
+ "source": "./src/InfoTip/index.ts",
404
+ "types": "./dist/InfoTip/index.d.ts",
405
+ "default": "./dist/InfoTip/index.js"
406
+ },
402
407
  "./InputGroup": {
403
408
  "source": "./src/InputGroup/index.ts",
404
409
  "types": "./dist/InputGroup/index.d.ts",
@@ -824,10 +829,10 @@
824
829
  "types": "./dist/internal/touch.d.ts",
825
830
  "default": "./dist/internal/touch.js"
826
831
  },
827
- "./internal/tokenizer-presentation": {
828
- "source": "./src/internal/tokenizer-presentation.ts",
829
- "types": "./dist/internal/tokenizer-presentation.d.ts",
830
- "default": "./dist/internal/tokenizer-presentation.js"
832
+ "./internal/touch-sheet": {
833
+ "source": "./src/internal/touch-sheet.ts",
834
+ "types": "./dist/internal/touch-sheet.d.ts",
835
+ "default": "./dist/internal/touch-sheet.js"
831
836
  }
832
837
  },
833
838
  "files": [
@@ -860,9 +865,9 @@
860
865
  "react-dom": ">=19.0.0"
861
866
  },
862
867
  "devDependencies": {
863
- "@astryxdesign/a11y-spec": "0.7.7-canary.550ff21",
864
- "@astryxdesign/cli": "0.7.7-canary.550ff21",
865
- "@astryxdesign/interaction-harness": "0.7.7-canary.550ff21",
868
+ "@astryxdesign/a11y-spec": "0.7.7-canary.58c5b8a",
869
+ "@astryxdesign/cli": "0.7.7-canary.58c5b8a",
870
+ "@astryxdesign/interaction-harness": "0.7.7-canary.58c5b8a",
866
871
  "@babel/cli": "^7.29.7",
867
872
  "@babel/core": "^7.29.7",
868
873
  "@babel/preset-react": "^7.29.7",
@@ -21,7 +21,7 @@ export const docs = {
21
21
  ],
22
22
  usage: {
23
23
  description:
24
- 'AlertDialog asks the user to confirm a destructive or irreversible action before it happens. Use it for things like deleting content, revoking access, or discarding unsaved changes.\n\nIt implements the WAI-ARIA APG [Alert Dialog pattern](https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/): `role="alertdialog"`, a title linked by `aria-labelledby`, a consequence description linked by `aria-describedby`, focus moved into the dialog on open and returned to the trigger on close, and no dismissal by clicking outside. Escape cancels.\n\nAlertDialog passes its requested width through to Dialog, which clamps the surface to the container and dynamic viewport with token gutters. Generic Dialog footers should wrap, but Dialog does not own action semantics or order; consumer composition controls that. AlertDialog owns its confirmation semantics: above 640px, actions render horizontally and may move onto another row; at 640px and below, the destructive action appears above Cancel and both buttons fill the footer width. Button labels retain their standard single-line behavior. The breakpoint follows available width, not pointer or hover capability. The body scrolls when block space is constrained.\n\nFor cases where you want to show an alert without managing open state, use the `useImperativeAlertDialog` hook: call `alert.show(options)` and render `alert.element` in your tree.',
24
+ 'AlertDialog asks the user to confirm a destructive or irreversible action before it happens. Use it for things like deleting content, revoking access, or discarding unsaved changes.\n\nIt implements the WAI-ARIA APG [Alert Dialog pattern](https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/): `role="alertdialog"`, a title linked by `aria-labelledby`, a consequence description linked by `aria-describedby`, focus moved into the dialog on open and returned to the trigger on close, and no dismissal by clicking outside. Escape cancels.\n\nAlertDialog passes its requested width through to Dialog, which clamps the surface to the container and dynamic viewport with token gutters. Generic Dialog footers should wrap, but Dialog does not own action semantics or order; consumer composition controls that. AlertDialog owns its confirmation semantics: above 640px, actions render horizontally and may move onto another row; at 640px and below, the destructive action appears above Cancel and both buttons fill the footer width. Button labels retain their standard single-line behavior. The breakpoint follows available width, not pointer or hover capability. The body scrolls when block space is constrained.\n\nThe two actions are tracked as one group under every pointer, the way iOS tracks the actions of an alert: the action under the pointer highlights as soon as it is pressed, the highlight follows the pointer from one action to the other, and the release runs the action under it. Releasing off both actions runs nothing. The keyboard and assistive technology keep the click of each button.\n\nFor cases where you want to show an alert without managing open state, use the `useImperativeAlertDialog` hook: call `alert.show(options)` and render `alert.element` in your tree.',
25
25
  bestPractices: [
26
26
  {
27
27
  guidance: true,
@@ -196,7 +196,7 @@ export const docsDense = {
196
196
  'Confirms destructive/irreversible action before it happens (delete, revoke access, discard unsaved changes).',
197
197
  usage: {
198
198
  description:
199
- 'AlertDialog confirms destructive/irreversible action (delete, revoke access, discard changes). Implements WAI-ARIA APG Alert Dialog pattern (https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/): role="alertdialog", aria-labelledby title, aria-describedby description, focus into dialog on open + back to trigger on close, no outside-click dismissal, Escape cancels. Dialog preserves requested width + clamps it to container/dynamic viewport gutters. Generic Dialog footers wrap while consumers own action order. AlertDialog owns confirmation action layout: >640px horizontal buttons may move to another row; <=640px puts the destructive action above Cancel and makes both buttons full width regardless of pointer/hover capability. Button labels remain single-line. Body scrolls when height constrained. To show w/o managing open state, use useImperativeAlertDialog hook: call alert.show(options) + render alert.element in tree.',
199
+ 'AlertDialog confirms destructive/irreversible action (delete, revoke access, discard changes). Implements WAI-ARIA APG Alert Dialog pattern (https://www.w3.org/WAI/ARIA/apg/patterns/alertdialog/): role="alertdialog", aria-labelledby title, aria-describedby description, focus into dialog on open + back to trigger on close, no outside-click dismissal, Escape cancels. Dialog preserves requested width + clamps it to container/dynamic viewport gutters. Generic Dialog footers wrap while consumers own action order. AlertDialog owns confirmation action layout: >640px horizontal buttons may move to another row; <=640px puts the destructive action above Cancel and makes both buttons full width regardless of pointer/hover capability. Button labels remain single-line. Body scrolls when height constrained. Every pointer: both actions tracked as one group like iOS alerts (action under pointer highlights at once, highlight follows pointer between actions, release runs action under pointer, release off both runs nothing); keyboard/AT keep each button click. To show w/o managing open state, use useImperativeAlertDialog hook: call alert.show(options) + render alert.element in tree.',
200
200
  bestPractices: [
201
201
  {
202
202
  guidance: true,
@@ -4,7 +4,9 @@
4
4
 
5
5
  /**
6
6
  * @file AlertDialog.tsx
7
- * @input Uses React, StyleX, Dialog, Layout, Heading, Text, Button
7
+ * @input Uses React, StyleX, Dialog, Layout, Heading, Text, Button, the
8
+ * action-group tracking (hooks/useActionGroupTracking) and the press-group
9
+ * marker (privateAttributes/pressGroupItem.stylex)
8
10
  * @output Exports AlertDialog component, AlertDialogProps type
9
11
  * @position Core implementation; consumed by index.ts, tested by AlertDialog.test.tsx
10
12
  *
@@ -12,11 +14,12 @@
12
14
  * - /packages/core/src/AlertDialog/AlertDialog.doc.mjs (props table, features, examples)
13
15
  * - /packages/core/src/AlertDialog/AlertDialog.test.tsx (tests for new/changed behavior)
14
16
  * - /packages/core/src/AlertDialog/index.ts (exports if types change)
17
+ * - /packages/core/src/AlertDialog/__tests__/AlertDialog.interaction.browser.spec.ts (touch tracking)
15
18
  * - /apps/storybook/stories/AlertDialog.stories.tsx (storybook stories)
16
19
  * - /packages/cli/assets/templates/blocks/components/AlertDialog/ (showcase blocks)
17
20
  */
18
21
 
19
- import React, {useId, useCallback} from 'react';
22
+ import React, {useId, useCallback, useRef} from 'react';
20
23
  import * as stylex from '@stylexjs/stylex';
21
24
  import {Dialog} from '../Dialog/Dialog';
22
25
  import {Layout} from '../Layout/Layout';
@@ -36,12 +39,22 @@ import {
36
39
  useComponentTranslator,
37
40
  } from '../i18n/useComponentTranslator';
38
41
  import english from '../i18n/generated-english/AlertDialog/AlertDialog.generated';
42
+ import {useActionGroupTracking} from '../hooks/useActionGroupTracking';
43
+ import {PressGroupContext} from '../hooks/pressGroupContext';
44
+ import {alertController} from '../motion/uikit/alert';
45
+ import {pressGroupItemProps} from '../privateAttributes/pressGroupItem.stylex';
39
46
 
40
47
  registerEnglishFallback(english);
41
48
 
42
49
  const SMALL_SCREEN_QUERY = '(max-width: 640px)';
43
50
 
44
51
  const styles = stylex.create({
52
+ // The browser may pinch-zoom on the actions but never pans there. Chrome on
53
+ // Android cancels a pointer it pans, which would cancel the group's press.
54
+ // The gesture host keeps an author's narrower touch-action.
55
+ trackingRow: {
56
+ touchAction: 'pinch-zoom',
57
+ },
45
58
  action: {
46
59
  maxWidth: '100%',
47
60
  minWidth: 0,
@@ -177,6 +190,19 @@ export function AlertDialog({
177
190
  onOpenChange(false);
178
191
  }, [onOpenChange]);
179
192
 
193
+ // Each action carries the press-group marker from its first render, so the
194
+ // tracker is its only painter.
195
+ const actionsRef = useRef<HTMLElement>(null);
196
+ const isTracking = isOpen && isInline !== true;
197
+ useActionGroupTracking(actionsRef, {
198
+ // The actions row holds only the two buttons.
199
+ itemSelector: 'button',
200
+ highlightOnsetMs: alertController.actions.highlightOnsetMs,
201
+ highlightExpansion: alertController.actions.highlightExpansion,
202
+ isEnabled: isTracking,
203
+ });
204
+ const actionTrackingProps = isTracking ? pressGroupItemProps : undefined;
205
+
180
206
  const buttonActionStyle = [
181
207
  styles.action,
182
208
  isSmallScreen && styles.stackedAction,
@@ -188,6 +214,7 @@ export function AlertDialog({
188
214
  label={cancelLabel}
189
215
  onClick={handleCancel}
190
216
  xstyle={buttonActionStyle}
217
+ {...actionTrackingProps}
191
218
  // Dialog focuses [data-autofocus] itself after showModal(), because
192
219
  // React's autoFocus runs during commit while the dialog is invisible.
193
220
  // Cancel is least destructive, so it remains the autofocus target even
@@ -203,6 +230,7 @@ export function AlertDialog({
203
230
  onClick={onAction}
204
231
  isLoading={isActionLoading}
205
232
  xstyle={buttonActionStyle}
233
+ {...actionTrackingProps}
206
234
  />
207
235
  );
208
236
 
@@ -244,13 +272,17 @@ export function AlertDialog({
244
272
  destructive-above-Cancel narrow order because confirmation
245
273
  actions have component-specific meaning here. */}
246
274
  <Stack
275
+ ref={actionsRef}
276
+ xstyle={isTracking && styles.trackingRow}
247
277
  direction={isSmallScreen ? 'vertical' : 'horizontal'}
248
278
  gap={2}
249
279
  hAlign={isSmallScreen ? 'stretch' : 'end'}
250
280
  wrap={isSmallScreen ? 'nowrap' : 'wrap'}>
251
- {isSmallScreen
252
- ? [actionButton, cancelButton]
253
- : [cancelButton, actionButton]}
281
+ <PressGroupContext value={isTracking}>
282
+ {isSmallScreen
283
+ ? [actionButton, cancelButton]
284
+ : [cancelButton, actionButton]}
285
+ </PressGroupContext>
254
286
  </Stack>
255
287
  </LayoutFooter>
256
288
  }
@@ -0,0 +1,52 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file useCloseMobileDrawerOnActivate.ts
7
+ * @input AppShellMobileContext, TopNav and SideNav render modes
8
+ * @output useCloseMobileDrawerOnActivate, useIsInAppShellMobileDrawer
9
+ * @position Internal AppShell helper for rows in the mobile drawer. Not
10
+ * exported from the package.
11
+ */
12
+
13
+ import {useAppShellMobile} from './AppShellMobileContext';
14
+ import {useSideNavRenderMode} from '../SideNav/SideNavRenderContext';
15
+ import {useTopNavRenderMode} from '../TopNav/TopNavRenderContext';
16
+
17
+ /**
18
+ * Returns a function that wraps a row's click handler. While
19
+ * `isInMobileDrawer` is true, the wrapped handler calls the row's handler and
20
+ * then closes the AppShell mobile drawer. Otherwise the row's handler comes
21
+ * back unchanged. Every drawer row closes the drawer through this one rule.
22
+ */
23
+ export function useCloseMobileDrawerOnActivate(
24
+ isInMobileDrawer: boolean,
25
+ ): <Args extends unknown[]>(
26
+ onClick: ((...args: Args) => void) | undefined,
27
+ ) => ((...args: Args) => void) | undefined {
28
+ const {closeMobileNav} = useAppShellMobile();
29
+ return onClick => {
30
+ if (!isInMobileDrawer) {
31
+ return onClick;
32
+ }
33
+ return (...args) => {
34
+ onClick?.(...args);
35
+ closeMobileNav();
36
+ };
37
+ };
38
+ }
39
+
40
+ /**
41
+ * Whether the caller renders inside the AppShell mobile drawer: in TopNav
42
+ * content or SideNav content shown there.
43
+ */
44
+ export function useIsInAppShellMobileDrawer(): boolean {
45
+ const topNavRenderMode = useTopNavRenderMode();
46
+ const sideNavRenderMode = useSideNavRenderMode();
47
+ return (
48
+ topNavRenderMode === 'drawer' ||
49
+ sideNavRenderMode === 'drawer' ||
50
+ sideNavRenderMode === 'drawer-content'
51
+ );
52
+ }
@@ -824,7 +824,9 @@ export function Avatar({
824
824
  </div>
825
825
  )}
826
826
  </div>
827
- {status && (
827
+ {/* The status slot renders for a truthy value only. A falsy one, 0
828
+ included, renders nothing, not a stray "0". */}
829
+ {Boolean(status) && (
828
830
  <div
829
831
  {...stylex.props(
830
832
  styles.status,
@@ -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) {