@astryxdesign/core 0.6.2 → 0.6.3-canary.0788c49

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 (558) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/dist/BottomSheet/BottomSheet.d.ts +1 -1
  3. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  4. package/dist/BottomSheet/BottomSheet.js +3 -1
  5. package/dist/BottomSheet/BottomSheetPanel.d.ts +7 -5
  6. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  7. package/dist/BottomSheet/BottomSheetPanel.js +56 -19
  8. package/dist/Button/Button.d.ts.map +1 -1
  9. package/dist/Button/Button.js +13 -28
  10. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  11. package/dist/Chat/ChatComposer.js +10 -5
  12. package/dist/Chat/ChatComposerDrawer.d.ts +19 -5
  13. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  14. package/dist/Chat/ChatComposerDrawer.js +48 -23
  15. package/dist/Chat/ChatComposerInput.d.ts +11 -3
  16. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  17. package/dist/Chat/ChatComposerInput.js +63 -16
  18. package/dist/Chat/ChatDictationButton.d.ts +3 -2
  19. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  20. package/dist/Chat/ChatDictationButton.js +6 -4
  21. package/dist/Chat/ChatLayout.d.ts +19 -0
  22. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  23. package/dist/Chat/ChatLayout.js +19 -0
  24. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  25. package/dist/Chat/ChatLayoutScrollButton.js +44 -34
  26. package/dist/Chat/ChatMessageBubble.d.ts +2 -0
  27. package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
  28. package/dist/Chat/ChatMessageBubble.js +5 -3
  29. package/dist/Chat/ChatMessageList.d.ts +2 -1
  30. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  31. package/dist/Chat/ChatMessageList.js +4 -3
  32. package/dist/Chat/ChatMessageMetadata.d.ts +5 -4
  33. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  34. package/dist/Chat/ChatMessageMetadata.js +12 -9
  35. package/dist/Chat/ChatSendButton.d.ts +2 -1
  36. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  37. package/dist/Chat/ChatSendButton.js +6 -4
  38. package/dist/Chat/index.d.ts +1 -1
  39. package/dist/Chat/index.d.ts.map +1 -1
  40. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  41. package/dist/CheckboxInput/CheckboxInput.js +12 -2
  42. package/dist/Citation/Citation.d.ts +1 -1
  43. package/dist/Citation/Citation.d.ts.map +1 -1
  44. package/dist/Citation/Citation.js +3 -2
  45. package/dist/CodeBlock/highlightRanges.d.ts.map +1 -1
  46. package/dist/CodeBlock/highlightRanges.js +14 -3
  47. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  48. package/dist/Collapsible/Collapsible.js +6 -1
  49. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  50. package/dist/CommandPalette/CommandPaletteInput.js +1 -1
  51. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  52. package/dist/ComplexSelector/ComplexSelector.js +1 -1
  53. package/dist/DateInput/DateInput.d.ts.map +1 -1
  54. package/dist/DateInput/DateInput.js +4 -4
  55. package/dist/DateInput/NativeDateField.d.ts.map +1 -1
  56. package/dist/DateInput/NativeDateField.js +16 -16
  57. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  58. package/dist/DateInput/TouchDateField.js +2 -2
  59. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  60. package/dist/DateRangeInput/DateRangeInput.js +4 -4
  61. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  62. package/dist/DateTimeInput/DateTimeInput.js +8 -8
  63. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  64. package/dist/DateTimeInput/TouchDateTimeField.js +4 -4
  65. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +9 -3
  66. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -1
  67. package/dist/DateTimeInput/nativePickerSegmentStyles.js +3 -3
  68. package/dist/Dialog/DialogHeader.d.ts +8 -1
  69. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  70. package/dist/Dialog/DialogHeader.js +13 -4
  71. package/dist/Field/InputClearButton.d.ts +4 -2
  72. package/dist/Field/InputClearButton.d.ts.map +1 -1
  73. package/dist/Field/InputClearButton.js +4 -2
  74. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  75. package/dist/Field/PanelSearchInput.js +1 -1
  76. package/dist/FileInput/FileInput.d.ts.map +1 -1
  77. package/dist/FileInput/FileInput.js +7 -7
  78. package/dist/Icon/Icon.d.ts +6 -31
  79. package/dist/Icon/Icon.d.ts.map +1 -1
  80. package/dist/Icon/Icon.js +8 -71
  81. package/dist/Icon/IconDefaultSizeContext.d.ts +4 -0
  82. package/dist/Icon/IconDefaultSizeContext.d.ts.map +1 -0
  83. package/dist/Icon/IconDefaultSizeContext.js +18 -0
  84. package/dist/Icon/IconSize.stylex.d.ts +65 -0
  85. package/dist/Icon/IconSize.stylex.d.ts.map +1 -0
  86. package/dist/Icon/IconSize.stylex.js +75 -0
  87. package/dist/Item/Item.d.ts +1 -1
  88. package/dist/Item/Item.d.ts.map +1 -1
  89. package/dist/Item/Item.js +4 -3
  90. package/dist/Kbd/Kbd.d.ts +5 -3
  91. package/dist/Kbd/Kbd.d.ts.map +1 -1
  92. package/dist/Kbd/Kbd.js +36 -42
  93. package/dist/Link/Link.d.ts.map +1 -1
  94. package/dist/Link/Link.js +6 -2
  95. package/dist/Link/useLinkComponent.d.ts +5 -15
  96. package/dist/Link/useLinkComponent.d.ts.map +1 -1
  97. package/dist/Link/useLinkComponent.js +34 -51
  98. package/dist/List/List.d.ts +19 -1
  99. package/dist/List/List.d.ts.map +1 -1
  100. package/dist/List/List.js +9 -2
  101. package/dist/List/ListContext.d.ts +1 -0
  102. package/dist/List/ListContext.d.ts.map +1 -1
  103. package/dist/List/ListContext.js +2 -1
  104. package/dist/List/ListItem.d.ts +1 -1
  105. package/dist/List/ListItem.d.ts.map +1 -1
  106. package/dist/List/ListItem.js +9 -2
  107. package/dist/Markdown/Markdown.d.ts +8 -2
  108. package/dist/Markdown/Markdown.d.ts.map +1 -1
  109. package/dist/Markdown/Markdown.fr23.bench.d.ts +2 -0
  110. package/dist/Markdown/Markdown.fr23.bench.d.ts.map +1 -0
  111. package/dist/Markdown/Markdown.fr23.bench.js +150 -0
  112. package/dist/Markdown/Markdown.fr23.sampling.d.ts +2 -0
  113. package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -0
  114. package/dist/Markdown/Markdown.fr23.sampling.js +43 -0
  115. package/dist/Markdown/Markdown.js +262 -109
  116. package/dist/Markdown/ast.d.ts +162 -0
  117. package/dist/Markdown/ast.d.ts.map +1 -0
  118. package/dist/Markdown/ast.js +74 -0
  119. package/dist/Markdown/index.d.ts +5 -3
  120. package/dist/Markdown/index.d.ts.map +1 -1
  121. package/dist/Markdown/index.js +3 -2
  122. package/dist/Markdown/parser/index.d.ts +10 -0
  123. package/dist/Markdown/parser/index.d.ts.map +1 -0
  124. package/dist/Markdown/parser/index.js +10 -0
  125. package/dist/Markdown/parser.d.ts +126 -58
  126. package/dist/Markdown/parser.d.ts.map +1 -1
  127. package/dist/Markdown/parser.js +726 -177
  128. package/dist/Markdown/plugins/frontmatter.d.ts +32 -0
  129. package/dist/Markdown/plugins/frontmatter.d.ts.map +1 -0
  130. package/dist/Markdown/plugins/frontmatter.js +132 -0
  131. package/dist/Markdown/plugins/index.d.ts +17 -0
  132. package/dist/Markdown/plugins/index.d.ts.map +1 -0
  133. package/dist/Markdown/plugins/index.js +14 -0
  134. package/dist/Markdown/plugins/protocol.d.ts +191 -0
  135. package/dist/Markdown/plugins/protocol.d.ts.map +1 -0
  136. package/dist/Markdown/plugins/protocol.js +957 -0
  137. package/dist/Markdown/plugins/semanticFence.d.ts +36 -0
  138. package/dist/Markdown/plugins/semanticFence.d.ts.map +1 -0
  139. package/dist/Markdown/plugins/semanticFence.js +213 -0
  140. package/dist/Markdown/plugins/softBreaks.d.ts +3 -0
  141. package/dist/Markdown/plugins/softBreaks.d.ts.map +1 -0
  142. package/dist/Markdown/plugins/softBreaks.js +172 -0
  143. package/dist/Markdown/plugins/sourceDecoration.d.ts +76 -0
  144. package/dist/Markdown/plugins/sourceDecoration.d.ts.map +1 -0
  145. package/dist/Markdown/plugins/sourceDecoration.js +393 -0
  146. package/dist/Markdown/plugins/textTransform.d.ts +30 -0
  147. package/dist/Markdown/plugins/textTransform.d.ts.map +1 -0
  148. package/dist/Markdown/plugins/textTransform.js +374 -0
  149. package/dist/Markdown/remark.d.ts +196 -0
  150. package/dist/Markdown/remark.d.ts.map +1 -0
  151. package/dist/Markdown/remark.js +1062 -0
  152. package/dist/Markdown/url.d.ts +6 -0
  153. package/dist/Markdown/url.d.ts.map +1 -0
  154. package/dist/Markdown/url.js +31 -0
  155. package/dist/Markdown/utils.d.ts +4 -2
  156. package/dist/Markdown/utils.d.ts.map +1 -1
  157. package/dist/Markdown/utils.js +2 -1
  158. package/dist/MetadataList/MetadataList.js +3 -3
  159. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  160. package/dist/NumberInput/NumberInput.js +4 -4
  161. package/dist/Outline/index.d.ts +1 -0
  162. package/dist/Outline/index.d.ts.map +1 -1
  163. package/dist/Outline/parseOutlineFromMarkdown.d.ts +7 -1
  164. package/dist/Outline/parseOutlineFromMarkdown.d.ts.map +1 -1
  165. package/dist/Outline/parseOutlineFromMarkdown.js +14 -8
  166. package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -1
  167. package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
  168. package/dist/Outline/useOutlineFromMarkdown.js +8 -3
  169. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  170. package/dist/PowerSearch/PowerSearchEditPopover.js +46 -30
  171. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  172. package/dist/PowerSearch/PowerSearchValueEditor.js +5 -0
  173. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  174. package/dist/ProgressBar/ProgressBar.js +36 -31
  175. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  176. package/dist/RadioList/RadioListItem.js +13 -1
  177. package/dist/ScrollableArea/ScrollableArea.d.ts +1 -0
  178. package/dist/ScrollableArea/ScrollableArea.d.ts.map +1 -1
  179. package/dist/ScrollableArea/ScrollableArea.js +1 -0
  180. package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
  181. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  182. package/dist/SegmentedControl/SegmentedControl.js +1 -0
  183. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  184. package/dist/SegmentedControl/SegmentedControlItem.js +5 -5
  185. package/dist/Selector/Selector.d.ts +9 -7
  186. package/dist/Selector/Selector.d.ts.map +1 -1
  187. package/dist/Selector/Selector.js +16 -7
  188. package/dist/SideNav/SideNav.d.ts +2 -1
  189. package/dist/SideNav/SideNav.d.ts.map +1 -1
  190. package/dist/SideNav/SideNav.js +9 -3
  191. package/dist/Slider/Slider.d.ts.map +1 -1
  192. package/dist/Slider/Slider.js +28 -12
  193. package/dist/Spinner/Spinner.d.ts.map +1 -1
  194. package/dist/Spinner/Spinner.js +23 -7
  195. package/dist/Switch/Switch.d.ts.map +1 -1
  196. package/dist/Switch/Switch.js +11 -0
  197. package/dist/TabList/Tab.d.ts +1 -1
  198. package/dist/TabList/Tab.d.ts.map +1 -1
  199. package/dist/TabList/Tab.js +20 -7
  200. package/dist/Table/Table.d.ts +1 -0
  201. package/dist/Table/Table.d.ts.map +1 -1
  202. package/dist/Table/Table.js +29 -13
  203. package/dist/TextArea/TextArea.d.ts.map +1 -1
  204. package/dist/TextArea/TextArea.js +1 -1
  205. package/dist/TextInput/TextInput.d.ts.map +1 -1
  206. package/dist/TextInput/TextInput.js +2 -2
  207. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  208. package/dist/TimeInput/TimeInput.js +4 -4
  209. package/dist/Timer/Timer.d.ts +49 -0
  210. package/dist/Timer/Timer.d.ts.map +1 -0
  211. package/dist/Timer/Timer.js +158 -0
  212. package/dist/Timer/index.d.ts +9 -0
  213. package/dist/Timer/index.d.ts.map +1 -0
  214. package/dist/Timer/index.js +10 -0
  215. package/dist/ToggleButton/ToggleButton.d.ts +9 -6
  216. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  217. package/dist/ToggleButton/ToggleButton.js +15 -27
  218. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  219. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  220. package/dist/TopNav/TopNavMenu.js +3 -2
  221. package/dist/TreeList/TreeList.d.ts.map +1 -1
  222. package/dist/TreeList/TreeList.js +3 -0
  223. package/dist/TreeList/TreeListItem.d.ts +6 -1
  224. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  225. package/dist/TreeList/TreeListItem.js +12 -2
  226. package/dist/TreeList/TreeListTypes.d.ts +8 -1
  227. package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
  228. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  229. package/dist/Typeahead/BaseTypeahead.js +16 -7
  230. package/dist/astryx.css +27 -11
  231. package/dist/hooks/scrollKeyboardDelegation.d.ts +3 -0
  232. package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -0
  233. package/dist/hooks/scrollKeyboardDelegation.js +146 -0
  234. package/dist/hooks/useClickableContainer.d.ts +10 -1
  235. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  236. package/dist/hooks/useClickableContainer.js +15 -4
  237. package/dist/hooks/useScrollableArea.d.ts +6 -2
  238. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  239. package/dist/hooks/useScrollableArea.js +17 -5
  240. package/dist/index.d.ts +1 -0
  241. package/dist/index.d.ts.map +1 -1
  242. package/dist/index.js +3 -0
  243. package/dist/theme/declarationBoundary.d.ts +17 -0
  244. package/dist/theme/declarationBoundary.d.ts.map +1 -0
  245. package/dist/theme/declarationBoundary.js +343 -0
  246. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  247. package/dist/theme/derivedVarRegistry.js +4 -0
  248. package/dist/theme/generateThemeRules.d.ts +13 -7
  249. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  250. package/dist/theme/generateThemeRules.js +140 -34
  251. package/dist/utils/interactionOverlay.stylex.d.ts +8 -0
  252. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  253. package/dist/utils/interactionOverlay.stylex.js +9 -0
  254. package/dist/utils/safeUrl.d.ts +11 -0
  255. package/dist/utils/safeUrl.d.ts.map +1 -0
  256. package/dist/utils/safeUrl.js +78 -0
  257. package/locales/af-ZA.json +530 -1
  258. package/locales/ar-SA.json +490 -1
  259. package/locales/ca-ES.json +514 -1
  260. package/locales/cs-CZ.json +498 -1
  261. package/locales/da-DK.json +522 -1
  262. package/locales/de-DE.json +522 -1
  263. package/locales/el-GR.json +498 -1
  264. package/locales/es-ES.json +510 -1
  265. package/locales/fi-FI.json +498 -1
  266. package/locales/fr-FR.json +534 -1
  267. package/locales/he-IL.json +498 -1
  268. package/locales/hu-HU.json +498 -1
  269. package/locales/it-IT.json +510 -1
  270. package/locales/ja-JP.json +490 -1
  271. package/locales/ko-KR.json +498 -1
  272. package/locales/nl-NL.json +534 -1
  273. package/locales/no-NO.json +510 -1
  274. package/locales/pl-PL.json +506 -1
  275. package/locales/pt-BR.json +506 -1
  276. package/locales/pt-PT.json +506 -1
  277. package/locales/ro-RO.json +506 -1
  278. package/locales/ru-RU.json +498 -1
  279. package/locales/sr-SP.json +498 -1
  280. package/locales/sv-SE.json +502 -1
  281. package/locales/tr-TR.json +498 -1
  282. package/locales/uk-UA.json +498 -1
  283. package/locales/vi-VN.json +502 -1
  284. package/locales/zh-CN.json +490 -1
  285. package/locales/zh-TW.json +490 -1
  286. package/package.json +24 -4
  287. package/src/BottomSheet/BottomSheet.doc.mjs +8 -1
  288. package/src/BottomSheet/BottomSheet.spec.md +46 -20
  289. package/src/BottomSheet/BottomSheet.test.tsx +6 -3
  290. package/src/BottomSheet/BottomSheet.tsx +3 -1
  291. package/src/BottomSheet/BottomSheetKeyboard.test.tsx +195 -0
  292. package/src/BottomSheet/BottomSheetPanel.test.tsx +11 -1
  293. package/src/BottomSheet/BottomSheetPanel.tsx +49 -16
  294. package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +344 -0
  295. package/src/Button/Button.doc.mjs +5 -5
  296. package/src/Button/Button.tsx +15 -13
  297. package/src/Button/__tests__/Button.a11y.chromium.spec.ts +17 -1
  298. package/src/Button/__tests__/Button.a11y.known-failures.ts +0 -29
  299. package/src/Button/__tests__/Button.a11y.renders.tsx +9 -2
  300. package/src/Button/__tests__/Button.a11y.states.ts +9 -0
  301. package/src/Chat/ChatComposer.doc.mjs +14 -0
  302. package/src/Chat/ChatComposer.spec.md +230 -0
  303. package/src/Chat/ChatComposer.test.tsx +57 -0
  304. package/src/Chat/ChatComposer.tsx +21 -9
  305. package/src/Chat/ChatComposerDrawer.doc.mjs +63 -5
  306. package/src/Chat/ChatComposerDrawer.spec.md +267 -0
  307. package/src/Chat/ChatComposerDrawer.test.tsx +81 -12
  308. package/src/Chat/ChatComposerDrawer.tsx +38 -9
  309. package/src/Chat/ChatComposerInput.doc.mjs +114 -26
  310. package/src/Chat/ChatComposerInput.spec.md +185 -0
  311. package/src/Chat/ChatComposerInput.test.tsx +113 -3
  312. package/src/Chat/ChatComposerInput.tsx +78 -13
  313. package/src/Chat/ChatComposerTokenElement.spec.md +152 -0
  314. package/src/Chat/ChatComposerTokenElement.test.tsx +85 -0
  315. package/src/Chat/ChatDictationButton.doc.mjs +3 -3
  316. package/src/Chat/ChatDictationButton.spec.md +160 -0
  317. package/src/Chat/ChatDictationButton.test.tsx +92 -27
  318. package/src/Chat/ChatDictationButton.tsx +8 -6
  319. package/src/Chat/ChatLayout.doc.mjs +12 -4
  320. package/src/Chat/ChatLayout.spec.md +271 -0
  321. package/src/Chat/ChatLayout.test.tsx +28 -0
  322. package/src/Chat/ChatLayout.tsx +19 -0
  323. package/src/Chat/ChatLayoutScrollButton.spec.md +338 -0
  324. package/src/Chat/ChatLayoutScrollButton.test.tsx +31 -0
  325. package/src/Chat/ChatLayoutScrollButton.tsx +31 -14
  326. package/src/Chat/ChatMessageBubble.doc.mjs +28 -15
  327. package/src/Chat/ChatMessageBubble.spec.md +263 -0
  328. package/src/Chat/ChatMessageBubble.test.tsx +93 -0
  329. package/src/Chat/ChatMessageBubble.tsx +8 -3
  330. package/src/Chat/ChatMessageList.spec.md +222 -0
  331. package/src/Chat/ChatMessageList.test.tsx +64 -2
  332. package/src/Chat/ChatMessageList.tsx +4 -3
  333. package/src/Chat/ChatMessageMetadata.doc.mjs +57 -3
  334. package/src/Chat/ChatMessageMetadata.spec.md +220 -0
  335. package/src/Chat/ChatMessageMetadata.test.tsx +34 -0
  336. package/src/Chat/ChatMessageMetadata.tsx +13 -13
  337. package/src/Chat/ChatSendButton.doc.mjs +32 -0
  338. package/src/Chat/ChatSendButton.spec.md +227 -0
  339. package/src/Chat/ChatSendButton.test.tsx +128 -8
  340. package/src/Chat/ChatSendButton.tsx +6 -4
  341. package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +514 -0
  342. package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +740 -0
  343. package/src/Chat/__tests__/ChatMessageBubble.a11y.chromium.spec.ts +457 -0
  344. package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.test.ts +91 -0
  345. package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.ts +91 -0
  346. package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +456 -0
  347. package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +413 -0
  348. package/src/Chat/__tests__/ChatSendButton.a11y.chromium.spec.ts +1522 -0
  349. package/src/Chat/index.ts +1 -0
  350. package/src/CheckboxInput/CheckboxInput.doc.mjs +11 -0
  351. package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
  352. package/src/CheckboxInput/CheckboxInput.tsx +21 -1
  353. package/src/Citation/Citation.doc.mjs +2 -2
  354. package/src/Citation/Citation.test.tsx +17 -0
  355. package/src/Citation/Citation.tsx +4 -2
  356. package/src/ClickableCard/ClickableCard.doc.mjs +2 -2
  357. package/src/ClickableCard/ClickableCard.test.tsx +102 -5
  358. package/src/CodeBlock/highlightRanges.test.ts +143 -1
  359. package/src/CodeBlock/highlightRanges.ts +15 -5
  360. package/src/Collapsible/Collapsible.doc.mjs +11 -0
  361. package/src/Collapsible/Collapsible.test.tsx +21 -0
  362. package/src/Collapsible/Collapsible.tsx +5 -0
  363. package/src/CommandPalette/CommandPaletteInput.tsx +6 -1
  364. package/src/ComplexSelector/ComplexSelector.tsx +6 -1
  365. package/src/DateInput/DateInput.tsx +6 -1
  366. package/src/DateInput/NativeDateField.tsx +24 -8
  367. package/src/DateInput/TouchDateField.tsx +6 -2
  368. package/src/DateRangeInput/DateRangeInput.tsx +6 -1
  369. package/src/DateTimeInput/DateTimeInput.tsx +6 -1
  370. package/src/DateTimeInput/TouchDateTimeField.tsx +6 -1
  371. package/src/DateTimeInput/nativePickerSegmentStyles.ts +24 -8
  372. package/src/Dialog/Dialog.doc.mjs +2 -0
  373. package/src/Dialog/DialogHeader.doc.mjs +22 -0
  374. package/src/Dialog/DialogHeader.test.tsx +167 -3
  375. package/src/Dialog/DialogHeader.tsx +37 -6
  376. package/src/Dialog/modules/DialogHeader.spec.md +101 -42
  377. package/src/DropdownMenu/DropdownMenu.test.tsx +5 -2
  378. package/src/Field/InputClearButton.test.tsx +17 -3
  379. package/src/Field/InputClearButton.tsx +5 -2
  380. package/src/Field/PanelSearchInput.tsx +5 -2
  381. package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +1 -1
  382. package/src/FileInput/FileInput.tsx +11 -2
  383. package/src/Icon/Icon.doc.mjs +7 -5
  384. package/src/Icon/Icon.spec.md +81 -40
  385. package/src/Icon/Icon.test.tsx +6 -3
  386. package/src/Icon/Icon.tsx +20 -68
  387. package/src/Icon/IconDefaultSizeContext.ts +23 -0
  388. package/src/Icon/IconSize.stylex.ts +70 -0
  389. package/src/IconButton/IconButton.doc.mjs +3 -3
  390. package/src/IconButton/IconButton.test.tsx +40 -0
  391. package/src/Item/Item.doc.mjs +6 -2
  392. package/src/Item/Item.tsx +9 -3
  393. package/src/Kbd/Kbd.doc.mjs +3 -3
  394. package/src/Kbd/Kbd.test.tsx +57 -1
  395. package/src/Kbd/Kbd.tsx +57 -37
  396. package/src/Layout/LayoutFooter.doc.mjs +17 -0
  397. package/src/Link/Link.doc.mjs +17 -4
  398. package/src/Link/Link.test.tsx +24 -0
  399. package/src/Link/Link.tsx +5 -0
  400. package/src/Link/LinkProvider.doc.mjs +2 -2
  401. package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +261 -0
  402. package/src/Link/useLinkComponent.test.tsx +333 -0
  403. package/src/Link/useLinkComponent.ts +29 -57
  404. package/src/List/List.doc.mjs +6 -0
  405. package/src/List/List.spec.md +200 -0
  406. package/src/List/List.test.tsx +117 -1
  407. package/src/List/List.tsx +22 -2
  408. package/src/List/ListContext.tsx +3 -1
  409. package/src/List/ListItem.doc.mjs +2 -2
  410. package/src/List/ListItem.source-build.test.mjs +41 -0
  411. package/src/List/ListItem.tsx +26 -2
  412. package/src/Markdown/Markdown.doc.mjs +300 -2
  413. package/src/Markdown/Markdown.fr23.bench.ts +174 -0
  414. package/src/Markdown/Markdown.fr23.perf.test.ts +249 -0
  415. package/src/Markdown/Markdown.fr23.sampling.ts +49 -0
  416. package/src/Markdown/Markdown.helpers.perf.test.ts +489 -0
  417. package/src/Markdown/Markdown.public.test.ts +130 -3
  418. package/src/Markdown/Markdown.renderBoundary.test.tsx +72 -0
  419. package/src/Markdown/Markdown.spec.md +210 -45
  420. package/src/Markdown/Markdown.test.tsx +87 -3
  421. package/src/Markdown/Markdown.tsx +414 -135
  422. package/src/Markdown/ast.test.ts +307 -0
  423. package/src/Markdown/ast.ts +337 -0
  424. package/src/Markdown/incremental.test.ts +43 -0
  425. package/src/Markdown/index.ts +37 -1
  426. package/src/Markdown/modules/remark.spec.md +269 -0
  427. package/src/Markdown/modules/softBreaks.spec.md +137 -0
  428. package/src/Markdown/parser/index.ts +64 -0
  429. package/src/Markdown/parser.public.test.ts +103 -0
  430. package/src/Markdown/parser.test.ts +38 -6
  431. package/src/Markdown/parser.ts +1221 -242
  432. package/src/Markdown/plugins/frontmatter.test.tsx +125 -0
  433. package/src/Markdown/plugins/frontmatter.ts +198 -0
  434. package/src/Markdown/plugins/index.ts +54 -0
  435. package/src/Markdown/plugins/protocol.test.tsx +1022 -0
  436. package/src/Markdown/plugins/protocol.ts +1618 -0
  437. package/src/Markdown/plugins/semanticFence.test.tsx +546 -0
  438. package/src/Markdown/plugins/semanticFence.ts +424 -0
  439. package/src/Markdown/plugins/softBreaks.test.tsx +172 -0
  440. package/src/Markdown/plugins/softBreaks.ts +169 -0
  441. package/src/Markdown/plugins/sourceDecoration.test.tsx +799 -0
  442. package/src/Markdown/plugins/sourceDecoration.ts +539 -0
  443. package/src/Markdown/plugins/textTransform.test.ts +467 -0
  444. package/src/Markdown/plugins/textTransform.ts +554 -0
  445. package/src/Markdown/remark.test.tsx +1877 -0
  446. package/src/Markdown/remark.ts +1574 -0
  447. package/src/Markdown/url.ts +36 -0
  448. package/src/Markdown/utils.ts +13 -1
  449. package/src/MetadataList/MetadataList.test.tsx +4 -2
  450. package/src/MetadataList/MetadataList.tsx +3 -3
  451. package/src/MultiSelector/MultiSelector.test.tsx +1 -35
  452. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +128 -0
  453. package/src/NumberInput/NumberInput.tsx +6 -1
  454. package/src/Outline/Outline.doc.mjs +7 -5
  455. package/src/Outline/Outline.spec.md +1 -1
  456. package/src/Outline/index.ts +1 -0
  457. package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +142 -0
  458. package/src/Outline/parseOutlineFromMarkdown.ts +40 -10
  459. package/src/Outline/useOutlineFromMarkdown.ts +15 -3
  460. package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
  461. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +150 -1
  462. package/src/PowerSearch/PowerSearchEditPopover.tsx +51 -28
  463. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +51 -0
  464. package/src/PowerSearch/PowerSearchValueEditor.tsx +4 -0
  465. package/src/ProgressBar/ProgressBar.test.tsx +29 -11
  466. package/src/ProgressBar/ProgressBar.tsx +59 -72
  467. package/src/RadioList/RadioList.doc.mjs +11 -0
  468. package/src/RadioList/RadioList.test.tsx +32 -0
  469. package/src/RadioList/RadioListItem.tsx +25 -1
  470. package/src/ScrollableArea/ScrollableArea.tsx +1 -0
  471. package/src/ScrollableArea/modules/useScrollableArea.spec.md +50 -22
  472. package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
  473. package/src/SegmentedControl/SegmentedControl.test.tsx +61 -0
  474. package/src/SegmentedControl/SegmentedControl.tsx +2 -1
  475. package/src/SegmentedControl/SegmentedControlItem.tsx +6 -9
  476. package/src/Selector/Selector.doc.mjs +3 -3
  477. package/src/Selector/Selector.spec.md +51 -49
  478. package/src/Selector/Selector.test.tsx +61 -55
  479. package/src/Selector/Selector.tsx +34 -15
  480. package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +130 -0
  481. package/src/Selector/__tests__/Listbox.a11y.dom.ts +38 -0
  482. package/src/Selector/__tests__/Listbox.a11y.inventory.test.ts +63 -0
  483. package/src/Selector/__tests__/Listbox.a11y.known-failures.ts +37 -0
  484. package/src/Selector/__tests__/Listbox.a11y.states.ts +232 -0
  485. package/src/Selector/__tests__/Selector.a11y.chromium.spec.ts +45 -0
  486. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +121 -0
  487. package/src/SideNav/SideNav.doc.mjs +1 -1
  488. package/src/SideNav/SideNav.test.tsx +10 -0
  489. package/src/SideNav/SideNav.tsx +14 -2
  490. package/src/Slider/Slider.doc.mjs +17 -3
  491. package/src/Slider/Slider.test.tsx +221 -0
  492. package/src/Slider/Slider.tsx +40 -9
  493. package/src/Spinner/Spinner.test.tsx +4 -0
  494. package/src/Spinner/Spinner.tsx +31 -18
  495. package/src/Switch/Switch.doc.mjs +11 -0
  496. package/src/Switch/Switch.test.tsx +16 -0
  497. package/src/Switch/Switch.tsx +28 -0
  498. package/src/TabList/Tab.tsx +35 -7
  499. package/src/TabList/TabList.doc.mjs +11 -0
  500. package/src/TabList/TabList.spec.md +204 -0
  501. package/src/TabList/TabList.test.tsx +66 -0
  502. package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +1 -34
  503. package/src/Table/Table.doc.mjs +1 -1
  504. package/src/Table/Table.spec.md +54 -40
  505. package/src/Table/Table.test.tsx +83 -10
  506. package/src/Table/Table.tsx +30 -22
  507. package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +137 -0
  508. package/src/TextArea/TextArea.tsx +6 -1
  509. package/src/TextInput/TextInput.test.tsx +20 -1
  510. package/src/TextInput/TextInput.tsx +6 -1
  511. package/src/TimeInput/TimeInput.tsx +6 -1
  512. package/src/Timer/Timer.doc.mjs +183 -0
  513. package/src/Timer/Timer.spec.md +215 -0
  514. package/src/Timer/Timer.test.tsx +302 -0
  515. package/src/Timer/Timer.tsx +258 -0
  516. package/src/Timer/index.ts +11 -0
  517. package/src/ToggleButton/ToggleButton.doc.mjs +3 -3
  518. package/src/ToggleButton/ToggleButton.test.tsx +299 -4
  519. package/src/ToggleButton/ToggleButton.tsx +26 -33
  520. package/src/ToggleButton/ToggleButtonGroup.doc.mjs +3 -3
  521. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +209 -0
  522. package/src/Token/Token.doc.mjs +2 -2
  523. package/src/Tokenizer/Tokenizer.spec.md +142 -75
  524. package/src/TopNav/TopNavMenu.doc.mjs +2 -2
  525. package/src/TopNav/TopNavMenu.test.tsx +30 -0
  526. package/src/TopNav/TopNavMenu.tsx +7 -2
  527. package/src/TreeList/TreeList.doc.mjs +3 -3
  528. package/src/TreeList/TreeList.spec.md +123 -75
  529. package/src/TreeList/TreeList.test.tsx +29 -0
  530. package/src/TreeList/TreeList.tsx +3 -0
  531. package/src/TreeList/TreeListItem.tsx +15 -1
  532. package/src/TreeList/TreeListTypes.ts +11 -1
  533. package/src/Typeahead/BaseTypeahead.spec.md +4 -3
  534. package/src/Typeahead/BaseTypeahead.tsx +21 -7
  535. package/src/Typeahead/Typeahead.test.tsx +53 -0
  536. package/src/__tests__/PressedState.a11y.chromium.spec.ts +813 -0
  537. package/src/__tests__/pressState.ts +93 -0
  538. package/src/hooks/scrollKeyboardDelegation.test.ts +155 -0
  539. package/src/hooks/scrollKeyboardDelegation.ts +233 -0
  540. package/src/hooks/useClickableContainer.test.tsx +236 -0
  541. package/src/hooks/useClickableContainer.ts +20 -4
  542. package/src/hooks/useScrollableArea.doc.mjs +15 -3
  543. package/src/hooks/useScrollableArea.test.tsx +59 -1
  544. package/src/hooks/useScrollableArea.ts +34 -10
  545. package/src/index.ts +3 -0
  546. package/src/inputFontFloor.test.ts +106 -0
  547. package/src/tailwind-theme.css +0 -6
  548. package/src/theme/Theme.test.tsx +32 -0
  549. package/src/theme/declarationBoundary.test.ts +126 -0
  550. package/src/theme/declarationBoundary.ts +347 -0
  551. package/src/theme/derivedVarRegistry.test.ts +7 -0
  552. package/src/theme/derivedVarRegistry.ts +1 -0
  553. package/src/theme/generateThemeRules.test.ts +526 -1
  554. package/src/theme/generateThemeRules.ts +228 -50
  555. package/src/theme/tokenValueCompat.test.ts +4 -1
  556. package/src/utils/interactionOverlay.stylex.ts +20 -0
  557. package/src/utils/safeUrl.test.ts +88 -0
  558. package/src/utils/safeUrl.ts +85 -0
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  import {describe, it, expect, vi} from 'vitest';
13
- import {render, screen} from '@testing-library/react';
13
+ import {act, render, screen} from '@testing-library/react';
14
14
  import * as stylex from '@stylexjs/stylex';
15
15
  import {BaseTable} from './BaseTable';
16
16
  import {Table} from './Table';
@@ -837,22 +837,95 @@ describe('Table', () => {
837
837
  expect(screen.getAllByRole('row')).toHaveLength(4);
838
838
  });
839
839
 
840
- it('wraps table in a scroll container', () => {
840
+ it('wraps the table in an observed scroll content box', () => {
841
841
  render(<Table data={users} columns={columns} />);
842
842
  const table = screen.getByRole('table');
843
- const wrapper = table.parentElement;
843
+ const content = table.parentElement;
844
+ const wrapper = content?.parentElement;
845
+ expect(content).toHaveAttribute('data-scroll-content');
844
846
  expect(wrapper).toBeTruthy();
845
847
  expect(wrapper!.className).toContain('astryx-table-scroll-wrapper');
846
848
  });
847
849
 
848
- it('makes the scroll container keyboard-focusable', () => {
850
+ it('keeps a fitting scroll container out of the keyboard order', () => {
849
851
  render(<Table data={users} columns={columns} />);
850
- const table = screen.getByRole('table');
851
- const wrapper = table.parentElement;
852
- expect(wrapper).toBeTruthy();
853
- expect(wrapper!).toHaveAttribute('tabindex', '0');
854
- expect(wrapper!).toHaveAttribute('role', 'group');
855
- expect(wrapper!).toHaveAttribute('aria-label', 'Table');
852
+ const wrapper = screen.getByRole('group', {name: 'Table'});
853
+ expect(wrapper).not.toHaveAttribute('tabindex');
854
+ expect(wrapper.style.overscrollBehaviorX).toBe('auto');
855
+ });
856
+
857
+ it('preserves scroll-wrapper HTML attributes from plugins', () => {
858
+ const plugin: TablePlugin<User> = {
859
+ transformScrollWrapper: props => ({
860
+ ...props,
861
+ htmlProps: {
862
+ ...props.htmlProps,
863
+ role: 'region',
864
+ 'aria-label': 'Orders',
865
+ tabIndex: 2,
866
+ },
867
+ }),
868
+ };
869
+ render(<Table data={users} columns={columns} plugins={{custom: plugin}} />);
870
+ const wrapper = screen.getByRole('region', {name: 'Orders'});
871
+ expect(wrapper).toHaveAttribute('tabindex', '2');
872
+ });
873
+
874
+ it('contains overscroll only while the table scrolls', () => {
875
+ const frames: FrameRequestCallback[] = [];
876
+ vi.stubGlobal(
877
+ 'requestAnimationFrame',
878
+ vi.fn((callback: FrameRequestCallback) => {
879
+ frames.push(callback);
880
+ return frames.length;
881
+ }),
882
+ );
883
+ vi.stubGlobal('cancelAnimationFrame', vi.fn());
884
+
885
+ try {
886
+ render(<Table data={users} columns={columns} />);
887
+ const wrapper = screen.getByRole('group', {name: 'Table'});
888
+ Object.assign(wrapper.style, {overflowX: 'auto'});
889
+ for (const [key, value] of Object.entries({
890
+ clientWidth: 100,
891
+ clientHeight: 100,
892
+ scrollWidth: 180,
893
+ scrollHeight: 100,
894
+ scrollLeft: 0,
895
+ scrollTop: 0,
896
+ })) {
897
+ Object.defineProperty(wrapper, key, {
898
+ configurable: true,
899
+ value,
900
+ writable: true,
901
+ });
902
+ }
903
+
904
+ act(() => {
905
+ wrapper.dispatchEvent(new Event('scroll'));
906
+ frames.splice(0).forEach(callback => callback(performance.now()));
907
+ });
908
+
909
+ expect(wrapper).toHaveAttribute('tabindex', '0');
910
+ expect(wrapper).toHaveAttribute('data-scrollable-inline', 'true');
911
+ expect(wrapper.style.overscrollBehaviorX).toBe('contain');
912
+
913
+ Object.defineProperty(wrapper, 'scrollWidth', {
914
+ configurable: true,
915
+ value: 100,
916
+ writable: true,
917
+ });
918
+ act(() => {
919
+ wrapper.dispatchEvent(new Event('scroll'));
920
+ frames.splice(0).forEach(callback => callback(performance.now()));
921
+ });
922
+
923
+ expect(wrapper).not.toHaveAttribute('tabindex');
924
+ expect(wrapper).not.toHaveAttribute('data-scrollable-inline');
925
+ expect(wrapper.style.overscrollBehaviorX).toBe('auto');
926
+ } finally {
927
+ vi.unstubAllGlobals();
928
+ }
856
929
  });
857
930
 
858
931
  it('uses table-layout: auto in children mode', () => {
@@ -11,6 +11,7 @@
11
11
  * SYNC: When modified, update these files to stay in sync:
12
12
  * - /packages/core/src/Table/Table.doc.mjs (props table, features, usage examples)
13
13
  * - /packages/core/src/Table/Table.test.tsx (tests for new/changed behavior)
14
+ * - /packages/core/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts (browser scroll behavior)
14
15
  * - /packages/core/src/Table/index.ts (exports if types change)
15
16
  * - /apps/storybook/stories/Table.stories.tsx (storybook stories)
16
17
  * - /packages/cli/assets/templates/blocks/components/Table/ (showcase blocks)
@@ -22,6 +23,7 @@ import {colorVars} from '../theme/tokens.stylex';
22
23
  import {BaseTable} from './BaseTable';
23
24
  import {TableContext} from './TableContext';
24
25
  import {useBaseTablePlugins} from './useBaseTablePlugins';
26
+ import {useScrollableArea} from '../hooks/useScrollableArea';
25
27
  import {mergeProps} from '../utils';
26
28
  import {themeProps} from '../utils/themeProps';
27
29
  import type {
@@ -149,30 +151,36 @@ function TableScrollWrapper({
149
151
  afterTable?: React.ReactNode;
150
152
  }) {
151
153
  const t = useTranslator();
154
+ const label = t('@astryx.table.label');
155
+ const {getViewportProps, getContentProps, state} = useScrollableArea({
156
+ axis: 'inline',
157
+ keyboardAccess: {owner: 'content'},
158
+ overscroll: 'contain',
159
+ });
152
160
  const {ref, ...restHtmlProps} = htmlProps ?? {};
161
+ const viewportProps = getViewportProps<HTMLDivElement>({
162
+ role: 'group',
163
+ 'aria-label': label,
164
+ ...(state.inline.isScrollable ? {tabIndex: 0} : {}),
165
+ ...restHtmlProps,
166
+ ref,
167
+ ...mergeProps(
168
+ themeProps('table-scroll-wrapper'),
169
+ stylex.props(
170
+ scrollWrapperStyles.base,
171
+ scrollWrapperStyles.containerBleed,
172
+ ...(pluginStyles ?? []),
173
+ ),
174
+ ),
175
+ });
176
+
153
177
  return (
154
- <div
155
- ref={ref}
156
- // Keyboard-focusable so keyboard users can scroll a horizontally
157
- // overflowing table. Uses role="group" (not "region") so multiple
158
- // tables on a page don't create duplicate same-named landmarks
159
- // (axe: landmark-unique). Callers may override role/aria-label via
160
- // htmlProps.
161
- tabIndex={0}
162
- role="group"
163
- aria-label={t('@astryx.table.label')}
164
- {...restHtmlProps}
165
- {...mergeProps(
166
- themeProps('table-scroll-wrapper'),
167
- stylex.props(
168
- scrollWrapperStyles.base,
169
- scrollWrapperStyles.containerBleed,
170
- ...(pluginStyles ?? []),
171
- ),
172
- )}>
173
- {beforeTable}
174
- {children}
175
- {afterTable}
178
+ <div {...viewportProps}>
179
+ <div {...getContentProps<HTMLDivElement>()}>
180
+ {beforeTable}
181
+ {children}
182
+ {afterTable}
183
+ </div>
176
184
  </div>
177
185
  );
178
186
  }
@@ -0,0 +1,137 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file TableScroll.a11y.chromium.spec.ts
5
+ * @input Built responsive Table story and real Chromium wheel input
6
+ * @output Browser evidence for conditional inline containment and scroll chaining
7
+ * @position Table integration proof for the shared useScrollableArea behavior
8
+ */
9
+
10
+ import {expect, test, type Locator, type Page} from '@playwright/test';
11
+ import {
12
+ DEFAULT_STORYBOOK_DIR,
13
+ serveStorybook,
14
+ type StaticServer,
15
+ } from '@astryxdesign/a11y-spec/storybook';
16
+
17
+ let storybook: StaticServer;
18
+ test.beforeAll(async () => {
19
+ storybook = await serveStorybook(
20
+ process.env.ASTRYX_STORYBOOK_DIR ?? DEFAULT_STORYBOOK_DIR,
21
+ );
22
+ });
23
+ test.afterAll(async () => {
24
+ await storybook?.close();
25
+ });
26
+
27
+ async function mount(page: Page) {
28
+ await page.goto(
29
+ `${storybook.origin}/iframe.html?id=core-table--responsive-scroll&viewMode=story`,
30
+ );
31
+ const wrappers = page.locator('.astryx-table-scroll-wrapper');
32
+ await expect(wrappers).toHaveCount(3);
33
+ return wrappers;
34
+ }
35
+
36
+ async function putInsideOuterScroller(
37
+ page: Page,
38
+ viewport: Locator,
39
+ viewportWidth: number,
40
+ contentWidth: number,
41
+ tableWidth: number,
42
+ ) {
43
+ await viewport.evaluate(
44
+ (node, sizes) => {
45
+ const outer = document.createElement('div');
46
+ outer.dataset.tableScrollOuter = '';
47
+ outer.style.inlineSize = `${sizes.viewportWidth}px`;
48
+ outer.style.overflowX = 'auto';
49
+ const content = document.createElement('div');
50
+ content.style.inlineSize = `${sizes.contentWidth}px`;
51
+ node.parentElement?.insertBefore(outer, node);
52
+ outer.append(content);
53
+ content.append(node);
54
+ (node as HTMLElement).style.inlineSize = `${sizes.tableWidth}px`;
55
+ },
56
+ {viewportWidth, contentWidth, tableWidth},
57
+ );
58
+ return page.locator('[data-table-scroll-outer]');
59
+ }
60
+
61
+ async function wheelInline(page: Page, target: Locator) {
62
+ const box = await target.boundingBox();
63
+ if (box == null) {
64
+ throw new Error('Table scroll viewport has no rendered bounds');
65
+ }
66
+ await page.mouse.move(box.x + Math.min(box.width / 2, 100), box.y + 20);
67
+ await page.mouse.wheel(200, 0);
68
+ }
69
+
70
+ test('an overflowing table contains horizontal wheel input at its edge', async ({
71
+ page,
72
+ }) => {
73
+ const wrappers = await mount(page);
74
+ const tableViewport = wrappers.nth(0);
75
+ await tableViewport.locator('table').evaluate(table => {
76
+ const viewport = table.closest<HTMLElement>('.astryx-table-scroll-wrapper');
77
+ if (viewport != null) {
78
+ table.style.minWidth = `${viewport.clientWidth + 400}px`;
79
+ }
80
+ });
81
+ await expect(tableViewport).toHaveAttribute('data-scrollable-inline', 'true');
82
+ await expect(tableViewport).toHaveAttribute('tabindex', '0');
83
+ await expect
84
+ .poll(async () =>
85
+ tableViewport.evaluate(
86
+ element => getComputedStyle(element).overscrollBehaviorX,
87
+ ),
88
+ )
89
+ .toBe('contain');
90
+
91
+ const outer = await putInsideOuterScroller(
92
+ page,
93
+ tableViewport,
94
+ 320,
95
+ 800,
96
+ 320,
97
+ );
98
+ await tableViewport.evaluate(element => {
99
+ element.scrollLeft = element.scrollWidth - element.clientWidth;
100
+ });
101
+ await wheelInline(page, tableViewport);
102
+ await expect
103
+ .poll(async () => outer.evaluate(element => element.scrollLeft))
104
+ .toBe(0);
105
+ });
106
+
107
+ test('a fitting table passes horizontal wheel input to its outer scroller', async ({
108
+ page,
109
+ }) => {
110
+ const wrappers = await mount(page);
111
+ const tableViewport = wrappers.nth(2);
112
+ const outer = await putInsideOuterScroller(
113
+ page,
114
+ tableViewport,
115
+ 320,
116
+ 800,
117
+ 800,
118
+ );
119
+
120
+ await expect(tableViewport).not.toHaveAttribute(
121
+ 'data-scrollable-inline',
122
+ 'true',
123
+ );
124
+ await expect(tableViewport).not.toHaveAttribute('tabindex');
125
+ await expect
126
+ .poll(async () =>
127
+ tableViewport.evaluate(
128
+ element => getComputedStyle(element).overscrollBehaviorX,
129
+ ),
130
+ )
131
+ .toBe('auto');
132
+
133
+ await wheelInline(page, tableViewport);
134
+ await expect
135
+ .poll(async () => outer.evaluate(element => element.scrollLeft))
136
+ .toBeGreaterThan(0);
137
+ });
@@ -95,9 +95,14 @@ const styles = stylex.create({
95
95
  paddingBlock: spacingVars['--spacing-1'],
96
96
  paddingInline: 'var(--_textarea-inline-padding)',
97
97
  fontFamily: typographyVars['--font-family-body'],
98
+ // The 16px floor is iOS-only: iOS Safari zooms the page when a focused
99
+ // control sits under 16px, and only iOS WebKit implements
100
+ // -webkit-touch-callout to key the coarse-pointer floor to it.
98
101
  fontSize: {
99
102
  default: typeScaleVars['--text-body-size'],
100
- '@media (pointer: coarse)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
103
+ '@media (pointer: coarse)': {
104
+ '@supports (-webkit-touch-callout: none)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
105
+ },
101
106
  },
102
107
  lineHeight: typeScaleVars['--text-body-leading'],
103
108
  color: colorVars['--color-text-primary'],
@@ -2,7 +2,8 @@
2
2
 
3
3
  /**
4
4
  * @file TextInput.test.tsx
5
- * @input Uses vitest, @testing-library/react, TextInput component
5
+ * @input Uses vitest, @testing-library/react, TextInput component, and the
6
+ * shared declaredValue StyleX read-back helper
6
7
  * @output Unit tests for TextInput component behavior
7
8
  * @position Testing; validates TextInput.tsx implementation
8
9
  *
@@ -13,6 +14,7 @@ import {describe, it, expect, vi, beforeEach} from 'vitest';
13
14
  import {render, screen, fireEvent, waitFor} from '@testing-library/react';
14
15
  import userEvent from '@testing-library/user-event';
15
16
  import {TestIcon} from '../__tests__/TestIcon';
17
+ import {declaredValue} from '../__tests__/stylexDeclarations';
16
18
  import {InputGroup} from '../InputGroup';
17
19
  import {TextInput} from './TextInput';
18
20
 
@@ -1113,3 +1115,20 @@ describe('TextInput clear button focus behavior', () => {
1113
1115
  rafSpy.mockRestore();
1114
1116
  });
1115
1117
  });
1118
+
1119
+ describe('TextInput text size', () => {
1120
+ it('renders the theme body size outside the iOS zoom gate', () => {
1121
+ // The 16px floor rides `@supports (-webkit-touch-callout: none)` inside
1122
+ // `@media (pointer: coarse)` — iOS Safari is the browser that zooms on
1123
+ // focus under 16px, so the floor targets it alone instead of every
1124
+ // coarse pointer. jsdom's CSSOM drops at-rule-wrapped declarations it
1125
+ // cannot parse, so the gate itself is pinned against the sources in
1126
+ // inputFontFloor.test.ts; what this asserts is the visible result off
1127
+ // the gate: the plain token size, not a floor.
1128
+ render(<TextInput label="Name" value="" onChange={() => {}} />);
1129
+ expect(declaredValue(screen.getByLabelText('Name'), 'font-size')).toBe(
1130
+ 'var(--text-body-size)',
1131
+ );
1132
+ });
1133
+ });
1134
+
@@ -58,9 +58,14 @@ const styles = stylex.create({
58
58
  borderStyle: 'none',
59
59
  padding: 0,
60
60
  fontFamily: typographyVars['--font-family-body'],
61
+ // The 16px floor is iOS-only: iOS Safari zooms the page when a focused
62
+ // control sits under 16px, and only iOS WebKit implements
63
+ // -webkit-touch-callout to key the coarse-pointer floor to it.
61
64
  fontSize: {
62
65
  default: typeScaleVars['--text-body-size'],
63
- '@media (pointer: coarse)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
66
+ '@media (pointer: coarse)': {
67
+ '@supports (-webkit-touch-callout: none)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
68
+ },
64
69
  },
65
70
  lineHeight: typeScaleVars['--text-body-leading'],
66
71
  color: colorVars['--color-text-primary'],
@@ -95,9 +95,14 @@ const styles = stylex.create({
95
95
  borderStyle: 'none',
96
96
  padding: 0,
97
97
  fontFamily: typographyVars['--font-family-body'],
98
+ // The 16px floor is iOS-only: iOS Safari zooms the page when a focused
99
+ // control sits under 16px, and only iOS WebKit implements
100
+ // -webkit-touch-callout to key the coarse-pointer floor to it.
98
101
  fontSize: {
99
102
  default: typeScaleVars['--text-body-size'],
100
- '@media (pointer: coarse)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
103
+ '@media (pointer: coarse)': {
104
+ '@supports (-webkit-touch-callout: none)': `max(1rem, ${typeScaleVars['--text-body-size']})`,
105
+ },
101
106
  },
102
107
  lineHeight: typeScaleVars['--text-body-leading'],
103
108
  color: colorVars['--color-text-primary'],
@@ -0,0 +1,183 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('@astryxdesign/cli/authoring').ComponentAnatomyElement[]} */
4
+ const anatomy = [
5
+ {
6
+ name: 'Elapsed time',
7
+ required: true,
8
+ description:
9
+ 'Semantic time element containing a standardized elapsed duration.',
10
+ },
11
+ ];
12
+
13
+ /** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */
14
+ export const docs = {
15
+ name: 'Timer',
16
+ displayName: 'Timer',
17
+ category: 'Content',
18
+ keywords: [
19
+ 'timer',
20
+ 'elapsed',
21
+ 'duration',
22
+ 'seconds',
23
+ 'minutes',
24
+ 'hours',
25
+ 'stopwatch',
26
+ 'waiting',
27
+ 'loading',
28
+ 'processing',
29
+ ],
30
+ props: [
31
+ {
32
+ name: 'startTime',
33
+ type: 'number',
34
+ description:
35
+ "Unix time in milliseconds when the measured operation began. Omit it to start from this Timer's mount.",
36
+ },
37
+ {
38
+ name: 'format',
39
+ type: "'elapsed' | 'clock'",
40
+ description:
41
+ 'Standard duration representation. Elapsed uses compact units and drops seconds after one hour; clock uses m:ss or h:mm:ss.',
42
+ default: "'elapsed'",
43
+ },
44
+ {
45
+ name: 'type',
46
+ type: "'body' | 'large' | 'label' | 'supporting' | 'code' | 'display-1' | 'display-2' | 'display-3' | 'inherit'",
47
+ description:
48
+ 'Semantic text type. Uses the same typography behavior as Timestamp.',
49
+ default: "'supporting'",
50
+ },
51
+ {
52
+ name: 'size',
53
+ type: "'4xs' | '3xs' | '2xs' | 'xsm' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl'",
54
+ description: 'Explicit font size override. Overrides the size from type.',
55
+ },
56
+ {
57
+ name: 'color',
58
+ type: "'primary' | 'secondary' | 'disabled' | 'placeholder' | 'accent' | 'inherit'",
59
+ description: 'Text color.',
60
+ default: "'secondary'",
61
+ },
62
+ {
63
+ name: 'weight',
64
+ type: "'normal' | 'medium' | 'semibold' | 'bold'",
65
+ description: 'Font weight override.',
66
+ },
67
+ {
68
+ name: 'xstyle',
69
+ type: 'StyleXStyles',
70
+ description:
71
+ 'StyleX styles for the Text wrapper. Must be a stylex.create() value.',
72
+ },
73
+ {
74
+ name: 'className',
75
+ type: 'string',
76
+ description:
77
+ 'CSS class name for the Text wrapper. Prefer xstyle for styling.',
78
+ },
79
+ {
80
+ name: 'style',
81
+ type: 'CSSProperties',
82
+ description:
83
+ 'Inline styles for the Text wrapper. Prefer xstyle for styling.',
84
+ },
85
+ ],
86
+ examples: [
87
+ {
88
+ label: 'Elapsed duration',
89
+ code: '<Timer />',
90
+ },
91
+ {
92
+ label: 'Stopwatch clock',
93
+ code: '<Timer format="clock" />',
94
+ },
95
+ {
96
+ label: 'Operation that started before mount',
97
+ code: '<Timer startTime={operationStartedAt} />',
98
+ },
99
+ {
100
+ label: 'Match surrounding text',
101
+ code: `<Text>
102
+ Processing for <Timer type="inherit" color="inherit" />
103
+ </Text>`,
104
+ },
105
+ {
106
+ label: 'Prominent elapsed time',
107
+ code: '<Timer type="body" size="lg" color="primary" weight="semibold" />',
108
+ },
109
+ ],
110
+ theming: {
111
+ targets: [{className: 'astryx-timer'}],
112
+ },
113
+ usage: {
114
+ anatomy,
115
+ description:
116
+ 'Displays a standardized elapsed duration for active work without scheduling a React render on every tick. Elapsed format updates by second below one hour and by minute after one hour; clock format remains second-precise.',
117
+ bestPractices: [
118
+ {
119
+ guidance: true,
120
+ description:
121
+ 'Use elapsed for compact duration text that may span seconds, minutes, or hours.',
122
+ },
123
+ {
124
+ guidance: true,
125
+ description:
126
+ 'Use clock for stopwatch-like surfaces where seconds remain meaningful after an hour.',
127
+ },
128
+ {
129
+ guidance: true,
130
+ description:
131
+ 'Pass startTime when the operation began before Timer mounted so the display reflects the complete wait.',
132
+ },
133
+ {
134
+ guidance: false,
135
+ description:
136
+ 'Do not use Timer for dates, time zones, or relative calendar language; use Timestamp instead.',
137
+ },
138
+ {
139
+ guidance: false,
140
+ description:
141
+ 'Do not add aria-live unless hearing an announcement every tick is appropriate for the specific task.',
142
+ },
143
+ ],
144
+ },
145
+ };
146
+
147
+ /** @type {import('@astryxdesign/cli/authoring').ComponentTranslationDoc} */
148
+ export const docsDense = {
149
+ description:
150
+ 'Standardized elapsed or stopwatch duration with clock-derived, non-rendering DOM updates.',
151
+ propDescriptions: {
152
+ startTime:
153
+ "operation start as Unix milliseconds; omit to count from Timer's mount",
154
+ format: 'elapsed compact units or clock stopwatch notation',
155
+ type: 'semantic text type; defaults to supporting like Timestamp',
156
+ size: 'explicit font size override',
157
+ color: 'text color; defaults to secondary like Timestamp',
158
+ weight: 'font weight override',
159
+ xstyle: 'StyleX styles for the Text wrapper',
160
+ className: 'CSS class for the Text wrapper',
161
+ style: 'inline styles for the Text wrapper',
162
+ },
163
+ usage: {
164
+ anatomy,
165
+ description:
166
+ 'Use for active-operation elapsed time when periodic React renders would add avoidable work.',
167
+ bestPractices: [
168
+ {
169
+ guidance: true,
170
+ description:
171
+ 'Use elapsed for compact durations and clock for stopwatch UI.',
172
+ },
173
+ {
174
+ guidance: true,
175
+ description: 'Pass startTime for work that began before mount.',
176
+ },
177
+ {
178
+ guidance: false,
179
+ description: 'Use Timestamp for dates and relative calendar language.',
180
+ },
181
+ ],
182
+ },
183
+ };