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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (595) hide show
  1. package/dist/AlertDialog/AlertDialog.d.ts +1 -1
  2. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  3. package/dist/AlertDialog/AlertDialog.js +5 -5
  4. package/dist/AppShell/AppShell.d.ts.map +1 -1
  5. package/dist/AppShell/AppShell.js +183 -5
  6. package/dist/AppShell/observeMainOverflow.d.ts +9 -0
  7. package/dist/AppShell/observeMainOverflow.d.ts.map +1 -0
  8. package/dist/AppShell/observeMainOverflow.js +125 -0
  9. package/dist/Avatar/Avatar.d.ts.map +1 -1
  10. package/dist/Avatar/Avatar.js +12 -3
  11. package/dist/Badge/Badge.d.ts.map +1 -1
  12. package/dist/Badge/Badge.js +7 -1
  13. package/dist/BottomSheet/BottomSheet.js +1 -1
  14. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  15. package/dist/BottomSheet/BottomSheetPanel.js +2 -1
  16. package/dist/BottomSheet/useSheetGestures.d.ts +12 -0
  17. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  18. package/dist/BottomSheet/useSheetGestures.js +30 -3
  19. package/dist/Button/Button.js +4 -4
  20. package/dist/Carousel/Carousel.d.ts +3 -1
  21. package/dist/Carousel/Carousel.d.ts.map +1 -1
  22. package/dist/Carousel/Carousel.js +12 -3
  23. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  24. package/dist/CheckboxInput/CheckboxInput.js +6 -5
  25. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  26. package/dist/ClickableCard/ClickableCard.js +37 -4
  27. package/dist/DateInput/DateInput.d.ts.map +1 -1
  28. package/dist/DateInput/DateInput.js +12 -4
  29. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  30. package/dist/DateInput/MonthScroller.js +101 -15
  31. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  32. package/dist/DateInput/TouchDateField.js +8 -3
  33. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  34. package/dist/DateRangeInput/DateRangeInput.js +1 -1
  35. package/dist/DateTimeInput/DateTimeInput.d.ts +5 -2
  36. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  37. package/dist/DateTimeInput/DateTimeInput.js +23 -12
  38. package/dist/DateTimeInput/NativeTimeSegment.d.ts.map +1 -1
  39. package/dist/DateTimeInput/NativeTimeSegment.js +5 -4
  40. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  41. package/dist/DateTimeInput/TouchDateTimeField.js +4 -3
  42. package/dist/Dialog/Dialog.d.ts.map +1 -1
  43. package/dist/Dialog/Dialog.js +34 -9
  44. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  45. package/dist/Dialog/DialogHeader.js +5 -4
  46. package/dist/Divider/Divider.d.ts.map +1 -1
  47. package/dist/Divider/Divider.js +2 -1
  48. package/dist/Drawer/Drawer.d.ts +1 -0
  49. package/dist/Drawer/Drawer.d.ts.map +1 -1
  50. package/dist/Drawer/Drawer.js +7 -2
  51. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  52. package/dist/DropdownMenu/DropdownMenu.js +7 -3
  53. package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -1
  54. package/dist/DropdownMenu/MenuBottomSheetActionList.js +6 -5
  55. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +20 -2
  56. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
  57. package/dist/DropdownMenu/lazyMenuBottomSheet.js +31 -3
  58. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  59. package/dist/DropdownMenu/renderDropdownItems.js +21 -16
  60. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  61. package/dist/EmptyState/EmptyState.js +2 -1
  62. package/dist/Field/FieldLabel.d.ts +1 -1
  63. package/dist/Field/FieldLabel.d.ts.map +1 -1
  64. package/dist/Field/FieldLabel.js +4 -4
  65. package/dist/Field/InputClearButton.js +3 -3
  66. package/dist/Field/PanelSearchInput.js +2 -2
  67. package/dist/FieldStatus/FieldStatus.js +2 -2
  68. package/dist/FileInput/FileInput.d.ts.map +1 -1
  69. package/dist/FileInput/FileInput.js +7 -1
  70. package/dist/Heading/Heading.js +1 -1
  71. package/dist/Icon/Icon.js +1 -1
  72. package/dist/Indicator/CheckIndicator.d.ts.map +1 -1
  73. package/dist/Indicator/CheckIndicator.js +2 -1
  74. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  75. package/dist/Indicator/CheckboxIndicator.js +3 -1
  76. package/dist/Indicator/RadioIndicator.d.ts.map +1 -1
  77. package/dist/Indicator/RadioIndicator.js +3 -1
  78. package/dist/Item/Item.d.ts.map +1 -1
  79. package/dist/Item/Item.js +2 -1
  80. package/dist/Item/ItemSwipeLayer.js +1 -1
  81. package/dist/Layer/popoverOperations.d.ts +27 -0
  82. package/dist/Layer/popoverOperations.d.ts.map +1 -0
  83. package/dist/Layer/popoverOperations.js +159 -0
  84. package/dist/Layer/useLayer.d.ts +1 -1
  85. package/dist/Layer/useLayer.d.ts.map +1 -1
  86. package/dist/Layer/useLayer.js +93 -59
  87. package/dist/Layout/Layout.js +1 -1
  88. package/dist/Layout/LayoutContent.js +1 -1
  89. package/dist/Layout/LayoutFooter.js +1 -1
  90. package/dist/Layout/LayoutHeader.js +1 -1
  91. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  92. package/dist/Lightbox/Lightbox.js +5 -0
  93. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.js +5 -4
  94. package/dist/List/List.js +1 -1
  95. package/dist/List/ListItem.js +3 -3
  96. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  97. package/dist/MobileNav/MobileNav.js +7 -2
  98. package/dist/MultiSelector/CreateRow.a11y.chromium.spec.js +7 -6
  99. package/dist/MultiSelector/MultiSelector.d.ts +1 -1
  100. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  101. package/dist/MultiSelector/MultiSelector.js +26 -10
  102. package/dist/NumberInput/NumberInput.d.ts +3 -1
  103. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  104. package/dist/NumberInput/NumberInput.js +3 -3
  105. package/dist/NumberInput/numberParser.d.ts +3 -0
  106. package/dist/NumberInput/numberParser.d.ts.map +1 -1
  107. package/dist/NumberInput/numberParser.js +7 -44
  108. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  109. package/dist/ProgressBar/ProgressBar.js +16 -12
  110. package/dist/Resizable/useResizable.d.ts.map +1 -1
  111. package/dist/Resizable/useResizable.js +28 -2
  112. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  113. package/dist/SegmentedControl/SegmentedControlItem.js +4 -1
  114. package/dist/Selector/useSelectorPresentation.d.ts +8 -1
  115. package/dist/Selector/useSelectorPresentation.d.ts.map +1 -1
  116. package/dist/Selector/useSelectorPresentation.js +20 -4
  117. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  118. package/dist/Skeleton/Skeleton.js +1 -1
  119. package/dist/Slider/Slider.d.ts.map +1 -1
  120. package/dist/Slider/Slider.js +10 -2
  121. package/dist/Spinner/Spinner.d.ts.map +1 -1
  122. package/dist/Spinner/Spinner.js +3 -3
  123. package/dist/Stack/Stack.js +1 -1
  124. package/dist/Stack/StackItem.js +1 -1
  125. package/dist/TabList/TabList.d.ts.map +1 -1
  126. package/dist/TabList/TabList.js +16 -1
  127. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  128. package/dist/Table/plugins/columnResize/useTableColumnResize.js +9 -1
  129. package/dist/Text/Text.js +1 -1
  130. package/dist/Text/useTruncation.d.ts.map +1 -1
  131. package/dist/Text/useTruncation.js +23 -5
  132. package/dist/TextArea/TextArea.d.ts +1 -1
  133. package/dist/TextArea/TextArea.d.ts.map +1 -1
  134. package/dist/TextArea/TextArea.js +13 -2
  135. package/dist/TextInput/TextInput.d.ts.map +1 -1
  136. package/dist/TextInput/TextInput.js +3 -3
  137. package/dist/TimeInput/TimeInput.d.ts +6 -2
  138. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  139. package/dist/TimeInput/TimeInput.js +21 -14
  140. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
  141. package/dist/TimeInput/TouchTimeField.js +5 -4
  142. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  143. package/dist/Timestamp/Timestamp.js +2 -2
  144. package/dist/Timestamp/TimestampHoverCard.js +4 -4
  145. package/dist/Toast/Toast.d.ts.map +1 -1
  146. package/dist/Toast/Toast.js +60 -20
  147. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  148. package/dist/Toast/ToastViewport.js +82 -51
  149. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  150. package/dist/Tokenizer/Tokenizer.js +13 -2
  151. package/dist/Tokenizer/TokenizerBottomSheet.js +3 -3
  152. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  153. package/dist/Toolbar/Toolbar.js +2 -1
  154. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  155. package/dist/TopNav/TopNavMegaMenu.js +3 -0
  156. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  157. package/dist/TopNav/TopNavMenu.js +1 -0
  158. package/dist/Typeahead/Typeahead.d.ts +1 -1
  159. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  160. package/dist/Typeahead/Typeahead.js +9 -1
  161. package/dist/astryx.css +21 -4
  162. package/dist/gestures/GestureArena.d.ts +6 -0
  163. package/dist/gestures/GestureArena.d.ts.map +1 -1
  164. package/dist/gestures/GestureArena.js +39 -0
  165. package/dist/gestures/GestureHost.d.ts +352 -0
  166. package/dist/gestures/GestureHost.d.ts.map +1 -0
  167. package/dist/gestures/GestureHost.js +1773 -0
  168. package/dist/gestures/GestureRecognizer.d.ts +10 -0
  169. package/dist/gestures/GestureRecognizer.d.ts.map +1 -1
  170. package/dist/gestures/GestureRecognizer.js +16 -0
  171. package/dist/gestures/LongPressGestureRecognizer.d.ts +1 -0
  172. package/dist/gestures/LongPressGestureRecognizer.d.ts.map +1 -1
  173. package/dist/gestures/LongPressGestureRecognizer.js +3 -0
  174. package/dist/gestures/PanGestureRecognizer.d.ts +1 -0
  175. package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -1
  176. package/dist/gestures/PanGestureRecognizer.js +3 -0
  177. package/dist/gestures/PinchGestureRecognizer.d.ts +31 -0
  178. package/dist/gestures/PinchGestureRecognizer.d.ts.map +1 -0
  179. package/dist/gestures/PinchGestureRecognizer.js +128 -0
  180. package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts +71 -0
  181. package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts.map +1 -0
  182. package/dist/gestures/ScreenEdgePanGestureRecognizer.js +223 -0
  183. package/dist/gestures/SwipeGestureRecognizer.d.ts +37 -0
  184. package/dist/gestures/SwipeGestureRecognizer.d.ts.map +1 -0
  185. package/dist/gestures/SwipeGestureRecognizer.js +148 -0
  186. package/dist/gestures/TapGestureRecognizer.d.ts +1 -0
  187. package/dist/gestures/TapGestureRecognizer.d.ts.map +1 -1
  188. package/dist/gestures/TapGestureRecognizer.js +3 -0
  189. package/dist/gestures/VelocityTracker.d.ts +6 -2
  190. package/dist/gestures/VelocityTracker.d.ts.map +1 -1
  191. package/dist/gestures/VelocityTracker.js +7 -3
  192. package/dist/gestures/haptics.d.ts +65 -0
  193. package/dist/gestures/haptics.d.ts.map +1 -0
  194. package/dist/gestures/haptics.js +182 -0
  195. package/dist/gestures/nativeScroll.d.ts +42 -0
  196. package/dist/gestures/nativeScroll.d.ts.map +1 -0
  197. package/dist/gestures/nativeScroll.js +228 -0
  198. package/dist/gestures/touchAction.d.ts +60 -0
  199. package/dist/gestures/touchAction.d.ts.map +1 -0
  200. package/dist/gestures/touchAction.js +157 -0
  201. package/dist/gestures/touchActionRule.d.ts +34 -0
  202. package/dist/gestures/touchActionRule.d.ts.map +1 -0
  203. package/dist/gestures/touchActionRule.js +140 -0
  204. package/dist/gestures/types.d.ts +18 -7
  205. package/dist/gestures/types.d.ts.map +1 -1
  206. package/dist/gestures/types.js +22 -2
  207. package/dist/hooks/index.d.ts +1 -1
  208. package/dist/hooks/index.d.ts.map +1 -1
  209. package/dist/hooks/modalAnnounce.d.ts.map +1 -1
  210. package/dist/hooks/modalAnnounce.js +107 -61
  211. package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -1
  212. package/dist/hooks/scrollKeyboardDelegation.js +7 -3
  213. package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -1
  214. package/dist/hooks/useAdaptivePresentation.js +4 -1
  215. package/dist/hooks/useAnnounce.d.ts +101 -42
  216. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  217. package/dist/hooks/useAnnounce.js +161 -75
  218. package/dist/hooks/useAnnounceRenderedText.d.ts +11 -3
  219. package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
  220. package/dist/hooks/useAnnounceRenderedText.js +5 -3
  221. package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
  222. package/dist/hooks/useBusyAnnouncement.js +6 -12
  223. package/dist/hooks/useMenuHover.d.ts.map +1 -1
  224. package/dist/hooks/useMenuHover.js +12 -1
  225. package/dist/hooks/useScrollOverflow.d.ts +2 -1
  226. package/dist/hooks/useScrollOverflow.d.ts.map +1 -1
  227. package/dist/hooks/useScrollOverflow.js +56 -10
  228. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  229. package/dist/i18n/generated-locales/en.generated.js +6 -0
  230. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  231. package/dist/i18n/generated-locales/pseudo.generated.js +6 -0
  232. package/dist/motion/animator.d.ts +7 -1
  233. package/dist/motion/animator.d.ts.map +1 -1
  234. package/dist/motion/animator.js +119 -27
  235. package/dist/theme/defineTheme.d.ts +19 -5
  236. package/dist/theme/defineTheme.d.ts.map +1 -1
  237. package/dist/theme/defineTheme.js +64 -4
  238. package/dist/theme/domainTokens/domainTokenDefaults.d.ts +3 -0
  239. package/dist/theme/domainTokens/domainTokenDefaults.d.ts.map +1 -0
  240. package/dist/theme/domainTokens/domainTokenDefaults.js +19 -0
  241. package/dist/theme/domainTokens/index.d.ts +5 -4
  242. package/dist/theme/domainTokens/index.d.ts.map +1 -1
  243. package/dist/theme/domainTokens/index.js +5 -9
  244. package/dist/theme/index.d.ts +1 -0
  245. package/dist/theme/index.d.ts.map +1 -1
  246. package/dist/theme/motionKnobs.d.ts +56 -0
  247. package/dist/theme/motionKnobs.d.ts.map +1 -0
  248. package/dist/theme/motionKnobs.js +48 -0
  249. package/dist/theme/resolveThemeValues.d.ts +11 -4
  250. package/dist/theme/resolveThemeValues.d.ts.map +1 -1
  251. package/dist/theme/resolveThemeValues.js +40 -4
  252. package/dist/theme/themeAdaptations.d.ts +7 -3
  253. package/dist/theme/themeAdaptations.d.ts.map +1 -1
  254. package/dist/theme/themeAdaptations.js +36 -7
  255. package/dist/theme/themeMotion.d.ts +96 -0
  256. package/dist/theme/themeMotion.d.ts.map +1 -0
  257. package/dist/theme/themeMotion.js +177 -0
  258. package/dist/theme/tokenReferences.d.ts +31 -0
  259. package/dist/theme/tokenReferences.d.ts.map +1 -0
  260. package/dist/theme/tokenReferences.js +132 -0
  261. package/dist/theme/tokens.d.ts +1 -0
  262. package/dist/theme/tokens.d.ts.map +1 -1
  263. package/dist/theme/tokens.js +9 -129
  264. package/dist/theme/tokens.stylex.d.ts +12 -0
  265. package/dist/theme/tokens.stylex.d.ts.map +1 -1
  266. package/dist/theme/tokens.stylex.js +12 -0
  267. package/dist/utils/focusReturn.d.ts +17 -1
  268. package/dist/utils/focusReturn.d.ts.map +1 -1
  269. package/dist/utils/focusReturn.js +11 -4
  270. package/dist/utils/getNodeText.d.ts +8 -0
  271. package/dist/utils/getNodeText.d.ts.map +1 -0
  272. package/dist/utils/getNodeText.js +37 -0
  273. package/dist/utils/interactionModality.d.ts +11 -2
  274. package/dist/utils/interactionModality.d.ts.map +1 -1
  275. package/dist/utils/interactionModality.js +58 -5
  276. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  277. package/dist/utils/interactionOverlay.stylex.js +17 -8
  278. package/dist/utils/plainDate.d.ts +2 -0
  279. package/dist/utils/plainDate.d.ts.map +1 -1
  280. package/dist/utils/plainDate.js +46 -3
  281. package/dist/utils/presentation.d.ts +50 -0
  282. package/dist/utils/presentation.d.ts.map +1 -0
  283. package/dist/utils/presentation.js +125 -0
  284. package/dist/utils/pressFeedback.d.ts.map +1 -1
  285. package/dist/utils/pressFeedback.js +20 -1
  286. package/dist/utils/primaryClick.d.ts +11 -0
  287. package/dist/utils/primaryClick.d.ts.map +1 -0
  288. package/dist/utils/primaryClick.js +25 -0
  289. package/dist/utils/sharedMutationObserver.d.ts +19 -11
  290. package/dist/utils/sharedMutationObserver.d.ts.map +1 -1
  291. package/dist/utils/sharedMutationObserver.js +66 -26
  292. package/dist/utils/timeFormat.d.ts +47 -0
  293. package/dist/utils/timeFormat.d.ts.map +1 -0
  294. package/dist/utils/timeFormat.js +240 -0
  295. package/dist/utils/touchPresentation.d.ts.map +1 -1
  296. package/dist/utils/touchPresentation.js +5 -3
  297. package/dist/utils/touchPresentation.stylex.d.ts +15 -0
  298. package/dist/utils/touchPresentation.stylex.d.ts.map +1 -0
  299. package/dist/utils/touchPresentation.stylex.js +33 -0
  300. package/dist/utils/unicodeDigits.d.ts +20 -0
  301. package/dist/utils/unicodeDigits.d.ts.map +1 -0
  302. package/dist/utils/unicodeDigits.js +70 -0
  303. package/locales/en.json +27 -3
  304. package/locales/pseudo.json +18 -0
  305. package/package.json +5 -4
  306. package/src/AlertDialog/AlertDialog.tsx +6 -5
  307. package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +18 -6
  308. package/src/AppShell/AppShell.doc.mjs +1 -1
  309. package/src/AppShell/AppShell.spec.md +9 -12
  310. package/src/AppShell/AppShell.test.tsx +164 -2
  311. package/src/AppShell/AppShell.tsx +225 -5
  312. package/src/AppShell/__tests__/AppShellMainKeyboard.a11y.browser.spec.ts +534 -0
  313. package/src/AppShell/observeMainOverflow.test.ts +173 -0
  314. package/src/AppShell/observeMainOverflow.ts +143 -0
  315. package/src/Avatar/Avatar.spec.md +22 -22
  316. package/src/Avatar/Avatar.tsx +18 -1
  317. package/src/Avatar/__tests__/AvatarForcedColors.a11y.chromium.spec.ts +126 -0
  318. package/src/Badge/Badge.doc.mjs +1 -1
  319. package/src/Badge/Badge.tsx +19 -2
  320. package/src/Badge/__tests__/BadgeLargerText.a11y.chromium.spec.ts +260 -0
  321. package/src/BottomSheet/BottomSheet.test.tsx +46 -0
  322. package/src/BottomSheet/BottomSheet.tsx +1 -1
  323. package/src/BottomSheet/BottomSheetPanel.tsx +2 -1
  324. package/src/BottomSheet/useSheetGestures.test.ts +52 -0
  325. package/src/BottomSheet/useSheetGestures.ts +37 -6
  326. package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.chromium.spec.ts +18 -6
  327. package/src/Button/Button.tsx +4 -4
  328. package/src/Calendar/Calendar.spec.md +87 -48
  329. package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +21 -7
  330. package/src/Carousel/Carousel.doc.mjs +1 -1
  331. package/src/Carousel/Carousel.spec.md +9 -9
  332. package/src/Carousel/Carousel.test.tsx +124 -3
  333. package/src/Carousel/Carousel.tsx +10 -2
  334. package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +21 -7
  335. package/src/Carousel/__tests__/Carousel.a11y.known-failures.ts +1 -16
  336. package/src/Chat/ChatComposerTokenElement.spec.md +45 -33
  337. package/src/CheckboxInput/CheckboxInput.tsx +6 -5
  338. package/src/ClickableCard/ClickableCard.test.tsx +96 -0
  339. package/src/ClickableCard/ClickableCard.tsx +48 -4
  340. package/src/Collapsible/Collapsible.spec.md +2 -0
  341. package/src/Collapsible/CollapsibleGroup.spec.md +57 -29
  342. package/src/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts +18 -7
  343. package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +18 -6
  344. package/src/ComplexSelector/ComplexSelector.test.tsx +37 -0
  345. package/src/ContextMenu/ContextMenu.test.tsx +35 -0
  346. package/src/DateInput/DateInput.test.tsx +115 -3
  347. package/src/DateInput/DateInput.tsx +29 -14
  348. package/src/DateInput/DateInputTouch.test.tsx +76 -0
  349. package/src/DateInput/MonthScroller.tsx +106 -20
  350. package/src/DateInput/MonthScrollerSettle.test.tsx +165 -0
  351. package/src/DateInput/TouchDateField.tsx +14 -3
  352. package/src/DateInput/__tests__/MonthScrollerSteps.interaction.browser.spec.ts +312 -0
  353. package/src/DateRangeInput/DateRangeInput.test.tsx +46 -3
  354. package/src/DateRangeInput/DateRangeInput.tsx +16 -12
  355. package/src/DateTimeInput/DateTimeInput.doc.mjs +10 -8
  356. package/src/DateTimeInput/DateTimeInput.spec.md +75 -51
  357. package/src/DateTimeInput/DateTimeInput.test.tsx +81 -0
  358. package/src/DateTimeInput/DateTimeInput.tsx +46 -24
  359. package/src/DateTimeInput/NativeTimeSegment.tsx +4 -6
  360. package/src/DateTimeInput/TouchDateTimeField.tsx +3 -7
  361. package/src/Dialog/Dialog.test.tsx +216 -2
  362. package/src/Dialog/Dialog.tsx +42 -9
  363. package/src/Dialog/DialogHeader.tsx +5 -4
  364. package/src/Dialog/__tests__/DialogSecondDocument.a11y.browser.spec.ts +202 -0
  365. package/src/Divider/Divider.tsx +2 -1
  366. package/src/Drawer/Drawer.spec.md +111 -80
  367. package/src/Drawer/Drawer.test.tsx +35 -0
  368. package/src/Drawer/Drawer.tsx +13 -2
  369. package/src/Drawer/DrawerHeader.spec.md +181 -0
  370. package/src/Drawer/__tests__/DrawerNonModalPageScroll.a11y.chromium.spec.ts +267 -0
  371. package/src/DropdownMenu/DropdownMenu.test.tsx +41 -0
  372. package/src/DropdownMenu/DropdownMenu.tsx +10 -3
  373. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +34 -0
  374. package/src/DropdownMenu/MenuBottomSheetActionList.tsx +6 -5
  375. package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +19 -7
  376. package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +21 -9
  377. package/src/DropdownMenu/lazyMenuBottomSheet.test.ts +60 -0
  378. package/src/DropdownMenu/lazyMenuBottomSheet.ts +36 -7
  379. package/src/DropdownMenu/renderDropdownItems.tsx +24 -19
  380. package/src/EmptyState/EmptyState.tsx +2 -1
  381. package/src/Field/FieldLabel.tsx +5 -4
  382. package/src/Field/InputClearButton.tsx +3 -3
  383. package/src/Field/PanelSearchInput.tsx +2 -2
  384. package/src/FieldStatus/FieldStatus.tsx +2 -2
  385. package/src/FileInput/FileInput.test.tsx +21 -0
  386. package/src/FileInput/FileInput.tsx +4 -1
  387. package/src/FormLayout/FormLayout.spec.md +7 -8
  388. package/src/Heading/Heading.tsx +1 -1
  389. package/src/Icon/Icon.tsx +1 -1
  390. package/src/Indicator/CheckIndicator.spec.md +47 -42
  391. package/src/Indicator/CheckIndicator.tsx +2 -1
  392. package/src/Indicator/CheckboxIndicator.spec.md +40 -37
  393. package/src/Indicator/CheckboxIndicator.tsx +3 -1
  394. package/src/Indicator/Indicator.spec.md +188 -0
  395. package/src/Indicator/RadioIndicator.tsx +3 -1
  396. package/src/Item/Item.tsx +2 -1
  397. package/src/Item/ItemSwipeLayer.tsx +1 -1
  398. package/src/Kbd/Kbd.spec.md +81 -38
  399. package/src/Layer/__tests__/LayerBrowserHide.a11y.chromium.spec.ts +126 -0
  400. package/src/Layer/popoverOperations.test.ts +205 -0
  401. package/src/Layer/popoverOperations.ts +172 -0
  402. package/src/Layer/useLayer.test.tsx +348 -1
  403. package/src/Layer/useLayer.tsx +118 -71
  404. package/src/Layout/Layout.spec.md +127 -131
  405. package/src/Layout/Layout.tsx +1 -1
  406. package/src/Layout/LayoutContent.spec.md +205 -0
  407. package/src/Layout/LayoutContent.tsx +1 -1
  408. package/src/Layout/LayoutFooter.spec.md +190 -0
  409. package/src/Layout/LayoutFooter.tsx +1 -1
  410. package/src/Layout/LayoutHeader.spec.md +193 -0
  411. package/src/Layout/LayoutHeader.tsx +1 -1
  412. package/src/Layout/LayoutPanel.spec.md +194 -0
  413. package/src/Layout/__tests__/Layout.a11y.chromium.spec.ts +18 -6
  414. package/src/Lightbox/Lightbox.test.tsx +18 -0
  415. package/src/Lightbox/Lightbox.tsx +5 -0
  416. package/src/Lightbox/LightboxViewport.a11y.browser.spec.ts +8 -4
  417. package/src/Link/__tests__/Link.a11y.chromium.spec.ts +18 -8
  418. package/src/List/List.tsx +1 -1
  419. package/src/List/ListItem.spec.md +205 -0
  420. package/src/List/ListItem.tsx +3 -3
  421. package/src/MetadataList/MetadataList.spec.md +187 -0
  422. package/src/MetadataList/MetadataListItem.spec.md +165 -0
  423. package/src/MobileNav/MobileNav.test.tsx +15 -0
  424. package/src/MobileNav/MobileNav.tsx +9 -1
  425. package/src/MobileNav/__tests__/MobileNavHeader.a11y.chromium.spec.ts +89 -0
  426. package/src/MoreMenu/MoreMenu.test.tsx +11 -0
  427. package/src/MultiSelector/CreateRow.a11y.chromium.spec.ts +7 -8
  428. package/src/MultiSelector/MultiSelector.spec.md +7 -4
  429. package/src/MultiSelector/MultiSelector.test.tsx +270 -1
  430. package/src/MultiSelector/MultiSelector.tsx +25 -10
  431. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +8 -1
  432. package/src/NavMenu/NavHeadingMenu.spec.md +1 -5
  433. package/src/NumberInput/NumberInput.doc.mjs +13 -7
  434. package/src/NumberInput/NumberInput.spec.md +59 -37
  435. package/src/NumberInput/NumberInput.tsx +13 -3
  436. package/src/NumberInput/__tests__/NumberInput.coarse-pointer.a11y.chromium.spec.ts +102 -0
  437. package/src/NumberInput/numberParser.ts +7 -45
  438. package/src/ProgressBar/ProgressBar.test.tsx +108 -32
  439. package/src/ProgressBar/ProgressBar.tsx +58 -10
  440. package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +21 -9
  441. package/src/ProgressBar/__tests__/ProgressBarMotion.a11y.chromium.spec.ts +831 -0
  442. package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +21 -14
  443. package/src/Resizable/useResizable.test.ts +43 -0
  444. package/src/Resizable/useResizable.ts +32 -9
  445. package/src/SegmentedControl/SegmentedControl.test.tsx +84 -0
  446. package/src/SegmentedControl/SegmentedControlItem.tsx +11 -5
  447. package/src/Selector/Selector.test.tsx +90 -1
  448. package/src/Selector/__tests__/Selector.combobox.a11y.test.tsx +8 -1
  449. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +8 -1
  450. package/src/Selector/useSelectorPresentation.ts +31 -3
  451. package/src/SideNav/SideNav.test.tsx +27 -0
  452. package/src/SideNav/__tests__/SideNavRailMotion.interaction.browser.spec.ts +176 -51
  453. package/src/Skeleton/Skeleton.tsx +3 -1
  454. package/src/Slider/Slider.test.tsx +31 -0
  455. package/src/Slider/Slider.tsx +8 -3
  456. package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +19 -7
  457. package/src/Spinner/Spinner.tsx +5 -3
  458. package/src/Stack/Stack.tsx +1 -1
  459. package/src/Stack/StackItem.tsx +1 -1
  460. package/src/TabList/TabList.test.tsx +58 -4
  461. package/src/TabList/TabList.tsx +16 -1
  462. package/src/TabList/__tests__/TabPressPointer.interaction.browser.spec.ts +163 -0
  463. package/src/Table/__tests__/Table.a11y.chromium.spec.ts +18 -6
  464. package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +22 -0
  465. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +8 -4
  466. package/src/Text/Text.tsx +1 -1
  467. package/src/Text/useTruncation.test.tsx +128 -1
  468. package/src/Text/useTruncation.ts +23 -5
  469. package/src/TextArea/TextArea.spec.md +10 -13
  470. package/src/TextArea/TextArea.test.tsx +60 -0
  471. package/src/TextArea/TextArea.tsx +15 -1
  472. package/src/TextInput/TextInput.test.tsx +21 -0
  473. package/src/TextInput/TextInput.tsx +3 -1
  474. package/src/TimeInput/NativeTimeInput.test.tsx +17 -0
  475. package/src/TimeInput/Presentation.test.tsx +21 -0
  476. package/src/TimeInput/TimeInput.doc.mjs +8 -8
  477. package/src/TimeInput/TimeInput.spec.md +45 -48
  478. package/src/TimeInput/TimeInput.test.tsx +76 -0
  479. package/src/TimeInput/TimeInput.tsx +36 -18
  480. package/src/TimeInput/TouchTimeField.tsx +4 -6
  481. package/src/Timestamp/Timestamp.spec.md +6 -12
  482. package/src/Timestamp/Timestamp.test.tsx +30 -5
  483. package/src/Timestamp/Timestamp.tsx +6 -2
  484. package/src/Timestamp/TimestampHoverCard.tsx +4 -4
  485. package/src/Toast/Toast.spec.md +14 -20
  486. package/src/Toast/Toast.tsx +104 -36
  487. package/src/Toast/ToastViewport.test.tsx +719 -1
  488. package/src/Toast/ToastViewport.tsx +100 -50
  489. package/src/Tokenizer/Tokenizer.spec.md +5 -3
  490. package/src/Tokenizer/Tokenizer.test.tsx +68 -0
  491. package/src/Tokenizer/Tokenizer.tsx +14 -2
  492. package/src/Tokenizer/TokenizerBottomSheet.test.tsx +15 -4
  493. package/src/Tokenizer/TokenizerBottomSheet.tsx +3 -3
  494. package/src/Toolbar/Toolbar.spec.md +5 -6
  495. package/src/Toolbar/Toolbar.test.tsx +30 -0
  496. package/src/Toolbar/Toolbar.tsx +2 -1
  497. package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +18 -6
  498. package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +18 -7
  499. package/src/TopNav/TopNav.test.tsx +27 -0
  500. package/src/TopNav/TopNavMegaMenu.test.tsx +21 -0
  501. package/src/TopNav/TopNavMegaMenu.tsx +4 -1
  502. package/src/TopNav/TopNavMenu.test.tsx +17 -0
  503. package/src/TopNav/TopNavMenu.tsx +1 -0
  504. package/src/Typeahead/Typeahead.test.tsx +40 -0
  505. package/src/Typeahead/Typeahead.tsx +12 -1
  506. package/src/__tests__/pressState.ts +8 -4
  507. package/src/gestures/GestureArena.ts +35 -0
  508. package/src/gestures/GestureHost.ts +2065 -0
  509. package/src/gestures/GestureRecognizer.ts +18 -0
  510. package/src/gestures/LongPressGestureRecognizer.ts +4 -0
  511. package/src/gestures/PanGestureRecognizer.ts +4 -0
  512. package/src/gestures/PinchGestureRecognizer.ts +148 -0
  513. package/src/gestures/ScreenEdgePanGestureRecognizer.ts +256 -0
  514. package/src/gestures/SwipeGestureRecognizer.ts +197 -0
  515. package/src/gestures/TapGestureRecognizer.ts +4 -0
  516. package/src/gestures/VelocityTracker.ts +10 -3
  517. package/src/gestures/__tests__/GestureHost.test.ts +2087 -0
  518. package/src/gestures/__tests__/PanGestureRecognizer.test.ts +4 -4
  519. package/src/gestures/__tests__/PinchGestureRecognizer.test.ts +74 -0
  520. package/src/gestures/__tests__/ScreenEdgePanGestureRecognizer.test.ts +498 -0
  521. package/src/gestures/__tests__/SwipeGestureRecognizer.test.ts +108 -0
  522. package/src/gestures/__tests__/arena.test.ts +5 -0
  523. package/src/gestures/__tests__/arenaPinchSwipeEdge.test.ts +193 -0
  524. package/src/gestures/__tests__/browser/build-fixture.mjs +46 -0
  525. package/src/gestures/__tests__/browser/fixture.ts +307 -0
  526. package/src/gestures/__tests__/browser/gestures.interaction.browser.spec.ts +1137 -0
  527. package/src/gestures/__tests__/browserNegotiation.test.ts +293 -0
  528. package/src/gestures/__tests__/haptics.test.ts +187 -0
  529. package/src/gestures/__tests__/harness.ts +21 -2
  530. package/src/gestures/__tests__/recognizerKind.test.ts +78 -0
  531. package/src/gestures/__tests__/touchActionRule.test.ts +54 -0
  532. package/src/gestures/haptics.ts +203 -0
  533. package/src/gestures/nativeScroll.ts +277 -0
  534. package/src/gestures/touchAction.ts +191 -0
  535. package/src/gestures/touchActionRule.ts +157 -0
  536. package/src/gestures/types.ts +30 -9
  537. package/src/hooks/index.ts +5 -1
  538. package/src/hooks/modalAnnounce.ts +129 -72
  539. package/src/hooks/scrollKeyboardDelegation.test.ts +33 -0
  540. package/src/hooks/scrollKeyboardDelegation.ts +9 -3
  541. package/src/hooks/useAdaptivePresentation.ts +4 -1
  542. package/src/hooks/useAnnounce.doc.mjs +35 -3
  543. package/src/hooks/useAnnounce.replace.test.tsx +516 -0
  544. package/src/hooks/useAnnounce.ts +209 -102
  545. package/src/hooks/useAnnounceRenderedText.adopters.test.tsx +10 -1
  546. package/src/hooks/useAnnounceRenderedText.ts +17 -3
  547. package/src/hooks/useBusyAnnouncement.ts +7 -10
  548. package/src/hooks/useMenuHover.ts +15 -1
  549. package/src/hooks/useScrollOverflow.doc.mjs +1 -1
  550. package/src/hooks/useScrollOverflow.test.tsx +102 -1
  551. package/src/hooks/useScrollOverflow.ts +59 -10
  552. package/src/i18n/generated-locales/en.generated.ts +7 -0
  553. package/src/i18n/generated-locales/pseudo.generated.ts +7 -0
  554. package/src/motion/README.md +11 -1
  555. package/src/motion/animator.test.ts +151 -3
  556. package/src/motion/animator.ts +149 -33
  557. package/src/theme/Theme.doc.mjs +1 -1
  558. package/src/theme/defineTheme.ts +117 -8
  559. package/src/theme/derivedVarRegistry.test.ts +4 -0
  560. package/src/theme/domainTokens/domainTokenDefaults.ts +19 -0
  561. package/src/theme/domainTokens/index.ts +6 -10
  562. package/src/theme/expandMotionScale.test.ts +1 -1
  563. package/src/theme/index.ts +5 -0
  564. package/src/theme/motionKnobs.ts +82 -0
  565. package/src/theme/resolveThemeValues.ts +68 -6
  566. package/src/theme/themeAdaptations.ts +52 -12
  567. package/src/theme/themeMotion.test.ts +620 -0
  568. package/src/theme/themeMotion.ts +221 -0
  569. package/src/theme/tokenReferences.ts +149 -0
  570. package/src/theme/tokens.stylex.ts +10 -0
  571. package/src/theme/tokens.ts +15 -158
  572. package/src/utils/focusReturn.ts +17 -6
  573. package/src/utils/getNodeText.test.ts +24 -0
  574. package/src/utils/getNodeText.ts +37 -0
  575. package/src/utils/interactionModality.test.ts +45 -1
  576. package/src/utils/interactionModality.ts +64 -5
  577. package/src/utils/interactionOverlay.stylex.ts +12 -3
  578. package/src/utils/plainDate.test.ts +90 -0
  579. package/src/utils/plainDate.ts +58 -3
  580. package/src/utils/presentation.test.ts +380 -0
  581. package/src/utils/presentation.ts +180 -0
  582. package/src/utils/pressFeedback.test.ts +138 -0
  583. package/src/utils/pressFeedback.ts +34 -11
  584. package/src/utils/pressPaintPriority.test.ts +80 -0
  585. package/src/utils/primaryClick.test.ts +38 -0
  586. package/src/utils/primaryClick.ts +28 -0
  587. package/src/utils/sharedMutationObserver.test.ts +54 -1
  588. package/src/utils/sharedMutationObserver.ts +87 -29
  589. package/src/utils/timeFormat.test.ts +204 -0
  590. package/src/utils/timeFormat.ts +314 -0
  591. package/src/utils/touchPresentation.stylex.ts +43 -0
  592. package/src/utils/touchPresentation.test.ts +140 -1
  593. package/src/utils/touchPresentation.ts +5 -3
  594. package/src/utils/unicodeDigits.test.ts +44 -0
  595. package/src/utils/unicodeDigits.ts +71 -0
@@ -120,16 +120,30 @@ function bindingState(id: string): CarouselBindingRow {
120
120
  return state;
121
121
  }
122
122
 
123
- test('every expectation is exercised by at least one Carousel state', async ({
124
- page,
125
- }) => {
126
- const cdp = await page.context().newCDPSession(page);
123
+ // Checking coverage runs every state again, which on a loaded runner nears
124
+ // the per-test timeout as one test. It runs as one serial part per state,
125
+ // sharing their results, then one check over all of them.
126
+ test.describe('every expectation is exercised by at least one Carousel state', () => {
127
+ test.describe.configure({mode: 'serial'});
127
128
  const results: BindingResult[] = [];
129
+
128
130
  for (const state of CAROUSEL_BINDING_STATES) {
129
- results.push(await runState(page, cdp, state));
131
+ test(`runs ${state.id}`, async ({page}) => {
132
+ const cdp = await page.context().newCDPSession(page);
133
+ results.push(await runState(page, cdp, state));
134
+ });
130
135
  }
131
- expect(neverExercised(results)).toEqual([]);
132
- expect(unmatchedKnownFailures(CAROUSEL_KNOWN_FAILURES, results)).toEqual([]);
136
+
137
+ test('no expectation is left unexercised', () => {
138
+ // Every part ran in this worker; this test alone proves nothing.
139
+ expect(results.map(result => result.state).sort()).toEqual(
140
+ CAROUSEL_BINDING_STATES.map(state => state.id).sort(),
141
+ );
142
+ expect(neverExercised(results)).toEqual([]);
143
+ expect(unmatchedKnownFailures(CAROUSEL_KNOWN_FAILURES, results)).toEqual(
144
+ [],
145
+ );
146
+ });
133
147
  });
134
148
 
135
149
  for (const state of CAROUSEL_BINDING_STATES) {
@@ -9,19 +9,4 @@
9
9
 
10
10
  import type {KnownFailure} from '@astryxdesign/a11y-spec';
11
11
 
12
- export const CAROUSEL_KNOWN_FAILURES: ReadonlyArray<KnownFailure> = [
13
- {
14
- expectation: 'carousel.scroller.role-and-name',
15
- binding: 'Carousel',
16
- state: 'scroller-keyboard',
17
- evidenceLayer: 'accessibility-tree',
18
- failureEquals:
19
- 'the browser exposes the focusable scroll container with no role',
20
- standardsReference:
21
- 'WCAG 2.2 4.1.2 Name, Role, Value; Astryx spec:AST-025 FR12 — a viewport that takes keyboard scrolling must provide an appropriate role and accessible name',
22
- userImpact:
23
- 'A keyboard user who tabs onto the scroll container hears nothing about where they are or what the arrow keys will do; the named region around it is the only clue.',
24
- reason:
25
- 'This test-only binding records the gap; naming the scroll container is a Carousel markup change that ships as its own spec-backed fix.',
26
- },
27
- ];
12
+ export const CAROUSEL_KNOWN_FAILURES: ReadonlyArray<KnownFailure> = [];
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  schema_version: 3
3
- template_version: 5
3
+ template_version: 7
4
4
  kind: component
5
5
  id: component:ChatComposerTokenElement
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, testing]
13
13
  verified_by:
@@ -33,15 +33,15 @@ system_specs: [spec:AST-002, spec:AST-029]
33
33
 
34
34
  ## Contract at a glance
35
35
 
36
- | Area | Contract |
37
- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
38
- | Public contract | No token shape, default, or rendering change. The public props type and existing span passthrough are directly reachable from the Chat package path. |
39
- | Behavior | A structured token renders Badge content; a custom token renders caller content. Both retain the serialized value marker and stay non-editable when placed inside a contenteditable composer. |
40
- | End-user impact | Token labels and caller content remain visible without becoming editable text. |
41
- | Builder impact | Builders can type the existing component props and attach neutral span attributes, styles, and a ref without recreating its contract. |
42
- | Compatibility/readiness | Additive patch-compatible contract repair. This observational record adds no token meaning or visual policy. |
43
- | Review checks | Reject a token wrapper that loses its serialized value, becomes editable, drops accepted span props, or changes the structured/custom rendering split. |
44
- | Governing rules | `architecture:public-component-api/INV1, INV5–INV6, INV8–INV9, INV12`; `architecture:component-test-sufficiency/INV1–INV8, INV10–INV11`; `spec:AST-029/FR3–FR5, FR7`. |
36
+ | Area | Contract |
37
+ | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
38
+ | Public contract | `ChatComposerTokenElement` with a required `token`: structured, which is `value` plus Badge props, of which only `label`, `variant`, and `icon` render and the rest are accepted and ignored; or custom `{value, render}`, `ref`, `xstyle`, `className`, `style`, and neutral span props. |
39
+ | Behavior | A structured token renders Badge content; a custom token renders caller content. Both retain the serialized value marker and stay non-editable when placed inside a contenteditable composer. |
40
+ | End-user impact | Token labels and caller content remain visible without becoming editable text. |
41
+ | Builder impact | None. |
42
+ | Compatibility/readiness | Records shipped behavior; no public change. Evidence still pending for AR1 and parts of FR1, FR2, and FR4 (read from source; see the verification map). |
43
+ | Review checks | Reject a token wrapper that loses its serialized value, becomes editable, drops accepted span props, or changes the structured/custom rendering split. |
44
+ | Governing rules | `architecture:public-component-api/INV1, INV5–INV6, INV8–INV9, INV12`; `architecture:component-test-sufficiency/INV1–INV8, INV10–INV11`; `spec:AST-029/FR3–FR5, FR7`. |
45
45
 
46
46
  This table is a review projection; the body below is authoritative.
47
47
 
@@ -54,11 +54,13 @@ their existing owners.
54
54
 
55
55
  ## Compatibility and migration
56
56
 
57
- - Released default preserved: yes
58
- - Compatibility class: additive props-type and DOM-passthrough repair
59
- - Token values and rendering branches: unchanged
57
+ - Released default preserved: `yes`
58
+ - Compatibility class: records shipped behavior; no public change
59
+ - Controlled/uncontrolled behavior: not applicable
60
60
  - Migration decision: none
61
61
 
62
+ Consumer migration instructions belong in consumer docs and release notes.
63
+
62
64
  ## Ownership boundary
63
65
 
64
66
  **Owns**
@@ -85,12 +87,12 @@ their existing owners.
85
87
 
86
88
  ## Behavioral and layout contract
87
89
 
88
- | ID | Candidate invariant | Basis | Draft review state |
89
- | --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------ |
90
- | FR1 | The root MUST expose `data-astryx-token` and the exact supplied `token.value`, and MUST remain `contentEditable={false}`. | shipped implementation, public docs, ChatComposerInput serialization | verify |
91
- | FR2 | Structured tokens MUST delegate label, variant, and icon rendering to Badge without changing the token value. | shipped implementation and public token type | verify |
92
- | FR3 | Custom tokens MUST render the caller function result without adding component-owned semantics or interaction. | shipped implementation and public token type | verify |
93
- | FR4 | Accepted ref, DOM/data/ARIA, className, style, and xstyle inputs MUST reach and compose on the root span while component-owned serialization attributes retain precedence. | `architecture:public-component-api/INV5–INV6, INV8` | settled |
90
+ | ID | Invariant | Basis |
91
+ | --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
92
+ | FR1 | The root MUST expose `data-astryx-token` and the exact supplied `token.value`, and MUST remain `contentEditable={false}`. | Current source, docs, and tests |
93
+ | FR2 | Structured tokens MUST delegate label, variant, and icon rendering to Badge without changing the token value. | shipped implementation and public token type |
94
+ | FR3 | Custom tokens MUST render the caller function result without adding component-owned semantics or interaction. | shipped implementation and public token type |
95
+ | FR4 | Accepted ref, DOM/data/ARIA, className, style, and xstyle inputs MUST reach and compose on the root span while component-owned serialization attributes retain precedence. | `architecture:public-component-api/INV5–INV6, INV8` |
94
96
 
95
97
  ### Allowed variation
96
98
 
@@ -108,15 +110,18 @@ their existing owners.
108
110
 
109
111
  ## Accessibility contract
110
112
 
111
- - The wrapper owns no interactive role or accessible name beyond accepted caller props.
112
- - Structured Badge text remains visible content; custom content semantics remain caller owned.
113
- - `contentEditable={false}` keeps the token atomically non-editable when nested in an editor.
113
+ - **AR1 — No owned semantics.** The wrapper owns no interactive role or
114
+ accessible name beyond accepted caller props.
115
+ - **AR2 — Visible content.** Structured Badge text remains visible content;
116
+ custom content semantics remain caller owned.
117
+ - **AR3 — Atomic token.** `contentEditable={false}` keeps the token atomically
118
+ non-editable when nested in an editor.
114
119
 
115
120
  ## Design relationships
116
121
 
117
122
  | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
118
123
  | ------------------ | ------------------------- | ------------------------ | -------------- | ------------------ |
119
- | token wrapper | Inline alignment only | observed implementation | supporting | FR1, FR4 |
124
+ | token wrapper | Inline alignment only | Current source | supporting | FR1, FR4 |
120
125
  | structured content | Badge presentation | `component:Badge` | supporting | FR2 |
121
126
  | custom content | caller-owned presentation | caller | supporting | FR3 |
122
127
 
@@ -128,19 +133,26 @@ target. Badge theming remains owned by Badge, and custom content remains caller
128
133
  - `component:ChatComposerInput` owns insertion, serialization traversal, deletion, and selection behavior.
129
134
  - `architecture:public-component-api` owns the public props type, ref, and BaseProps composition.
130
135
  - `architecture:component-test-sufficiency` owns direct evidence for the established public serialization seam.
131
- - `spec:AST-029` owns this observational audit backfill and its finite evidence inventory.
136
+ - `spec:AST-029` owns the audit evidence inventory this record's verification map follows.
132
137
 
133
138
  ## Verification map
134
139
 
135
- | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
136
- | --------------- | ------------------------------------------------------------------ | -------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------- |
137
- | FR1–FR3 | `ChatComposerTokenElement.test.tsx`; direct Storybook stories | structured and custom tokens | A marker/value disappears, the wrapper becomes editable, or the wrong rendering branch appears. | `audit:ChatComposerTokenElement/behavior` |
138
- | FR4 | focused ref and DOM-passthrough test; public typecheck | ref, ARIA/data props, styling seams | An accepted input is dropped or an owned serialization marker is replaced. | `audit:ChatComposerTokenElement/api` |
139
- | rendered states | direct Storybook stories and exact-head visual/accessibility gates | Badge and custom content in supported themes | A story is unreachable or introduces an accessibility/visual regression. | `audit:ChatComposerTokenElement/rendered` |
140
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
141
+ | ---------------- | ------------------------------------------------------------- | -------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------- |
142
+ | FR1–FR3, AR2–AR3 | `ChatComposerTokenElement.test.tsx`; direct Storybook stories | structured and custom tokens | A marker/value disappears, the wrapper becomes editable, or the wrong rendering branch appears. | `audit:ChatComposerTokenElement/behavior` |
143
+ | FR4 | focused ref and DOM-passthrough test; public typecheck | ref, ARIA/data props, styling seams | An accepted input is dropped or an owned serialization marker is replaced. | `audit:ChatComposerTokenElement/api` |
144
+ | rendered states | direct Storybook stories | Badge and custom content in supported themes | An unreachable story fails the story checks. | `audit:ChatComposerTokenElement/rendered` |
145
+
146
+ Read from source, with no focused test yet:
147
+
148
+ - AR1: the wrapper adding no role or accessible name of its own.
149
+ - FR1: `contentEditable` staying `false` when a caller passes it.
150
+ - FR2: `variant` and `icon` reaching the Badge.
151
+ - FR4: `className`, `style`, and `xstyle` composing on the span.
140
152
 
141
153
  ## Decision log
142
154
 
143
- No component-local policy decision is created by this observational draft.
155
+ No component-local decision is recorded.
144
156
 
145
157
  ## Open questions
146
158
 
@@ -41,17 +41,18 @@ import {FieldLabel} from '../Field/FieldLabel';
41
41
  import {FieldStatus} from '../FieldStatus/FieldStatus';
42
42
  import type {IconType} from '../Icon';
43
43
  import type {InputStatus} from '../Field/types';
44
- import {Spinner} from '../Spinner';
45
- import {useTooltip} from '../Tooltip';
46
- import {mergeProps, rtlStyles} from '../utils';
44
+ import {Spinner} from '../Spinner/Spinner';
45
+ import {useTooltip} from '../Tooltip/useTooltip';
46
+ import {mergeProps} from '../utils/mergeProps';
47
+ import {rtlStyles} from '../utils/rtlStyles';
47
48
  import {indicatorScope} from '../Indicator/indicator.markers.stylex';
48
49
  import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
49
- import {useTranslator} from '../i18n';
50
+ import {useTranslator} from '../i18n/useTranslator';
50
51
  import {useIndicatorFocusRing} from '../hooks/useIndicatorFocusRing';
51
52
  import {useBusyAnnouncement} from '../hooks/useBusyAnnouncement';
52
53
  import {usePressFeedback} from '../hooks/usePressFeedback';
53
54
  import {useResolvedRequired} from '../hooks/useResolvedRequired';
54
- import {useIndicator} from '../Indicator';
55
+ import {useIndicator} from '../Indicator/useIndicator';
55
56
  import {themeProps} from '../utils/themeProps';
56
57
 
57
58
  import {useMergedRefs} from '../hooks/useMergedRefs';
@@ -1,9 +1,11 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
+ import {Activity, type ReactNode} from 'react';
3
4
  import {describe, it, expect, vi} from 'vitest';
4
5
  import {render, screen, fireEvent} from '@testing-library/react';
5
6
  import userEvent from '@testing-library/user-event';
6
7
  import {ClickableCard} from './ClickableCard';
8
+ import {LinkProvider} from '../Link';
7
9
  import {
8
10
  afterPaintsPress,
9
11
  hasReleaseFade,
@@ -171,6 +173,100 @@ describe('ClickableCard', () => {
171
173
  expect(handleClick).not.toHaveBeenCalled();
172
174
  });
173
175
 
176
+ it('does not render a disabled link through the router link component', () => {
177
+ function RouterLink({
178
+ href,
179
+ children,
180
+ }: {
181
+ href?: string;
182
+ children?: ReactNode;
183
+ }) {
184
+ if (href == null) {
185
+ throw new Error('Router link requires an href');
186
+ }
187
+ return <a href={href}>{children}</a>;
188
+ }
189
+
190
+ render(
191
+ <LinkProvider component={RouterLink}>
192
+ <ClickableCard label="Disabled link" href="/settings" isDisabled>
193
+ <span>Content</span>
194
+ </ClickableCard>
195
+ </LinkProvider>,
196
+ );
197
+
198
+ const link = screen.getByRole('link', {name: 'Disabled link'});
199
+ expect(link).toHaveAttribute('aria-disabled', 'true');
200
+ expect(link).not.toHaveAttribute('href');
201
+ });
202
+
203
+ it('keeps focus when a focused link card toggles its disabled state', async () => {
204
+ const user = userEvent.setup();
205
+ const {rerender} = render(
206
+ <ClickableCard label="Focus card" href="/settings">
207
+ <span>Content</span>
208
+ </ClickableCard>,
209
+ );
210
+
211
+ await user.tab();
212
+ expect(screen.getByRole('link', {name: 'Focus card'})).toHaveFocus();
213
+
214
+ rerender(
215
+ <ClickableCard label="Focus card" href="/settings" isDisabled>
216
+ <span>Content</span>
217
+ </ClickableCard>,
218
+ );
219
+ expect(screen.getByRole('link', {name: 'Focus card'})).toHaveFocus();
220
+
221
+ rerender(
222
+ <ClickableCard label="Focus card" href="/settings">
223
+ <span>Content</span>
224
+ </ClickableCard>,
225
+ );
226
+ expect(screen.getByRole('link', {name: 'Focus card'})).toHaveFocus();
227
+ });
228
+
229
+ it('leaves focus where the person put it when a hidden card is revealed', async () => {
230
+ const user = userEvent.setup();
231
+ function Harness({isHidden}: {isHidden: boolean}) {
232
+ return (
233
+ <>
234
+ <Activity mode={isHidden ? 'hidden' : 'visible'}>
235
+ <ClickableCard label="Hidden card" href="/settings">
236
+ <span>Content</span>
237
+ </ClickableCard>
238
+ </Activity>
239
+ <button type="button">Elsewhere</button>
240
+ </>
241
+ );
242
+ }
243
+ const {rerender} = render(<Harness isHidden={false} />);
244
+ await user.tab();
245
+ expect(screen.getByRole('link', {name: 'Hidden card'})).toHaveFocus();
246
+ rerender(<Harness isHidden />);
247
+ screen.getByRole('button', {name: 'Elsewhere'}).focus();
248
+ rerender(<Harness isHidden={false} />);
249
+ expect(screen.getByRole('button', {name: 'Elsewhere'})).toHaveFocus();
250
+ });
251
+
252
+ it('takes focus back without scrolling the page', async () => {
253
+ const user = userEvent.setup();
254
+ const {rerender} = render(
255
+ <ClickableCard label="Scroll card" href="/settings">
256
+ <span>Content</span>
257
+ </ClickableCard>,
258
+ );
259
+ await user.tab();
260
+ const focus = vi.spyOn(HTMLElement.prototype, 'focus');
261
+ rerender(
262
+ <ClickableCard label="Scroll card" href="/settings" isDisabled>
263
+ <span>Content</span>
264
+ </ClickableCard>,
265
+ );
266
+ expect(focus).toHaveBeenCalledWith({preventScroll: true});
267
+ focus.mockRestore();
268
+ });
269
+
174
270
  it('runs onClick once from the keyboard via the hidden button', async () => {
175
271
  const user = userEvent.setup();
176
272
  const handleClick = vi.fn();
@@ -29,7 +29,13 @@
29
29
  * For toggle selection, use SelectableCard.
30
30
  */
31
31
 
32
- import {type ReactNode, type MouseEvent, useRef, type Ref} from 'react';
32
+ import {
33
+ type ReactNode,
34
+ type MouseEvent,
35
+ useCallback,
36
+ useRef,
37
+ type Ref,
38
+ } from 'react';
33
39
  import * as stylex from '@stylexjs/stylex';
34
40
  import type {StyleXStyles} from '@stylexjs/stylex';
35
41
  import {
@@ -327,6 +333,41 @@ export function ClickableCard({
327
333
  const pressable = usePressFeedback();
328
334
  const containerRef = useRef<HTMLDivElement | null>(null);
329
335
  const interactiveRef = useRef<HTMLElement | null>(null);
336
+ const restoreFocusRef = useRef(false);
337
+ // The isDisabled value of the link that just detached: a link card that
338
+ // flips it replaces its hidden link (router component and plain anchor),
339
+ // and only that replacement takes focus back.
340
+ const detachedDisabledRef = useRef<boolean | null>(null);
341
+
342
+ // A focused link remounts when isDisabled changes: the replacement takes
343
+ // focus back, without scrolling, if focus fell to the page. Any other
344
+ // detach and attach (a hidden Activity or Suspense boundary revealed
345
+ // again) leaves focus where the person put it.
346
+ const setInteractiveRef = useCallback(
347
+ (node: HTMLElement | null) => {
348
+ if (node == null) {
349
+ const previous = interactiveRef.current;
350
+ restoreFocusRef.current =
351
+ previous != null && previous === previous.ownerDocument.activeElement;
352
+ detachedDisabledRef.current = isDisabled;
353
+ interactiveRef.current = null;
354
+ return;
355
+ }
356
+ interactiveRef.current = node;
357
+ const isFlip =
358
+ detachedDisabledRef.current != null &&
359
+ detachedDisabledRef.current !== isDisabled;
360
+ const active = node.ownerDocument.activeElement;
361
+ const hasFallen = active == null || active === node.ownerDocument.body;
362
+ if (restoreFocusRef.current && isFlip && hasFallen) {
363
+ node.focus({preventScroll: true});
364
+ }
365
+ restoreFocusRef.current = false;
366
+ detachedDisabledRef.current = null;
367
+ },
368
+ [isDisabled],
369
+ );
370
+
330
371
  const LinkComponent = useLinkComponent();
331
372
 
332
373
  const {onClick, onMouseUp} = useClickableContainer({
@@ -347,6 +388,9 @@ export function ClickableCard({
347
388
 
348
389
  const isLink = href != null;
349
390
 
391
+ // Disabled links have no href, so bypass the router and render an anchor.
392
+ const LinkRoot = isDisabled ? 'a' : LinkComponent;
393
+
350
394
  // Only the `default` variant has a visible border. Card draws a transparent
351
395
  // 1px border on every other variant purely to avoid layout jitter; we drop
352
396
  // it here so the hover overlay covers the full box with no untinted ring.
@@ -385,8 +429,8 @@ export function ClickableCard({
385
429
  onMouseUp={!isDisabled ? handleMouseUp : undefined}
386
430
  {...props}>
387
431
  {isLink ? (
388
- <LinkComponent
389
- ref={interactiveRef as React.Ref<HTMLAnchorElement>}
432
+ <LinkRoot
433
+ ref={setInteractiveRef}
390
434
  href={isDisabled ? undefined : href}
391
435
  target={isDisabled ? undefined : target}
392
436
  role={isDisabled ? 'link' : undefined}
@@ -399,7 +443,7 @@ export function ClickableCard({
399
443
  />
400
444
  ) : (
401
445
  <button
402
- ref={interactiveRef as React.Ref<HTMLButtonElement>}
446
+ ref={setInteractiveRef}
403
447
  type="button"
404
448
  aria-label={label}
405
449
  aria-disabled={isDisabled || undefined}
@@ -69,6 +69,8 @@ Consumer migration instructions belong in consumer docs and release notes.
69
69
  - caller-provided chevron, cue, icon, or render-function escape hatches;
70
70
  - TreeList, Table, or another component's disclosure indicator;
71
71
  - generic icon resolution or artwork customization;
72
+ - sibling open-value coordination, group state, and the divided group wrapper
73
+ — owned by `component:CollapsibleGroup`;
72
74
  - a shared responsive or directional API; or
73
75
  - new content-reveal motion behavior. Existing behavior outside this decision stays
74
76
  unchanged until its own current authority changes it.