@astryxdesign/core 0.7.5 → 0.7.6-canary.00507ba

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 (595) hide show
  1. package/dist/AlertDialog/AlertDialog.d.ts +1 -1
  2. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  3. package/dist/AlertDialog/AlertDialog.js +5 -5
  4. package/dist/AppShell/AppShell.d.ts.map +1 -1
  5. package/dist/AppShell/AppShell.js +183 -5
  6. package/dist/AppShell/observeMainOverflow.d.ts +9 -0
  7. package/dist/AppShell/observeMainOverflow.d.ts.map +1 -0
  8. package/dist/AppShell/observeMainOverflow.js +125 -0
  9. package/dist/Avatar/Avatar.d.ts.map +1 -1
  10. package/dist/Avatar/Avatar.js +12 -3
  11. package/dist/Badge/Badge.d.ts.map +1 -1
  12. package/dist/Badge/Badge.js +7 -1
  13. package/dist/BottomSheet/BottomSheet.js +1 -1
  14. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  15. package/dist/BottomSheet/BottomSheetPanel.js +2 -1
  16. package/dist/BottomSheet/useSheetGestures.d.ts +12 -0
  17. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  18. package/dist/BottomSheet/useSheetGestures.js +30 -3
  19. package/dist/Button/Button.js +4 -4
  20. package/dist/Carousel/Carousel.d.ts +3 -1
  21. package/dist/Carousel/Carousel.d.ts.map +1 -1
  22. package/dist/Carousel/Carousel.js +12 -3
  23. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  24. package/dist/CheckboxInput/CheckboxInput.js +6 -5
  25. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  26. package/dist/ClickableCard/ClickableCard.js +37 -4
  27. package/dist/DateInput/DateInput.d.ts.map +1 -1
  28. package/dist/DateInput/DateInput.js +12 -4
  29. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  30. package/dist/DateInput/MonthScroller.js +101 -15
  31. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  32. package/dist/DateInput/TouchDateField.js +8 -3
  33. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  34. package/dist/DateRangeInput/DateRangeInput.js +1 -1
  35. package/dist/DateTimeInput/DateTimeInput.d.ts +5 -2
  36. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  37. package/dist/DateTimeInput/DateTimeInput.js +23 -12
  38. package/dist/DateTimeInput/NativeTimeSegment.d.ts.map +1 -1
  39. package/dist/DateTimeInput/NativeTimeSegment.js +5 -4
  40. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  41. package/dist/DateTimeInput/TouchDateTimeField.js +4 -3
  42. package/dist/Dialog/Dialog.d.ts.map +1 -1
  43. package/dist/Dialog/Dialog.js +34 -9
  44. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  45. package/dist/Dialog/DialogHeader.js +5 -4
  46. package/dist/Divider/Divider.d.ts.map +1 -1
  47. package/dist/Divider/Divider.js +2 -1
  48. package/dist/Drawer/Drawer.d.ts +1 -0
  49. package/dist/Drawer/Drawer.d.ts.map +1 -1
  50. package/dist/Drawer/Drawer.js +7 -2
  51. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  52. package/dist/DropdownMenu/DropdownMenu.js +7 -3
  53. package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -1
  54. package/dist/DropdownMenu/MenuBottomSheetActionList.js +6 -5
  55. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +20 -2
  56. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
  57. package/dist/DropdownMenu/lazyMenuBottomSheet.js +31 -3
  58. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  59. package/dist/DropdownMenu/renderDropdownItems.js +21 -16
  60. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  61. package/dist/EmptyState/EmptyState.js +2 -1
  62. package/dist/Field/FieldLabel.d.ts +1 -1
  63. package/dist/Field/FieldLabel.d.ts.map +1 -1
  64. package/dist/Field/FieldLabel.js +4 -4
  65. package/dist/Field/InputClearButton.js +3 -3
  66. package/dist/Field/PanelSearchInput.js +2 -2
  67. package/dist/FieldStatus/FieldStatus.js +2 -2
  68. package/dist/FileInput/FileInput.d.ts.map +1 -1
  69. package/dist/FileInput/FileInput.js +7 -1
  70. package/dist/Heading/Heading.js +1 -1
  71. package/dist/Icon/Icon.js +1 -1
  72. package/dist/Indicator/CheckIndicator.d.ts.map +1 -1
  73. package/dist/Indicator/CheckIndicator.js +2 -1
  74. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  75. package/dist/Indicator/CheckboxIndicator.js +3 -1
  76. package/dist/Indicator/RadioIndicator.d.ts.map +1 -1
  77. package/dist/Indicator/RadioIndicator.js +3 -1
  78. package/dist/Item/Item.d.ts.map +1 -1
  79. package/dist/Item/Item.js +2 -1
  80. package/dist/Item/ItemSwipeLayer.js +1 -1
  81. package/dist/Layer/popoverOperations.d.ts +27 -0
  82. package/dist/Layer/popoverOperations.d.ts.map +1 -0
  83. package/dist/Layer/popoverOperations.js +159 -0
  84. package/dist/Layer/useLayer.d.ts +1 -1
  85. package/dist/Layer/useLayer.d.ts.map +1 -1
  86. package/dist/Layer/useLayer.js +93 -59
  87. package/dist/Layout/Layout.js +1 -1
  88. package/dist/Layout/LayoutContent.js +1 -1
  89. package/dist/Layout/LayoutFooter.js +1 -1
  90. package/dist/Layout/LayoutHeader.js +1 -1
  91. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  92. package/dist/Lightbox/Lightbox.js +5 -0
  93. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.js +5 -4
  94. package/dist/List/List.js +1 -1
  95. package/dist/List/ListItem.js +3 -3
  96. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  97. package/dist/MobileNav/MobileNav.js +7 -2
  98. package/dist/MultiSelector/CreateRow.a11y.chromium.spec.js +7 -6
  99. package/dist/MultiSelector/MultiSelector.d.ts +1 -1
  100. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  101. package/dist/MultiSelector/MultiSelector.js +26 -10
  102. package/dist/NumberInput/NumberInput.d.ts +3 -1
  103. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  104. package/dist/NumberInput/NumberInput.js +3 -3
  105. package/dist/NumberInput/numberParser.d.ts +3 -0
  106. package/dist/NumberInput/numberParser.d.ts.map +1 -1
  107. package/dist/NumberInput/numberParser.js +7 -44
  108. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  109. package/dist/ProgressBar/ProgressBar.js +16 -12
  110. package/dist/Resizable/useResizable.d.ts.map +1 -1
  111. package/dist/Resizable/useResizable.js +28 -2
  112. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  113. package/dist/SegmentedControl/SegmentedControlItem.js +4 -1
  114. package/dist/Selector/useSelectorPresentation.d.ts +8 -1
  115. package/dist/Selector/useSelectorPresentation.d.ts.map +1 -1
  116. package/dist/Selector/useSelectorPresentation.js +20 -4
  117. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  118. package/dist/Skeleton/Skeleton.js +1 -1
  119. package/dist/Slider/Slider.d.ts.map +1 -1
  120. package/dist/Slider/Slider.js +10 -2
  121. package/dist/Spinner/Spinner.d.ts.map +1 -1
  122. package/dist/Spinner/Spinner.js +3 -3
  123. package/dist/Stack/Stack.js +1 -1
  124. package/dist/Stack/StackItem.js +1 -1
  125. package/dist/TabList/TabList.d.ts.map +1 -1
  126. package/dist/TabList/TabList.js +16 -1
  127. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  128. package/dist/Table/plugins/columnResize/useTableColumnResize.js +9 -1
  129. package/dist/Text/Text.js +1 -1
  130. package/dist/Text/useTruncation.d.ts.map +1 -1
  131. package/dist/Text/useTruncation.js +23 -5
  132. package/dist/TextArea/TextArea.d.ts +1 -1
  133. package/dist/TextArea/TextArea.d.ts.map +1 -1
  134. package/dist/TextArea/TextArea.js +13 -2
  135. package/dist/TextInput/TextInput.d.ts.map +1 -1
  136. package/dist/TextInput/TextInput.js +3 -3
  137. package/dist/TimeInput/TimeInput.d.ts +6 -2
  138. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  139. package/dist/TimeInput/TimeInput.js +21 -14
  140. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
  141. package/dist/TimeInput/TouchTimeField.js +5 -4
  142. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  143. package/dist/Timestamp/Timestamp.js +2 -2
  144. package/dist/Timestamp/TimestampHoverCard.js +4 -4
  145. package/dist/Toast/Toast.d.ts.map +1 -1
  146. package/dist/Toast/Toast.js +60 -20
  147. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  148. package/dist/Toast/ToastViewport.js +82 -51
  149. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  150. package/dist/Tokenizer/Tokenizer.js +13 -2
  151. package/dist/Tokenizer/TokenizerBottomSheet.js +3 -3
  152. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  153. package/dist/Toolbar/Toolbar.js +2 -1
  154. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  155. package/dist/TopNav/TopNavMegaMenu.js +3 -0
  156. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  157. package/dist/TopNav/TopNavMenu.js +1 -0
  158. package/dist/Typeahead/Typeahead.d.ts +1 -1
  159. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  160. package/dist/Typeahead/Typeahead.js +9 -1
  161. package/dist/astryx.css +21 -4
  162. package/dist/gestures/GestureArena.d.ts +6 -0
  163. package/dist/gestures/GestureArena.d.ts.map +1 -1
  164. package/dist/gestures/GestureArena.js +39 -0
  165. package/dist/gestures/GestureHost.d.ts +352 -0
  166. package/dist/gestures/GestureHost.d.ts.map +1 -0
  167. package/dist/gestures/GestureHost.js +1773 -0
  168. package/dist/gestures/GestureRecognizer.d.ts +10 -0
  169. package/dist/gestures/GestureRecognizer.d.ts.map +1 -1
  170. package/dist/gestures/GestureRecognizer.js +16 -0
  171. package/dist/gestures/LongPressGestureRecognizer.d.ts +1 -0
  172. package/dist/gestures/LongPressGestureRecognizer.d.ts.map +1 -1
  173. package/dist/gestures/LongPressGestureRecognizer.js +3 -0
  174. package/dist/gestures/PanGestureRecognizer.d.ts +1 -0
  175. package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -1
  176. package/dist/gestures/PanGestureRecognizer.js +3 -0
  177. package/dist/gestures/PinchGestureRecognizer.d.ts +31 -0
  178. package/dist/gestures/PinchGestureRecognizer.d.ts.map +1 -0
  179. package/dist/gestures/PinchGestureRecognizer.js +128 -0
  180. package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts +71 -0
  181. package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts.map +1 -0
  182. package/dist/gestures/ScreenEdgePanGestureRecognizer.js +223 -0
  183. package/dist/gestures/SwipeGestureRecognizer.d.ts +37 -0
  184. package/dist/gestures/SwipeGestureRecognizer.d.ts.map +1 -0
  185. package/dist/gestures/SwipeGestureRecognizer.js +148 -0
  186. package/dist/gestures/TapGestureRecognizer.d.ts +1 -0
  187. package/dist/gestures/TapGestureRecognizer.d.ts.map +1 -1
  188. package/dist/gestures/TapGestureRecognizer.js +3 -0
  189. package/dist/gestures/VelocityTracker.d.ts +6 -2
  190. package/dist/gestures/VelocityTracker.d.ts.map +1 -1
  191. package/dist/gestures/VelocityTracker.js +7 -3
  192. package/dist/gestures/haptics.d.ts +65 -0
  193. package/dist/gestures/haptics.d.ts.map +1 -0
  194. package/dist/gestures/haptics.js +182 -0
  195. package/dist/gestures/nativeScroll.d.ts +42 -0
  196. package/dist/gestures/nativeScroll.d.ts.map +1 -0
  197. package/dist/gestures/nativeScroll.js +228 -0
  198. package/dist/gestures/touchAction.d.ts +60 -0
  199. package/dist/gestures/touchAction.d.ts.map +1 -0
  200. package/dist/gestures/touchAction.js +157 -0
  201. package/dist/gestures/touchActionRule.d.ts +34 -0
  202. package/dist/gestures/touchActionRule.d.ts.map +1 -0
  203. package/dist/gestures/touchActionRule.js +140 -0
  204. package/dist/gestures/types.d.ts +18 -7
  205. package/dist/gestures/types.d.ts.map +1 -1
  206. package/dist/gestures/types.js +22 -2
  207. package/dist/hooks/index.d.ts +1 -1
  208. package/dist/hooks/index.d.ts.map +1 -1
  209. package/dist/hooks/modalAnnounce.d.ts.map +1 -1
  210. package/dist/hooks/modalAnnounce.js +107 -61
  211. package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -1
  212. package/dist/hooks/scrollKeyboardDelegation.js +7 -3
  213. package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -1
  214. package/dist/hooks/useAdaptivePresentation.js +4 -1
  215. package/dist/hooks/useAnnounce.d.ts +101 -42
  216. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  217. package/dist/hooks/useAnnounce.js +161 -75
  218. package/dist/hooks/useAnnounceRenderedText.d.ts +11 -3
  219. package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
  220. package/dist/hooks/useAnnounceRenderedText.js +5 -3
  221. package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
  222. package/dist/hooks/useBusyAnnouncement.js +6 -12
  223. package/dist/hooks/useMenuHover.d.ts.map +1 -1
  224. package/dist/hooks/useMenuHover.js +12 -1
  225. package/dist/hooks/useScrollOverflow.d.ts +2 -1
  226. package/dist/hooks/useScrollOverflow.d.ts.map +1 -1
  227. package/dist/hooks/useScrollOverflow.js +56 -10
  228. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  229. package/dist/i18n/generated-locales/en.generated.js +6 -0
  230. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  231. package/dist/i18n/generated-locales/pseudo.generated.js +6 -0
  232. package/dist/motion/animator.d.ts +7 -1
  233. package/dist/motion/animator.d.ts.map +1 -1
  234. package/dist/motion/animator.js +119 -27
  235. package/dist/theme/defineTheme.d.ts +19 -5
  236. package/dist/theme/defineTheme.d.ts.map +1 -1
  237. package/dist/theme/defineTheme.js +64 -4
  238. package/dist/theme/domainTokens/domainTokenDefaults.d.ts +3 -0
  239. package/dist/theme/domainTokens/domainTokenDefaults.d.ts.map +1 -0
  240. package/dist/theme/domainTokens/domainTokenDefaults.js +19 -0
  241. package/dist/theme/domainTokens/index.d.ts +5 -4
  242. package/dist/theme/domainTokens/index.d.ts.map +1 -1
  243. package/dist/theme/domainTokens/index.js +5 -9
  244. package/dist/theme/index.d.ts +1 -0
  245. package/dist/theme/index.d.ts.map +1 -1
  246. package/dist/theme/motionKnobs.d.ts +56 -0
  247. package/dist/theme/motionKnobs.d.ts.map +1 -0
  248. package/dist/theme/motionKnobs.js +48 -0
  249. package/dist/theme/resolveThemeValues.d.ts +11 -4
  250. package/dist/theme/resolveThemeValues.d.ts.map +1 -1
  251. package/dist/theme/resolveThemeValues.js +40 -4
  252. package/dist/theme/themeAdaptations.d.ts +7 -3
  253. package/dist/theme/themeAdaptations.d.ts.map +1 -1
  254. package/dist/theme/themeAdaptations.js +36 -7
  255. package/dist/theme/themeMotion.d.ts +96 -0
  256. package/dist/theme/themeMotion.d.ts.map +1 -0
  257. package/dist/theme/themeMotion.js +177 -0
  258. package/dist/theme/tokenReferences.d.ts +31 -0
  259. package/dist/theme/tokenReferences.d.ts.map +1 -0
  260. package/dist/theme/tokenReferences.js +132 -0
  261. package/dist/theme/tokens.d.ts +1 -0
  262. package/dist/theme/tokens.d.ts.map +1 -1
  263. package/dist/theme/tokens.js +9 -129
  264. package/dist/theme/tokens.stylex.d.ts +12 -0
  265. package/dist/theme/tokens.stylex.d.ts.map +1 -1
  266. package/dist/theme/tokens.stylex.js +12 -0
  267. package/dist/utils/focusReturn.d.ts +17 -1
  268. package/dist/utils/focusReturn.d.ts.map +1 -1
  269. package/dist/utils/focusReturn.js +11 -4
  270. package/dist/utils/getNodeText.d.ts +8 -0
  271. package/dist/utils/getNodeText.d.ts.map +1 -0
  272. package/dist/utils/getNodeText.js +37 -0
  273. package/dist/utils/interactionModality.d.ts +11 -2
  274. package/dist/utils/interactionModality.d.ts.map +1 -1
  275. package/dist/utils/interactionModality.js +58 -5
  276. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  277. package/dist/utils/interactionOverlay.stylex.js +17 -8
  278. package/dist/utils/plainDate.d.ts +2 -0
  279. package/dist/utils/plainDate.d.ts.map +1 -1
  280. package/dist/utils/plainDate.js +46 -3
  281. package/dist/utils/presentation.d.ts +50 -0
  282. package/dist/utils/presentation.d.ts.map +1 -0
  283. package/dist/utils/presentation.js +125 -0
  284. package/dist/utils/pressFeedback.d.ts.map +1 -1
  285. package/dist/utils/pressFeedback.js +20 -1
  286. package/dist/utils/primaryClick.d.ts +11 -0
  287. package/dist/utils/primaryClick.d.ts.map +1 -0
  288. package/dist/utils/primaryClick.js +25 -0
  289. package/dist/utils/sharedMutationObserver.d.ts +19 -11
  290. package/dist/utils/sharedMutationObserver.d.ts.map +1 -1
  291. package/dist/utils/sharedMutationObserver.js +66 -26
  292. package/dist/utils/timeFormat.d.ts +47 -0
  293. package/dist/utils/timeFormat.d.ts.map +1 -0
  294. package/dist/utils/timeFormat.js +240 -0
  295. package/dist/utils/touchPresentation.d.ts.map +1 -1
  296. package/dist/utils/touchPresentation.js +5 -3
  297. package/dist/utils/touchPresentation.stylex.d.ts +15 -0
  298. package/dist/utils/touchPresentation.stylex.d.ts.map +1 -0
  299. package/dist/utils/touchPresentation.stylex.js +33 -0
  300. package/dist/utils/unicodeDigits.d.ts +20 -0
  301. package/dist/utils/unicodeDigits.d.ts.map +1 -0
  302. package/dist/utils/unicodeDigits.js +70 -0
  303. package/locales/en.json +27 -3
  304. package/locales/pseudo.json +18 -0
  305. package/package.json +5 -4
  306. package/src/AlertDialog/AlertDialog.tsx +6 -5
  307. package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +18 -6
  308. package/src/AppShell/AppShell.doc.mjs +1 -1
  309. package/src/AppShell/AppShell.spec.md +9 -12
  310. package/src/AppShell/AppShell.test.tsx +164 -2
  311. package/src/AppShell/AppShell.tsx +225 -5
  312. package/src/AppShell/__tests__/AppShellMainKeyboard.a11y.browser.spec.ts +534 -0
  313. package/src/AppShell/observeMainOverflow.test.ts +173 -0
  314. package/src/AppShell/observeMainOverflow.ts +143 -0
  315. package/src/Avatar/Avatar.spec.md +22 -22
  316. package/src/Avatar/Avatar.tsx +18 -1
  317. package/src/Avatar/__tests__/AvatarForcedColors.a11y.chromium.spec.ts +126 -0
  318. package/src/Badge/Badge.doc.mjs +1 -1
  319. package/src/Badge/Badge.tsx +19 -2
  320. package/src/Badge/__tests__/BadgeLargerText.a11y.chromium.spec.ts +260 -0
  321. package/src/BottomSheet/BottomSheet.test.tsx +46 -0
  322. package/src/BottomSheet/BottomSheet.tsx +1 -1
  323. package/src/BottomSheet/BottomSheetPanel.tsx +2 -1
  324. package/src/BottomSheet/useSheetGestures.test.ts +52 -0
  325. package/src/BottomSheet/useSheetGestures.ts +37 -6
  326. package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.chromium.spec.ts +18 -6
  327. package/src/Button/Button.tsx +4 -4
  328. package/src/Calendar/Calendar.spec.md +87 -48
  329. package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +21 -7
  330. package/src/Carousel/Carousel.doc.mjs +1 -1
  331. package/src/Carousel/Carousel.spec.md +9 -9
  332. package/src/Carousel/Carousel.test.tsx +124 -3
  333. package/src/Carousel/Carousel.tsx +10 -2
  334. package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +21 -7
  335. package/src/Carousel/__tests__/Carousel.a11y.known-failures.ts +1 -16
  336. package/src/Chat/ChatComposerTokenElement.spec.md +45 -33
  337. package/src/CheckboxInput/CheckboxInput.tsx +6 -5
  338. package/src/ClickableCard/ClickableCard.test.tsx +96 -0
  339. package/src/ClickableCard/ClickableCard.tsx +48 -4
  340. package/src/Collapsible/Collapsible.spec.md +2 -0
  341. package/src/Collapsible/CollapsibleGroup.spec.md +57 -29
  342. package/src/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts +18 -7
  343. package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +18 -6
  344. package/src/ComplexSelector/ComplexSelector.test.tsx +37 -0
  345. package/src/ContextMenu/ContextMenu.test.tsx +35 -0
  346. package/src/DateInput/DateInput.test.tsx +115 -3
  347. package/src/DateInput/DateInput.tsx +29 -14
  348. package/src/DateInput/DateInputTouch.test.tsx +76 -0
  349. package/src/DateInput/MonthScroller.tsx +106 -20
  350. package/src/DateInput/MonthScrollerSettle.test.tsx +165 -0
  351. package/src/DateInput/TouchDateField.tsx +14 -3
  352. package/src/DateInput/__tests__/MonthScrollerSteps.interaction.browser.spec.ts +312 -0
  353. package/src/DateRangeInput/DateRangeInput.test.tsx +46 -3
  354. package/src/DateRangeInput/DateRangeInput.tsx +16 -12
  355. package/src/DateTimeInput/DateTimeInput.doc.mjs +10 -8
  356. package/src/DateTimeInput/DateTimeInput.spec.md +75 -51
  357. package/src/DateTimeInput/DateTimeInput.test.tsx +81 -0
  358. package/src/DateTimeInput/DateTimeInput.tsx +46 -24
  359. package/src/DateTimeInput/NativeTimeSegment.tsx +4 -6
  360. package/src/DateTimeInput/TouchDateTimeField.tsx +3 -7
  361. package/src/Dialog/Dialog.test.tsx +216 -2
  362. package/src/Dialog/Dialog.tsx +42 -9
  363. package/src/Dialog/DialogHeader.tsx +5 -4
  364. package/src/Dialog/__tests__/DialogSecondDocument.a11y.browser.spec.ts +202 -0
  365. package/src/Divider/Divider.tsx +2 -1
  366. package/src/Drawer/Drawer.spec.md +111 -80
  367. package/src/Drawer/Drawer.test.tsx +35 -0
  368. package/src/Drawer/Drawer.tsx +13 -2
  369. package/src/Drawer/DrawerHeader.spec.md +181 -0
  370. package/src/Drawer/__tests__/DrawerNonModalPageScroll.a11y.chromium.spec.ts +267 -0
  371. package/src/DropdownMenu/DropdownMenu.test.tsx +41 -0
  372. package/src/DropdownMenu/DropdownMenu.tsx +10 -3
  373. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +34 -0
  374. package/src/DropdownMenu/MenuBottomSheetActionList.tsx +6 -5
  375. package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +19 -7
  376. package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +21 -9
  377. package/src/DropdownMenu/lazyMenuBottomSheet.test.ts +60 -0
  378. package/src/DropdownMenu/lazyMenuBottomSheet.ts +36 -7
  379. package/src/DropdownMenu/renderDropdownItems.tsx +24 -19
  380. package/src/EmptyState/EmptyState.tsx +2 -1
  381. package/src/Field/FieldLabel.tsx +5 -4
  382. package/src/Field/InputClearButton.tsx +3 -3
  383. package/src/Field/PanelSearchInput.tsx +2 -2
  384. package/src/FieldStatus/FieldStatus.tsx +2 -2
  385. package/src/FileInput/FileInput.test.tsx +21 -0
  386. package/src/FileInput/FileInput.tsx +4 -1
  387. package/src/FormLayout/FormLayout.spec.md +7 -8
  388. package/src/Heading/Heading.tsx +1 -1
  389. package/src/Icon/Icon.tsx +1 -1
  390. package/src/Indicator/CheckIndicator.spec.md +47 -42
  391. package/src/Indicator/CheckIndicator.tsx +2 -1
  392. package/src/Indicator/CheckboxIndicator.spec.md +40 -37
  393. package/src/Indicator/CheckboxIndicator.tsx +3 -1
  394. package/src/Indicator/Indicator.spec.md +188 -0
  395. package/src/Indicator/RadioIndicator.tsx +3 -1
  396. package/src/Item/Item.tsx +2 -1
  397. package/src/Item/ItemSwipeLayer.tsx +1 -1
  398. package/src/Kbd/Kbd.spec.md +81 -38
  399. package/src/Layer/__tests__/LayerBrowserHide.a11y.chromium.spec.ts +126 -0
  400. package/src/Layer/popoverOperations.test.ts +205 -0
  401. package/src/Layer/popoverOperations.ts +172 -0
  402. package/src/Layer/useLayer.test.tsx +348 -1
  403. package/src/Layer/useLayer.tsx +118 -71
  404. package/src/Layout/Layout.spec.md +127 -131
  405. package/src/Layout/Layout.tsx +1 -1
  406. package/src/Layout/LayoutContent.spec.md +205 -0
  407. package/src/Layout/LayoutContent.tsx +1 -1
  408. package/src/Layout/LayoutFooter.spec.md +190 -0
  409. package/src/Layout/LayoutFooter.tsx +1 -1
  410. package/src/Layout/LayoutHeader.spec.md +193 -0
  411. package/src/Layout/LayoutHeader.tsx +1 -1
  412. package/src/Layout/LayoutPanel.spec.md +194 -0
  413. package/src/Layout/__tests__/Layout.a11y.chromium.spec.ts +18 -6
  414. package/src/Lightbox/Lightbox.test.tsx +18 -0
  415. package/src/Lightbox/Lightbox.tsx +5 -0
  416. package/src/Lightbox/LightboxViewport.a11y.browser.spec.ts +8 -4
  417. package/src/Link/__tests__/Link.a11y.chromium.spec.ts +18 -8
  418. package/src/List/List.tsx +1 -1
  419. package/src/List/ListItem.spec.md +205 -0
  420. package/src/List/ListItem.tsx +3 -3
  421. package/src/MetadataList/MetadataList.spec.md +187 -0
  422. package/src/MetadataList/MetadataListItem.spec.md +165 -0
  423. package/src/MobileNav/MobileNav.test.tsx +15 -0
  424. package/src/MobileNav/MobileNav.tsx +9 -1
  425. package/src/MobileNav/__tests__/MobileNavHeader.a11y.chromium.spec.ts +89 -0
  426. package/src/MoreMenu/MoreMenu.test.tsx +11 -0
  427. package/src/MultiSelector/CreateRow.a11y.chromium.spec.ts +7 -8
  428. package/src/MultiSelector/MultiSelector.spec.md +7 -4
  429. package/src/MultiSelector/MultiSelector.test.tsx +270 -1
  430. package/src/MultiSelector/MultiSelector.tsx +25 -10
  431. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +8 -1
  432. package/src/NavMenu/NavHeadingMenu.spec.md +1 -5
  433. package/src/NumberInput/NumberInput.doc.mjs +13 -7
  434. package/src/NumberInput/NumberInput.spec.md +59 -37
  435. package/src/NumberInput/NumberInput.tsx +13 -3
  436. package/src/NumberInput/__tests__/NumberInput.coarse-pointer.a11y.chromium.spec.ts +102 -0
  437. package/src/NumberInput/numberParser.ts +7 -45
  438. package/src/ProgressBar/ProgressBar.test.tsx +108 -32
  439. package/src/ProgressBar/ProgressBar.tsx +58 -10
  440. package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +21 -9
  441. package/src/ProgressBar/__tests__/ProgressBarMotion.a11y.chromium.spec.ts +831 -0
  442. package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +21 -14
  443. package/src/Resizable/useResizable.test.ts +43 -0
  444. package/src/Resizable/useResizable.ts +32 -9
  445. package/src/SegmentedControl/SegmentedControl.test.tsx +84 -0
  446. package/src/SegmentedControl/SegmentedControlItem.tsx +11 -5
  447. package/src/Selector/Selector.test.tsx +90 -1
  448. package/src/Selector/__tests__/Selector.combobox.a11y.test.tsx +8 -1
  449. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +8 -1
  450. package/src/Selector/useSelectorPresentation.ts +31 -3
  451. package/src/SideNav/SideNav.test.tsx +27 -0
  452. package/src/SideNav/__tests__/SideNavRailMotion.interaction.browser.spec.ts +176 -51
  453. package/src/Skeleton/Skeleton.tsx +3 -1
  454. package/src/Slider/Slider.test.tsx +31 -0
  455. package/src/Slider/Slider.tsx +8 -3
  456. package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +19 -7
  457. package/src/Spinner/Spinner.tsx +5 -3
  458. package/src/Stack/Stack.tsx +1 -1
  459. package/src/Stack/StackItem.tsx +1 -1
  460. package/src/TabList/TabList.test.tsx +58 -4
  461. package/src/TabList/TabList.tsx +16 -1
  462. package/src/TabList/__tests__/TabPressPointer.interaction.browser.spec.ts +163 -0
  463. package/src/Table/__tests__/Table.a11y.chromium.spec.ts +18 -6
  464. package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +22 -0
  465. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +8 -4
  466. package/src/Text/Text.tsx +1 -1
  467. package/src/Text/useTruncation.test.tsx +128 -1
  468. package/src/Text/useTruncation.ts +23 -5
  469. package/src/TextArea/TextArea.spec.md +10 -13
  470. package/src/TextArea/TextArea.test.tsx +60 -0
  471. package/src/TextArea/TextArea.tsx +15 -1
  472. package/src/TextInput/TextInput.test.tsx +21 -0
  473. package/src/TextInput/TextInput.tsx +3 -1
  474. package/src/TimeInput/NativeTimeInput.test.tsx +17 -0
  475. package/src/TimeInput/Presentation.test.tsx +21 -0
  476. package/src/TimeInput/TimeInput.doc.mjs +8 -8
  477. package/src/TimeInput/TimeInput.spec.md +45 -48
  478. package/src/TimeInput/TimeInput.test.tsx +76 -0
  479. package/src/TimeInput/TimeInput.tsx +36 -18
  480. package/src/TimeInput/TouchTimeField.tsx +4 -6
  481. package/src/Timestamp/Timestamp.spec.md +6 -12
  482. package/src/Timestamp/Timestamp.test.tsx +30 -5
  483. package/src/Timestamp/Timestamp.tsx +6 -2
  484. package/src/Timestamp/TimestampHoverCard.tsx +4 -4
  485. package/src/Toast/Toast.spec.md +14 -20
  486. package/src/Toast/Toast.tsx +104 -36
  487. package/src/Toast/ToastViewport.test.tsx +719 -1
  488. package/src/Toast/ToastViewport.tsx +100 -50
  489. package/src/Tokenizer/Tokenizer.spec.md +5 -3
  490. package/src/Tokenizer/Tokenizer.test.tsx +68 -0
  491. package/src/Tokenizer/Tokenizer.tsx +14 -2
  492. package/src/Tokenizer/TokenizerBottomSheet.test.tsx +15 -4
  493. package/src/Tokenizer/TokenizerBottomSheet.tsx +3 -3
  494. package/src/Toolbar/Toolbar.spec.md +5 -6
  495. package/src/Toolbar/Toolbar.test.tsx +30 -0
  496. package/src/Toolbar/Toolbar.tsx +2 -1
  497. package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +18 -6
  498. package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +18 -7
  499. package/src/TopNav/TopNav.test.tsx +27 -0
  500. package/src/TopNav/TopNavMegaMenu.test.tsx +21 -0
  501. package/src/TopNav/TopNavMegaMenu.tsx +4 -1
  502. package/src/TopNav/TopNavMenu.test.tsx +17 -0
  503. package/src/TopNav/TopNavMenu.tsx +1 -0
  504. package/src/Typeahead/Typeahead.test.tsx +40 -0
  505. package/src/Typeahead/Typeahead.tsx +12 -1
  506. package/src/__tests__/pressState.ts +8 -4
  507. package/src/gestures/GestureArena.ts +35 -0
  508. package/src/gestures/GestureHost.ts +2065 -0
  509. package/src/gestures/GestureRecognizer.ts +18 -0
  510. package/src/gestures/LongPressGestureRecognizer.ts +4 -0
  511. package/src/gestures/PanGestureRecognizer.ts +4 -0
  512. package/src/gestures/PinchGestureRecognizer.ts +148 -0
  513. package/src/gestures/ScreenEdgePanGestureRecognizer.ts +256 -0
  514. package/src/gestures/SwipeGestureRecognizer.ts +197 -0
  515. package/src/gestures/TapGestureRecognizer.ts +4 -0
  516. package/src/gestures/VelocityTracker.ts +10 -3
  517. package/src/gestures/__tests__/GestureHost.test.ts +2087 -0
  518. package/src/gestures/__tests__/PanGestureRecognizer.test.ts +4 -4
  519. package/src/gestures/__tests__/PinchGestureRecognizer.test.ts +74 -0
  520. package/src/gestures/__tests__/ScreenEdgePanGestureRecognizer.test.ts +498 -0
  521. package/src/gestures/__tests__/SwipeGestureRecognizer.test.ts +108 -0
  522. package/src/gestures/__tests__/arena.test.ts +5 -0
  523. package/src/gestures/__tests__/arenaPinchSwipeEdge.test.ts +193 -0
  524. package/src/gestures/__tests__/browser/build-fixture.mjs +46 -0
  525. package/src/gestures/__tests__/browser/fixture.ts +307 -0
  526. package/src/gestures/__tests__/browser/gestures.interaction.browser.spec.ts +1137 -0
  527. package/src/gestures/__tests__/browserNegotiation.test.ts +293 -0
  528. package/src/gestures/__tests__/haptics.test.ts +187 -0
  529. package/src/gestures/__tests__/harness.ts +21 -2
  530. package/src/gestures/__tests__/recognizerKind.test.ts +78 -0
  531. package/src/gestures/__tests__/touchActionRule.test.ts +54 -0
  532. package/src/gestures/haptics.ts +203 -0
  533. package/src/gestures/nativeScroll.ts +277 -0
  534. package/src/gestures/touchAction.ts +191 -0
  535. package/src/gestures/touchActionRule.ts +157 -0
  536. package/src/gestures/types.ts +30 -9
  537. package/src/hooks/index.ts +5 -1
  538. package/src/hooks/modalAnnounce.ts +129 -72
  539. package/src/hooks/scrollKeyboardDelegation.test.ts +33 -0
  540. package/src/hooks/scrollKeyboardDelegation.ts +9 -3
  541. package/src/hooks/useAdaptivePresentation.ts +4 -1
  542. package/src/hooks/useAnnounce.doc.mjs +35 -3
  543. package/src/hooks/useAnnounce.replace.test.tsx +516 -0
  544. package/src/hooks/useAnnounce.ts +209 -102
  545. package/src/hooks/useAnnounceRenderedText.adopters.test.tsx +10 -1
  546. package/src/hooks/useAnnounceRenderedText.ts +17 -3
  547. package/src/hooks/useBusyAnnouncement.ts +7 -10
  548. package/src/hooks/useMenuHover.ts +15 -1
  549. package/src/hooks/useScrollOverflow.doc.mjs +1 -1
  550. package/src/hooks/useScrollOverflow.test.tsx +102 -1
  551. package/src/hooks/useScrollOverflow.ts +59 -10
  552. package/src/i18n/generated-locales/en.generated.ts +7 -0
  553. package/src/i18n/generated-locales/pseudo.generated.ts +7 -0
  554. package/src/motion/README.md +11 -1
  555. package/src/motion/animator.test.ts +151 -3
  556. package/src/motion/animator.ts +149 -33
  557. package/src/theme/Theme.doc.mjs +1 -1
  558. package/src/theme/defineTheme.ts +117 -8
  559. package/src/theme/derivedVarRegistry.test.ts +4 -0
  560. package/src/theme/domainTokens/domainTokenDefaults.ts +19 -0
  561. package/src/theme/domainTokens/index.ts +6 -10
  562. package/src/theme/expandMotionScale.test.ts +1 -1
  563. package/src/theme/index.ts +5 -0
  564. package/src/theme/motionKnobs.ts +82 -0
  565. package/src/theme/resolveThemeValues.ts +68 -6
  566. package/src/theme/themeAdaptations.ts +52 -12
  567. package/src/theme/themeMotion.test.ts +620 -0
  568. package/src/theme/themeMotion.ts +221 -0
  569. package/src/theme/tokenReferences.ts +149 -0
  570. package/src/theme/tokens.stylex.ts +10 -0
  571. package/src/theme/tokens.ts +15 -158
  572. package/src/utils/focusReturn.ts +17 -6
  573. package/src/utils/getNodeText.test.ts +24 -0
  574. package/src/utils/getNodeText.ts +37 -0
  575. package/src/utils/interactionModality.test.ts +45 -1
  576. package/src/utils/interactionModality.ts +64 -5
  577. package/src/utils/interactionOverlay.stylex.ts +12 -3
  578. package/src/utils/plainDate.test.ts +90 -0
  579. package/src/utils/plainDate.ts +58 -3
  580. package/src/utils/presentation.test.ts +380 -0
  581. package/src/utils/presentation.ts +180 -0
  582. package/src/utils/pressFeedback.test.ts +138 -0
  583. package/src/utils/pressFeedback.ts +34 -11
  584. package/src/utils/pressPaintPriority.test.ts +80 -0
  585. package/src/utils/primaryClick.test.ts +38 -0
  586. package/src/utils/primaryClick.ts +28 -0
  587. package/src/utils/sharedMutationObserver.test.ts +54 -1
  588. package/src/utils/sharedMutationObserver.ts +87 -29
  589. package/src/utils/timeFormat.test.ts +204 -0
  590. package/src/utils/timeFormat.ts +314 -0
  591. package/src/utils/touchPresentation.stylex.ts +43 -0
  592. package/src/utils/touchPresentation.test.ts +140 -1
  593. package/src/utils/touchPresentation.ts +5 -3
  594. package/src/utils/unicodeDigits.test.ts +44 -0
  595. package/src/utils/unicodeDigits.ts +71 -0
@@ -3,7 +3,8 @@
3
3
  /**
4
4
  * @file useScrollOverflow.test.tsx
5
5
  * @input Uses vitest, @testing-library/react, useScrollOverflow
6
- * @output Unit tests for the hook's measurement and its rendered-only gate
6
+ * @output Unit tests for the hook's measurement, what it observes (the
7
+ * container's scroll and size, and its content), and its rendered-only gate
7
8
  * @position Testing; jsdom lays nothing out, so the scroll box is faked and
8
9
  * `checkVisibility` is stubbed per element.
9
10
  */
@@ -18,7 +19,10 @@ import {useScrollOverflow} from './useScrollOverflow';
18
19
  let deliverResize: ((entries: ResizeObserverEntry[]) => void) | null = null;
19
20
 
20
21
  class FakeResizeObserver implements ResizeObserver {
22
+ /** The shared observer, so a test can read what it observes. */
23
+ static last: FakeResizeObserver | null = null;
21
24
  constructor(callback: ResizeObserverCallback) {
25
+ FakeResizeObserver.last = this;
22
26
  deliverResize = entries => callback(entries, this);
23
27
  }
24
28
  observe = vi.fn();
@@ -69,7 +73,9 @@ beforeEach(() => {
69
73
 
70
74
  afterEach(() => {
71
75
  vi.unstubAllGlobals();
76
+ vi.restoreAllMocks();
72
77
  deliverResize = null;
78
+ FakeResizeObserver.last = null;
73
79
  });
74
80
 
75
81
  describe('useScrollOverflow', () => {
@@ -200,6 +206,101 @@ describe('useScrollOverflow', () => {
200
206
  unmount();
201
207
  });
202
208
 
209
+ // The overflow is the content's width against the container's: it changes
210
+ // when the content does, with the container keeping its size.
211
+ it('measures again when a child is added or removed, though the container keeps its size', async () => {
212
+ const el = document.createElement('div');
213
+ fakeScrollBox(el, {scrollWidth: 300, clientWidth: 300});
214
+ stubRendered(el, true);
215
+ const {result, unmount} = renderHook(() => useScrollOverflow());
216
+ act(() => {
217
+ result.current.scrollRef(el);
218
+ });
219
+ expect(result.current.hasOverflow).toBe(false);
220
+
221
+ const child = document.createElement('div');
222
+ fakeScrollBox(el, {scrollWidth: 600, clientWidth: 300});
223
+ await act(async () => {
224
+ el.append(child);
225
+ });
226
+ expect(result.current.hasOverflow).toBe(true);
227
+
228
+ fakeScrollBox(el, {scrollWidth: 300, clientWidth: 300});
229
+ await act(async () => {
230
+ child.remove();
231
+ });
232
+ expect(result.current.hasOverflow).toBe(false);
233
+ unmount();
234
+ });
235
+
236
+ it('measures again when a child resizes, though the container keeps its size', () => {
237
+ const el = document.createElement('div');
238
+ const child = document.createElement('div');
239
+ el.append(child);
240
+ fakeScrollBox(el, {scrollWidth: 300, clientWidth: 300});
241
+ stubRendered(el, true);
242
+ const {result, unmount} = renderHook(() => useScrollOverflow());
243
+ act(() => {
244
+ result.current.scrollRef(el);
245
+ });
246
+ expect(result.current.hasOverflow).toBe(false);
247
+
248
+ // The child's content grows past the container.
249
+ fakeScrollBox(el, {scrollWidth: 600, clientWidth: 300});
250
+ act(() => {
251
+ deliverResize?.([resizeEntry(child)]);
252
+ });
253
+ expect(result.current.hasOverflow).toBe(true);
254
+ unmount();
255
+ });
256
+
257
+ it("measures again when the container's class or style changes, as a new gap does", async () => {
258
+ const el = document.createElement('div');
259
+ fakeScrollBox(el, {scrollWidth: 300, clientWidth: 300});
260
+ stubRendered(el, true);
261
+ const {result, unmount} = renderHook(() => useScrollOverflow());
262
+ act(() => {
263
+ result.current.scrollRef(el);
264
+ });
265
+ expect(result.current.hasOverflow).toBe(false);
266
+
267
+ fakeScrollBox(el, {scrollWidth: 340, clientWidth: 300});
268
+ await act(async () => {
269
+ el.className = 'wider-gap';
270
+ });
271
+ expect(result.current.hasOverflow).toBe(true);
272
+
273
+ fakeScrollBox(el, {scrollWidth: 300, clientWidth: 300});
274
+ await act(async () => {
275
+ el.style.columnGap = '0px';
276
+ });
277
+ expect(result.current.hasOverflow).toBe(false);
278
+ unmount();
279
+ });
280
+
281
+ it('stops observing the content when the container detaches', () => {
282
+ const el = document.createElement('div');
283
+ const child = document.createElement('div');
284
+ el.append(child);
285
+ fakeScrollBox(el, {scrollWidth: 300, clientWidth: 300});
286
+ stubRendered(el, true);
287
+ const disconnect = vi.spyOn(MutationObserver.prototype, 'disconnect');
288
+ const {result, unmount} = renderHook(() => useScrollOverflow());
289
+ act(() => {
290
+ result.current.scrollRef(el);
291
+ });
292
+ const observer = FakeResizeObserver.last;
293
+ expect(observer?.observe).toHaveBeenCalledWith(child);
294
+
295
+ act(() => {
296
+ result.current.scrollRef(null);
297
+ });
298
+ expect(disconnect).toHaveBeenCalled();
299
+ expect(observer?.unobserve).toHaveBeenCalledWith(child);
300
+ expect(observer?.unobserve).toHaveBeenCalledWith(el);
301
+ unmount();
302
+ });
303
+
203
304
  it('follows a scroll on a rendered container', () => {
204
305
  const el = document.createElement('div');
205
306
  fakeScrollBox(el, {scrollWidth: 600, clientWidth: 300});
@@ -10,12 +10,15 @@
10
10
  * state
11
11
  *
12
12
  * Observes a scroll container and reports whether content overflows at the
13
- * start, end, or both edges. Updates on every scroll, and on a resize while
14
- * the container is rendered: a layout read on an element the browser is not
13
+ * start, end, or both edges. Updates on every scroll, and while the container
14
+ * is rendered on what else changes the overflow with or without the
15
+ * container resizing: its own size, a child's size (a slide's content
16
+ * growing), a child added or removed, and its class or style (a new gap or
17
+ * padding). A layout read on an element the browser is not
15
18
  * rendering (an ancestor with `display: none`, or a `content-visibility:
16
19
  * hidden` subtree) either answers zeros or makes the browser lay out that
17
- * whole hidden subtree for the answer, so a resize observation delivered for
18
- * a hidden container, and the measurement at registration inside one, are
20
+ * whole hidden subtree for the answer, so an observation delivered for a
21
+ * hidden container, and the measurement at registration inside one, are
19
22
  * skipped; the hook keeps its last state until the resize observation that
20
23
  * follows the reveal (one frame after it paints). A scroll is measured
21
24
  * whether or not the container is rendered: a scroll of a hidden container
@@ -52,11 +55,57 @@ function isRendered(el: HTMLElement): boolean {
52
55
  return typeof el.checkVisibility !== 'function' || el.checkVisibility();
53
56
  }
54
57
 
58
+ /**
59
+ * Observes what changes `el`'s overflow besides its scroll: its own size,
60
+ * each child's size, the children added or removed, and its class or style.
61
+ * Returns the teardown, which ends every observation.
62
+ */
63
+ function observeContent(el: HTMLElement, measure: () => void): () => void {
64
+ const unobserveContainer = observeResize(el, measure);
65
+ const unobserveChildren = new Map<Element, () => void>();
66
+ const followChildren = () => {
67
+ const children = new Set(el.children);
68
+ for (const [child, unobserve] of unobserveChildren) {
69
+ if (!children.has(child)) {
70
+ unobserve();
71
+ unobserveChildren.delete(child);
72
+ }
73
+ }
74
+ for (const child of children) {
75
+ if (!unobserveChildren.has(child)) {
76
+ unobserveChildren.set(child, observeResize(child, measure));
77
+ }
78
+ }
79
+ };
80
+ followChildren();
81
+ const mutations =
82
+ typeof MutationObserver === 'function'
83
+ ? new MutationObserver(() => {
84
+ followChildren();
85
+ measure();
86
+ })
87
+ : null;
88
+ mutations?.observe(el, {
89
+ childList: true,
90
+ attributes: true,
91
+ attributeFilter: ['class', 'style'],
92
+ });
93
+ return () => {
94
+ mutations?.disconnect();
95
+ for (const unobserve of unobserveChildren.values()) {
96
+ unobserve();
97
+ }
98
+ unobserveChildren.clear();
99
+ unobserveContainer();
100
+ };
101
+ }
102
+
55
103
  /**
56
104
  * Tracks scroll overflow state for a horizontally scrollable container.
57
105
  *
58
106
  * Returns a ref callback to attach to the scroll container and a state
59
- * object that updates as the user scrolls or the container resizes.
107
+ * object that updates as the user scrolls, the container resizes, or its
108
+ * content changes.
60
109
  *
61
110
  * @example
62
111
  * ```
@@ -95,10 +144,10 @@ export function useScrollOverflow() {
95
144
  });
96
145
  }, []);
97
146
 
98
- // Registration and resize: only a rendered container. A hidden one has no
99
- // edges to report, and reading its layout would make the browser render
100
- // the hidden subtree it sits in; the resize observation that follows the
101
- // reveal measures again.
147
+ // Registration, resize and content changes: only a rendered container. A
148
+ // hidden one has no edges to report, and reading its layout would make the
149
+ // browser render the hidden subtree it sits in; the resize observation that
150
+ // follows the reveal measures again.
102
151
  const measure = useCallback(() => {
103
152
  const el = elRef.current;
104
153
  if (el && isRendered(el)) {
@@ -129,7 +178,7 @@ export function useScrollOverflow() {
129
178
 
130
179
  if (el) {
131
180
  el.addEventListener('scroll', measureOnScroll, {passive: true});
132
- unobserveRef.current = observeResize(el, measure);
181
+ unobserveRef.current = observeContent(el, measure);
133
182
  }
134
183
  },
135
184
  [measure, measureOnScroll],
@@ -230,9 +230,12 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
230
230
  '@astryx.sideNav.label': 'Side navigation',
231
231
  '@astryx.sideNav.resizeSidebar': 'Resize sidebar',
232
232
  '@astryx.sideNav.heading.openMenu': 'Open menu',
233
+ '@astryx.slider.minimumThumb': 'Minimum value',
234
+ '@astryx.slider.maximumThumb': 'Maximum value',
233
235
  '@astryx.tabList.label': 'Tabs',
234
236
  '@astryx.table.label': 'Table',
235
237
  '@astryx.table.noData': 'No data',
238
+ '@astryx.table.columnResize.resizeColumn': 'Resize column {label}',
236
239
  '@astryx.table.filter.allPlaceholder': 'All',
237
240
  '@astryx.table.filter.reset': 'Reset',
238
241
  '@astryx.table.filter.apply': 'Apply',
@@ -427,6 +430,7 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
427
430
  '@astryx.tableTree.expandRow': 'Expand row',
428
431
  '@astryx.tableTree.collapseAllRows': 'Collapse all rows',
429
432
  '@astryx.tableTree.expandAllRows': 'Expand all rows',
433
+ '@astryx.textArea.counter': '{count, number}/{limit, number}',
430
434
  '@astryx.textArea.charactersRemaining':
431
435
  '{count, number} {count, plural, one {character} other {characters}} remaining',
432
436
  '@astryx.textArea.charactersOverLimit':
@@ -449,6 +453,8 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
449
453
  '@astryx.multiSelector.allSelected': 'All selected',
450
454
  '@astryx.multiSelector.selectionCount':
451
455
  '{count, number} of {total, number} selected',
456
+ '@astryx.multiSelector.selectedCount':
457
+ '{count, plural, one {# selected} other {# selected}}',
452
458
  '@astryx.multiSelector.createOption': 'Create "{query}"',
453
459
  '@astryx.multiSelector.optionCreated': '{label} created',
454
460
  '@astryx.multiSelector.emptySearchResults': 'No results found',
@@ -595,6 +601,7 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
595
601
  '@astryx.comments.resolveFailed': "This thread couldn't be resolved.",
596
602
  '@astryx.comments.resolved': 'Resolved',
597
603
  '@astryx.comments.resolvedBy': 'Resolved by {name}',
604
+ '@astryx.comments.errorAnnouncement': '{title} {description}',
598
605
  '@astryx.comments.retryFailed': "Retrying didn't work.",
599
606
  '@astryx.comments.sendFailed': "Couldn't send this comment.",
600
607
  '@astryx.comments.threadLabel': 'Thread by {name}',
@@ -236,9 +236,12 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
236
236
  '@astryx.sideNav.label': '⟦Šíðé ñàṽíĝàţíóñ⟧',
237
237
  '@astryx.sideNav.resizeSidebar': '⟦Řéšížé šíðéƀàř⟧',
238
238
  '@astryx.sideNav.heading.openMenu': '⟦Óþéñ ɱéñú⟧',
239
+ '@astryx.slider.minimumThumb': '⟦Ṁíñíɱúɱ ṽàłúé⟧',
240
+ '@astryx.slider.maximumThumb': '⟦Ṁàẋíɱúɱ ṽàłúé⟧',
239
241
  '@astryx.tabList.label': '⟦Ţàƀš⟧',
240
242
  '@astryx.table.label': '⟦Ţàƀłé⟧',
241
243
  '@astryx.table.noData': '⟦Ñó ðàţà⟧',
244
+ '@astryx.table.columnResize.resizeColumn': '⟦Řéšížé çółúɱñ {label}⟧',
242
245
  '@astryx.table.filter.allPlaceholder': '⟦Àłł⟧',
243
246
  '@astryx.table.filter.reset': '⟦Řéšéţ⟧',
244
247
  '@astryx.table.filter.apply': '⟦Àþþłý⟧',
@@ -436,6 +439,7 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
436
439
  '@astryx.tableTree.expandRow': '⟦Éẋþàñð řóŵ⟧',
437
440
  '@astryx.tableTree.collapseAllRows': '⟦Çółłàþšé àłł řóŵš⟧',
438
441
  '@astryx.tableTree.expandAllRows': '⟦Éẋþàñð àłł řóŵš⟧',
442
+ '@astryx.textArea.counter': '⟦{count, number}/{limit, number}⟧',
439
443
  '@astryx.textArea.charactersRemaining':
440
444
  '⟦{count, number} {count, plural, one {character} other {characters}} řéɱàíñíñĝ⟧',
441
445
  '@astryx.textArea.charactersOverLimit':
@@ -458,6 +462,8 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
458
462
  '@astryx.multiSelector.allSelected': '⟦Àłł šéłéçţéð⟧',
459
463
  '@astryx.multiSelector.selectionCount':
460
464
  '⟦{count, number} óƒ {total, number} šéłéçţéð⟧',
465
+ '@astryx.multiSelector.selectedCount':
466
+ '⟦{count, plural, one {# selected} other {# selected}}⟧',
461
467
  '@astryx.multiSelector.createOption': '⟦Çřéàţé "{query}"⟧',
462
468
  '@astryx.multiSelector.optionCreated': '⟦{label} çřéàţéð⟧',
463
469
  '@astryx.multiSelector.emptySearchResults': '⟦Ñó řéšúłţš ƒóúñð⟧',
@@ -606,6 +612,7 @@ const runtimeCatalog: Readonly<Record<string, string>> = {
606
612
  '@astryx.comments.resolveFailed': "⟦Ţĥíš ţĥřéàð çóúłðñ'ţ ƀé řéšółṽéð.⟧",
607
613
  '@astryx.comments.resolved': '⟦Řéšółṽéð⟧',
608
614
  '@astryx.comments.resolvedBy': '⟦Řéšółṽéð ƀý {name}⟧',
615
+ '@astryx.comments.errorAnnouncement': '⟦{title} {description}⟧',
609
616
  '@astryx.comments.retryFailed': "⟦Řéţřýíñĝ ðíðñ'ţ ŵóřķ.⟧",
610
617
  '@astryx.comments.sendFailed': "⟦Çóúłðñ'ţ šéñð ţĥíš çóɱɱéñţ.⟧",
611
618
  '@astryx.comments.threadLabel': '⟦Ţĥřéàð ƀý {name}⟧',
@@ -81,7 +81,10 @@ await handle.finished; // true if it ran to the end, false if interrupted
81
81
  - Promotion: every animation the animator creates, and every `set`, gives its
82
82
  channels a compositing layer in the same task (inline `will-change`, merged
83
83
  with the element's own), cleared 500 ms after the last motion. Mobile Safari
84
- needs it to run a curve through a blocked main thread.
84
+ needs it to run a curve through a blocked main thread. A pseudo-element is
85
+ promoted through `--astryx-motion-will-change-<pseudo>` on its host; its
86
+ style opts in with
87
+ `willChange: 'var(--astryx-motion-will-change-before, auto)'`.
85
88
  - `atRest(properties)` resolves once none of them is moving, after the last
86
89
  curve ends, whoever started it.
87
90
  - `rebase({y: -shift})` moves properties at once, as a layout shift does; a
@@ -121,6 +124,13 @@ await handle.finished; // true if it ran to the end, false if interrupted
121
124
  - `animatorFor(element)` returns the one animator for an element, so code
122
125
  that animates it from several places (a swipe on x, a removal on y)
123
126
  composes in one `translate` track.
127
+ - `createAnimator(dialog, {pseudoElement: '::backdrop'})` drives a
128
+ pseudo-element; with no inline style to hold it, a static filling animation
129
+ holds its end value until the next animation replaces it, while the
130
+ pseudo-element exists. A dialog's `::backdrop` is made again each time the
131
+ dialog opens, so a presentation `set`s its starting value right after
132
+ `showModal()`, in the same task (a `set` before it lands on the backdrop
133
+ the open replaces).
124
134
 
125
135
  ### How it stays on the compositor
126
136
 
@@ -67,18 +67,23 @@ const requestFrame = (callback: () => void) => {
67
67
  * properties, so the page is modeled here).
68
68
  */
69
69
  let stylesheet: Record<string, string> = {};
70
+ /** The stylesheet's values for a pseudo-element of the element. */
71
+ let pseudoStylesheet: Record<string, string> = {};
70
72
 
71
73
  beforeEach(() => {
72
74
  clock = 1000;
73
75
  recorded = [];
74
76
  frameQueue = [];
75
77
  stylesheet = {};
78
+ pseudoStylesheet = {};
76
79
  vi.spyOn(window, 'getComputedStyle').mockImplementation(
77
- element =>
80
+ (element, pseudo) =>
78
81
  ({
79
82
  getPropertyValue: (property: string) =>
80
- (element as HTMLElement).style.getPropertyValue(property) ||
81
- (stylesheet[property] ?? ''),
83
+ pseudo != null
84
+ ? (pseudoStylesheet[property] ?? '')
85
+ : (element as HTMLElement).style.getPropertyValue(property) ||
86
+ (stylesheet[property] ?? ''),
82
87
  }) as unknown as CSSStyleDeclaration,
83
88
  );
84
89
  vi.useFakeTimers();
@@ -799,6 +804,12 @@ describe('animatorFor: one animator per element', () => {
799
804
  const b = document.createElement('div');
800
805
  expect(animatorFor(a)).toBe(animatorFor(a));
801
806
  expect(animatorFor(a)).not.toBe(animatorFor(b));
807
+ expect(animatorFor(a, {pseudoElement: '::backdrop'})).toBe(
808
+ animatorFor(a, {pseudoElement: '::backdrop'}),
809
+ );
810
+ expect(animatorFor(a, {pseudoElement: '::backdrop'})).not.toBe(
811
+ animatorFor(a),
812
+ );
802
813
  });
803
814
 
804
815
  it('composes two callers’ axes in one translate track', async () => {
@@ -902,6 +913,24 @@ describe('promotion: a compositing layer while it moves', () => {
902
913
  expect(element.style.willChange).toBe('');
903
914
  });
904
915
 
916
+ it('promotes a pseudo-element through a custom property on its host', async () => {
917
+ const {animator, element} = setup({pseudoElement: '::backdrop'});
918
+ animator.set({opacity: 0});
919
+ // set() promotes a pseudo-element too.
920
+ expect(
921
+ element.style.getPropertyValue('--astryx-motion-will-change-backdrop'),
922
+ ).toBe('opacity');
923
+ animator.animate({opacity: 1}, {spring: springs.alertPresent});
924
+ expect(
925
+ element.style.getPropertyValue('--astryx-motion-will-change-backdrop'),
926
+ ).toBe('opacity');
927
+ expect(element.style.willChange).toBe('');
928
+ await advance(5000 + PROMOTION_LINGER_MS);
929
+ expect(
930
+ element.style.getPropertyValue('--astryx-motion-will-change-backdrop'),
931
+ ).toBe('');
932
+ });
933
+
905
934
  it('ends promotion on the element it leaves', () => {
906
935
  const {animator, element} = setup();
907
936
  animator.animate({x: 50}, {spring: springs.settle});
@@ -1937,6 +1966,75 @@ describe('Reduced Motion (design:reduced-motion)', () => {
1937
1966
  expect(element.style.translate).toBe('100px 0px');
1938
1967
  });
1939
1968
 
1969
+ it("a pseudo-element's dip borrows its own opacity and hands it back without touching the host", async () => {
1970
+ for (const role of [undefined, 'exit'] as const) {
1971
+ const {animator, element} = setup({
1972
+ reduced: true,
1973
+ coarse: true,
1974
+ pseudoElement: '::before',
1975
+ });
1976
+ element.style.opacity = '0.5'; // the host's own, untouched
1977
+ pseudoStylesheet = {opacity: '0.3'};
1978
+ animator.animate(
1979
+ {x: 100},
1980
+ {spring: springs.navigationPush},
1981
+ role == null ? {} : {crossfadeAs: role},
1982
+ );
1983
+ await commitFrame(clock);
1984
+ const [fadeLayer] = live('opacity');
1985
+ const values = fadeLayer.keyframes.map(k => Number(k.opacity));
1986
+ expect(Math.max(...values)).toBeCloseTo(0.3, 9);
1987
+ await advance(fade * 2 + END_HOLD_MS + 1);
1988
+ expect(animator.get('x')).toBe(100);
1989
+ // The pseudo-element's stylesheet owns its opacity again; the host
1990
+ // keeps its own.
1991
+ expect(live('opacity')).toEqual([]);
1992
+ expect(element.style.opacity).toBe('0.5');
1993
+ }
1994
+ });
1995
+
1996
+ it("a pseudo-element's identity hold follows a node replacement", () => {
1997
+ const {animator, element} = setup({pseudoElement: '::backdrop'});
1998
+ pseudoStylesheet = {opacity: '0'};
1999
+ animator.set({opacity: 1});
2000
+ animator.attach(null);
2001
+ const next = document.createElement('div');
2002
+ document.body.append(next);
2003
+ animator.attach(next);
2004
+ const held = live('opacity').filter(
2005
+ animation => animation.element === next,
2006
+ );
2007
+ expect(held).toHaveLength(1);
2008
+ expect(Number(held[0].keyframes.at(-1)!.opacity)).toBe(1);
2009
+ expect(live('opacity').some(a => a.element === element)).toBe(false);
2010
+ next.remove();
2011
+ });
2012
+
2013
+ it('a pseudo-element shown over a hiding stylesheet keeps its own opacity through a move', async () => {
2014
+ for (const role of [undefined, 'entrance'] as const) {
2015
+ const {animator} = setup({
2016
+ reduced: true,
2017
+ coarse: true,
2018
+ pseudoElement: '::backdrop',
2019
+ });
2020
+ pseudoStylesheet = {opacity: '0'};
2021
+ animator.set({opacity: 1});
2022
+ animator.animate(
2023
+ {x: 100},
2024
+ {spring: springs.navigationPush},
2025
+ role == null ? {} : {crossfadeAs: role},
2026
+ );
2027
+ await commitFrame(clock);
2028
+ for (let step = 0; step < 8; step++) {
2029
+ await advance(fade / 4);
2030
+ }
2031
+ expect(animator.get('x')).toBe(100);
2032
+ expect(animator.get('opacity')).toBe(1);
2033
+ const [held] = live('opacity');
2034
+ expect(Number(held.keyframes.at(-1)?.opacity)).toBe(1);
2035
+ }
2036
+ });
2037
+
1940
2038
  it('a move dips: fades out, lands while transparent, fades back in', async () => {
1941
2039
  const {animator, element} = reduced();
1942
2040
  animator.animate({x: 100}, {spring: springs.navigationPush});
@@ -2555,6 +2653,56 @@ describe('decay: momentum curves (a coast)', () => {
2555
2653
  });
2556
2654
  });
2557
2655
 
2656
+ describe('pseudoElement: a dialog\u2019s ::backdrop', () => {
2657
+ it('targets the pseudo-element, writes no inline style and holds the end state', async () => {
2658
+ const {animator, element} = setup({pseudoElement: '::backdrop'});
2659
+ animator.set({opacity: 0});
2660
+ const [held] = live('opacity');
2661
+ expect(held.options).toMatchObject({
2662
+ fill: 'both',
2663
+ pseudoElement: '::backdrop',
2664
+ });
2665
+ expect(held.keyframes.map(k => k.opacity)).toEqual(['0', '0']);
2666
+ expect(element.style.opacity).toBe('');
2667
+
2668
+ animator.animate({opacity: 1}, {spring: springs.alertPresent});
2669
+ // The new animation exists before the hold goes: no frame in between.
2670
+ expect(held.cancelled).toBe(true);
2671
+ const [fade] = live('opacity');
2672
+ expect(fade.options).toMatchObject({
2673
+ fill: 'both',
2674
+ pseudoElement: '::backdrop',
2675
+ });
2676
+ expect(fade.keyframes[fade.keyframes.length - 1].opacity).toBe('1');
2677
+ expect(element.style.opacity).toBe('');
2678
+ await advance(Number(fade.options.duration) + 1000);
2679
+ // Past the curve's end, a static animation holds the end value.
2680
+ expect(fade.cancelled).toBe(true);
2681
+ const [rest] = live('opacity');
2682
+ expect(rest.options).toMatchObject({
2683
+ fill: 'both',
2684
+ pseudoElement: '::backdrop',
2685
+ });
2686
+ expect(rest.keyframes.map(k => k.opacity)).toEqual(['1', '1']);
2687
+ expect(animator.get('opacity')).toBe(1);
2688
+ });
2689
+
2690
+ it('an exit holds 0 until the next animation replaces it', async () => {
2691
+ const {animator} = setup({
2692
+ pseudoElement: '::backdrop',
2693
+ initial: {opacity: 1},
2694
+ });
2695
+ animator.animate({opacity: 0}, {spring: springs.alertDismiss});
2696
+ const [fade] = live('opacity');
2697
+ await advance(Number(fade.options.duration) + 1000);
2698
+ const [rest] = live('opacity');
2699
+ expect(rest.keyframes.map(k => k.opacity)).toEqual(['0', '0']);
2700
+ animator.animate({opacity: 1}, {spring: springs.alertPresent});
2701
+ expect(rest.cancelled).toBe(true);
2702
+ expect(live('opacity')).toHaveLength(1);
2703
+ });
2704
+ });
2705
+
2558
2706
  describe('attach', () => {
2559
2707
  it('keeps state without an element and resumes the curve on attach', () => {
2560
2708
  const animator = createAnimator(null, {