@astryxdesign/core 0.6.2 → 0.6.3-canary.0899f21

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 (549) 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.js +1 -1
  36. package/dist/Chat/index.d.ts +1 -1
  37. package/dist/Chat/index.d.ts.map +1 -1
  38. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  39. package/dist/CheckboxInput/CheckboxInput.js +12 -2
  40. package/dist/Citation/Citation.d.ts +1 -1
  41. package/dist/Citation/Citation.d.ts.map +1 -1
  42. package/dist/Citation/Citation.js +3 -2
  43. package/dist/CodeBlock/highlightRanges.d.ts.map +1 -1
  44. package/dist/CodeBlock/highlightRanges.js +14 -3
  45. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  46. package/dist/Collapsible/Collapsible.js +6 -1
  47. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  48. package/dist/CommandPalette/CommandPaletteInput.js +1 -1
  49. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  50. package/dist/ComplexSelector/ComplexSelector.js +1 -1
  51. package/dist/DateInput/DateInput.d.ts.map +1 -1
  52. package/dist/DateInput/DateInput.js +4 -4
  53. package/dist/DateInput/NativeDateField.d.ts.map +1 -1
  54. package/dist/DateInput/NativeDateField.js +16 -16
  55. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  56. package/dist/DateInput/TouchDateField.js +2 -2
  57. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  58. package/dist/DateRangeInput/DateRangeInput.js +4 -4
  59. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  60. package/dist/DateTimeInput/DateTimeInput.js +8 -8
  61. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  62. package/dist/DateTimeInput/TouchDateTimeField.js +4 -4
  63. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +9 -3
  64. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -1
  65. package/dist/DateTimeInput/nativePickerSegmentStyles.js +3 -3
  66. package/dist/Dialog/DialogHeader.d.ts +8 -1
  67. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  68. package/dist/Dialog/DialogHeader.js +13 -4
  69. package/dist/Field/InputClearButton.d.ts +4 -2
  70. package/dist/Field/InputClearButton.d.ts.map +1 -1
  71. package/dist/Field/InputClearButton.js +4 -2
  72. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  73. package/dist/Field/PanelSearchInput.js +1 -1
  74. package/dist/FileInput/FileInput.d.ts.map +1 -1
  75. package/dist/FileInput/FileInput.js +7 -7
  76. package/dist/Icon/Icon.d.ts +6 -31
  77. package/dist/Icon/Icon.d.ts.map +1 -1
  78. package/dist/Icon/Icon.js +8 -71
  79. package/dist/Icon/IconDefaultSizeContext.d.ts +4 -0
  80. package/dist/Icon/IconDefaultSizeContext.d.ts.map +1 -0
  81. package/dist/Icon/IconDefaultSizeContext.js +18 -0
  82. package/dist/Icon/IconSize.stylex.d.ts +65 -0
  83. package/dist/Icon/IconSize.stylex.d.ts.map +1 -0
  84. package/dist/Icon/IconSize.stylex.js +75 -0
  85. package/dist/Item/Item.d.ts +1 -1
  86. package/dist/Item/Item.d.ts.map +1 -1
  87. package/dist/Item/Item.js +4 -3
  88. package/dist/Kbd/Kbd.d.ts +5 -3
  89. package/dist/Kbd/Kbd.d.ts.map +1 -1
  90. package/dist/Kbd/Kbd.js +36 -42
  91. package/dist/Link/Link.d.ts.map +1 -1
  92. package/dist/Link/Link.js +6 -2
  93. package/dist/Link/useLinkComponent.d.ts +5 -15
  94. package/dist/Link/useLinkComponent.d.ts.map +1 -1
  95. package/dist/Link/useLinkComponent.js +34 -51
  96. package/dist/List/List.d.ts +19 -1
  97. package/dist/List/List.d.ts.map +1 -1
  98. package/dist/List/List.js +9 -2
  99. package/dist/List/ListContext.d.ts +1 -0
  100. package/dist/List/ListContext.d.ts.map +1 -1
  101. package/dist/List/ListContext.js +2 -1
  102. package/dist/List/ListItem.d.ts +1 -1
  103. package/dist/List/ListItem.d.ts.map +1 -1
  104. package/dist/List/ListItem.js +9 -2
  105. package/dist/Markdown/Markdown.d.ts +8 -2
  106. package/dist/Markdown/Markdown.d.ts.map +1 -1
  107. package/dist/Markdown/Markdown.fr23.bench.d.ts +2 -0
  108. package/dist/Markdown/Markdown.fr23.bench.d.ts.map +1 -0
  109. package/dist/Markdown/Markdown.fr23.bench.js +150 -0
  110. package/dist/Markdown/Markdown.fr23.sampling.d.ts +2 -0
  111. package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -0
  112. package/dist/Markdown/Markdown.fr23.sampling.js +43 -0
  113. package/dist/Markdown/Markdown.js +262 -109
  114. package/dist/Markdown/ast.d.ts +162 -0
  115. package/dist/Markdown/ast.d.ts.map +1 -0
  116. package/dist/Markdown/ast.js +74 -0
  117. package/dist/Markdown/index.d.ts +5 -3
  118. package/dist/Markdown/index.d.ts.map +1 -1
  119. package/dist/Markdown/index.js +3 -2
  120. package/dist/Markdown/parser/index.d.ts +10 -0
  121. package/dist/Markdown/parser/index.d.ts.map +1 -0
  122. package/dist/Markdown/parser/index.js +10 -0
  123. package/dist/Markdown/parser.d.ts +126 -58
  124. package/dist/Markdown/parser.d.ts.map +1 -1
  125. package/dist/Markdown/parser.js +716 -167
  126. package/dist/Markdown/plugins/frontmatter.d.ts +32 -0
  127. package/dist/Markdown/plugins/frontmatter.d.ts.map +1 -0
  128. package/dist/Markdown/plugins/frontmatter.js +132 -0
  129. package/dist/Markdown/plugins/index.d.ts +17 -0
  130. package/dist/Markdown/plugins/index.d.ts.map +1 -0
  131. package/dist/Markdown/plugins/index.js +14 -0
  132. package/dist/Markdown/plugins/protocol.d.ts +191 -0
  133. package/dist/Markdown/plugins/protocol.d.ts.map +1 -0
  134. package/dist/Markdown/plugins/protocol.js +957 -0
  135. package/dist/Markdown/plugins/semanticFence.d.ts +36 -0
  136. package/dist/Markdown/plugins/semanticFence.d.ts.map +1 -0
  137. package/dist/Markdown/plugins/semanticFence.js +213 -0
  138. package/dist/Markdown/plugins/softBreaks.d.ts +3 -0
  139. package/dist/Markdown/plugins/softBreaks.d.ts.map +1 -0
  140. package/dist/Markdown/plugins/softBreaks.js +172 -0
  141. package/dist/Markdown/plugins/sourceDecoration.d.ts +76 -0
  142. package/dist/Markdown/plugins/sourceDecoration.d.ts.map +1 -0
  143. package/dist/Markdown/plugins/sourceDecoration.js +393 -0
  144. package/dist/Markdown/plugins/textTransform.d.ts +30 -0
  145. package/dist/Markdown/plugins/textTransform.d.ts.map +1 -0
  146. package/dist/Markdown/plugins/textTransform.js +374 -0
  147. package/dist/Markdown/remark.d.ts +196 -0
  148. package/dist/Markdown/remark.d.ts.map +1 -0
  149. package/dist/Markdown/remark.js +1062 -0
  150. package/dist/Markdown/url.d.ts +6 -0
  151. package/dist/Markdown/url.d.ts.map +1 -0
  152. package/dist/Markdown/url.js +31 -0
  153. package/dist/Markdown/utils.d.ts +4 -2
  154. package/dist/Markdown/utils.d.ts.map +1 -1
  155. package/dist/Markdown/utils.js +2 -1
  156. package/dist/MetadataList/MetadataList.js +3 -3
  157. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  158. package/dist/NumberInput/NumberInput.js +4 -4
  159. package/dist/Outline/index.d.ts +1 -0
  160. package/dist/Outline/index.d.ts.map +1 -1
  161. package/dist/Outline/parseOutlineFromMarkdown.d.ts +7 -1
  162. package/dist/Outline/parseOutlineFromMarkdown.d.ts.map +1 -1
  163. package/dist/Outline/parseOutlineFromMarkdown.js +14 -8
  164. package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -1
  165. package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
  166. package/dist/Outline/useOutlineFromMarkdown.js +8 -3
  167. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  168. package/dist/PowerSearch/PowerSearchEditPopover.js +46 -30
  169. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  170. package/dist/PowerSearch/PowerSearchValueEditor.js +5 -0
  171. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  172. package/dist/ProgressBar/ProgressBar.js +36 -31
  173. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  174. package/dist/RadioList/RadioListItem.js +13 -1
  175. package/dist/ScrollableArea/ScrollableArea.d.ts +1 -0
  176. package/dist/ScrollableArea/ScrollableArea.d.ts.map +1 -1
  177. package/dist/ScrollableArea/ScrollableArea.js +1 -0
  178. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  179. package/dist/SegmentedControl/SegmentedControlItem.js +5 -5
  180. package/dist/Selector/Selector.d.ts +9 -7
  181. package/dist/Selector/Selector.d.ts.map +1 -1
  182. package/dist/Selector/Selector.js +16 -7
  183. package/dist/SideNav/SideNav.d.ts +2 -1
  184. package/dist/SideNav/SideNav.d.ts.map +1 -1
  185. package/dist/SideNav/SideNav.js +9 -3
  186. package/dist/Slider/Slider.d.ts.map +1 -1
  187. package/dist/Slider/Slider.js +28 -12
  188. package/dist/Spinner/Spinner.d.ts.map +1 -1
  189. package/dist/Spinner/Spinner.js +23 -7
  190. package/dist/Switch/Switch.d.ts.map +1 -1
  191. package/dist/Switch/Switch.js +11 -0
  192. package/dist/TabList/Tab.d.ts +1 -1
  193. package/dist/TabList/Tab.d.ts.map +1 -1
  194. package/dist/TabList/Tab.js +20 -7
  195. package/dist/Table/Table.d.ts +1 -0
  196. package/dist/Table/Table.d.ts.map +1 -1
  197. package/dist/Table/Table.js +29 -13
  198. package/dist/TextArea/TextArea.d.ts.map +1 -1
  199. package/dist/TextArea/TextArea.js +1 -1
  200. package/dist/TextInput/TextInput.d.ts.map +1 -1
  201. package/dist/TextInput/TextInput.js +2 -2
  202. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  203. package/dist/TimeInput/TimeInput.js +4 -4
  204. package/dist/Timer/Timer.d.ts +49 -0
  205. package/dist/Timer/Timer.d.ts.map +1 -0
  206. package/dist/Timer/Timer.js +158 -0
  207. package/dist/Timer/index.d.ts +9 -0
  208. package/dist/Timer/index.d.ts.map +1 -0
  209. package/dist/Timer/index.js +10 -0
  210. package/dist/ToggleButton/ToggleButton.d.ts +9 -6
  211. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  212. package/dist/ToggleButton/ToggleButton.js +15 -27
  213. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  214. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  215. package/dist/TopNav/TopNavMenu.js +3 -2
  216. package/dist/TreeList/TreeList.d.ts.map +1 -1
  217. package/dist/TreeList/TreeList.js +3 -0
  218. package/dist/TreeList/TreeListItem.d.ts +6 -1
  219. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  220. package/dist/TreeList/TreeListItem.js +12 -2
  221. package/dist/TreeList/TreeListTypes.d.ts +8 -1
  222. package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
  223. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  224. package/dist/Typeahead/BaseTypeahead.js +16 -7
  225. package/dist/astryx.css +27 -11
  226. package/dist/hooks/scrollKeyboardDelegation.d.ts +3 -0
  227. package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -0
  228. package/dist/hooks/scrollKeyboardDelegation.js +146 -0
  229. package/dist/hooks/useClickableContainer.d.ts +10 -1
  230. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  231. package/dist/hooks/useClickableContainer.js +15 -4
  232. package/dist/hooks/useScrollableArea.d.ts +6 -2
  233. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  234. package/dist/hooks/useScrollableArea.js +17 -5
  235. package/dist/index.d.ts +1 -0
  236. package/dist/index.d.ts.map +1 -1
  237. package/dist/index.js +3 -0
  238. package/dist/theme/declarationBoundary.d.ts +17 -0
  239. package/dist/theme/declarationBoundary.d.ts.map +1 -0
  240. package/dist/theme/declarationBoundary.js +343 -0
  241. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  242. package/dist/theme/derivedVarRegistry.js +4 -0
  243. package/dist/theme/generateThemeRules.d.ts +13 -7
  244. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  245. package/dist/theme/generateThemeRules.js +140 -34
  246. package/dist/utils/interactionOverlay.stylex.d.ts +8 -0
  247. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  248. package/dist/utils/interactionOverlay.stylex.js +9 -0
  249. package/dist/utils/safeUrl.d.ts +11 -0
  250. package/dist/utils/safeUrl.d.ts.map +1 -0
  251. package/dist/utils/safeUrl.js +78 -0
  252. package/locales/af-ZA.json +530 -1
  253. package/locales/ar-SA.json +490 -1
  254. package/locales/ca-ES.json +514 -1
  255. package/locales/cs-CZ.json +498 -1
  256. package/locales/da-DK.json +522 -1
  257. package/locales/de-DE.json +522 -1
  258. package/locales/el-GR.json +498 -1
  259. package/locales/es-ES.json +510 -1
  260. package/locales/fi-FI.json +498 -1
  261. package/locales/fr-FR.json +534 -1
  262. package/locales/he-IL.json +498 -1
  263. package/locales/hu-HU.json +498 -1
  264. package/locales/it-IT.json +510 -1
  265. package/locales/ja-JP.json +490 -1
  266. package/locales/ko-KR.json +498 -1
  267. package/locales/nl-NL.json +534 -1
  268. package/locales/no-NO.json +510 -1
  269. package/locales/pl-PL.json +506 -1
  270. package/locales/pt-BR.json +506 -1
  271. package/locales/pt-PT.json +506 -1
  272. package/locales/ro-RO.json +506 -1
  273. package/locales/ru-RU.json +498 -1
  274. package/locales/sr-SP.json +498 -1
  275. package/locales/sv-SE.json +502 -1
  276. package/locales/tr-TR.json +498 -1
  277. package/locales/uk-UA.json +498 -1
  278. package/locales/vi-VN.json +502 -1
  279. package/locales/zh-CN.json +490 -1
  280. package/locales/zh-TW.json +490 -1
  281. package/package.json +24 -4
  282. package/src/BottomSheet/BottomSheet.doc.mjs +8 -1
  283. package/src/BottomSheet/BottomSheet.spec.md +46 -20
  284. package/src/BottomSheet/BottomSheet.test.tsx +6 -3
  285. package/src/BottomSheet/BottomSheet.tsx +3 -1
  286. package/src/BottomSheet/BottomSheetKeyboard.test.tsx +195 -0
  287. package/src/BottomSheet/BottomSheetPanel.test.tsx +11 -1
  288. package/src/BottomSheet/BottomSheetPanel.tsx +49 -16
  289. package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +344 -0
  290. package/src/Button/Button.doc.mjs +5 -5
  291. package/src/Button/Button.tsx +15 -13
  292. package/src/Button/__tests__/Button.a11y.chromium.spec.ts +17 -1
  293. package/src/Button/__tests__/Button.a11y.known-failures.ts +0 -29
  294. package/src/Button/__tests__/Button.a11y.renders.tsx +9 -2
  295. package/src/Button/__tests__/Button.a11y.states.ts +9 -0
  296. package/src/Chat/ChatComposer.doc.mjs +14 -0
  297. package/src/Chat/ChatComposer.spec.md +230 -0
  298. package/src/Chat/ChatComposer.test.tsx +57 -0
  299. package/src/Chat/ChatComposer.tsx +21 -9
  300. package/src/Chat/ChatComposerDrawer.doc.mjs +63 -5
  301. package/src/Chat/ChatComposerDrawer.spec.md +267 -0
  302. package/src/Chat/ChatComposerDrawer.test.tsx +81 -12
  303. package/src/Chat/ChatComposerDrawer.tsx +38 -9
  304. package/src/Chat/ChatComposerInput.doc.mjs +114 -26
  305. package/src/Chat/ChatComposerInput.spec.md +185 -0
  306. package/src/Chat/ChatComposerInput.test.tsx +113 -3
  307. package/src/Chat/ChatComposerInput.tsx +78 -13
  308. package/src/Chat/ChatComposerTokenElement.spec.md +152 -0
  309. package/src/Chat/ChatComposerTokenElement.test.tsx +85 -0
  310. package/src/Chat/ChatDictationButton.doc.mjs +3 -3
  311. package/src/Chat/ChatDictationButton.spec.md +160 -0
  312. package/src/Chat/ChatDictationButton.test.tsx +92 -27
  313. package/src/Chat/ChatDictationButton.tsx +8 -6
  314. package/src/Chat/ChatLayout.doc.mjs +12 -4
  315. package/src/Chat/ChatLayout.spec.md +271 -0
  316. package/src/Chat/ChatLayout.test.tsx +28 -0
  317. package/src/Chat/ChatLayout.tsx +19 -0
  318. package/src/Chat/ChatLayoutScrollButton.spec.md +338 -0
  319. package/src/Chat/ChatLayoutScrollButton.test.tsx +31 -0
  320. package/src/Chat/ChatLayoutScrollButton.tsx +31 -14
  321. package/src/Chat/ChatMessageBubble.doc.mjs +28 -15
  322. package/src/Chat/ChatMessageBubble.spec.md +263 -0
  323. package/src/Chat/ChatMessageBubble.test.tsx +93 -0
  324. package/src/Chat/ChatMessageBubble.tsx +8 -3
  325. package/src/Chat/ChatMessageList.spec.md +222 -0
  326. package/src/Chat/ChatMessageList.test.tsx +64 -2
  327. package/src/Chat/ChatMessageList.tsx +4 -3
  328. package/src/Chat/ChatMessageMetadata.doc.mjs +57 -3
  329. package/src/Chat/ChatMessageMetadata.spec.md +220 -0
  330. package/src/Chat/ChatMessageMetadata.test.tsx +34 -0
  331. package/src/Chat/ChatMessageMetadata.tsx +13 -13
  332. package/src/Chat/ChatSendButton.test.tsx +1 -4
  333. package/src/Chat/ChatSendButton.tsx +1 -1
  334. package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +514 -0
  335. package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +740 -0
  336. package/src/Chat/__tests__/ChatMessageBubble.a11y.chromium.spec.ts +457 -0
  337. package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.test.ts +91 -0
  338. package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.ts +91 -0
  339. package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +456 -0
  340. package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +413 -0
  341. package/src/Chat/index.ts +1 -0
  342. package/src/CheckboxInput/CheckboxInput.doc.mjs +11 -0
  343. package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
  344. package/src/CheckboxInput/CheckboxInput.tsx +21 -1
  345. package/src/Citation/Citation.doc.mjs +2 -2
  346. package/src/Citation/Citation.test.tsx +17 -0
  347. package/src/Citation/Citation.tsx +4 -2
  348. package/src/ClickableCard/ClickableCard.doc.mjs +2 -2
  349. package/src/ClickableCard/ClickableCard.test.tsx +102 -5
  350. package/src/CodeBlock/highlightRanges.test.ts +143 -1
  351. package/src/CodeBlock/highlightRanges.ts +15 -5
  352. package/src/Collapsible/Collapsible.doc.mjs +11 -0
  353. package/src/Collapsible/Collapsible.test.tsx +21 -0
  354. package/src/Collapsible/Collapsible.tsx +5 -0
  355. package/src/CommandPalette/CommandPaletteInput.tsx +6 -1
  356. package/src/ComplexSelector/ComplexSelector.tsx +6 -1
  357. package/src/DateInput/DateInput.tsx +6 -1
  358. package/src/DateInput/NativeDateField.tsx +24 -8
  359. package/src/DateInput/TouchDateField.tsx +6 -2
  360. package/src/DateRangeInput/DateRangeInput.tsx +6 -1
  361. package/src/DateTimeInput/DateTimeInput.tsx +6 -1
  362. package/src/DateTimeInput/TouchDateTimeField.tsx +6 -1
  363. package/src/DateTimeInput/nativePickerSegmentStyles.ts +24 -8
  364. package/src/Dialog/Dialog.doc.mjs +2 -0
  365. package/src/Dialog/DialogHeader.doc.mjs +22 -0
  366. package/src/Dialog/DialogHeader.test.tsx +167 -3
  367. package/src/Dialog/DialogHeader.tsx +37 -6
  368. package/src/Dialog/modules/DialogHeader.spec.md +101 -42
  369. package/src/DropdownMenu/DropdownMenu.test.tsx +5 -2
  370. package/src/Field/InputClearButton.test.tsx +17 -3
  371. package/src/Field/InputClearButton.tsx +5 -2
  372. package/src/Field/PanelSearchInput.tsx +5 -2
  373. package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +1 -1
  374. package/src/FileInput/FileInput.tsx +11 -2
  375. package/src/Icon/Icon.doc.mjs +7 -5
  376. package/src/Icon/Icon.spec.md +81 -40
  377. package/src/Icon/Icon.test.tsx +6 -3
  378. package/src/Icon/Icon.tsx +20 -68
  379. package/src/Icon/IconDefaultSizeContext.ts +23 -0
  380. package/src/Icon/IconSize.stylex.ts +70 -0
  381. package/src/IconButton/IconButton.doc.mjs +3 -3
  382. package/src/IconButton/IconButton.test.tsx +40 -0
  383. package/src/Item/Item.doc.mjs +6 -2
  384. package/src/Item/Item.tsx +9 -3
  385. package/src/Kbd/Kbd.doc.mjs +3 -3
  386. package/src/Kbd/Kbd.test.tsx +57 -1
  387. package/src/Kbd/Kbd.tsx +57 -37
  388. package/src/Layout/LayoutFooter.doc.mjs +17 -0
  389. package/src/Link/Link.doc.mjs +17 -4
  390. package/src/Link/Link.test.tsx +24 -0
  391. package/src/Link/Link.tsx +5 -0
  392. package/src/Link/LinkProvider.doc.mjs +2 -2
  393. package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +261 -0
  394. package/src/Link/useLinkComponent.test.tsx +333 -0
  395. package/src/Link/useLinkComponent.ts +29 -57
  396. package/src/List/List.doc.mjs +6 -0
  397. package/src/List/List.spec.md +200 -0
  398. package/src/List/List.test.tsx +117 -1
  399. package/src/List/List.tsx +22 -2
  400. package/src/List/ListContext.tsx +3 -1
  401. package/src/List/ListItem.doc.mjs +2 -2
  402. package/src/List/ListItem.source-build.test.mjs +41 -0
  403. package/src/List/ListItem.tsx +26 -2
  404. package/src/Markdown/Markdown.doc.mjs +300 -2
  405. package/src/Markdown/Markdown.fr23.bench.ts +174 -0
  406. package/src/Markdown/Markdown.fr23.perf.test.ts +249 -0
  407. package/src/Markdown/Markdown.fr23.sampling.ts +49 -0
  408. package/src/Markdown/Markdown.helpers.perf.test.ts +489 -0
  409. package/src/Markdown/Markdown.public.test.ts +130 -3
  410. package/src/Markdown/Markdown.renderBoundary.test.tsx +72 -0
  411. package/src/Markdown/Markdown.spec.md +203 -45
  412. package/src/Markdown/Markdown.test.tsx +63 -0
  413. package/src/Markdown/Markdown.tsx +414 -135
  414. package/src/Markdown/ast.test.ts +307 -0
  415. package/src/Markdown/ast.ts +337 -0
  416. package/src/Markdown/incremental.test.ts +12 -0
  417. package/src/Markdown/index.ts +37 -1
  418. package/src/Markdown/modules/remark.spec.md +269 -0
  419. package/src/Markdown/modules/softBreaks.spec.md +137 -0
  420. package/src/Markdown/parser/index.ts +64 -0
  421. package/src/Markdown/parser.public.test.ts +103 -0
  422. package/src/Markdown/parser.test.ts +20 -0
  423. package/src/Markdown/parser.ts +1180 -235
  424. package/src/Markdown/plugins/frontmatter.test.tsx +125 -0
  425. package/src/Markdown/plugins/frontmatter.ts +198 -0
  426. package/src/Markdown/plugins/index.ts +54 -0
  427. package/src/Markdown/plugins/protocol.test.tsx +1022 -0
  428. package/src/Markdown/plugins/protocol.ts +1618 -0
  429. package/src/Markdown/plugins/semanticFence.test.tsx +546 -0
  430. package/src/Markdown/plugins/semanticFence.ts +424 -0
  431. package/src/Markdown/plugins/softBreaks.test.tsx +172 -0
  432. package/src/Markdown/plugins/softBreaks.ts +169 -0
  433. package/src/Markdown/plugins/sourceDecoration.test.tsx +799 -0
  434. package/src/Markdown/plugins/sourceDecoration.ts +539 -0
  435. package/src/Markdown/plugins/textTransform.test.ts +467 -0
  436. package/src/Markdown/plugins/textTransform.ts +554 -0
  437. package/src/Markdown/remark.test.tsx +1877 -0
  438. package/src/Markdown/remark.ts +1574 -0
  439. package/src/Markdown/url.ts +36 -0
  440. package/src/Markdown/utils.ts +13 -1
  441. package/src/MetadataList/MetadataList.test.tsx +4 -2
  442. package/src/MetadataList/MetadataList.tsx +3 -3
  443. package/src/MultiSelector/MultiSelector.test.tsx +1 -35
  444. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +128 -0
  445. package/src/NumberInput/NumberInput.tsx +6 -1
  446. package/src/Outline/Outline.doc.mjs +7 -5
  447. package/src/Outline/Outline.spec.md +1 -1
  448. package/src/Outline/index.ts +1 -0
  449. package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +142 -0
  450. package/src/Outline/parseOutlineFromMarkdown.ts +40 -10
  451. package/src/Outline/useOutlineFromMarkdown.ts +15 -3
  452. package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
  453. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +150 -1
  454. package/src/PowerSearch/PowerSearchEditPopover.tsx +51 -28
  455. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +51 -0
  456. package/src/PowerSearch/PowerSearchValueEditor.tsx +4 -0
  457. package/src/ProgressBar/ProgressBar.test.tsx +29 -11
  458. package/src/ProgressBar/ProgressBar.tsx +59 -72
  459. package/src/RadioList/RadioList.doc.mjs +11 -0
  460. package/src/RadioList/RadioList.test.tsx +32 -0
  461. package/src/RadioList/RadioListItem.tsx +25 -1
  462. package/src/ScrollableArea/ScrollableArea.tsx +1 -0
  463. package/src/ScrollableArea/modules/useScrollableArea.spec.md +50 -22
  464. package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
  465. package/src/SegmentedControl/SegmentedControl.test.tsx +31 -0
  466. package/src/SegmentedControl/SegmentedControlItem.tsx +6 -9
  467. package/src/Selector/Selector.doc.mjs +2 -2
  468. package/src/Selector/Selector.spec.md +51 -49
  469. package/src/Selector/Selector.test.tsx +61 -55
  470. package/src/Selector/Selector.tsx +34 -15
  471. package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +130 -0
  472. package/src/Selector/__tests__/Listbox.a11y.dom.ts +38 -0
  473. package/src/Selector/__tests__/Listbox.a11y.inventory.test.ts +63 -0
  474. package/src/Selector/__tests__/Listbox.a11y.known-failures.ts +37 -0
  475. package/src/Selector/__tests__/Listbox.a11y.states.ts +232 -0
  476. package/src/Selector/__tests__/Selector.a11y.chromium.spec.ts +45 -0
  477. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +121 -0
  478. package/src/SideNav/SideNav.doc.mjs +1 -1
  479. package/src/SideNav/SideNav.test.tsx +10 -0
  480. package/src/SideNav/SideNav.tsx +14 -2
  481. package/src/Slider/Slider.doc.mjs +17 -3
  482. package/src/Slider/Slider.test.tsx +221 -0
  483. package/src/Slider/Slider.tsx +40 -9
  484. package/src/Spinner/Spinner.test.tsx +4 -0
  485. package/src/Spinner/Spinner.tsx +31 -18
  486. package/src/Switch/Switch.doc.mjs +11 -0
  487. package/src/Switch/Switch.test.tsx +16 -0
  488. package/src/Switch/Switch.tsx +28 -0
  489. package/src/TabList/Tab.tsx +35 -7
  490. package/src/TabList/TabList.doc.mjs +11 -0
  491. package/src/TabList/TabList.spec.md +204 -0
  492. package/src/TabList/TabList.test.tsx +66 -0
  493. package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +1 -34
  494. package/src/Table/Table.doc.mjs +1 -1
  495. package/src/Table/Table.spec.md +54 -40
  496. package/src/Table/Table.test.tsx +83 -10
  497. package/src/Table/Table.tsx +30 -22
  498. package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +137 -0
  499. package/src/TextArea/TextArea.tsx +6 -1
  500. package/src/TextInput/TextInput.test.tsx +20 -1
  501. package/src/TextInput/TextInput.tsx +6 -1
  502. package/src/TimeInput/TimeInput.tsx +6 -1
  503. package/src/Timer/Timer.doc.mjs +183 -0
  504. package/src/Timer/Timer.spec.md +215 -0
  505. package/src/Timer/Timer.test.tsx +302 -0
  506. package/src/Timer/Timer.tsx +258 -0
  507. package/src/Timer/index.ts +11 -0
  508. package/src/ToggleButton/ToggleButton.doc.mjs +3 -3
  509. package/src/ToggleButton/ToggleButton.test.tsx +299 -4
  510. package/src/ToggleButton/ToggleButton.tsx +26 -33
  511. package/src/ToggleButton/ToggleButtonGroup.doc.mjs +3 -3
  512. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +209 -0
  513. package/src/Token/Token.doc.mjs +2 -2
  514. package/src/Tokenizer/Tokenizer.spec.md +142 -75
  515. package/src/TopNav/TopNavMenu.doc.mjs +2 -2
  516. package/src/TopNav/TopNavMenu.test.tsx +30 -0
  517. package/src/TopNav/TopNavMenu.tsx +7 -2
  518. package/src/TreeList/TreeList.doc.mjs +3 -3
  519. package/src/TreeList/TreeList.spec.md +123 -75
  520. package/src/TreeList/TreeList.test.tsx +29 -0
  521. package/src/TreeList/TreeList.tsx +3 -0
  522. package/src/TreeList/TreeListItem.tsx +15 -1
  523. package/src/TreeList/TreeListTypes.ts +11 -1
  524. package/src/Typeahead/BaseTypeahead.spec.md +4 -3
  525. package/src/Typeahead/BaseTypeahead.tsx +21 -7
  526. package/src/Typeahead/Typeahead.test.tsx +53 -0
  527. package/src/__tests__/PressedState.a11y.chromium.spec.ts +813 -0
  528. package/src/__tests__/pressState.ts +93 -0
  529. package/src/hooks/scrollKeyboardDelegation.test.ts +155 -0
  530. package/src/hooks/scrollKeyboardDelegation.ts +233 -0
  531. package/src/hooks/useClickableContainer.test.tsx +236 -0
  532. package/src/hooks/useClickableContainer.ts +20 -4
  533. package/src/hooks/useScrollableArea.doc.mjs +15 -3
  534. package/src/hooks/useScrollableArea.test.tsx +59 -1
  535. package/src/hooks/useScrollableArea.ts +34 -10
  536. package/src/index.ts +3 -0
  537. package/src/inputFontFloor.test.ts +106 -0
  538. package/src/tailwind-theme.css +0 -6
  539. package/src/theme/Theme.test.tsx +32 -0
  540. package/src/theme/declarationBoundary.test.ts +126 -0
  541. package/src/theme/declarationBoundary.ts +347 -0
  542. package/src/theme/derivedVarRegistry.test.ts +7 -0
  543. package/src/theme/derivedVarRegistry.ts +1 -0
  544. package/src/theme/generateThemeRules.test.ts +526 -1
  545. package/src/theme/generateThemeRules.ts +228 -50
  546. package/src/theme/tokenValueCompat.test.ts +4 -1
  547. package/src/utils/interactionOverlay.stylex.ts +20 -0
  548. package/src/utils/safeUrl.test.ts +88 -0
  549. package/src/utils/safeUrl.ts +85 -0
@@ -0,0 +1,267 @@
1
+ ---
2
+ schema_version: 3
3
+ template_version: 5
4
+ kind: component
5
+ id: component:ChatComposerDrawer
6
+ authority: current
7
+ archive_reason: null
8
+ superseded_by: null
9
+ approved_by: cixzhang
10
+ approved_at: 2026-09-21
11
+ owners: [cixzhang]
12
+ review_triggers: [public-api, behavior, layout, theming, accessibility]
13
+ verified_by:
14
+ [
15
+ packages/core/src/Chat/ChatComposerDrawer.test.tsx,
16
+ apps/storybook/stories/ChatComposerDrawer.stories.tsx,
17
+ apps/storybook/rtl-audit/verified-not-applicable.json,
18
+ ]
19
+ modules: []
20
+ families: []
21
+ design_specs: []
22
+ architecture:
23
+ [
24
+ architecture:component-theming-surface,
25
+ architecture:interaction-modality,
26
+ architecture:knowledge-contracts,
27
+ architecture:public-component-api,
28
+ ]
29
+ contributing: [contributing:api-conventions]
30
+ system_specs: [spec:AST-002/DEC-1, spec:AST-002/DEC-2]
31
+ ---
32
+
33
+ # ChatComposerDrawer component contract
34
+
35
+ ## Contract at a glance
36
+
37
+ | Area | Contract |
38
+ | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
39
+ | Public contract | Add one optional `collapsedSummary?: ReactNode` slot, named from the canonical **Collapsed summary** anatomy part, for caller-composed visual content. |
40
+ | Behavior | `count` continues to enable the disclosure. Omitting `collapsedSummary` keeps the neutral Badge count plus resolved label; providing it replaces that complete visual summary without changing collapse behavior or naming. |
41
+ | End-user impact | People retain the established Badge hierarchy by default. Products that need a quieter or differently composed collapsed row may provide one localized visual summary without weakening disclosure semantics. |
42
+ | Builder impact | Existing callsites do not change. A builder choosing the slot owns its visual content and localization, while `label` continues to identify the controlled content for the component-owned accessible name. |
43
+ | Compatibility/readiness | Additive and default-preserving. This record is current authority; the slot and its mapped implementation, consumer docs, tests, and rendered evidence have not shipped yet. |
44
+ | Review checks | Reject a plain-text default, a second summary API, custom content that changes naming or collapse state, reachable interactive descendants inside the visual summary, or any regression to the no-slot and no-count paths. |
45
+ | Governing rules | `component:ChatComposerDrawer/FR1–FR10, AR1–AR4, DEC-1–DEC-2`; `architecture:public-component-api/INV3–INV4, INV9, INV13`; `spec:AST-002/DEC-1, DEC-2`. |
46
+
47
+ This table is a review projection; the body below is authoritative.
48
+
49
+ ## Intent
50
+
51
+ ChatComposerDrawer composes supplementary content above ChatComposer input. When
52
+ `count` is present, builders may let people collapse that content while keeping a
53
+ compact summary available.
54
+
55
+ Two otherwise identical drawers may need different visual hierarchy in the
56
+ collapsed state. The product builder knows whether the established count Badge or
57
+ a quieter, product-specific summary fits that context, and ChatComposerDrawer
58
+ cannot derive that distinction from count, content, layout, locale, or collapse
59
+ state. The component therefore exposes one visual composition seam while retaining
60
+ its existing default and owning all disclosure behavior.
61
+
62
+ ## Compatibility and migration
63
+
64
+ - Released default preserved: yes. Omitting `collapsedSummary` keeps the neutral
65
+ count Badge followed by the resolved label.
66
+ - Compatibility class: additive optional composition slot with no default change.
67
+ - Controlled/uncontrolled behavior: unchanged.
68
+ - Migration decision: none. Existing callsites require no edits.
69
+
70
+ Consumer migration instructions belong in consumer docs and release notes.
71
+
72
+ ## Ownership boundary
73
+
74
+ **Owns**
75
+
76
+ - The drawer surface, optional disclosure state, disclosure association, and
77
+ availability of collapsed descendants.
78
+ - Controlled and uncontrolled collapse requests.
79
+ - The Badge-preserving default summary and the presentation-only boundary for one
80
+ caller-composed collapsed summary.
81
+ - The disclosure's localized accessible name, independently of visual summary
82
+ content.
83
+
84
+ **Does not own / non-goals**
85
+
86
+ - The meaning, styling, or localization of caller-provided drawer children or custom
87
+ summary content.
88
+ - Interactive behavior inside the custom summary; the summary is visual-only and
89
+ never creates another focus or activation target.
90
+ - ChatComposer input, submission, status, and action behavior.
91
+ - A presentation enum, Badge toggle, render callback, summary-specific theme target,
92
+ or a second accessible-name prop.
93
+
94
+ ## Public concepts
95
+
96
+ | Concept | Closed values or states | Meaning | Availability by state | Default | Owner | Stability | Invalid-value behavior |
97
+ | ----------------- | -------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------- | ------------------------ | ------------------------------ | ------------------- | ------------------------------------------------------------------ |
98
+ | drawer content | any React node | Supplementary content composed above the chat input. | always | none | `component:ChatComposerDrawer` | stable | Missing content is rejected by the required type. |
99
+ | collapse support | unavailable, expanded, collapsed | Presence of `count`, including zero, enables one disclosure and supplies its summary count. | unavailable when `count` is omitted | unavailable | `component:ChatComposerDrawer` | stable | Collapse inputs have no visible effect without `count`. |
100
+ | collapse control | uncontrolled, controlled | Internal state or `isCollapsed` determines the current disclosure state. | when collapse support is available | uncontrolled | `component:ChatComposerDrawer` | stable | Controlled state wins over the initial default. |
101
+ | collapsed summary | default, caller-composed | Visual content shown for the collapsed disclosure. | when collapse support is available | neutral Badge plus label | caller choice; component seam | accepted, unshipped | Omission uses the default; without `count`, no summary is exposed. |
102
+ | collapse request | next state | Activation asks for the opposite effective collapsed state. | when collapse support is available | none | `component:ChatComposerDrawer` | stable | No request is emitted without a disclosure. |
103
+
104
+ `collapsedSummary` is the camelCase public API projection of the canonical
105
+ **Collapsed summary** anatomy part. It is the complete custom visual summary, not
106
+ an addition before or after the default. The component does not parse, clone,
107
+ decorate, or supply data to the node. Builders already own the values they pass as
108
+ `count` and `label`; when a custom summary forms a sentence or formats a number,
109
+ its callsite owns the complete localized message.
110
+
111
+ ## Behavioral and layout contract
112
+
113
+ | ID | Invariant | Basis |
114
+ | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
115
+ | FR1 | When `count` is present, including when it is `0`, the component MUST expose one named disclosure control with `aria-expanded` and a resolvable `aria-controls` relationship. | released API and implementation; WAI-ARIA disclosure semantics |
116
+ | FR2 | Pointer activation, Enter, and Space MUST request the opposite effective collapsed state exactly once. | released implementation and public callback contract |
117
+ | FR3 | In controlled mode, `isCollapsed` MUST remain authoritative; in uncontrolled mode, activation MUST update internal state before the next render. | released implementation and consumer docs |
118
+ | FR4 | Collapsed drawer content MAY remain mounted for the grid transition, but its descendants MUST be absent from keyboard and assistive-technology navigation. | WAI-ARIA disclosure semantics; WCAG 2.4.3 and 2.4.7 |
119
+ | FR5 | Keyboard focus on the disclosure MUST remain visibly perceivable through the shared focus-indicator mechanism. | `architecture:interaction-modality/INV1–INV4` |
120
+ | FR6 | Omitting `count` MUST render drawer content directly, MUST NOT create a disclosure control, and MUST NOT expose `collapsedSummary`. Existing collapse inputs continue to have no visible effect in this state. | released no-count behavior and compatibility |
121
+ | FR7 | The root MUST continue forwarding its ref, BaseProps attributes, and styling seams without moving them to an internal child. | released public surface and `architecture:public-component-api/INV5–INV6, INV8–INV9` |
122
+ | FR8 | `collapsedSummary` MUST remain the camelCase public name of the canonical **Collapsed summary** anatomy part. When omitted, the collapsed disclosure MUST preserve the existing neutral Badge containing `count`, followed by the resolved `label`; when provided, the node MUST replace that complete anatomy part exactly once. | approved anatomy-aligned caller-composition boundary and released default |
123
+ | FR9 | The custom summary MUST affect visual content only. It MUST NOT change whether collapse is available, effective collapse state, toggle activation, callback values, the controlled region, or the component-owned accessible name. | constrained slot contract and `spec:AST-002/DEC-2` |
124
+ | FR10 | The summary subtree MUST remain presentation-only: the disclosure is the sole focus and activation target, summary descendants MUST be absent from the tab order and accessibility tree, and custom content MUST NOT add another action. | WAI-ARIA disclosure semantics and component-owned accessibility boundary |
125
+
126
+ ### Allowed variation
127
+
128
+ - **AV1 — Drawer child composition.** Builders choose the drawer content and its own
129
+ semantics.
130
+ - **AV2 — Custom summary composition.** Builders may compose any visual content that
131
+ fits the presentation-only boundary, including localized text or existing Astryx
132
+ display components.
133
+ - **AV3 — Summary lifecycle.** The component may keep the default or custom summary
134
+ mounted while visually expanded to preserve animation. Callers MUST NOT depend on
135
+ mount or unmount timing.
136
+ - **AV4 — Custom summary styling.** Caller-composed content retains the styling and
137
+ theme seams of the components it uses. ChatComposerDrawer adds no summary-specific
138
+ target.
139
+
140
+ ### Representative states
141
+
142
+ | State | Required invariant | Allowed variation |
143
+ | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
144
+ | `count` omitted | Content is visible; no disclosure or summary is exposed. | Child content and root styling. |
145
+ | default summary, collapsed | One disclosure shows the neutral count Badge plus resolved label. | Count value and localized label. |
146
+ | custom summary, collapsed | One disclosure shows the caller node instead of both default summary parts. | Presentation-only custom content and styling. |
147
+ | custom summary, expanded | The disclosure retains its state and name; the custom summary may stay mounted but is visually and semantically hidden. | Internal crossfade and mount timing. |
148
+ | controlled expanded or collapsed | Rendered state follows `isCollapsed`; activation reports the requested next state. | Parent timing and whether it accepts the request. |
149
+
150
+ ### Transformation and precedence order
151
+
152
+ - **ORD1 — Collapse availability.** `count` present → disclosure enabled; `count`
153
+ omitted → no disclosure or collapsed summary.
154
+ - **ORD2 — Effective state.** `isCollapsed` when defined → otherwise internal state
155
+ initialized from `defaultIsCollapsed`.
156
+ - **ORD3 — Visual summary.** Caller-provided `collapsedSummary` → otherwise the
157
+ neutral Badge for `count` followed by the resolved `label`.
158
+ - **ORD4 — Accessible name.** Resolve `label` from the prop or locale catalog → use
159
+ the catalog's expand or collapse action message for the effective state. Visual
160
+ summary content never enters or overrides this pipeline.
161
+
162
+ ### Performance and resources
163
+
164
+ - **PR1 — Local state only.** The summary seam MUST NOT require an Effect, observer,
165
+ listener, timer, or external resource.
166
+
167
+ ## Accessibility contract
168
+
169
+ - **AR1 — Disclosure relationship.** The toggle exposes one localized name, expanded
170
+ state, and a resolvable controlled-content ID.
171
+ - **AR2 — Naming stays component-owned.** `label` identifies the controlled drawer
172
+ content in the expand/collapse catalog message. Default or custom visual summary
173
+ text MUST NOT replace, duplicate, or concatenate into that accessible name.
174
+ - **AR3 — Hidden content is unavailable.** Visually collapsed drawer descendants are
175
+ unavailable until expansion.
176
+ - **AR4 — Custom summary remains presentation-only.** Custom content cannot add a
177
+ second focus stop, activation target, role, or announcement inside the disclosure.
178
+
179
+ ## Design relationships
180
+
181
+ No current design specification governs this component-local representation.
182
+
183
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
184
+ | ----------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------ | -------------- | ------------------ |
185
+ | root surface | Existing released surface remains unchanged by this decision. | released behavior | supporting | FR7 |
186
+ | disclosure toggle | One operable, named control owns collapse interaction. | component-owned | supporting | FR1–FR5, AR1 |
187
+ | collapsed summary | Badge hierarchy remains the default; callers may choose one visual composition slot. | component default or caller-selected composition | supporting | FR8–FR10, AR2–AR4 |
188
+ | content area | Collapsed descendants remain unavailable to keyboard and assistive technology. | component-owned | supporting | FR4, FR6, AR3 |
189
+
190
+ The existing `chat-composer-drawer` target remains on the painted root. The
191
+ Badge-preserving default delegates count paint to Badge. Caller-composed summary
192
+ content retains the theme ownership of the components it supplies. This decision
193
+ adds no ChatComposerDrawer summary target and does not make arbitrary slot internals
194
+ part of ChatComposerDrawer's theming API.
195
+
196
+ ## Family and system relationships
197
+
198
+ - `architecture:public-component-api` owns reachability, naming grammar, and
199
+ compatibility of the additive slot; this component owns its local meaning and
200
+ default.
201
+ - `architecture:interaction-modality` owns shared focus-visibility mechanics; this
202
+ component owns the disclosure as its semantic focus owner.
203
+ - `architecture:component-theming-surface` owns target and anatomy mapping rules; the
204
+ custom summary does not create a new target or transfer ownership of caller
205
+ content.
206
+ - `architecture:knowledge-contracts` limits this current authority to the explicit
207
+ claims in this record.
208
+ - `spec:AST-002/DEC-1` admits the slot because otherwise-identical drawers may need
209
+ a caller-owned visual hierarchy the component cannot derive. `DEC-2` requires the
210
+ seam to preserve a dependable, accessibility-safe outcome.
211
+
212
+ ## Verification map
213
+
214
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
215
+ | ------------------------ | ----------------------------------------------------------------------- | -------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
216
+ | FR1–FR3, FR6, ORD1–2 | focused ChatComposerDrawer state and keyboard tests | no count; zero count; controlled; uncontrolled; pointer; Enter; Space | Presence/truthiness changes collapse availability, state authority changes, or callback reports the wrong next state. | `audit:ChatComposerDrawer/behavior` |
217
+ | FR8–FR9, ORD3 | focused default/custom summary tests and consumer-doc projection checks | default; custom node; expanded; collapsed; no count | The default Badge disappears, default and custom content render together, custom content changes behavior, or no-count exposes it. | `audit:ChatComposerDrawer/api` |
218
+ | FR4, FR10, AR2–AR4 | focused inert-state and custom-descendant tests plus exact-head a11y CI | default text; custom text; custom focusable descendant; collapsed/expanded | Hidden drawer content or custom summary becomes focusable, announced, or a second action; visual text replaces the catalog name. | `audit:ChatComposerDrawer/accessibility` |
219
+ | FR5, AR1 | `KeyboardFocus` Storybook play and exact-head visual/a11y gates | keyboard focus in representative light and dark themes | Focus has no shared visible indicator or the disclosure relationship/name breaks. | `audit:ChatComposerDrawer/accessibility` |
220
+ | FR7 | focused DOM/type tests and package checks | ref, BaseProps, xstyle, className, style | Root ownership or a styling seam moves or disappears. | `audit:ChatComposerDrawer/api` |
221
+ | AV4 and theming boundary | source/runtime theme inspection of default and custom summaries | default Badge; caller-composed Astryx content | A new summary target appears, Badge loses its target, or caller-owned content is retargeted as ChatComposerDrawer anatomy. | `audit:ChatComposerDrawer/theming` |
222
+
223
+ ## Decision log
224
+
225
+ ### DEC-1 — One visual slot preserves the Badge default
226
+
227
+ **Reference:** `component:ChatComposerDrawer/DEC-1`
228
+ **Decider:** `cixzhang`, `2026-09-21`
229
+
230
+ ChatComposerDrawer admits one optional `collapsedSummary` node for the complete
231
+ visual summary. Product builders own whether a particular collapsed row needs the
232
+ established Badge hierarchy or a quieter localized composition, and the component
233
+ cannot derive that visual hierarchy. Omitting the slot preserves the existing
234
+ neutral Badge plus label, so no current builder receives a new choice or migration.
235
+
236
+ Rejected: replacing the default with a `{count} {label}` sentence, adding a Badge
237
+ boolean or finite presentation enum, adding a render callback for values already
238
+ owned by the caller, or exposing parallel summary seams. Those shapes either break
239
+ the released default, encode presentation machinery, invite locale-unsafe string
240
+ concatenation, or add more API than the caller-owned distinction requires.
241
+
242
+ ### DEC-2 — Visual composition does not own disclosure semantics
243
+
244
+ **Reference:** `component:ChatComposerDrawer/DEC-2`
245
+ **Decider:** `cixzhang`, `2026-09-21`
246
+
247
+ The custom summary is presentation-only. The existing `label` and locale catalog
248
+ continue to name the expand/collapse action; `count` continues to enable the
249
+ disclosure; and the component keeps summary descendants out of focus, activation,
250
+ and assistive-technology navigation. The seam cannot replace these obligations.
251
+
252
+ Rejected: deriving the accessible name from arbitrary summary content or letting a
253
+ custom summary introduce another action inside the disclosure. Both make correct
254
+ semantics depend on caller markup the component cannot verify.
255
+
256
+ ## Open questions
257
+
258
+ None for this contract slice.
259
+
260
+ ## Content boundary
261
+
262
+ This file owns ChatComposerDrawer's collapsed-summary composition boundary,
263
+ Badge-preserving default, collapse gating and state behavior, accessible naming,
264
+ compatibility, and required evidence. It does not duplicate the complete consumer
265
+ prop reference, implementation steps, current audit score, or unrelated component
266
+ gaps. Current authority is claim-scoped to the explicit requirements above and does
267
+ not certify every ChatComposerDrawer behavior.
@@ -1,6 +1,6 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
- import {describe, it, expect} from 'vitest';
3
+ import {describe, it, expect, vi} from 'vitest';
4
4
  import {render, screen, fireEvent} from '@testing-library/react';
5
5
  import {ChatComposerDrawer} from './ChatComposerDrawer';
6
6
 
@@ -36,26 +36,95 @@ describe('ChatComposerDrawer', () => {
36
36
  expect(region).toContainElement(screen.getByText('Drawer content'));
37
37
  });
38
38
 
39
- it('toggles aria-expanded when the toggle is activated', () => {
39
+ it('removes collapsed children from the focus order and restores them on expand', () => {
40
40
  render(
41
- <ChatComposerDrawer count={2} label="Attachments">
41
+ <ChatComposerDrawer count={1} label="Attachment">
42
+ <button type="button">Remove attachment</button>
43
+ </ChatComposerDrawer>,
44
+ );
45
+
46
+ const toggle = screen.getByRole('button', {name: /Attachment/});
47
+ const region = document.getElementById(
48
+ toggle.getAttribute('aria-controls') as string,
49
+ )!;
50
+ expect(region).not.toHaveAttribute('inert');
51
+
52
+ fireEvent.click(toggle);
53
+ expect(toggle).toHaveAttribute('aria-expanded', 'false');
54
+ expect(region).toHaveAttribute('inert');
55
+ expect(
56
+ screen
57
+ .getByRole('button', {name: 'Remove attachment'})
58
+ .closest('[inert]'),
59
+ ).toBe(region);
60
+
61
+ fireEvent.click(toggle);
62
+ expect(toggle).toHaveAttribute('aria-expanded', 'true');
63
+ expect(region).not.toHaveAttribute('inert');
64
+ });
65
+
66
+ it('supports both disclosure keys and reports the requested state', () => {
67
+ const onCollapsedChange = vi.fn();
68
+ render(
69
+ <ChatComposerDrawer
70
+ count={2}
71
+ label="Attachments"
72
+ onCollapsedChange={onCollapsedChange}>
42
73
  <span>Drawer content</span>
43
74
  </ChatComposerDrawer>,
44
75
  );
45
76
 
46
77
  const toggle = screen.getByRole('button', {name: /Attachments/});
47
- expect(toggle).toHaveAttribute('aria-expanded', 'true');
78
+ fireEvent.keyDown(toggle, {key: 'Enter'});
79
+ expect(onCollapsedChange).toHaveBeenLastCalledWith(true);
48
80
 
49
- fireEvent.click(toggle);
50
- expect(screen.getByRole('button', {name: /Attachments/})).toHaveAttribute(
51
- 'aria-expanded',
52
- 'false',
81
+ fireEvent.keyDown(toggle, {key: ' '});
82
+ expect(onCollapsedChange).toHaveBeenLastCalledWith(false);
83
+ });
84
+
85
+ it('preserves the Badge and label as the default collapsed summary', () => {
86
+ const {container} = render(
87
+ <ChatComposerDrawer count={3} label="Attachments" defaultIsCollapsed>
88
+ <span>Drawer content</span>
89
+ </ChatComposerDrawer>,
53
90
  );
54
91
 
55
- fireEvent.click(screen.getByRole('button', {name: /Attachments/}));
56
- expect(screen.getByRole('button', {name: /Attachments/})).toHaveAttribute(
57
- 'aria-expanded',
58
- 'true',
92
+ expect(container.querySelector('.astryx-badge')).toHaveTextContent('3');
93
+ expect(screen.getByText('Attachments')).toBeInTheDocument();
94
+ });
95
+
96
+ it('replaces the complete collapsed summary with caller content', () => {
97
+ const {container} = render(
98
+ <ChatComposerDrawer
99
+ count={3}
100
+ label="Attachments"
101
+ collapsedSummary={<button type="button">Files ready</button>}
102
+ defaultIsCollapsed>
103
+ <span>Drawer content</span>
104
+ </ChatComposerDrawer>,
59
105
  );
106
+
107
+ const toggle = screen.getByRole('button', {name: /Attachments/});
108
+ const customSummary = screen.getByText('Files ready');
109
+ const summaryBoundary = customSummary.closest('[inert]');
110
+ expect(toggle).not.toHaveAccessibleName(/Files ready/);
111
+ expect(summaryBoundary).toHaveAttribute('aria-hidden', 'true');
112
+ expect(container.querySelector('.astryx-badge')).toBeNull();
113
+ expect(screen.queryByText('Attachments')).toBeNull();
114
+ expect(
115
+ screen.queryByRole('button', {name: 'Files ready'}),
116
+ ).not.toBeInTheDocument();
117
+ });
118
+
119
+ it('does not expose collapsedSummary when count is omitted', () => {
120
+ render(
121
+ <ChatComposerDrawer collapsedSummary={<span>Files ready</span>}>
122
+ <span>Drawer content</span>
123
+ </ChatComposerDrawer>,
124
+ );
125
+
126
+ expect(screen.queryByText('Files ready')).not.toBeInTheDocument();
127
+ expect(screen.queryByRole('button')).not.toBeInTheDocument();
128
+ expect(screen.getByText('Drawer content')).toBeInTheDocument();
60
129
  });
61
130
  });
@@ -7,12 +7,16 @@
7
7
  * @input Uses React, StyleX, theme tokens
8
8
  * @output Exports ChatComposerDrawer component
9
9
  * @position Collapsible drawer panel for ChatComposer.
10
- * Supports expanded (full content) and collapsed (count + label) states
11
- * with fade animation and grid-template-rows height transition.
10
+ * Supports expanded (full content) and collapsed (default or caller-composed
11
+ * summary) states with fade animation and grid-template-rows height transition.
12
12
  * The collapse toggle exposes aria-expanded + aria-controls linking it to
13
13
  * the content region (disclosure pattern).
14
14
  *
15
15
  * SYNC: When modified, update:
16
+ * - /packages/core/src/Chat/ChatComposerDrawer.test.tsx
17
+ * - /packages/core/src/Chat/ChatComposerDrawer.doc.mjs
18
+ * - /packages/core/src/Chat/ChatComposerDrawer.spec.md
19
+ * - /apps/storybook/stories/ChatComposerDrawer.stories.tsx
16
20
  * - /packages/core/src/Chat/index.ts (exports)
17
21
  * - /packages/cli/assets/templates/blocks/components/ChatComposerDrawer/ (block examples)
18
22
  */
@@ -32,6 +36,7 @@ import {Badge} from '../Badge';
32
36
  import {mergeProps} from '../utils';
33
37
  import type {BaseProps} from '../BaseProps';
34
38
  import {themeProps} from '../utils/themeProps';
39
+ import {focusOutlineProps} from '../utils/focusOutline.stylex';
35
40
  import {useTranslator} from '../i18n';
36
41
 
37
42
  export interface ChatComposerDrawerProps extends BaseProps<HTMLDivElement> {
@@ -46,10 +51,18 @@ export interface ChatComposerDrawerProps extends BaseProps<HTMLDivElement> {
46
51
  */
47
52
  count?: number;
48
53
  /**
49
- * Label shown next to the count in collapsed state.
54
+ * Label shown next to the count in the default collapsed summary and used to
55
+ * name the expand/collapse action.
50
56
  * @default 'Items'
51
57
  */
52
58
  label?: string;
59
+ /**
60
+ * Visual content for the canonical Collapsed summary anatomy part. Replaces
61
+ * the complete default Badge and label when count enables collapse. The
62
+ * component keeps this content presentation-only and owns disclosure
63
+ * semantics and accessible naming.
64
+ */
65
+ collapsedSummary?: ReactNode;
53
66
  /**
54
67
  * Whether the drawer is collapsed.
55
68
  * Uncontrolled by default (internal toggle).
@@ -72,7 +85,9 @@ export interface ChatComposerDrawerProps extends BaseProps<HTMLDivElement> {
72
85
  * @example
73
86
  * ```
74
87
  * const styles = stylex.create({ wrapper: { marginTop: 8 } });
75
- * <ChatComposerDrawer xstyle={styles.wrapper} />
88
+ * <ChatComposerDrawer xstyle={styles.wrapper}>
89
+ * <AttachmentThumbnail />
90
+ * </ChatComposerDrawer>
76
91
  * ```
77
92
  */
78
93
  xstyle?: StyleXStyles;
@@ -108,8 +123,8 @@ const styles = stylex.create({
108
123
  borderStartEndRadius: radiusVars['--radius-chat'],
109
124
  },
110
125
 
111
- // Toggle row — both the bar handle and badge+label live in the
112
- // same grid cell so they crossfade without layout shift.
126
+ // Toggle row — both the collapsed summary and bar handle live in the same
127
+ // grid cell so they crossfade without layout shift.
113
128
  toggleRow: {
114
129
  display: 'grid',
115
130
  gridTemplateColumns: '1fr',
@@ -130,6 +145,7 @@ const styles = stylex.create({
130
145
  justifySelf: 'start',
131
146
  display: 'inline-flex',
132
147
  alignItems: 'center',
148
+ pointerEvents: 'none',
133
149
  height: spacingVars['--spacing-5'],
134
150
  gap: spacingVars['--spacing-2'],
135
151
  borderRadius: radiusVars['--radius-full'],
@@ -227,6 +243,7 @@ export function ChatComposerDrawer({
227
243
  children,
228
244
  count,
229
245
  label: labelFromProps,
246
+ collapsedSummary,
230
247
  isCollapsed: controlledCollapsed,
231
248
  defaultIsCollapsed = false,
232
249
  onCollapsedChange,
@@ -274,7 +291,7 @@ export function ChatComposerDrawer({
274
291
  {...htmlProps}>
275
292
  {canCollapse && (
276
293
  <div
277
- {...stylex.props(
294
+ {...focusOutlineProps.focusVisible(
278
295
  styles.toggleRow,
279
296
  isCollapsed && styles.toggleCollapsed,
280
297
  stylex.defaultMarker(),
@@ -296,12 +313,20 @@ export function ChatComposerDrawer({
296
313
  }
297
314
  }}>
298
315
  <div
316
+ aria-hidden="true"
317
+ inert
299
318
  {...stylex.props(
300
319
  styles.toggleContent,
301
320
  !isCollapsed && styles.toggleContentHidden,
302
321
  )}>
303
- <Badge variant="neutral" label={count} />
304
- <span {...stylex.props(styles.collapseLabel)}>{label}</span>
322
+ {collapsedSummary === undefined ? (
323
+ <>
324
+ <Badge variant="neutral" label={count} />
325
+ <span {...stylex.props(styles.collapseLabel)}>{label}</span>
326
+ </>
327
+ ) : (
328
+ collapsedSummary
329
+ )}
305
330
  </div>
306
331
  <div
307
332
  {...stylex.props(
@@ -314,6 +339,10 @@ export function ChatComposerDrawer({
314
339
 
315
340
  <div
316
341
  id={contentId}
342
+ // The 0fr row keeps the collapse animation in place. `inert` also
343
+ // removes visually hidden descendants from keyboard and assistive-
344
+ // technology navigation until the drawer expands again.
345
+ inert={canCollapse && isCollapsed ? true : undefined}
317
346
  {...stylex.props(
318
347
  styles.contentGrid,
319
348
  canCollapse && isCollapsed && styles.contentGridCollapsed,