@astryxdesign/core 0.7.5 → 0.7.6-canary.0d71e8d

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 (912) 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/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  28. package/dist/ComplexSelector/ComplexSelector.js +41 -4
  29. package/dist/DateInput/DateInput.d.ts.map +1 -1
  30. package/dist/DateInput/DateInput.js +12 -4
  31. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  32. package/dist/DateInput/MonthScroller.js +101 -15
  33. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  34. package/dist/DateInput/TouchDateField.js +8 -3
  35. package/dist/DateInput/Wheel.d.ts.map +1 -1
  36. package/dist/DateInput/Wheel.js +11 -7
  37. package/dist/DateInput/usePointerDragScroll.d.ts +10 -1
  38. package/dist/DateInput/usePointerDragScroll.d.ts.map +1 -1
  39. package/dist/DateInput/usePointerDragScroll.js +25 -9
  40. package/dist/DateInput/useScrollSettle.d.ts +3 -1
  41. package/dist/DateInput/useScrollSettle.d.ts.map +1 -1
  42. package/dist/DateInput/useScrollSettle.js +37 -8
  43. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  44. package/dist/DateRangeInput/DateRangeInput.js +1 -1
  45. package/dist/DateTimeInput/DateTimeInput.d.ts +5 -2
  46. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  47. package/dist/DateTimeInput/DateTimeInput.js +23 -12
  48. package/dist/DateTimeInput/NativeTimeSegment.d.ts.map +1 -1
  49. package/dist/DateTimeInput/NativeTimeSegment.js +5 -4
  50. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  51. package/dist/DateTimeInput/TouchDateTimeField.js +4 -3
  52. package/dist/Dialog/Dialog.d.ts.map +1 -1
  53. package/dist/Dialog/Dialog.js +34 -9
  54. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  55. package/dist/Dialog/DialogHeader.js +5 -4
  56. package/dist/Divider/Divider.d.ts.map +1 -1
  57. package/dist/Divider/Divider.js +2 -1
  58. package/dist/Drawer/Drawer.d.ts +1 -0
  59. package/dist/Drawer/Drawer.d.ts.map +1 -1
  60. package/dist/Drawer/Drawer.js +7 -2
  61. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  62. package/dist/DropdownMenu/DropdownMenu.js +35 -22
  63. package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -1
  64. package/dist/DropdownMenu/MenuBottomSheetActionList.js +6 -5
  65. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +20 -2
  66. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
  67. package/dist/DropdownMenu/lazyMenuBottomSheet.js +31 -3
  68. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  69. package/dist/DropdownMenu/renderDropdownItems.js +21 -16
  70. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  71. package/dist/EmptyState/EmptyState.js +2 -1
  72. package/dist/Field/FieldLabel.d.ts +1 -1
  73. package/dist/Field/FieldLabel.d.ts.map +1 -1
  74. package/dist/Field/FieldLabel.js +4 -4
  75. package/dist/Field/InputClearButton.js +3 -3
  76. package/dist/Field/PanelSearchInput.js +2 -2
  77. package/dist/FieldStatus/FieldStatus.d.ts +3 -0
  78. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  79. package/dist/FieldStatus/FieldStatus.js +3 -2
  80. package/dist/FileInput/FileInput.d.ts +3 -0
  81. package/dist/FileInput/FileInput.d.ts.map +1 -1
  82. package/dist/FileInput/FileInput.js +34 -13
  83. package/dist/Heading/Heading.js +1 -1
  84. package/dist/Icon/Icon.js +1 -1
  85. package/dist/Indicator/CheckIndicator.d.ts.map +1 -1
  86. package/dist/Indicator/CheckIndicator.js +2 -1
  87. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  88. package/dist/Indicator/CheckboxIndicator.js +3 -1
  89. package/dist/Indicator/RadioIndicator.d.ts.map +1 -1
  90. package/dist/Indicator/RadioIndicator.js +3 -1
  91. package/dist/Item/Item.d.ts.map +1 -1
  92. package/dist/Item/Item.js +21 -7
  93. package/dist/Item/ItemSwipeLayer.js +1 -1
  94. package/dist/Layer/popoverOperations.d.ts +27 -0
  95. package/dist/Layer/popoverOperations.d.ts.map +1 -0
  96. package/dist/Layer/popoverOperations.js +159 -0
  97. package/dist/Layer/useLayer.d.ts +1 -1
  98. package/dist/Layer/useLayer.d.ts.map +1 -1
  99. package/dist/Layer/useLayer.js +120 -65
  100. package/dist/Layout/Layout.js +1 -1
  101. package/dist/Layout/LayoutContent.js +1 -1
  102. package/dist/Layout/LayoutFooter.js +1 -1
  103. package/dist/Layout/LayoutHeader.js +1 -1
  104. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  105. package/dist/Lightbox/Lightbox.js +5 -0
  106. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.js +5 -4
  107. package/dist/Link/Link.d.ts.map +1 -1
  108. package/dist/Link/Link.js +8 -3
  109. package/dist/List/List.js +1 -1
  110. package/dist/List/ListItem.js +3 -3
  111. package/dist/Markdown/plugins/headingLinks.a11y.chromium.spec.js +1 -1
  112. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  113. package/dist/MobileNav/MobileNav.js +7 -2
  114. package/dist/MultiSelector/CreateRow.a11y.chromium.spec.js +7 -6
  115. package/dist/MultiSelector/MultiSelector.d.ts +1 -1
  116. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  117. package/dist/MultiSelector/MultiSelector.js +26 -10
  118. package/dist/NavMenu/NavHeadingMenuItem.d.ts.map +1 -1
  119. package/dist/NavMenu/NavHeadingMenuItem.js +5 -29
  120. package/dist/NumberInput/NumberInput.d.ts +3 -1
  121. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  122. package/dist/NumberInput/NumberInput.js +26 -5
  123. package/dist/NumberInput/numberParser.d.ts +3 -0
  124. package/dist/NumberInput/numberParser.d.ts.map +1 -1
  125. package/dist/NumberInput/numberParser.js +7 -44
  126. package/dist/Outline/Outline.d.ts.map +1 -1
  127. package/dist/Outline/Outline.js +27 -0
  128. package/dist/Popover/Popover.d.ts.map +1 -1
  129. package/dist/Popover/Popover.js +32 -12
  130. package/dist/Popover/usePopover.d.ts.map +1 -1
  131. package/dist/Popover/usePopover.js +10 -3
  132. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  133. package/dist/PowerSearch/PowerSearch.js +37 -30
  134. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  135. package/dist/ProgressBar/ProgressBar.js +16 -12
  136. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  137. package/dist/RadioList/RadioListItem.js +11 -3
  138. package/dist/Resizable/useResizable.d.ts.map +1 -1
  139. package/dist/Resizable/useResizable.js +28 -2
  140. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  141. package/dist/SegmentedControl/SegmentedControlItem.js +4 -1
  142. package/dist/Selector/useSelectorPresentation.d.ts +8 -1
  143. package/dist/Selector/useSelectorPresentation.d.ts.map +1 -1
  144. package/dist/Selector/useSelectorPresentation.js +20 -4
  145. package/dist/SideNav/SideNavItem.d.ts +2 -2
  146. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  147. package/dist/SideNav/SideNavItem.js +18 -7
  148. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  149. package/dist/Skeleton/Skeleton.js +1 -1
  150. package/dist/Slider/Slider.d.ts.map +1 -1
  151. package/dist/Slider/Slider.js +10 -2
  152. package/dist/Spinner/Spinner.d.ts.map +1 -1
  153. package/dist/Spinner/Spinner.js +3 -3
  154. package/dist/Stack/Stack.js +1 -1
  155. package/dist/Stack/StackItem.js +1 -1
  156. package/dist/Stepper/Step.d.ts.map +1 -1
  157. package/dist/Stepper/Step.js +26 -6
  158. package/dist/Switch/Switch.d.ts.map +1 -1
  159. package/dist/Switch/Switch.js +10 -3
  160. package/dist/TabList/TabList.d.ts.map +1 -1
  161. package/dist/TabList/TabList.js +16 -1
  162. package/dist/Table/Table.d.ts.map +1 -1
  163. package/dist/Table/Table.js +36 -10
  164. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  165. package/dist/Table/plugins/columnResize/useTableColumnResize.js +9 -1
  166. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  167. package/dist/Table/plugins/sortable/useTableSortable.js +46 -58
  168. package/dist/Text/Text.js +1 -1
  169. package/dist/Text/useTruncation.d.ts.map +1 -1
  170. package/dist/Text/useTruncation.js +23 -5
  171. package/dist/TextArea/TextArea.d.ts +1 -1
  172. package/dist/TextArea/TextArea.d.ts.map +1 -1
  173. package/dist/TextArea/TextArea.js +13 -2
  174. package/dist/TextInput/TextInput.d.ts.map +1 -1
  175. package/dist/TextInput/TextInput.js +3 -3
  176. package/dist/TimeInput/TimeInput.d.ts +6 -2
  177. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  178. package/dist/TimeInput/TimeInput.js +21 -14
  179. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
  180. package/dist/TimeInput/TouchTimeField.js +5 -4
  181. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  182. package/dist/Timestamp/Timestamp.js +2 -2
  183. package/dist/Timestamp/TimestampHoverCard.js +4 -4
  184. package/dist/Toast/Toast.d.ts.map +1 -1
  185. package/dist/Toast/Toast.js +60 -20
  186. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  187. package/dist/Toast/ToastViewport.js +101 -54
  188. package/dist/ToggleButton/ToggleButtonGroup.d.ts +7 -1
  189. package/dist/ToggleButton/ToggleButtonGroup.d.ts.map +1 -1
  190. package/dist/ToggleButton/ToggleButtonGroup.js +16 -2
  191. package/dist/Token/Token.d.ts +1 -1
  192. package/dist/Token/Token.d.ts.map +1 -1
  193. package/dist/Token/Token.js +52 -5
  194. package/dist/Token/TokenLink.d.ts.map +1 -1
  195. package/dist/Token/TokenLink.js +14 -2
  196. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  197. package/dist/Tokenizer/Tokenizer.js +44 -7
  198. package/dist/Tokenizer/TokenizerBottomSheet.js +3 -3
  199. package/dist/Tokenizer/TokenizerClearAllMessageContext.d.ts +2 -0
  200. package/dist/Tokenizer/TokenizerClearAllMessageContext.d.ts.map +1 -0
  201. package/dist/Tokenizer/TokenizerClearAllMessageContext.js +17 -0
  202. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  203. package/dist/Toolbar/Toolbar.js +2 -1
  204. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  205. package/dist/TopNav/TopNavMegaMenu.js +3 -0
  206. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  207. package/dist/TopNav/TopNavMenu.js +1 -0
  208. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  209. package/dist/TreeList/TreeListItem.js +27 -4
  210. package/dist/Typeahead/BaseTypeahead.d.ts +4 -4
  211. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  212. package/dist/Typeahead/BaseTypeahead.js +43 -7
  213. package/dist/Typeahead/Typeahead.d.ts +1 -1
  214. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  215. package/dist/Typeahead/Typeahead.js +43 -9
  216. package/dist/astryx.css +25 -4
  217. package/dist/gestures/GestureArena.d.ts +32 -1
  218. package/dist/gestures/GestureArena.d.ts.map +1 -1
  219. package/dist/gestures/GestureArena.js +110 -9
  220. package/dist/gestures/GestureHost.d.ts +351 -0
  221. package/dist/gestures/GestureHost.d.ts.map +1 -0
  222. package/dist/gestures/GestureHost.js +1773 -0
  223. package/dist/gestures/GestureRecognizer.d.ts +13 -1
  224. package/dist/gestures/GestureRecognizer.d.ts.map +1 -1
  225. package/dist/gestures/GestureRecognizer.js +19 -1
  226. package/dist/gestures/LongPressGestureRecognizer.d.ts +1 -0
  227. package/dist/gestures/LongPressGestureRecognizer.d.ts.map +1 -1
  228. package/dist/gestures/LongPressGestureRecognizer.js +3 -0
  229. package/dist/gestures/PanGestureRecognizer.d.ts +1 -0
  230. package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -1
  231. package/dist/gestures/PanGestureRecognizer.js +3 -0
  232. package/dist/gestures/PinchGestureRecognizer.d.ts +31 -0
  233. package/dist/gestures/PinchGestureRecognizer.d.ts.map +1 -0
  234. package/dist/gestures/PinchGestureRecognizer.js +128 -0
  235. package/dist/gestures/PressTracker.d.ts +112 -0
  236. package/dist/gestures/PressTracker.d.ts.map +1 -0
  237. package/dist/gestures/PressTracker.js +267 -0
  238. package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts +71 -0
  239. package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts.map +1 -0
  240. package/dist/gestures/ScreenEdgePanGestureRecognizer.js +223 -0
  241. package/dist/gestures/SwipeGestureRecognizer.d.ts +37 -0
  242. package/dist/gestures/SwipeGestureRecognizer.d.ts.map +1 -0
  243. package/dist/gestures/SwipeGestureRecognizer.js +148 -0
  244. package/dist/gestures/TapGestureRecognizer.d.ts +1 -0
  245. package/dist/gestures/TapGestureRecognizer.d.ts.map +1 -1
  246. package/dist/gestures/TapGestureRecognizer.js +3 -0
  247. package/dist/gestures/VelocityTracker.d.ts +6 -2
  248. package/dist/gestures/VelocityTracker.d.ts.map +1 -1
  249. package/dist/gestures/VelocityTracker.js +7 -3
  250. package/dist/gestures/haptics.d.ts +65 -0
  251. package/dist/gestures/haptics.d.ts.map +1 -0
  252. package/dist/gestures/haptics.js +182 -0
  253. package/dist/gestures/index.d.ts +37 -0
  254. package/dist/gestures/index.d.ts.map +1 -0
  255. package/dist/gestures/index.js +25 -0
  256. package/dist/gestures/nativeScroll.d.ts +42 -0
  257. package/dist/gestures/nativeScroll.d.ts.map +1 -0
  258. package/dist/gestures/nativeScroll.js +228 -0
  259. package/dist/gestures/touchAction.d.ts +60 -0
  260. package/dist/gestures/touchAction.d.ts.map +1 -0
  261. package/dist/gestures/touchAction.js +157 -0
  262. package/dist/gestures/touchActionRule.d.ts +34 -0
  263. package/dist/gestures/touchActionRule.d.ts.map +1 -0
  264. package/dist/gestures/touchActionRule.js +140 -0
  265. package/dist/gestures/types.d.ts +18 -7
  266. package/dist/gestures/types.d.ts.map +1 -1
  267. package/dist/gestures/types.js +22 -2
  268. package/dist/gestures/useGestureRecognizer.d.ts +56 -0
  269. package/dist/gestures/useGestureRecognizer.d.ts.map +1 -0
  270. package/dist/gestures/useGestureRecognizer.js +226 -0
  271. package/dist/hooks/index.d.ts +1 -1
  272. package/dist/hooks/index.d.ts.map +1 -1
  273. package/dist/hooks/modalAnnounce.d.ts.map +1 -1
  274. package/dist/hooks/modalAnnounce.js +107 -61
  275. package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -1
  276. package/dist/hooks/scrollKeyboardDelegation.js +7 -3
  277. package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -1
  278. package/dist/hooks/useAdaptivePresentation.js +4 -1
  279. package/dist/hooks/useAnnounce.d.ts +101 -42
  280. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  281. package/dist/hooks/useAnnounce.js +161 -75
  282. package/dist/hooks/useAnnounceRenderedText.d.ts +11 -3
  283. package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
  284. package/dist/hooks/useAnnounceRenderedText.js +5 -3
  285. package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
  286. package/dist/hooks/useBusyAnnouncement.js +6 -12
  287. package/dist/hooks/useMenuHover.d.ts.map +1 -1
  288. package/dist/hooks/useMenuHover.js +12 -1
  289. package/dist/hooks/useScrollOverflow.d.ts +2 -1
  290. package/dist/hooks/useScrollOverflow.d.ts.map +1 -1
  291. package/dist/hooks/useScrollOverflow.js +56 -10
  292. package/dist/i18n/generated-locales/af-ZA.generated.d.ts.map +1 -1
  293. package/dist/i18n/generated-locales/af-ZA.generated.js +0 -5
  294. package/dist/i18n/generated-locales/ar-SA.generated.d.ts.map +1 -1
  295. package/dist/i18n/generated-locales/ar-SA.generated.js +0 -5
  296. package/dist/i18n/generated-locales/ca-ES.generated.d.ts.map +1 -1
  297. package/dist/i18n/generated-locales/ca-ES.generated.js +0 -5
  298. package/dist/i18n/generated-locales/cs-CZ.generated.d.ts.map +1 -1
  299. package/dist/i18n/generated-locales/cs-CZ.generated.js +0 -5
  300. package/dist/i18n/generated-locales/da-DK.generated.d.ts.map +1 -1
  301. package/dist/i18n/generated-locales/da-DK.generated.js +0 -5
  302. package/dist/i18n/generated-locales/de-DE.generated.d.ts.map +1 -1
  303. package/dist/i18n/generated-locales/de-DE.generated.js +0 -5
  304. package/dist/i18n/generated-locales/el-GR.generated.d.ts.map +1 -1
  305. package/dist/i18n/generated-locales/el-GR.generated.js +0 -5
  306. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  307. package/dist/i18n/generated-locales/en.generated.js +8 -5
  308. package/dist/i18n/generated-locales/es-ES.generated.d.ts.map +1 -1
  309. package/dist/i18n/generated-locales/es-ES.generated.js +0 -5
  310. package/dist/i18n/generated-locales/fi-FI.generated.d.ts.map +1 -1
  311. package/dist/i18n/generated-locales/fi-FI.generated.js +0 -5
  312. package/dist/i18n/generated-locales/fr-FR.generated.d.ts.map +1 -1
  313. package/dist/i18n/generated-locales/fr-FR.generated.js +0 -5
  314. package/dist/i18n/generated-locales/he-IL.generated.d.ts.map +1 -1
  315. package/dist/i18n/generated-locales/he-IL.generated.js +0 -5
  316. package/dist/i18n/generated-locales/hu-HU.generated.d.ts.map +1 -1
  317. package/dist/i18n/generated-locales/hu-HU.generated.js +0 -5
  318. package/dist/i18n/generated-locales/it-IT.generated.d.ts.map +1 -1
  319. package/dist/i18n/generated-locales/it-IT.generated.js +0 -5
  320. package/dist/i18n/generated-locales/ja-JP.generated.d.ts.map +1 -1
  321. package/dist/i18n/generated-locales/ja-JP.generated.js +0 -5
  322. package/dist/i18n/generated-locales/ko-KR.generated.d.ts.map +1 -1
  323. package/dist/i18n/generated-locales/ko-KR.generated.js +0 -5
  324. package/dist/i18n/generated-locales/nl-NL.generated.d.ts.map +1 -1
  325. package/dist/i18n/generated-locales/nl-NL.generated.js +0 -5
  326. package/dist/i18n/generated-locales/no-NO.generated.d.ts.map +1 -1
  327. package/dist/i18n/generated-locales/no-NO.generated.js +0 -5
  328. package/dist/i18n/generated-locales/pl-PL.generated.d.ts.map +1 -1
  329. package/dist/i18n/generated-locales/pl-PL.generated.js +0 -5
  330. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  331. package/dist/i18n/generated-locales/pseudo.generated.js +8 -5
  332. package/dist/i18n/generated-locales/pt-BR.generated.d.ts.map +1 -1
  333. package/dist/i18n/generated-locales/pt-BR.generated.js +0 -5
  334. package/dist/i18n/generated-locales/pt-PT.generated.d.ts.map +1 -1
  335. package/dist/i18n/generated-locales/pt-PT.generated.js +0 -5
  336. package/dist/i18n/generated-locales/ro-RO.generated.d.ts.map +1 -1
  337. package/dist/i18n/generated-locales/ro-RO.generated.js +0 -5
  338. package/dist/i18n/generated-locales/ru-RU.generated.d.ts.map +1 -1
  339. package/dist/i18n/generated-locales/ru-RU.generated.js +0 -5
  340. package/dist/i18n/generated-locales/sr-SP.generated.d.ts.map +1 -1
  341. package/dist/i18n/generated-locales/sr-SP.generated.js +0 -5
  342. package/dist/i18n/generated-locales/sv-SE.generated.d.ts.map +1 -1
  343. package/dist/i18n/generated-locales/sv-SE.generated.js +0 -5
  344. package/dist/i18n/generated-locales/tr-TR.generated.d.ts.map +1 -1
  345. package/dist/i18n/generated-locales/tr-TR.generated.js +0 -5
  346. package/dist/i18n/generated-locales/uk-UA.generated.d.ts.map +1 -1
  347. package/dist/i18n/generated-locales/uk-UA.generated.js +0 -5
  348. package/dist/i18n/generated-locales/vi-VN.generated.d.ts.map +1 -1
  349. package/dist/i18n/generated-locales/vi-VN.generated.js +0 -5
  350. package/dist/i18n/generated-locales/zh-CN.generated.d.ts.map +1 -1
  351. package/dist/i18n/generated-locales/zh-CN.generated.js +0 -5
  352. package/dist/i18n/generated-locales/zh-TW.generated.d.ts.map +1 -1
  353. package/dist/i18n/generated-locales/zh-TW.generated.js +0 -5
  354. package/dist/i18n/useListFormatter.d.ts +9 -0
  355. package/dist/i18n/useListFormatter.d.ts.map +1 -0
  356. package/dist/i18n/useListFormatter.js +41 -0
  357. package/dist/motion/animator.d.ts +83 -8
  358. package/dist/motion/animator.d.ts.map +1 -1
  359. package/dist/motion/animator.js +701 -119
  360. package/dist/motion/coast.d.ts +4 -1
  361. package/dist/motion/coast.d.ts.map +1 -1
  362. package/dist/motion/coast.js +4 -2
  363. package/dist/motion/reducedMotion.d.ts.map +1 -1
  364. package/dist/motion/reducedMotion.js +6 -2
  365. package/dist/motion/reducedMotionPlan.d.ts +7 -0
  366. package/dist/motion/reducedMotionPlan.d.ts.map +1 -1
  367. package/dist/motion/reducedMotionPlan.js +14 -1
  368. package/dist/motion/resolveMotion.d.ts +42 -0
  369. package/dist/motion/resolveMotion.d.ts.map +1 -0
  370. package/dist/motion/resolveMotion.js +43 -0
  371. package/dist/motion/roleValue.d.ts +2 -1
  372. package/dist/motion/roleValue.d.ts.map +1 -1
  373. package/dist/motion/roleValue.js +2 -1
  374. package/dist/motion/uikit/timing.d.ts +7 -1
  375. package/dist/motion/uikit/timing.d.ts.map +1 -1
  376. package/dist/motion/uikit/timing.js +19 -1
  377. package/dist/theme/defineTheme.d.ts +19 -5
  378. package/dist/theme/defineTheme.d.ts.map +1 -1
  379. package/dist/theme/defineTheme.js +64 -4
  380. package/dist/theme/domainTokens/domainTokenDefaults.d.ts +3 -0
  381. package/dist/theme/domainTokens/domainTokenDefaults.d.ts.map +1 -0
  382. package/dist/theme/domainTokens/domainTokenDefaults.js +19 -0
  383. package/dist/theme/domainTokens/index.d.ts +5 -4
  384. package/dist/theme/domainTokens/index.d.ts.map +1 -1
  385. package/dist/theme/domainTokens/index.js +5 -9
  386. package/dist/theme/index.d.ts +1 -0
  387. package/dist/theme/index.d.ts.map +1 -1
  388. package/dist/theme/motionKnobs.d.ts +56 -0
  389. package/dist/theme/motionKnobs.d.ts.map +1 -0
  390. package/dist/theme/motionKnobs.js +48 -0
  391. package/dist/theme/resolveThemeValues.d.ts +11 -4
  392. package/dist/theme/resolveThemeValues.d.ts.map +1 -1
  393. package/dist/theme/resolveThemeValues.js +40 -4
  394. package/dist/theme/themeAdaptations.d.ts +7 -3
  395. package/dist/theme/themeAdaptations.d.ts.map +1 -1
  396. package/dist/theme/themeAdaptations.js +36 -7
  397. package/dist/theme/themeMotion.d.ts +96 -0
  398. package/dist/theme/themeMotion.d.ts.map +1 -0
  399. package/dist/theme/themeMotion.js +177 -0
  400. package/dist/theme/tokenReferences.d.ts +31 -0
  401. package/dist/theme/tokenReferences.d.ts.map +1 -0
  402. package/dist/theme/tokenReferences.js +132 -0
  403. package/dist/theme/tokens.d.ts +1 -0
  404. package/dist/theme/tokens.d.ts.map +1 -1
  405. package/dist/theme/tokens.js +9 -129
  406. package/dist/theme/tokens.stylex.d.ts +12 -0
  407. package/dist/theme/tokens.stylex.d.ts.map +1 -1
  408. package/dist/theme/tokens.stylex.js +12 -0
  409. package/dist/utils/focusOutline.stylex.d.ts +6 -0
  410. package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
  411. package/dist/utils/focusOutline.stylex.js +7 -0
  412. package/dist/utils/focusReturn.d.ts +17 -1
  413. package/dist/utils/focusReturn.d.ts.map +1 -1
  414. package/dist/utils/focusReturn.js +11 -4
  415. package/dist/utils/getNodeText.d.ts +8 -0
  416. package/dist/utils/getNodeText.d.ts.map +1 -0
  417. package/dist/utils/getNodeText.js +37 -0
  418. package/dist/utils/interactionModality.d.ts +11 -2
  419. package/dist/utils/interactionModality.d.ts.map +1 -1
  420. package/dist/utils/interactionModality.js +58 -5
  421. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  422. package/dist/utils/interactionOverlay.stylex.js +17 -8
  423. package/dist/utils/plainDate.d.ts +2 -0
  424. package/dist/utils/plainDate.d.ts.map +1 -1
  425. package/dist/utils/plainDate.js +46 -3
  426. package/dist/utils/presentation.d.ts +50 -0
  427. package/dist/utils/presentation.d.ts.map +1 -0
  428. package/dist/utils/presentation.js +125 -0
  429. package/dist/utils/pressFeedback.d.ts.map +1 -1
  430. package/dist/utils/pressFeedback.js +20 -1
  431. package/dist/utils/primaryClick.d.ts +11 -0
  432. package/dist/utils/primaryClick.d.ts.map +1 -0
  433. package/dist/utils/primaryClick.js +25 -0
  434. package/dist/utils/sharedMutationObserver.d.ts +19 -11
  435. package/dist/utils/sharedMutationObserver.d.ts.map +1 -1
  436. package/dist/utils/sharedMutationObserver.js +66 -26
  437. package/dist/utils/timeFormat.d.ts +47 -0
  438. package/dist/utils/timeFormat.d.ts.map +1 -0
  439. package/dist/utils/timeFormat.js +240 -0
  440. package/dist/utils/touchPresentation.d.ts +2 -2
  441. package/dist/utils/touchPresentation.d.ts.map +1 -1
  442. package/dist/utils/touchPresentation.js +13 -8
  443. package/dist/utils/touchPresentation.stylex.d.ts +15 -0
  444. package/dist/utils/touchPresentation.stylex.d.ts.map +1 -0
  445. package/dist/utils/touchPresentation.stylex.js +33 -0
  446. package/dist/utils/touchQueries.d.ts +13 -0
  447. package/dist/utils/touchQueries.d.ts.map +1 -0
  448. package/dist/utils/touchQueries.js +15 -0
  449. package/dist/utils/unicodeDigits.d.ts +20 -0
  450. package/dist/utils/unicodeDigits.d.ts.map +1 -0
  451. package/dist/utils/unicodeDigits.js +70 -0
  452. package/dist/utils/useFocusAcrossSwap.d.ts +19 -0
  453. package/dist/utils/useFocusAcrossSwap.d.ts.map +1 -0
  454. package/dist/utils/useFocusAcrossSwap.js +41 -0
  455. package/locales/af-ZA.json +0 -21
  456. package/locales/ar-SA.json +0 -21
  457. package/locales/ca-ES.json +0 -21
  458. package/locales/cs-CZ.json +0 -21
  459. package/locales/da-DK.json +0 -21
  460. package/locales/de-DE.json +0 -21
  461. package/locales/el-GR.json +0 -21
  462. package/locales/en.json +35 -23
  463. package/locales/es-ES.json +0 -21
  464. package/locales/fi-FI.json +0 -21
  465. package/locales/fr-FR.json +0 -21
  466. package/locales/he-IL.json +0 -21
  467. package/locales/hu-HU.json +0 -21
  468. package/locales/it-IT.json +0 -21
  469. package/locales/ja-JP.json +0 -21
  470. package/locales/ko-KR.json +0 -21
  471. package/locales/nl-NL.json +0 -21
  472. package/locales/no-NO.json +0 -21
  473. package/locales/pl-PL.json +0 -21
  474. package/locales/pseudo.json +23 -14
  475. package/locales/pt-BR.json +0 -21
  476. package/locales/pt-PT.json +0 -21
  477. package/locales/ro-RO.json +0 -21
  478. package/locales/ru-RU.json +0 -21
  479. package/locales/sr-SP.json +0 -21
  480. package/locales/sv-SE.json +0 -21
  481. package/locales/tr-TR.json +0 -21
  482. package/locales/uk-UA.json +0 -21
  483. package/locales/vi-VN.json +0 -21
  484. package/locales/zh-CN.json +0 -21
  485. package/locales/zh-TW.json +0 -21
  486. package/package.json +5 -4
  487. package/src/AlertDialog/AlertDialog.tsx +6 -5
  488. package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +18 -6
  489. package/src/AppShell/AppShell.doc.mjs +1 -1
  490. package/src/AppShell/AppShell.spec.md +9 -12
  491. package/src/AppShell/AppShell.test.tsx +164 -2
  492. package/src/AppShell/AppShell.tsx +225 -5
  493. package/src/AppShell/__tests__/AppShellMainKeyboard.a11y.browser.spec.ts +534 -0
  494. package/src/AppShell/observeMainOverflow.test.ts +173 -0
  495. package/src/AppShell/observeMainOverflow.ts +143 -0
  496. package/src/Avatar/Avatar.spec.md +22 -22
  497. package/src/Avatar/Avatar.tsx +18 -1
  498. package/src/Avatar/__tests__/AvatarForcedColors.a11y.chromium.spec.ts +126 -0
  499. package/src/Badge/Badge.doc.mjs +1 -1
  500. package/src/Badge/Badge.tsx +19 -2
  501. package/src/Badge/__tests__/BadgeLargerText.a11y.chromium.spec.ts +260 -0
  502. package/src/BottomSheet/BottomSheet.test.tsx +46 -0
  503. package/src/BottomSheet/BottomSheet.tsx +1 -1
  504. package/src/BottomSheet/BottomSheetPanel.tsx +2 -1
  505. package/src/BottomSheet/useSheetGestures.test.ts +52 -0
  506. package/src/BottomSheet/useSheetGestures.ts +37 -6
  507. package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.chromium.spec.ts +18 -6
  508. package/src/Button/Button.tsx +4 -4
  509. package/src/Calendar/Calendar.spec.md +87 -48
  510. package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +21 -7
  511. package/src/Carousel/Carousel.doc.mjs +1 -1
  512. package/src/Carousel/Carousel.spec.md +9 -9
  513. package/src/Carousel/Carousel.test.tsx +124 -3
  514. package/src/Carousel/Carousel.tsx +10 -2
  515. package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +21 -7
  516. package/src/Carousel/__tests__/Carousel.a11y.known-failures.ts +1 -16
  517. package/src/Chat/ChatComposer.spec.md +75 -59
  518. package/src/Chat/ChatComposerTokenElement.spec.md +45 -33
  519. package/src/Chat/ChatDictationButton.spec.md +126 -81
  520. package/src/Chat/ChatLayout.spec.md +41 -36
  521. package/src/Chat/ChatLayoutScrollButton.spec.md +87 -103
  522. package/src/Chat/ChatMessage.spec.md +64 -65
  523. package/src/Chat/ChatSendButton.spec.md +78 -67
  524. package/src/CheckboxInput/CheckboxInput.tsx +6 -5
  525. package/src/Citation/Citation.spec.md +60 -47
  526. package/src/ClickableCard/ClickableCard.test.tsx +96 -0
  527. package/src/ClickableCard/ClickableCard.tsx +48 -4
  528. package/src/CodeBlock/__tests__/CodeBlockCopyClearance.a11y.chromium.spec.ts +38 -3
  529. package/src/Collapsible/Collapsible.spec.md +2 -0
  530. package/src/Collapsible/CollapsibleGroup.spec.md +57 -29
  531. package/src/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts +18 -7
  532. package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +18 -6
  533. package/src/ComplexSelector/ComplexSelector.test.tsx +148 -0
  534. package/src/ComplexSelector/ComplexSelector.tsx +41 -4
  535. package/src/ContextMenu/ContextMenu.spec.md +84 -56
  536. package/src/ContextMenu/ContextMenu.test.tsx +35 -0
  537. package/src/ContextMenu/ContextMenuItem.spec.md +132 -0
  538. package/src/DateInput/DateInput.spec.md +74 -57
  539. package/src/DateInput/DateInput.test.tsx +115 -3
  540. package/src/DateInput/DateInput.tsx +29 -14
  541. package/src/DateInput/DateInputTouch.test.tsx +120 -0
  542. package/src/DateInput/MonthScroller.tsx +106 -20
  543. package/src/DateInput/MonthScrollerSettle.test.tsx +165 -0
  544. package/src/DateInput/TouchDateField.tsx +14 -3
  545. package/src/DateInput/Wheel.tsx +9 -6
  546. package/src/DateInput/__tests__/MonthScrollerSteps.interaction.browser.spec.ts +312 -0
  547. package/src/DateInput/usePointerDragScroll.ts +34 -10
  548. package/src/DateInput/useScrollSettle.ts +38 -7
  549. package/src/DateRangeInput/DateRangeInput.test.tsx +46 -3
  550. package/src/DateRangeInput/DateRangeInput.tsx +16 -12
  551. package/src/DateTimeInput/DateTimeInput.doc.mjs +10 -8
  552. package/src/DateTimeInput/DateTimeInput.spec.md +75 -51
  553. package/src/DateTimeInput/DateTimeInput.test.tsx +81 -0
  554. package/src/DateTimeInput/DateTimeInput.tsx +46 -24
  555. package/src/DateTimeInput/NativeTimeSegment.tsx +4 -6
  556. package/src/DateTimeInput/TouchDateTimeField.tsx +3 -7
  557. package/src/Dialog/Dialog.test.tsx +216 -2
  558. package/src/Dialog/Dialog.tsx +42 -9
  559. package/src/Dialog/DialogHeader.tsx +5 -4
  560. package/src/Dialog/__tests__/DialogSecondDocument.a11y.browser.spec.ts +202 -0
  561. package/src/Divider/Divider.tsx +2 -1
  562. package/src/Drawer/Drawer.spec.md +111 -80
  563. package/src/Drawer/Drawer.test.tsx +35 -0
  564. package/src/Drawer/Drawer.tsx +13 -2
  565. package/src/Drawer/DrawerHeader.spec.md +181 -0
  566. package/src/Drawer/__tests__/DrawerNonModalPageScroll.a11y.chromium.spec.ts +267 -0
  567. package/src/DropdownMenu/DropdownMenu.spec.md +198 -218
  568. package/src/DropdownMenu/DropdownMenu.test.tsx +158 -0
  569. package/src/DropdownMenu/DropdownMenu.tsx +43 -21
  570. package/src/DropdownMenu/DropdownMenuCheckboxItem.spec.md +192 -0
  571. package/src/DropdownMenu/DropdownMenuDivider.spec.md +25 -31
  572. package/src/DropdownMenu/DropdownMenuGroup.spec.md +145 -0
  573. package/src/DropdownMenu/DropdownMenuItem.spec.md +48 -42
  574. package/src/DropdownMenu/DropdownMenuRadioGroup.spec.md +34 -37
  575. package/src/DropdownMenu/DropdownMenuRadioItem.spec.md +54 -53
  576. package/src/DropdownMenu/DropdownMenuSubMenu.spec.md +47 -41
  577. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +34 -0
  578. package/src/DropdownMenu/MenuBottomSheetActionList.tsx +6 -5
  579. package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +19 -7
  580. package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +21 -9
  581. package/src/DropdownMenu/lazyMenuBottomSheet.test.ts +60 -0
  582. package/src/DropdownMenu/lazyMenuBottomSheet.ts +36 -7
  583. package/src/DropdownMenu/renderDropdownItems.tsx +24 -19
  584. package/src/EmptyState/EmptyState.spec.md +35 -29
  585. package/src/EmptyState/EmptyState.tsx +2 -1
  586. package/src/Field/FieldLabel.tsx +5 -4
  587. package/src/Field/InputClearButton.tsx +3 -3
  588. package/src/Field/PanelSearchInput.tsx +2 -2
  589. package/src/FieldStatus/FieldStatus.tsx +9 -2
  590. package/src/FieldStatus/__tests__/FieldStatusAudit.a11y.chromium.spec.ts +477 -0
  591. package/src/FileInput/FileInput.test.tsx +159 -0
  592. package/src/FileInput/FileInput.tsx +34 -6
  593. package/src/FileInput/__tests__/FileInputAudit.a11y.chromium.spec.ts +796 -0
  594. package/src/FormLayout/FormLayout.spec.md +11 -20
  595. package/src/Heading/Heading.tsx +1 -1
  596. package/src/Icon/Icon.tsx +1 -1
  597. package/src/Indicator/CheckIndicator.spec.md +47 -42
  598. package/src/Indicator/CheckIndicator.tsx +2 -1
  599. package/src/Indicator/CheckboxIndicator.spec.md +40 -37
  600. package/src/Indicator/CheckboxIndicator.tsx +3 -1
  601. package/src/Indicator/Indicator.spec.md +188 -0
  602. package/src/Indicator/RadioIndicator.tsx +3 -1
  603. package/src/Item/Item.test.tsx +60 -0
  604. package/src/Item/Item.tsx +16 -8
  605. package/src/Item/ItemSwipeLayer.tsx +1 -1
  606. package/src/Kbd/Kbd.spec.md +81 -38
  607. package/src/Layer/__tests__/LayerBrowserHide.a11y.chromium.spec.ts +126 -0
  608. package/src/Layer/popoverOperations.test.ts +205 -0
  609. package/src/Layer/popoverOperations.ts +172 -0
  610. package/src/Layer/useLayer.test.tsx +426 -4
  611. package/src/Layer/useLayer.tsx +145 -77
  612. package/src/Layout/Layout.spec.md +127 -131
  613. package/src/Layout/Layout.tsx +1 -1
  614. package/src/Layout/LayoutContent.spec.md +205 -0
  615. package/src/Layout/LayoutContent.tsx +1 -1
  616. package/src/Layout/LayoutFooter.spec.md +190 -0
  617. package/src/Layout/LayoutFooter.tsx +1 -1
  618. package/src/Layout/LayoutHeader.spec.md +193 -0
  619. package/src/Layout/LayoutHeader.tsx +1 -1
  620. package/src/Layout/LayoutPanel.spec.md +194 -0
  621. package/src/Layout/__tests__/Layout.a11y.chromium.spec.ts +18 -6
  622. package/src/Lightbox/Lightbox.test.tsx +18 -0
  623. package/src/Lightbox/Lightbox.tsx +5 -0
  624. package/src/Lightbox/LightboxViewport.a11y.browser.spec.ts +8 -4
  625. package/src/Link/Link.spec.md +3 -2
  626. package/src/Link/Link.tsx +11 -0
  627. package/src/Link/__tests__/Link.a11y.chromium.spec.ts +18 -8
  628. package/src/Link/__tests__/Link.truncation.a11y.chromium.spec.ts +58 -0
  629. package/src/List/List.tsx +1 -1
  630. package/src/List/ListItem.spec.md +205 -0
  631. package/src/List/ListItem.tsx +3 -3
  632. package/src/Markdown/plugins/headingLinks.a11y.chromium.spec.ts +1 -1
  633. package/src/MetadataList/MetadataList.spec.md +187 -0
  634. package/src/MetadataList/MetadataListItem.spec.md +165 -0
  635. package/src/MobileNav/MobileNav.test.tsx +15 -0
  636. package/src/MobileNav/MobileNav.tsx +9 -1
  637. package/src/MobileNav/__tests__/MobileNavHeader.a11y.chromium.spec.ts +89 -0
  638. package/src/MoreMenu/MoreMenu.test.tsx +11 -0
  639. package/src/MultiSelector/CreateRow.a11y.chromium.spec.ts +7 -8
  640. package/src/MultiSelector/MultiSelector.spec.md +7 -4
  641. package/src/MultiSelector/MultiSelector.test.tsx +270 -1
  642. package/src/MultiSelector/MultiSelector.tsx +25 -10
  643. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +8 -1
  644. package/src/NavMenu/NavHeadingMenu.spec.md +1 -5
  645. package/src/NavMenu/NavHeadingMenuItem.tsx +5 -39
  646. package/src/NumberInput/NumberInput.doc.mjs +13 -7
  647. package/src/NumberInput/NumberInput.spec.md +59 -37
  648. package/src/NumberInput/NumberInput.test.tsx +68 -7
  649. package/src/NumberInput/NumberInput.tsx +44 -4
  650. package/src/NumberInput/__tests__/NumberInput.coarse-pointer.a11y.chromium.spec.ts +102 -0
  651. package/src/NumberInput/numberParser.ts +7 -45
  652. package/src/Outline/Outline.spec.md +165 -69
  653. package/src/Outline/Outline.test.tsx +67 -2
  654. package/src/Outline/Outline.tsx +23 -0
  655. package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +3 -4
  656. package/src/OverflowList/OverflowList.spec.md +102 -55
  657. package/src/Pagination/Pagination.spec.md +158 -84
  658. package/src/Popover/Popover.test.tsx +84 -0
  659. package/src/Popover/Popover.tsx +34 -14
  660. package/src/Popover/__tests__/PopoverSecondDocument.a11y.chromium.spec.ts +70 -8
  661. package/src/Popover/usePopover.tsx +10 -3
  662. package/src/PowerSearch/PowerSearch.test.tsx +24 -0
  663. package/src/PowerSearch/PowerSearch.tsx +42 -31
  664. package/src/ProgressBar/ProgressBar.spec.md +143 -119
  665. package/src/ProgressBar/ProgressBar.test.tsx +108 -32
  666. package/src/ProgressBar/ProgressBar.tsx +58 -10
  667. package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +21 -9
  668. package/src/ProgressBar/__tests__/ProgressBarMotion.a11y.chromium.spec.ts +831 -0
  669. package/src/RadioList/RadioList.spec.md +1 -1
  670. package/src/RadioList/RadioList.test.tsx +84 -0
  671. package/src/RadioList/RadioListItem.tsx +11 -2
  672. package/src/Resizable/Resizable.spec.md +144 -124
  673. package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +21 -14
  674. package/src/Resizable/useResizable.test.ts +43 -0
  675. package/src/Resizable/useResizable.ts +32 -9
  676. package/src/SegmentedControl/SegmentedControl.test.tsx +84 -0
  677. package/src/SegmentedControl/SegmentedControlItem.tsx +11 -5
  678. package/src/Selector/Selector.test.tsx +90 -1
  679. package/src/Selector/__tests__/Selector.combobox.a11y.test.tsx +8 -1
  680. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +8 -1
  681. package/src/Selector/useSelectorPresentation.ts +31 -3
  682. package/src/SideNav/SideNav.test.tsx +151 -4
  683. package/src/SideNav/SideNavItem.spec.md +14 -24
  684. package/src/SideNav/SideNavItem.tsx +27 -10
  685. package/src/SideNav/__tests__/SideNavRailMotion.interaction.browser.spec.ts +176 -51
  686. package/src/Skeleton/Skeleton.tsx +3 -1
  687. package/src/Slider/Slider.test.tsx +31 -0
  688. package/src/Slider/Slider.tsx +8 -3
  689. package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +19 -7
  690. package/src/Spinner/Spinner.tsx +5 -3
  691. package/src/Stack/Stack.tsx +1 -1
  692. package/src/Stack/StackItem.tsx +1 -1
  693. package/src/Stepper/Step.spec.md +36 -42
  694. package/src/Stepper/Step.tsx +33 -6
  695. package/src/Stepper/Stepper.doc.mjs +1 -1
  696. package/src/Stepper/Stepper.test.tsx +69 -7
  697. package/src/Switch/Switch.spec.md +1 -1
  698. package/src/Switch/Switch.test.tsx +66 -1
  699. package/src/Switch/Switch.tsx +11 -3
  700. package/src/TabList/TabList.test.tsx +58 -4
  701. package/src/TabList/TabList.tsx +16 -1
  702. package/src/TabList/__tests__/TabPressPointer.interaction.browser.spec.ts +163 -0
  703. package/src/Table/Table.spec.md +1 -1
  704. package/src/Table/Table.test.tsx +32 -0
  705. package/src/Table/Table.tsx +43 -11
  706. package/src/Table/__tests__/Table.a11y.chromium.spec.ts +18 -6
  707. package/src/Table/__tests__/Table.a11y.states.ts +1 -5
  708. package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +22 -0
  709. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +8 -4
  710. package/src/Table/plugins/sortable/useTableSortable.test.tsx +73 -144
  711. package/src/Table/plugins/sortable/useTableSortable.tsx +44 -73
  712. package/src/Table/plugins/sortable/useTableSortableState.test.tsx +9 -21
  713. package/src/Text/Text.tsx +1 -1
  714. package/src/Text/useTruncation.test.tsx +128 -1
  715. package/src/Text/useTruncation.ts +23 -5
  716. package/src/TextArea/TextArea.spec.md +10 -13
  717. package/src/TextArea/TextArea.test.tsx +60 -0
  718. package/src/TextArea/TextArea.tsx +15 -1
  719. package/src/TextInput/TextInput.test.tsx +21 -0
  720. package/src/TextInput/TextInput.tsx +3 -1
  721. package/src/TimeInput/NativeTimeInput.test.tsx +17 -0
  722. package/src/TimeInput/Presentation.test.tsx +21 -0
  723. package/src/TimeInput/TimeInput.doc.mjs +8 -8
  724. package/src/TimeInput/TimeInput.spec.md +58 -61
  725. package/src/TimeInput/TimeInput.test.tsx +76 -0
  726. package/src/TimeInput/TimeInput.tsx +36 -18
  727. package/src/TimeInput/TouchTimeField.tsx +4 -6
  728. package/src/Timestamp/Timestamp.spec.md +6 -12
  729. package/src/Timestamp/Timestamp.test.tsx +30 -5
  730. package/src/Timestamp/Timestamp.tsx +6 -2
  731. package/src/Timestamp/TimestampHoverCard.tsx +4 -4
  732. package/src/Toast/Toast.spec.md +15 -24
  733. package/src/Toast/Toast.tsx +104 -36
  734. package/src/Toast/ToastViewport.test.tsx +798 -1
  735. package/src/Toast/ToastViewport.tsx +121 -53
  736. package/src/ToggleButton/ToggleButton.test.tsx +27 -0
  737. package/src/ToggleButton/ToggleButtonGroup.tsx +20 -1
  738. package/src/Token/Token.doc.mjs +2 -2
  739. package/src/Token/Token.spec.md +52 -61
  740. package/src/Token/Token.test.tsx +104 -0
  741. package/src/Token/Token.tsx +75 -5
  742. package/src/Token/TokenLink.tsx +21 -7
  743. package/src/Tokenizer/Tokenizer.spec.md +18 -4
  744. package/src/Tokenizer/Tokenizer.test.tsx +176 -0
  745. package/src/Tokenizer/Tokenizer.tsx +48 -12
  746. package/src/Tokenizer/TokenizerBottomSheet.test.tsx +23 -4
  747. package/src/Tokenizer/TokenizerBottomSheet.tsx +3 -3
  748. package/src/Tokenizer/TokenizerClearAllMessageContext.ts +21 -0
  749. package/src/Toolbar/Toolbar.spec.md +5 -6
  750. package/src/Toolbar/Toolbar.test.tsx +30 -0
  751. package/src/Toolbar/Toolbar.tsx +2 -1
  752. package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +18 -6
  753. package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +18 -7
  754. package/src/TopNav/TopNav.test.tsx +27 -0
  755. package/src/TopNav/TopNavMegaMenu.test.tsx +21 -0
  756. package/src/TopNav/TopNavMegaMenu.tsx +4 -1
  757. package/src/TopNav/TopNavMenu.test.tsx +17 -0
  758. package/src/TopNav/TopNavMenu.tsx +1 -0
  759. package/src/TreeList/TreeList.test.tsx +26 -0
  760. package/src/TreeList/TreeListItem.tsx +26 -4
  761. package/src/Typeahead/BaseTypeahead.doc.mjs +3 -3
  762. package/src/Typeahead/BaseTypeahead.spec.md +45 -45
  763. package/src/Typeahead/BaseTypeahead.tsx +48 -9
  764. package/src/Typeahead/Typeahead.test.tsx +294 -11
  765. package/src/Typeahead/Typeahead.tsx +51 -9
  766. package/src/__tests__/internalModulesNotExperimental.test.ts +88 -0
  767. package/src/__tests__/pressState.ts +8 -4
  768. package/src/gestures/GestureArena.ts +111 -11
  769. package/src/gestures/GestureHost.ts +2064 -0
  770. package/src/gestures/GestureRecognizer.ts +21 -1
  771. package/src/gestures/LongPressGestureRecognizer.ts +4 -0
  772. package/src/gestures/PanGestureRecognizer.ts +4 -0
  773. package/src/gestures/PinchGestureRecognizer.ts +148 -0
  774. package/src/gestures/PressTracker.ts +386 -0
  775. package/src/gestures/README.md +420 -0
  776. package/src/gestures/ScreenEdgePanGestureRecognizer.ts +256 -0
  777. package/src/gestures/SwipeGestureRecognizer.ts +197 -0
  778. package/src/gestures/TapGestureRecognizer.ts +4 -0
  779. package/src/gestures/VelocityTracker.ts +10 -3
  780. package/src/gestures/__tests__/GestureHost.test.ts +2136 -0
  781. package/src/gestures/__tests__/PanGestureRecognizer.test.ts +4 -4
  782. package/src/gestures/__tests__/PinchGestureRecognizer.test.ts +74 -0
  783. package/src/gestures/__tests__/PressTracker.test.ts +275 -0
  784. package/src/gestures/__tests__/ScreenEdgePanGestureRecognizer.test.ts +498 -0
  785. package/src/gestures/__tests__/SwipeGestureRecognizer.test.ts +108 -0
  786. package/src/gestures/__tests__/arena.test.ts +40 -0
  787. package/src/gestures/__tests__/arenaPinchSwipeEdge.test.ts +193 -0
  788. package/src/gestures/__tests__/browser/build-fixture.mjs +46 -0
  789. package/src/gestures/__tests__/browser/fixture.ts +307 -0
  790. package/src/gestures/__tests__/browser/gestures.interaction.browser.spec.ts +1137 -0
  791. package/src/gestures/__tests__/browserNegotiation.test.ts +293 -0
  792. package/src/gestures/__tests__/haptics.test.ts +187 -0
  793. package/src/gestures/__tests__/harness.ts +52 -4
  794. package/src/gestures/__tests__/pressTrackerFactory.test.ts +59 -0
  795. package/src/gestures/__tests__/recognizerKind.test.ts +78 -0
  796. package/src/gestures/__tests__/touchActionRule.test.ts +54 -0
  797. package/src/gestures/__tests__/useGestureRecognizer.test.tsx +570 -0
  798. package/src/gestures/haptics.ts +203 -0
  799. package/src/gestures/index.ts +79 -0
  800. package/src/gestures/nativeScroll.ts +277 -0
  801. package/src/gestures/touchAction.ts +191 -0
  802. package/src/gestures/touchActionRule.ts +157 -0
  803. package/src/gestures/types.ts +30 -9
  804. package/src/gestures/useGestureRecognizer.ts +305 -0
  805. package/src/hooks/index.ts +5 -1
  806. package/src/hooks/modalAnnounce.ts +129 -72
  807. package/src/hooks/scrollKeyboardDelegation.test.ts +33 -0
  808. package/src/hooks/scrollKeyboardDelegation.ts +9 -3
  809. package/src/hooks/useAdaptivePresentation.ts +4 -1
  810. package/src/hooks/useAnnounce.doc.mjs +35 -3
  811. package/src/hooks/useAnnounce.replace.test.tsx +516 -0
  812. package/src/hooks/useAnnounce.ts +209 -102
  813. package/src/hooks/useAnnounceRenderedText.adopters.test.tsx +10 -1
  814. package/src/hooks/useAnnounceRenderedText.ts +17 -3
  815. package/src/hooks/useBusyAnnouncement.ts +7 -10
  816. package/src/hooks/useMenuHover.ts +15 -1
  817. package/src/hooks/useScrollOverflow.doc.mjs +1 -1
  818. package/src/hooks/useScrollOverflow.test.tsx +102 -1
  819. package/src/hooks/useScrollOverflow.ts +59 -10
  820. package/src/i18n/__tests__/useListFormatter.test.tsx +58 -0
  821. package/src/i18n/generated-locales/af-ZA.generated.ts +0 -7
  822. package/src/i18n/generated-locales/ar-SA.generated.ts +0 -6
  823. package/src/i18n/generated-locales/ca-ES.generated.ts +0 -7
  824. package/src/i18n/generated-locales/cs-CZ.generated.ts +0 -6
  825. package/src/i18n/generated-locales/da-DK.generated.ts +0 -6
  826. package/src/i18n/generated-locales/de-DE.generated.ts +0 -6
  827. package/src/i18n/generated-locales/el-GR.generated.ts +0 -7
  828. package/src/i18n/generated-locales/en.generated.ts +9 -6
  829. package/src/i18n/generated-locales/es-ES.generated.ts +0 -7
  830. package/src/i18n/generated-locales/fi-FI.generated.ts +0 -6
  831. package/src/i18n/generated-locales/fr-FR.generated.ts +0 -7
  832. package/src/i18n/generated-locales/he-IL.generated.ts +0 -6
  833. package/src/i18n/generated-locales/hu-HU.generated.ts +0 -6
  834. package/src/i18n/generated-locales/it-IT.generated.ts +0 -7
  835. package/src/i18n/generated-locales/ja-JP.generated.ts +0 -6
  836. package/src/i18n/generated-locales/ko-KR.generated.ts +0 -6
  837. package/src/i18n/generated-locales/nl-NL.generated.ts +0 -6
  838. package/src/i18n/generated-locales/no-NO.generated.ts +0 -6
  839. package/src/i18n/generated-locales/pl-PL.generated.ts +0 -7
  840. package/src/i18n/generated-locales/pseudo.generated.ts +9 -6
  841. package/src/i18n/generated-locales/pt-BR.generated.ts +0 -7
  842. package/src/i18n/generated-locales/pt-PT.generated.ts +0 -7
  843. package/src/i18n/generated-locales/ro-RO.generated.ts +0 -6
  844. package/src/i18n/generated-locales/ru-RU.generated.ts +0 -7
  845. package/src/i18n/generated-locales/sr-SP.generated.ts +0 -6
  846. package/src/i18n/generated-locales/sv-SE.generated.ts +0 -6
  847. package/src/i18n/generated-locales/tr-TR.generated.ts +0 -7
  848. package/src/i18n/generated-locales/uk-UA.generated.ts +0 -7
  849. package/src/i18n/generated-locales/vi-VN.generated.ts +0 -6
  850. package/src/i18n/generated-locales/zh-CN.generated.ts +0 -6
  851. package/src/i18n/generated-locales/zh-TW.generated.ts +0 -6
  852. package/src/i18n/useListFormatter.ts +42 -0
  853. package/src/motion/MEASUREMENTS.md +2 -1
  854. package/src/motion/README.md +113 -33
  855. package/src/motion/__tests__/animator.interaction.browser.spec.ts +843 -0
  856. package/src/motion/__tests__/motionBundle.ts +14 -0
  857. package/src/motion/animator.test.ts +1125 -32
  858. package/src/motion/animator.ts +932 -130
  859. package/src/motion/coast.ts +10 -3
  860. package/src/motion/reducedMotion.ts +12 -2
  861. package/src/motion/reducedMotionPlan.test.ts +26 -0
  862. package/src/motion/reducedMotionPlan.ts +20 -1
  863. package/src/motion/resolveMotion.test.ts +123 -0
  864. package/src/motion/resolveMotion.ts +68 -0
  865. package/src/motion/roleValue.ts +2 -1
  866. package/src/motion/roles.test.ts +21 -4
  867. package/src/motion/uikit/tableImports.test.ts +293 -0
  868. package/src/motion/uikit/timing.ts +15 -1
  869. package/src/motion/uikit/values.test.ts +23 -12
  870. package/src/theme/Theme.doc.mjs +1 -1
  871. package/src/theme/defineTheme.ts +117 -8
  872. package/src/theme/derivedVarRegistry.test.ts +4 -0
  873. package/src/theme/domainTokens/domainTokenDefaults.ts +19 -0
  874. package/src/theme/domainTokens/index.ts +6 -10
  875. package/src/theme/expandMotionScale.test.ts +1 -1
  876. package/src/theme/index.ts +5 -0
  877. package/src/theme/motionKnobs.ts +82 -0
  878. package/src/theme/resolveThemeValues.ts +68 -6
  879. package/src/theme/themeAdaptations.ts +52 -12
  880. package/src/theme/themeMotion.test.ts +620 -0
  881. package/src/theme/themeMotion.ts +221 -0
  882. package/src/theme/tokenReferences.ts +149 -0
  883. package/src/theme/tokens.stylex.ts +10 -0
  884. package/src/theme/tokens.ts +15 -158
  885. package/src/utils/focusOutline.stylex.ts +28 -0
  886. package/src/utils/focusReturn.ts +17 -6
  887. package/src/utils/getNodeText.test.ts +24 -0
  888. package/src/utils/getNodeText.ts +37 -0
  889. package/src/utils/interactionModality.test.ts +45 -1
  890. package/src/utils/interactionModality.ts +64 -5
  891. package/src/utils/interactionOverlay.stylex.ts +12 -3
  892. package/src/utils/plainDate.test.ts +90 -0
  893. package/src/utils/plainDate.ts +58 -3
  894. package/src/utils/presentation.test.ts +380 -0
  895. package/src/utils/presentation.ts +180 -0
  896. package/src/utils/pressFeedback.test.ts +138 -0
  897. package/src/utils/pressFeedback.ts +34 -11
  898. package/src/utils/pressGesture.test.ts +9 -0
  899. package/src/utils/pressPaintPriority.test.ts +80 -0
  900. package/src/utils/primaryClick.test.ts +38 -0
  901. package/src/utils/primaryClick.ts +28 -0
  902. package/src/utils/sharedMutationObserver.test.ts +54 -1
  903. package/src/utils/sharedMutationObserver.ts +87 -29
  904. package/src/utils/timeFormat.test.ts +204 -0
  905. package/src/utils/timeFormat.ts +314 -0
  906. package/src/utils/touchPresentation.stylex.ts +43 -0
  907. package/src/utils/touchPresentation.test.ts +140 -1
  908. package/src/utils/touchPresentation.ts +13 -8
  909. package/src/utils/touchQueries.ts +15 -0
  910. package/src/utils/unicodeDigits.test.ts +44 -0
  911. package/src/utils/unicodeDigits.ts +71 -0
  912. package/src/utils/useFocusAcrossSwap.ts +55 -0
@@ -3,45 +3,48 @@ schema_version: 3
3
3
  template_version: 7
4
4
  kind: component
5
5
  id: component:Calendar
6
- authority: draft
6
+ authority: current
7
7
  archive_reason: null
8
8
  superseded_by: null
9
- approved_by: null
10
- approved_at: null
9
+ approved_by: cixzhang
10
+ approved_at: 2026-10-31
11
11
  owners: [cixzhang]
12
12
  review_triggers: [public-api, behavior, accessibility, theming]
13
13
  verified_by:
14
14
  [
15
15
  packages/core/src/Calendar/Calendar.test.tsx,
16
16
  packages/core/src/hooks/useGridFocus.test.tsx,
17
+ packages/core/src/Calendar/__tests__/Calendar.a11y.test.tsx,
18
+ packages/core/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts,
17
19
  scripts/check-knowledge.mjs,
18
20
  ]
19
21
  modules: []
20
22
  families: []
21
- design_specs: []
23
+ design_specs: [design:bidirectionality, design:reduced-motion]
22
24
  architecture:
23
25
  [
26
+ architecture:internationalization,
24
27
  architecture:public-component-api,
25
28
  architecture:component-theming-surface,
26
29
  architecture:react-component-runtime,
27
30
  ]
28
31
  contributing: []
29
- system_specs: [spec:AST-020/FR15]
32
+ system_specs: [spec:AST-020/FR15, spec:AST-085, spec:AST-102]
30
33
  ---
31
34
 
32
35
  # Calendar component contract
33
36
 
34
37
  ## Contract at a glance
35
38
 
36
- | Area | Contract |
37
- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
38
- | Public contract | None changes. `Calendar` and `CalendarProps` are exported from `@astryxdesign/core/Calendar`; `mode` selects a single date or a range, with `value`/`defaultValue`/`onChange`, bounds, constraints, span limits, focus date, and display options. |
39
- | Behavior | One or two months render as day grids; a day is picked by pointer or keyboard; each month grid holds at most one roving Tab stop, which arrow, Home/End, and Page keys move, following the reading direction. |
40
- | End-user impact | A keyboard or screen-reader user meets a named month grid, moves through it by day, week, and month, and hears each day's name, selection, today marker, and disabled state. |
41
- | Builder impact | None. |
42
- | Compatibility/readiness | Released behavior as observed; this draft records it and adopts the APG Grid pattern for the day grid (AR1) under `spec:AST-020/FR15`. |
43
- | Review checks | Reject a day grid without `role="grid"` or a name, two days in one month holding a Tab stop, an arrow key that stops following the reading direction, or a selection or today state carried only by colour. |
44
- | Governing rules | `architecture:public-component-api/INV1,INV5–INV8`; `architecture:component-theming-surface/INV3–INV7`; `spec:AST-020/FR15`. |
39
+ | Area | Contract |
40
+ | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
41
+ | Public contract | None changes. `Calendar` and `CalendarProps` are exported from `@astryxdesign/core/Calendar`; `mode` selects a single date or a range, with `value`/`defaultValue`/`onChange`, bounds, constraints, span limits, focus date, and display options. |
42
+ | Behavior | One or two months render as day grids; a day is picked by pointer or keyboard; each month grid holds at most one roving Tab stop, which arrow, Home/End, and Page keys move, following the reading direction. |
43
+ | End-user impact | A keyboard or screen-reader user meets a named month grid, moves through it by day, week, and month, and hears each day's name, selection, today marker, and disabled state. |
44
+ | Builder impact | None. |
45
+ | Compatibility/readiness | Records shipped behavior; no API, default, or DOM change. The month buttons use native `disabled` at a bound and scale under reduced motion, day buttons hold a fixed size, day and week numbers use ASCII digits, and a key-moved Tab stop can go stale; all are listed under Current-state impact. |
46
+ | Review checks | Reject a day grid without `role="grid"` or a name, two days in one month holding a Tab stop, an arrow key that stops following the reading direction, or a selection or today state carried only by colour. |
47
+ | Governing rules | `architecture:public-component-api/INV1,INV5–INV8`; `architecture:component-theming-surface/INV3–INV7`; `spec:AST-020/FR15`; `spec:AST-085/FR1, FR4`; `spec:AST-102` FR4; `design:bidirectionality` DR6; `design:reduced-motion` DR1; `architecture:internationalization` INV8. |
45
48
 
46
49
  This table is a review projection; the body below is authoritative.
47
50
 
@@ -54,10 +57,10 @@ keyboard model that moves through days; date fields compose it.
54
57
  ## Compatibility and migration
55
58
 
56
59
  - Released default preserved: `yes`
57
- - Compatibility class: additive documentation; runtime, DOM, styling, targets, and
58
- public API are unchanged
59
- - Controlled/uncontrolled behavior: unchanged — `value` with `onChange` is
60
- controlled; `defaultValue` starts internal state
60
+ - Compatibility class: records shipped behavior; no public prop, default,
61
+ export, or DOM change
62
+ - Controlled/uncontrolled behavior: `value` with `onChange` is controlled;
63
+ `defaultValue` starts internal state
61
64
  - Migration decision: none
62
65
 
63
66
  Consumer migration instructions belong in consumer docs and release notes.
@@ -74,8 +77,11 @@ Consumer migration instructions belong in consumer docs and release notes.
74
77
  **Does not own / non-goals**
75
78
 
76
79
  - The text field, popover, and bottom sheet that present a Calendar — owned by
77
- `component:DateInput` and its siblings.
78
- - Time of day — owned by `component:DateTimeInput`.
80
+ DateInput and its siblings.
81
+ - Time of day — owned by DateTimeInput.
82
+ - `handleRef`, `onFocusDateChange`, the opening month inside the `min`/`max`
83
+ window, `weekStartsOn`, and `numberOfMonths` clamping — shipped and covered
84
+ by the consumer docs and tests, uncontracted here beyond FR1–FR7.
79
85
 
80
86
  ## Public concepts
81
87
 
@@ -87,16 +93,15 @@ Consumer migration instructions belong in consumer docs and release notes.
87
93
 
88
94
  ## Behavioral and layout contract
89
95
 
90
- Draft requirements identify their basis so observed code is not mistaken for an
91
- intentional decision. A `current` contract contains no unresolved rows.
92
-
93
- | ID | Candidate invariant | Basis | Draft review state |
94
- | --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ------------------ |
95
- | FR1 | Each rendered month is one `role="grid"` named for its month and year, with a `columnheader` per weekday (and, with week numbers, a named `columnheader` above the `rowheader` column) and one `row` per week. | shipped source and focused tests | verify |
96
- | FR2 | At most one day button in each month's grid holds `tabIndex={0}`; every other day button in that grid is `-1`. | shipped `useGridFocus` behavior; Grid accessibility contract (pending) | verify |
97
- | FR3 | A disabled day (outside bounds or rejected by a constraint) stays in the grid, is exposed as disabled, and cannot be picked. | shipped source and focused tests | verify |
98
- | FR4 | In `range` mode the first pick starts the range and the second ends it, a second pick before the start swapping the two so the end never precedes the start; `minRangeSpan`/`maxRangeSpan` bound it. Escape, or picking the start day again when `minRangeSpan` is above 1, clears an in-progress range. | shipped source and focused tests | verify |
99
- | FR5 | Moving the focused day across a month boundary navigates the visible month so the focused day stays visible, in one month or two; a borrowed adjacent-month day is exposed `aria-disabled` and cannot be picked; arrow keys, Home and End skip it, and a page never lands on it. | shipped source and focused tests | verify |
96
+ | ID | Invariant | Basis |
97
+ | --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
98
+ | FR1 | Each rendered month is one `role="grid"` named for its month and year, with a `columnheader` per weekday (and, with week numbers, a named `columnheader` above the `rowheader` column) and one `row` per week. Month and year labels and day names come from the provider locale. Day and week numbers MUST use the locale's digits (`architecture:internationalization` INV8). Implementation gap: they render as ASCII digits in every locale. | shipped source and focused tests; `architecture:internationalization` INV8 |
99
+ | FR2 | At most one day button in each month's grid holds `tabIndex={0}`; every other day button in that grid is `-1`. Each day button is the shared `sm` element size (inside an `md`-sized cell) as a minimum that grows with a set text size (`spec:AST-102` FR4). Implementation gap: the day buttons hold a fixed size. | shipped `useGridFocus` behavior; `Calendar.test.tsx` single-Tab-stop assertion; `spec:AST-102` FR4 |
100
+ | FR3 | A disabled day (outside bounds or rejected by a constraint) stays in the grid, stays focusable with `aria-disabled` and no native `disabled`, never holds the grid's Tab stop, and cannot be picked. Implementation gap: once a key move (arrow, Home, End, or Page key) has placed the Tab stop, it stays on that day when every day of the month becomes disabled (for example a range span cap in a two-month view). | `spec:AST-085` FR1, FR2; shipped source and focused tests |
101
+ | FR4 | In `range` mode the first pick starts the range and the second ends it, a second pick before the start swapping the two so the end never precedes the start; `minRangeSpan`/`maxRangeSpan` bound it. Escape, or picking the start day again when `minRangeSpan` is above 1, clears an in-progress range. | shipped source and focused tests |
102
+ | FR5 | Moving the focused day across a month boundary navigates the visible month so the focused day stays visible, in one month or two; a borrowed adjacent-month day is exposed `aria-disabled` and cannot be picked; arrow keys, Home and End skip it, and a page never lands on it. | shipped source and focused tests |
103
+ | FR6 | The month header shows the month and year between Previous and Next month buttons (ghost, icon-only Buttons whose chevrons mirror under RTL), which carry `calendar-nav` with `data-nav` and `data-disabled`. A button whose direction would leave `min` or `max` MUST stay focusable with `aria-disabled`, change nothing, and keep focus (`spec:AST-085` FR1, FR4). Implementation gap: it is natively disabled, so a focused button that reaches the bound drops focus. The month buttons are `component:Button`s, so their press scale MUST NOT apply under reduced motion (`design:reduced-motion` DR1). Implementation gap: it still applies under reduced motion. | `spec:AST-085`; shipped source and focused tests; `design:reduced-motion` DR1 |
104
+ | FR7 | When the visible month changes, by the month buttons, a Page key, an arrow across a month edge, or the handle, the new month (both months in a two-month view) is announced politely; the first render and a pick that leaves the month in place announce nothing. In `range` mode the first pick announces the start and prompts for an end, the second announces the completed range in chronological order, and picking the start again when `minRangeSpan` is above 1 announces the cleared start; Escape clears an in-progress range without an announcement. Every announcement uses the provider locale. | shipped source and focused tests |
100
105
 
101
106
  ### Allowed variation
102
107
 
@@ -107,13 +112,13 @@ intentional decision. A `current` contract contains no unresolved rows.
107
112
 
108
113
  ### Representative states
109
114
 
110
- | State | Required invariant | Allowed variation |
111
- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------- | --------------------- |
112
- | single, nothing picked | Today holds its month's Tab stop when it is enabled, otherwise the month's first enabled day does; no day is selected. | Month shown. |
113
- | single, picked | The selected day is exposed as selected and holds the Tab stop. | Month shown. |
114
- | range, in progress | The start is selected; hovered days preview the range. | Pointer position. |
115
- | two months | Both grids are named; at most one Tab stop in each. | Which month is first. |
116
- | bounded | Days outside `min`/`max` are disabled. | Which days. |
115
+ | State | Required invariant | Allowed variation |
116
+ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------- |
117
+ | single, nothing picked | Today holds its month's Tab stop when it is enabled, otherwise the month's first enabled day does; no day is selected. | Month shown. |
118
+ | single, picked | The selected day is exposed as selected and holds the Tab stop. Implementation gap: after a key move places the stop, a later pointer pick can leave it there, always when the picked day comes later in the grid. | Month shown. |
119
+ | range, in progress | The start is selected; hovered days preview the range. | Pointer position. |
120
+ | two months | Both grids are named; at most one Tab stop in each. | Which month is first. |
121
+ | bounded | Days outside `min`/`max` are disabled. | Which days. |
117
122
 
118
123
  ### Transformation and precedence order
119
124
 
@@ -124,7 +129,8 @@ intentional decision. A `current` contract contains no unresolved rows.
124
129
  ### Performance and resources
125
130
 
126
131
  - **PR1 — Render-owned grid.** Day cells render from props and state; focus
127
- movement reads the grid's cells on demand and keeps no per-cell listeners.
132
+ movement reads the grid's cells on demand; day buttons share the press
133
+ controller's window and document listeners; Calendar owns no observer.
128
134
 
129
135
  ## Accessibility contract
130
136
 
@@ -132,12 +138,17 @@ intentional decision. A `current` contract contains no unresolved rows.
132
138
  one composite control: each month is `role="grid"` with an accessible name,
133
139
  weekday `columnheader` cells, week `row`s, and day `gridcell`s that carry
134
140
  `aria-selected` when selected or in range and hold one `button` named by the
135
- full date, which exposes `aria-current="date"` for today and `aria-disabled`
141
+ full date plus its selection or range role (selected, range start, range end,
142
+ or in range), which exposes `aria-current="date"` for today and `aria-disabled`
136
143
  when disabled; one day button holds the Tab stop — the selected day in
137
144
  `single` mode when it is in that month and enabled, else today when it is in
138
145
  that month and enabled, else the month's first enabled day; a month with no
139
- enabled day has no Tab stop.
140
- ArrowLeft and ArrowRight move by a day following the reading direction,
146
+ enabled day has no Tab stop. Implementation gap: once a key move (arrow, Home,
147
+ End, or Page key) has placed the stop, a later pointer pick can leave it
148
+ there (always when the picked day comes later in the grid), and when every
149
+ day of that month becomes disabled it stays on a disabled day.
150
+ ArrowLeft and ArrowRight move by a day following the reading direction
151
+ (`design:bidirectionality` DR6),
141
152
  ArrowUp and ArrowDown by a week, Home and End to the first and last enabled day of the
142
153
  week, PageUp and PageDown by a month, and Enter or Space picks the focused day;
143
154
  an arrow skips a day disabled by a constraint and continues in the
@@ -149,10 +160,13 @@ intentional decision. A `current` contract contains no unresolved rows.
149
160
 
150
161
  ## Design relationships
151
162
 
163
+ `design:bidirectionality` DR6 governs the arrow-key direction (AR1), and
164
+ `design:reduced-motion` governs the month buttons' press scale (FR6).
165
+
152
166
  | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
153
167
  | ---------------- | ---------------------------------------------------------------------- | ------------------------------ | -------------- | ------------------ |
154
168
  | Calendar root | Holds the header and the grid; carries the component's theming target. | Current source and public docs | Supporting | FR1 |
155
- | Month header | Names the month and offers previous/next navigation. | Current source and public docs | Supporting | FR1, FR5 |
169
+ | Month header | Names the month and offers previous/next navigation. | Current source and public docs | Supporting | FR1, FR5, FR6 |
156
170
  | Day button | The control a date is picked with; carries the day target. | Current source and public docs | Prominent | FR2, FR3, AR1 |
157
171
  | Day grid | Presents the weeks and days as a named grid. | Current source and public docs | Prominent | FR1, FR2, AR1 |
158
172
  | Selected day | Marks the chosen day or range without relying on colour alone. | Current source and public docs | Prominent | FR4, AR1 |
@@ -185,18 +199,43 @@ button.
185
199
 
186
200
  - `spec:AST-020/FR15` decides which APG parts a component adopts; the day grid
187
201
  adopts the Grid pattern because it already acts as one composite control.
202
+ - `spec:AST-085` owns disabled focusability; days meet it and the month
203
+ buttons do not (FR6).
204
+ - `component:Button` renders the month buttons.
188
205
 
189
206
  ## Verification map
190
207
 
191
- | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
192
- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
193
- | FR1–FR5 | `Calendar.test.tsx` structure ("renders a valid APG grid: one grid, header row of columnheaders inside it, week rows of gridcells", "with week numbers, the header row's corner cell is a named columnheader, so every row child is a grid cell"), selection ("handles reverse range selection (end before start)", "caps the range highlight next to a disabled mid-range day (#2715)", "Escape cancels range selection in progress", "clears the in-progress start when the anchor is clicked again"), bounds ("prev button is disabled when focusDate month contains min", "next button is disabled when focusDate month contains max"), and navigation ("navigates to next month", "calls onFocusDateChange when navigating") suites | single, range, two months, bounded | A missing header row, a reverse pick that does not swap, a range highlight that reaches a disabled day, or a Previous/Next button enabled past `min`/`max` fails. | `audit:Calendar/behavior` |
194
- | AR1 | `Calendar.test.tsx` ("has accessible grid structure", "sets aria-multiselectable on both grids in a two-month range view", "does not set aria-multiselectable in single mode", "announces the new month politely when clicking next", "displays day names") and `useGridFocus.test.tsx` ("ArrowDown moves the tab stop one row down", "flips ArrowLeft/ArrowRight under RTL"); `Calendar.test.tsx` "ArrowUp skips a disabled cell in the same column to the next enabled row (complex-2)" for the disabled-day skip; `Calendar.test.tsx` Page-key cases ("moves the focused day by a month with PageDown and PageUp, into the month now shown", "pages from a borrowed adjacent-month day onto the real day in the month already shown", "an arrow past max changes nothing and leaves no pending target behind", "a page into a month with no enabled day changes nothing and keeps focus", "a page onto a day disabled by a constraint moves the month and focuses its first enabled day", "a page whose target lies past max changes nothing and keeps focus", "in a two-month view a boundary blocks only out-of-range targets, not month movement", "in a two-month view PageDown from the second month moves both months and a later Next click selects no stale day"); borrowed-day cases ("skips borrowed adjacent-month days and crosses into their month instead", "in a two-month view an arrow from the first month lands on the real day, never a borrowed one", "an arrow toward a direction where every remaining day is disabled changes nothing", "an arrow resolves the next enabled day in its direction first: weekdays-only ArrowRight from Friday January 30 reaches Monday February 2", "an arrow whose next day in range does not exist changes nothing: max January 25, ArrowDown from January 21"); the at-most-one-Tab-stop-per-month (FR2), Home/End and activation keys on Calendar itself under the Grid accessibility contract (`internal/a11y-spec`, pending) | LTR and RTL; month boundary; selected, today, disabled days | A day loses its role, name or state, two days in one month hold a Tab stop, or an arrow, Home/End, Page or activation key stops moving or picking. | `audit:Calendar/accessibility` |
208
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
209
+ | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
210
+ | FR1–FR5 | `Calendar.test.tsx` structure ("renders a valid APG grid: one grid, header row of columnheaders inside it, week rows of gridcells", "with week numbers, the header row's corner cell is a named columnheader, so every row child is a grid cell"), selection ("handles reverse range selection (end before start)", "caps the range highlight next to a disabled mid-range day (#2715)", "Escape cancels range selection in progress", "clears the in-progress start when the anchor is clicked again"), bounds ("prev button is disabled when focusDate month contains min", "next button is disabled when focusDate month contains max"), and navigation ("navigates to next month", "calls onFocusDateChange when navigating") suites | single, range, two months, bounded | A missing header row, a reverse pick that does not swap, a range highlight that reaches a disabled day, or a Previous/Next button enabled past `min`/`max` fails. Evidence gap: no test asserts locale digits for day or week numbers. | `audit:Calendar/behavior` |
211
+ | AR1 | `Calendar.test.tsx` ("has accessible grid structure", "sets aria-multiselectable on both grids in a two-month range view", "does not set aria-multiselectable in single mode", "announces the new month politely when clicking next", "displays day names") and `useGridFocus.test.tsx` ("ArrowDown moves the tab stop one row down", "flips ArrowLeft/ArrowRight under RTL"); `Calendar.test.tsx` "ArrowUp skips a disabled cell in the same column to the next enabled row (complex-2)" for the disabled-day skip; `Calendar.test.tsx` Page-key cases ("moves the focused day by a month with PageDown and PageUp, into the month now shown", "pages from a borrowed adjacent-month day onto the real day in the month already shown", "an arrow past max changes nothing and leaves no pending target behind", "a page into a month with no enabled day changes nothing and keeps focus", "a page onto a day disabled by a constraint moves the month and focuses its first enabled day", "a page whose target lies past max changes nothing and keeps focus", "in a two-month view a boundary blocks only out-of-range targets, not month movement", "in a two-month view PageDown from the second month moves both months and a later Next click selects no stale day"); borrowed-day cases ("skips borrowed adjacent-month days and crosses into their month instead", "in a two-month view an arrow from the first month lands on the real day, never a borrowed one", "an arrow toward a direction where every remaining day is disabled changes nothing", "an arrow resolves the next enabled day in its direction first: weekdays-only ArrowRight from Friday January 30 reaches Monday February 2", "an arrow whose next day in range does not exist changes nothing: max January 25, ArrowDown from January 21"); the single-Tab-stop assertion in the AST-085 range-cap case (FR2). `Calendar.test.tsx` selection-state accessible-name cases ("appends 'selected' to the selected day's button name in single mode", "marks range start, end, and in-range days in their accessible names"). Evidence gap: no Calendar-level test of Home, End, Enter, or Space; no test covers the Tab stop after a key move followed by a pointer pick or a fully disabled month | LTR and RTL; month boundary; selected, today, disabled days | A day loses its role, name or state, two days in one month hold a Tab stop, or an arrow, Home/End, Page or activation key stops moving or picking. | `audit:Calendar/accessibility` |
212
+ | FR6 | `Calendar.test.tsx` navigation, bound, theming-target ("renders the astryx-calendar-nav target on both month-nav buttons", "reflects the disabled nav state as a data attribute at the range edges", "keeps the default nav rendering unchanged (still a ghost icon button)"), and RTL month-navigation cases | Previous and Next; at `min` and `max`; `dir="rtl"` | A button enabled past a bound, a missing `calendar-nav` target or state attribute, or a lost shared chevron wrapper fails. Evidence gap: no test asserts focus kept at a bound (the FR6 gap), the mirrored chevron pixels, or the press under reduced motion. | `audit:Calendar/behavior` |
213
+ | FR7 | `Calendar.test.tsx` month-change announcement cases ("does not announce on initial render", "announces the new month politely when clicking next", "announces the next month when paging the grid with PageDown", "announces both months in a two-month view", "does not announce when selecting a date leaves the visible month unchanged") and range announcement cases ("announces the start pick and prompts for an end date", "announces the completed range in chronological order for a reverse pick") | Month buttons, Page keys, handle; single and two months; range start, complete, cleared | A missing, extra, or out-of-order announcement fails. Evidence gap: no test reaches the cleared-start announcement (the cleared-range case sets no `minRangeSpan`). | `audit:Calendar/accessibility` |
214
+ | FR2 (size) | Evidence gap: no test asserts day-button size or text growth | — | — | `audit:Calendar/layout` |
215
+ | AR1 (browser) | `Calendar.a11y.test.tsx` and `Calendar.a11y.chromium.spec.ts` over the shared grid states | Every representative state | A lost grid name, role, or start neighbourhood fails; browser-owned outcomes are reported. | `audit:Calendar/accessibility` |
216
+ | ORD1, ORD2, PR1 | ORD1 and ORD2 are covered by the FR3–FR5 and AR1 rows. Evidence gap: no test asserts the absence of per-cell listeners | — | — | `audit:Calendar/behavior` |
217
+
218
+ ## Current-state impact
219
+
220
+ - **Day and week digits (FR1).** Day and week numbers render as ASCII digits
221
+ in every locale, while month labels follow the locale, against
222
+ `architecture:internationalization` INV8.
223
+ - **Stale Tab stop (FR3, AR1).** After a key move places the Tab stop, a later
224
+ pointer pick can leave it there (always when the picked day comes later in
225
+ the grid), and when every day of that month becomes disabled it stays on a
226
+ disabled day, so Tab can land on an unselected or disabled day.
227
+ - **Month buttons under reduced motion (FR6).** The Previous and Next buttons
228
+ scale on a press when the person prefers reduced motion, as `component:Button`
229
+ FR15 records, against `design:reduced-motion` DR1.
230
+ - **Fixed day size (FR2).** Day buttons hold a fixed size instead of growing
231
+ with a set text size, against `spec:AST-102` FR4.
232
+ - **Month buttons at a bound (FR6).** Previous and Next become natively
233
+ disabled at `min` and `max`, so a keyboard user on the button that reaches the
234
+ bound loses focus, against `spec:AST-085` FR1 and FR4.
195
235
 
196
236
  ## Decision log
197
237
 
198
- None. This draft records shipped behavior; the Grid adoption follows the system
199
- rule rather than a component-local decision.
238
+ No component-local decision. The Grid adoption follows `spec:AST-020/FR15`.
200
239
 
201
240
  ## Open questions
202
241
 
@@ -101,16 +101,30 @@ async function runState(
101
101
  });
102
102
  }
103
103
 
104
- test('every grid expectation is exercised by a Calendar state', async ({
105
- page,
106
- }) => {
107
- const cdp = await page.context().newCDPSession(page);
104
+ // Checking coverage runs every state again, which on a loaded runner nears
105
+ // the per-test timeout as one test. It runs as one serial part per state,
106
+ // sharing their results, then one check over all of them.
107
+ test.describe('every grid expectation is exercised by a Calendar state', () => {
108
+ test.describe.configure({mode: 'serial'});
108
109
  const results: BindingResult[] = [];
110
+
109
111
  for (const state of CALENDAR_BINDING_STATES) {
110
- results.push(await runState(page, cdp, state));
112
+ test(`runs ${state.id}`, async ({page}) => {
113
+ const cdp = await page.context().newCDPSession(page);
114
+ results.push(await runState(page, cdp, state));
115
+ });
111
116
  }
112
- expect(neverExercised(results)).toEqual([]);
113
- expect(unmatchedKnownFailures(CALENDAR_KNOWN_FAILURES, results)).toEqual([]);
117
+
118
+ test('no expectation is left unexercised', () => {
119
+ // Every part ran in this worker; this test alone proves nothing.
120
+ expect(results.map(result => result.state).sort()).toEqual(
121
+ CALENDAR_BINDING_STATES.map(state => state.id).sort(),
122
+ );
123
+ expect(neverExercised(results)).toEqual([]);
124
+ expect(unmatchedKnownFailures(CALENDAR_KNOWN_FAILURES, results)).toEqual(
125
+ [],
126
+ );
127
+ });
114
128
  });
115
129
 
116
130
  for (const state of CALENDAR_BINDING_STATES) {
@@ -14,7 +14,7 @@ export const docs = {
14
14
  {guidance: true, description: 'Enable scroll-snap when each item should land precisely at the start edge, like a gallery or product list.'},
15
15
  {guidance: true, description: 'Reach for hasLoop on small, cyclable sets like a photo gallery, where wrapping past the last item back to the first feels natural.'},
16
16
  {guidance: true, description: 'Always provide an aria-label that describes what the carousel contains, like "Featured products" or "Team members".'},
17
- {guidance: true, description: 'Carousel implements the WAI-ARIA APG carousel pattern (https://www.w3.org/WAI/ARIA/apg/patterns/carousel/) without auto-rotation: the region is labelled and carries aria-roledescription="carousel", each item is a group named "Slide N of M", and the scroll container is a tab stop so keyboard users can pan it with the arrow keys.'},
17
+ {guidance: true, description: 'Carousel implements the WAI-ARIA APG carousel pattern (https://www.w3.org/WAI/ARIA/apg/patterns/carousel/) without auto-rotation: the region is labelled and carries aria-roledescription="carousel", each item is a group named "Slide N of M", and the scroll container is a tab stop while its content overflows, so keyboard users can pan it with the arrow keys; while everything fits it stays out of the tab order.'},
18
18
  {guidance: true, description: 'Use a consistent gap and item width so the carousel looks intentional, not like content overflowing by accident.'},
19
19
  {guidance: true, description: 'Trust the built-in navigation: trackpad users can swipe horizontally, and mouse users can hold Shift while scrolling the wheel to move through items.'},
20
20
  {guidance: false, description: 'Use a carousel for content every user must see. Not everyone scrolls horizontally, so put critical content above the fold.'},
@@ -27,15 +27,15 @@ system_specs: [spec:AST-085, spec:AST-025]
27
27
 
28
28
  ## Contract at a glance
29
29
 
30
- | Area | Contract |
31
- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
32
- | Public contract | None changes. |
33
- | Behavior | An edge scroll button whose direction has run out is hidden and takes no tab stop. When the focused edge button runs out, focus moves to the scroll area. |
34
- | End-user impact | A keyboard user who scrolls to the first or last item stays inside the carousel instead of landing on the page body or on an invisible control. The scroll area has no role or name yet, so screen-reader users hear little at the destination until it meets `spec:AST-025` FR12. |
35
- | Builder impact | None. |
36
- | Compatibility/readiness | No API change. Shipped Carousel and its current tests still use native `disabled` and hand focus to the opposite button; they change with conformance work. |
37
- | Review checks | Reject focus left on a hidden edge button, focus dropped to the page body, or an edge handoff that moves focus to anything but the scroll area. |
38
- | Governing rules | `spec:AST-085` FR1, FR4; `spec:AST-025` FR12; `architecture:interaction-modality` INV1. |
30
+ | Area | Contract |
31
+ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
32
+ | Public contract | None changes. |
33
+ | Behavior | An edge scroll button whose direction has run out is hidden and takes no tab stop. When the focused edge button runs out, focus moves to the scroll area. |
34
+ | End-user impact | A keyboard user who scrolls to the first or last item stays inside the carousel instead of landing on the page body or on an invisible control. The scroll area is a group named like the carousel (`spec:AST-025` FR12), so screen-reader users hear where they landed. |
35
+ | Builder impact | None. |
36
+ | Compatibility/readiness | No API change. Shipped Carousel and its current tests still use native `disabled` and hand focus to the opposite button; they change with conformance work. |
37
+ | Review checks | Reject focus left on a hidden edge button, focus dropped to the page body, or an edge handoff that moves focus to anything but the scroll area. |
38
+ | Governing rules | `spec:AST-085` FR1, FR4; `spec:AST-025` FR12; `architecture:interaction-modality` INV1. |
39
39
 
40
40
  This table is a review projection; the body below is authoritative.
41
41
 
@@ -2,15 +2,18 @@
2
2
 
3
3
  import {describe, it, expect, vi} from 'vitest';
4
4
  import {createRef} from 'react';
5
- import {render, screen, fireEvent} from '@testing-library/react';
5
+ import {act, render, screen, fireEvent} from '@testing-library/react';
6
6
  import userEvent from '@testing-library/user-event';
7
7
  import {Carousel, type CarouselHandle} from './Carousel';
8
8
 
9
9
  // Mock ResizeObserver (not available in jsdom)
10
10
  class MockResizeObserver {
11
+ /** The shared observer, so a test can deliver a resize. */
12
+ static last: MockResizeObserver | null = null;
11
13
  callback: ResizeObserverCallback;
12
14
  constructor(callback: ResizeObserverCallback) {
13
15
  this.callback = callback;
16
+ MockResizeObserver.last = this;
14
17
  }
15
18
  observe() {}
16
19
  unobserve() {}
@@ -43,8 +46,9 @@ describe('Carousel', () => {
43
46
  </Carousel>,
44
47
  );
45
48
  // APG carousel pattern: each slide container is role=group with
46
- // aria-roledescription="slide" and an "N of M" accessible name.
47
- const slides = screen.getAllByRole('group');
49
+ // aria-roledescription="slide" and an "N of M" accessible name. (The
50
+ // scroll area around them is a group too, named like the carousel.)
51
+ const slides = screen.getAllByRole('group', {name: /^Slide /});
48
52
  expect(slides).toHaveLength(3);
49
53
  slides.forEach((slide, i) => {
50
54
  expect(slide).toHaveAttribute('aria-roledescription', 'slide');
@@ -52,6 +56,123 @@ describe('Carousel', () => {
52
56
  });
53
57
  });
54
58
 
59
+ describe('scroll area (spec:AST-025 FR12)', () => {
60
+ function getScroller() {
61
+ return screen.getByRole('group', {name: 'Photos'});
62
+ }
63
+
64
+ function setOverflow(el: HTMLElement, overflowing: boolean) {
65
+ Object.defineProperty(el, 'scrollWidth', {
66
+ value: overflowing ? 500 : 200,
67
+ configurable: true,
68
+ });
69
+ Object.defineProperty(el, 'clientWidth', {
70
+ value: 200,
71
+ configurable: true,
72
+ });
73
+ fireEvent.scroll(el);
74
+ }
75
+
76
+ it('is a group named like the carousel', () => {
77
+ render(
78
+ <Carousel aria-label="Photos">
79
+ <div>One</div>
80
+ <div>Two</div>
81
+ </Carousel>,
82
+ );
83
+ const scroller = getScroller();
84
+ expect(scroller).toHaveAttribute('role', 'group');
85
+ expect(scroller).toHaveAccessibleName('Photos');
86
+ // It is the region's scroll container, not a slide.
87
+ expect(scroller).not.toHaveAttribute('aria-roledescription');
88
+ expect(scroller.parentElement).toBe(
89
+ screen.getByRole('region', {name: 'Photos'}),
90
+ );
91
+ });
92
+
93
+ // Named by its owner (spec:AST-025 FR12): the caller's label above, else
94
+ // the carousel's translated default.
95
+ it("takes the carousel's translated default name when the caller gives none", () => {
96
+ render(
97
+ <Carousel>
98
+ <div>One</div>
99
+ <div>Two</div>
100
+ </Carousel>,
101
+ );
102
+ const scroller = screen.getByRole('group', {name: 'Carousel'});
103
+ expect(scroller).toHaveAccessibleName('Carousel');
104
+ expect(scroller.parentElement).toBe(
105
+ screen.getByRole('region', {name: 'Carousel'}),
106
+ );
107
+ });
108
+
109
+ it('takes a tab stop only while its content overflows', () => {
110
+ render(
111
+ <Carousel aria-label="Photos">
112
+ <div>One</div>
113
+ <div>Two</div>
114
+ </Carousel>,
115
+ );
116
+ const scroller = getScroller();
117
+ // Fitting: out of the tab order, still focusable from script (FR2).
118
+ setOverflow(scroller, false);
119
+ expect(scroller).toHaveAttribute('tabindex', '-1');
120
+ act(() => scroller.focus());
121
+ expect(scroller).toHaveFocus();
122
+ act(() => scroller.blur());
123
+ // Overflowing: a tab stop.
124
+ setOverflow(scroller, true);
125
+ expect(scroller).toHaveAttribute('tabindex', '0');
126
+ // Fitting again: leaves the tab order.
127
+ setOverflow(scroller, false);
128
+ expect(scroller).toHaveAttribute('tabindex', '-1');
129
+ });
130
+
131
+ // The content can come to overflow, or stop, with the scroll area
132
+ // keeping its size: the tab stop follows it.
133
+ it('follows its content: slides added or removed, or a slide that grows, move the tab stop', async () => {
134
+ const slides = (count: number) =>
135
+ Array.from({length: count}, (_, i) => <div key={i}>Slide {i}</div>);
136
+ const view = render(<Carousel aria-label="Photos">{slides(1)}</Carousel>);
137
+ const scroller = getScroller();
138
+ // A 200 px scroll area; 150 px of content per slide, plus what a slide
139
+ // grows by.
140
+ let grown = 0;
141
+ Object.defineProperty(scroller, 'clientWidth', {
142
+ value: 200,
143
+ configurable: true,
144
+ });
145
+ Object.defineProperty(scroller, 'scrollWidth', {
146
+ configurable: true,
147
+ get: () => scroller.children.length * 150 + grown,
148
+ });
149
+ expect(scroller).toHaveAttribute('tabindex', '-1');
150
+
151
+ view.rerender(<Carousel aria-label="Photos">{slides(2)}</Carousel>);
152
+ await act(async () => {});
153
+ expect(scroller).toHaveAttribute('tabindex', '0');
154
+
155
+ view.rerender(<Carousel aria-label="Photos">{slides(1)}</Carousel>);
156
+ await act(async () => {});
157
+ expect(scroller).toHaveAttribute('tabindex', '-1');
158
+
159
+ // The one slide's content grows past the scroll area.
160
+ grown = 100;
161
+ const observer = MockResizeObserver.last;
162
+ act(() => {
163
+ observer?.callback(
164
+ [
165
+ {
166
+ target: scroller.firstElementChild,
167
+ } as unknown as ResizeObserverEntry,
168
+ ],
169
+ observer,
170
+ );
171
+ });
172
+ expect(scroller).toHaveAttribute('tabindex', '0');
173
+ });
174
+ });
175
+
55
176
  it('renders children', () => {
56
177
  render(
57
178
  <Carousel aria-label="Test carousel">
@@ -14,7 +14,9 @@
14
14
  * scroll control. Exposes APG
15
15
  * carousel semantics: the root is a labelled region with
16
16
  * aria-roledescription="carousel" and each item wrapper is a group with
17
- * aria-roledescription="slide" named "Slide N of M".
17
+ * aria-roledescription="slide" named "Slide N of M". The scroll area is a
18
+ * group named like the carousel and a tab stop only while its content
19
+ * overflows (AST-025 FR12).
18
20
  *
19
21
  * SYNC: When modified, update:
20
22
  * - /packages/core/src/Carousel/index.ts (exports)
@@ -591,7 +593,13 @@ export function Carousel({
591
593
  aria-roledescription="carousel">
592
594
  <div
593
595
  ref={composedRef}
594
- tabIndex={0}
596
+ // The scroll area takes keyboard scrolling (spec:AST-025 FR12): a
597
+ // group named like the carousel, in the tab order only while its
598
+ // content overflows. While it fits it still takes focus
599
+ // programmatically, for the edge buttons' hand-off (FR2).
600
+ role="group"
601
+ aria-label={ariaLabel}
602
+ tabIndex={hasOverflow ? 0 : -1}
595
603
  onWheel={handleWheel}
596
604
  {...mergeProps(
597
605
  themeProps('carousel-scroller', {