@astryxdesign/core 0.6.2 → 0.6.3-canary.039a67e

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 (621) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/dist/Avatar/Avatar.d.ts.map +1 -1
  3. package/dist/Avatar/Avatar.js +33 -12
  4. package/dist/BottomSheet/BottomSheet.d.ts +1 -1
  5. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  6. package/dist/BottomSheet/BottomSheet.js +3 -1
  7. package/dist/BottomSheet/BottomSheetPanel.d.ts +7 -5
  8. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  9. package/dist/BottomSheet/BottomSheetPanel.js +56 -19
  10. package/dist/Button/Button.d.ts.map +1 -1
  11. package/dist/Button/Button.js +13 -28
  12. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  13. package/dist/Chat/ChatComposer.js +10 -5
  14. package/dist/Chat/ChatComposerDrawer.d.ts +19 -5
  15. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  16. package/dist/Chat/ChatComposerDrawer.js +48 -23
  17. package/dist/Chat/ChatComposerInput.d.ts +11 -3
  18. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  19. package/dist/Chat/ChatComposerInput.js +63 -16
  20. package/dist/Chat/ChatDictationButton.d.ts +3 -2
  21. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  22. package/dist/Chat/ChatDictationButton.js +6 -4
  23. package/dist/Chat/ChatLayout.d.ts +19 -0
  24. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  25. package/dist/Chat/ChatLayout.js +19 -0
  26. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  27. package/dist/Chat/ChatLayoutScrollButton.js +44 -34
  28. package/dist/Chat/ChatMessageBubble.d.ts +2 -0
  29. package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
  30. package/dist/Chat/ChatMessageBubble.js +5 -3
  31. package/dist/Chat/ChatMessageList.d.ts +2 -1
  32. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  33. package/dist/Chat/ChatMessageList.js +4 -3
  34. package/dist/Chat/ChatMessageMetadata.d.ts +5 -4
  35. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  36. package/dist/Chat/ChatMessageMetadata.js +12 -9
  37. package/dist/Chat/ChatSendButton.d.ts +2 -1
  38. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  39. package/dist/Chat/ChatSendButton.js +6 -4
  40. package/dist/Chat/ChatSystemMessage.d.ts +3 -3
  41. package/dist/Chat/ChatSystemMessage.d.ts.map +1 -1
  42. package/dist/Chat/ChatSystemMessage.js +2 -2
  43. package/dist/Chat/ChatTokenizedText.d.ts +6 -6
  44. package/dist/Chat/ChatTokenizedText.js +10 -6
  45. package/dist/Chat/ChatToolCalls.d.ts +7 -9
  46. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  47. package/dist/Chat/ChatToolCalls.js +43 -26
  48. package/dist/Chat/index.d.ts +1 -1
  49. package/dist/Chat/index.d.ts.map +1 -1
  50. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  51. package/dist/CheckboxInput/CheckboxInput.js +12 -2
  52. package/dist/Citation/Citation.d.ts +1 -1
  53. package/dist/Citation/Citation.d.ts.map +1 -1
  54. package/dist/Citation/Citation.js +3 -2
  55. package/dist/CodeBlock/highlightRanges.d.ts.map +1 -1
  56. package/dist/CodeBlock/highlightRanges.js +14 -3
  57. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  58. package/dist/Collapsible/Collapsible.js +6 -1
  59. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  60. package/dist/CommandPalette/CommandPaletteInput.js +1 -1
  61. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  62. package/dist/ComplexSelector/ComplexSelector.js +1 -1
  63. package/dist/DateInput/DateInput.d.ts +25 -5
  64. package/dist/DateInput/DateInput.d.ts.map +1 -1
  65. package/dist/DateInput/DateInput.js +29 -17
  66. package/dist/DateInput/NativeDateField.d.ts.map +1 -1
  67. package/dist/DateInput/NativeDateField.js +16 -16
  68. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  69. package/dist/DateInput/TouchDateField.js +2 -2
  70. package/dist/DateInput/index.d.ts +1 -1
  71. package/dist/DateInput/index.d.ts.map +1 -1
  72. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  73. package/dist/DateRangeInput/DateRangeInput.js +4 -4
  74. package/dist/DateTimeInput/DateTimeInput.d.ts +32 -15
  75. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  76. package/dist/DateTimeInput/DateTimeInput.js +55 -30
  77. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  78. package/dist/DateTimeInput/TouchDateTimeField.js +4 -4
  79. package/dist/DateTimeInput/index.d.ts +1 -1
  80. package/dist/DateTimeInput/index.d.ts.map +1 -1
  81. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +9 -3
  82. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -1
  83. package/dist/DateTimeInput/nativePickerSegmentStyles.js +3 -3
  84. package/dist/Dialog/DialogHeader.d.ts +8 -1
  85. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  86. package/dist/Dialog/DialogHeader.js +13 -4
  87. package/dist/Field/InputClearButton.d.ts +4 -2
  88. package/dist/Field/InputClearButton.d.ts.map +1 -1
  89. package/dist/Field/InputClearButton.js +4 -2
  90. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  91. package/dist/Field/PanelSearchInput.js +1 -1
  92. package/dist/FileInput/FileInput.d.ts.map +1 -1
  93. package/dist/FileInput/FileInput.js +7 -7
  94. package/dist/Icon/Icon.d.ts +6 -31
  95. package/dist/Icon/Icon.d.ts.map +1 -1
  96. package/dist/Icon/Icon.js +8 -71
  97. package/dist/Icon/IconDefaultSizeContext.d.ts +4 -0
  98. package/dist/Icon/IconDefaultSizeContext.d.ts.map +1 -0
  99. package/dist/Icon/IconDefaultSizeContext.js +18 -0
  100. package/dist/Icon/IconSize.stylex.d.ts +65 -0
  101. package/dist/Icon/IconSize.stylex.d.ts.map +1 -0
  102. package/dist/Icon/IconSize.stylex.js +75 -0
  103. package/dist/Item/Item.d.ts +1 -1
  104. package/dist/Item/Item.d.ts.map +1 -1
  105. package/dist/Item/Item.js +4 -3
  106. package/dist/Kbd/Kbd.d.ts +5 -3
  107. package/dist/Kbd/Kbd.d.ts.map +1 -1
  108. package/dist/Kbd/Kbd.js +36 -42
  109. package/dist/Link/Link.d.ts.map +1 -1
  110. package/dist/Link/Link.js +6 -2
  111. package/dist/Link/useLinkComponent.d.ts +5 -15
  112. package/dist/Link/useLinkComponent.d.ts.map +1 -1
  113. package/dist/Link/useLinkComponent.js +34 -51
  114. package/dist/List/List.d.ts +19 -1
  115. package/dist/List/List.d.ts.map +1 -1
  116. package/dist/List/List.js +9 -2
  117. package/dist/List/ListContext.d.ts +1 -0
  118. package/dist/List/ListContext.d.ts.map +1 -1
  119. package/dist/List/ListContext.js +2 -1
  120. package/dist/List/ListItem.d.ts +1 -1
  121. package/dist/List/ListItem.d.ts.map +1 -1
  122. package/dist/List/ListItem.js +9 -2
  123. package/dist/Markdown/Markdown.d.ts +8 -2
  124. package/dist/Markdown/Markdown.d.ts.map +1 -1
  125. package/dist/Markdown/Markdown.fr23.bench.d.ts +2 -0
  126. package/dist/Markdown/Markdown.fr23.bench.d.ts.map +1 -0
  127. package/dist/Markdown/Markdown.fr23.bench.js +150 -0
  128. package/dist/Markdown/Markdown.fr23.sampling.d.ts +2 -0
  129. package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -0
  130. package/dist/Markdown/Markdown.fr23.sampling.js +43 -0
  131. package/dist/Markdown/Markdown.js +262 -109
  132. package/dist/Markdown/ast.d.ts +162 -0
  133. package/dist/Markdown/ast.d.ts.map +1 -0
  134. package/dist/Markdown/ast.js +74 -0
  135. package/dist/Markdown/index.d.ts +5 -3
  136. package/dist/Markdown/index.d.ts.map +1 -1
  137. package/dist/Markdown/index.js +3 -2
  138. package/dist/Markdown/parser/index.d.ts +10 -0
  139. package/dist/Markdown/parser/index.d.ts.map +1 -0
  140. package/dist/Markdown/parser/index.js +10 -0
  141. package/dist/Markdown/parser.d.ts +126 -58
  142. package/dist/Markdown/parser.d.ts.map +1 -1
  143. package/dist/Markdown/parser.js +726 -177
  144. package/dist/Markdown/plugins/frontmatter.d.ts +32 -0
  145. package/dist/Markdown/plugins/frontmatter.d.ts.map +1 -0
  146. package/dist/Markdown/plugins/frontmatter.js +132 -0
  147. package/dist/Markdown/plugins/index.d.ts +17 -0
  148. package/dist/Markdown/plugins/index.d.ts.map +1 -0
  149. package/dist/Markdown/plugins/index.js +14 -0
  150. package/dist/Markdown/plugins/protocol.d.ts +191 -0
  151. package/dist/Markdown/plugins/protocol.d.ts.map +1 -0
  152. package/dist/Markdown/plugins/protocol.js +957 -0
  153. package/dist/Markdown/plugins/semanticFence.d.ts +36 -0
  154. package/dist/Markdown/plugins/semanticFence.d.ts.map +1 -0
  155. package/dist/Markdown/plugins/semanticFence.js +213 -0
  156. package/dist/Markdown/plugins/softBreaks.d.ts +3 -0
  157. package/dist/Markdown/plugins/softBreaks.d.ts.map +1 -0
  158. package/dist/Markdown/plugins/softBreaks.js +172 -0
  159. package/dist/Markdown/plugins/sourceDecoration.d.ts +76 -0
  160. package/dist/Markdown/plugins/sourceDecoration.d.ts.map +1 -0
  161. package/dist/Markdown/plugins/sourceDecoration.js +393 -0
  162. package/dist/Markdown/plugins/textTransform.d.ts +30 -0
  163. package/dist/Markdown/plugins/textTransform.d.ts.map +1 -0
  164. package/dist/Markdown/plugins/textTransform.js +374 -0
  165. package/dist/Markdown/remark.d.ts +196 -0
  166. package/dist/Markdown/remark.d.ts.map +1 -0
  167. package/dist/Markdown/remark.js +1062 -0
  168. package/dist/Markdown/url.d.ts +6 -0
  169. package/dist/Markdown/url.d.ts.map +1 -0
  170. package/dist/Markdown/url.js +31 -0
  171. package/dist/Markdown/utils.d.ts +4 -2
  172. package/dist/Markdown/utils.d.ts.map +1 -1
  173. package/dist/Markdown/utils.js +2 -1
  174. package/dist/MetadataList/MetadataList.js +3 -3
  175. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  176. package/dist/NumberInput/NumberInput.js +4 -4
  177. package/dist/Outline/index.d.ts +1 -0
  178. package/dist/Outline/index.d.ts.map +1 -1
  179. package/dist/Outline/parseOutlineFromMarkdown.d.ts +7 -1
  180. package/dist/Outline/parseOutlineFromMarkdown.d.ts.map +1 -1
  181. package/dist/Outline/parseOutlineFromMarkdown.js +14 -8
  182. package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -1
  183. package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
  184. package/dist/Outline/useOutlineFromMarkdown.js +8 -3
  185. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  186. package/dist/PowerSearch/PowerSearchEditPopover.js +46 -30
  187. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  188. package/dist/PowerSearch/PowerSearchValueEditor.js +5 -0
  189. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  190. package/dist/ProgressBar/ProgressBar.js +36 -31
  191. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  192. package/dist/RadioList/RadioListItem.js +13 -1
  193. package/dist/ScrollableArea/ScrollableArea.d.ts +1 -0
  194. package/dist/ScrollableArea/ScrollableArea.d.ts.map +1 -1
  195. package/dist/ScrollableArea/ScrollableArea.js +1 -0
  196. package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
  197. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  198. package/dist/SegmentedControl/SegmentedControl.js +1 -0
  199. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  200. package/dist/SegmentedControl/SegmentedControlItem.js +5 -5
  201. package/dist/Selector/Selector.d.ts +9 -7
  202. package/dist/Selector/Selector.d.ts.map +1 -1
  203. package/dist/Selector/Selector.js +16 -7
  204. package/dist/SideNav/SideNav.d.ts +2 -1
  205. package/dist/SideNav/SideNav.d.ts.map +1 -1
  206. package/dist/SideNav/SideNav.js +9 -3
  207. package/dist/Slider/Slider.d.ts.map +1 -1
  208. package/dist/Slider/Slider.js +28 -12
  209. package/dist/Spinner/Spinner.d.ts.map +1 -1
  210. package/dist/Spinner/Spinner.js +23 -7
  211. package/dist/Switch/Switch.d.ts.map +1 -1
  212. package/dist/Switch/Switch.js +11 -0
  213. package/dist/TabList/Tab.d.ts +1 -1
  214. package/dist/TabList/Tab.d.ts.map +1 -1
  215. package/dist/TabList/Tab.js +20 -7
  216. package/dist/Table/Table.d.ts +1 -0
  217. package/dist/Table/Table.d.ts.map +1 -1
  218. package/dist/Table/Table.js +29 -13
  219. package/dist/TextArea/TextArea.d.ts.map +1 -1
  220. package/dist/TextArea/TextArea.js +1 -1
  221. package/dist/TextInput/TextInput.d.ts.map +1 -1
  222. package/dist/TextInput/TextInput.js +2 -2
  223. package/dist/TimeInput/TimeInput.d.ts +30 -14
  224. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  225. package/dist/TimeInput/TimeInput.js +61 -13
  226. package/dist/TimeInput/TouchTimeField.d.ts +11 -0
  227. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -0
  228. package/dist/TimeInput/TouchTimeField.js +417 -0
  229. package/dist/TimeInput/index.d.ts +1 -1
  230. package/dist/TimeInput/index.d.ts.map +1 -1
  231. package/dist/Timer/Timer.d.ts +49 -0
  232. package/dist/Timer/Timer.d.ts.map +1 -0
  233. package/dist/Timer/Timer.js +158 -0
  234. package/dist/Timer/index.d.ts +9 -0
  235. package/dist/Timer/index.d.ts.map +1 -0
  236. package/dist/Timer/index.js +10 -0
  237. package/dist/ToggleButton/ToggleButton.d.ts +9 -6
  238. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  239. package/dist/ToggleButton/ToggleButton.js +15 -27
  240. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  241. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  242. package/dist/TopNav/TopNavMenu.js +3 -2
  243. package/dist/TreeList/TreeList.d.ts.map +1 -1
  244. package/dist/TreeList/TreeList.js +3 -0
  245. package/dist/TreeList/TreeListItem.d.ts +6 -1
  246. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  247. package/dist/TreeList/TreeListItem.js +12 -2
  248. package/dist/TreeList/TreeListTypes.d.ts +8 -1
  249. package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
  250. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  251. package/dist/Typeahead/BaseTypeahead.js +16 -7
  252. package/dist/astryx.css +27 -11
  253. package/dist/hooks/scrollKeyboardDelegation.d.ts +3 -0
  254. package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -0
  255. package/dist/hooks/scrollKeyboardDelegation.js +146 -0
  256. package/dist/hooks/useClickableContainer.d.ts +10 -1
  257. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  258. package/dist/hooks/useClickableContainer.js +15 -4
  259. package/dist/hooks/useScrollableArea.d.ts +6 -2
  260. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  261. package/dist/hooks/useScrollableArea.js +17 -5
  262. package/dist/index.d.ts +1 -0
  263. package/dist/index.d.ts.map +1 -1
  264. package/dist/index.js +3 -0
  265. package/dist/theme/declarationBoundary.d.ts +17 -0
  266. package/dist/theme/declarationBoundary.d.ts.map +1 -0
  267. package/dist/theme/declarationBoundary.js +343 -0
  268. package/dist/theme/defineTheme.d.ts +3 -0
  269. package/dist/theme/defineTheme.d.ts.map +1 -1
  270. package/dist/theme/defineTheme.js +4 -1
  271. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  272. package/dist/theme/derivedVarRegistry.js +4 -0
  273. package/dist/theme/generateThemeRules.d.ts +15 -7
  274. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  275. package/dist/theme/generateThemeRules.js +143 -35
  276. package/dist/theme/themeAdaptations.d.ts +5 -3
  277. package/dist/theme/themeAdaptations.d.ts.map +1 -1
  278. package/dist/theme/themeAdaptations.js +33 -5
  279. package/dist/utils/inputPresentation.d.ts +55 -0
  280. package/dist/utils/inputPresentation.d.ts.map +1 -0
  281. package/dist/utils/inputPresentation.js +108 -0
  282. package/dist/utils/interactionOverlay.stylex.d.ts +8 -0
  283. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  284. package/dist/utils/interactionOverlay.stylex.js +9 -0
  285. package/dist/utils/safeUrl.d.ts +11 -0
  286. package/dist/utils/safeUrl.d.ts.map +1 -0
  287. package/dist/utils/safeUrl.js +78 -0
  288. package/locales/af-ZA.json +530 -1
  289. package/locales/ar-SA.json +490 -1
  290. package/locales/ca-ES.json +514 -1
  291. package/locales/cs-CZ.json +498 -1
  292. package/locales/da-DK.json +522 -1
  293. package/locales/de-DE.json +522 -1
  294. package/locales/el-GR.json +498 -1
  295. package/locales/es-ES.json +510 -1
  296. package/locales/fi-FI.json +498 -1
  297. package/locales/fr-FR.json +534 -1
  298. package/locales/he-IL.json +498 -1
  299. package/locales/hu-HU.json +498 -1
  300. package/locales/it-IT.json +510 -1
  301. package/locales/ja-JP.json +490 -1
  302. package/locales/ko-KR.json +498 -1
  303. package/locales/nl-NL.json +534 -1
  304. package/locales/no-NO.json +510 -1
  305. package/locales/pl-PL.json +506 -1
  306. package/locales/pt-BR.json +506 -1
  307. package/locales/pt-PT.json +506 -1
  308. package/locales/ro-RO.json +506 -1
  309. package/locales/ru-RU.json +498 -1
  310. package/locales/sr-SP.json +498 -1
  311. package/locales/sv-SE.json +502 -1
  312. package/locales/tr-TR.json +498 -1
  313. package/locales/uk-UA.json +498 -1
  314. package/locales/vi-VN.json +502 -1
  315. package/locales/zh-CN.json +490 -1
  316. package/locales/zh-TW.json +490 -1
  317. package/package.json +24 -4
  318. package/src/Avatar/Avatar.doc.mjs +1 -1
  319. package/src/Avatar/Avatar.test.tsx +30 -0
  320. package/src/Avatar/Avatar.tsx +38 -14
  321. package/src/BottomSheet/BottomSheet.doc.mjs +8 -1
  322. package/src/BottomSheet/BottomSheet.spec.md +46 -20
  323. package/src/BottomSheet/BottomSheet.test.tsx +6 -3
  324. package/src/BottomSheet/BottomSheet.tsx +3 -1
  325. package/src/BottomSheet/BottomSheetKeyboard.test.tsx +195 -0
  326. package/src/BottomSheet/BottomSheetPanel.test.tsx +11 -1
  327. package/src/BottomSheet/BottomSheetPanel.tsx +49 -16
  328. package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +344 -0
  329. package/src/Button/Button.doc.mjs +5 -5
  330. package/src/Button/Button.tsx +15 -13
  331. package/src/Button/__tests__/Button.a11y.chromium.spec.ts +17 -1
  332. package/src/Button/__tests__/Button.a11y.known-failures.ts +0 -29
  333. package/src/Button/__tests__/Button.a11y.renders.tsx +9 -2
  334. package/src/Button/__tests__/Button.a11y.states.ts +9 -0
  335. package/src/Chat/ChatComposer.doc.mjs +14 -0
  336. package/src/Chat/ChatComposer.spec.md +230 -0
  337. package/src/Chat/ChatComposer.test.tsx +57 -0
  338. package/src/Chat/ChatComposer.tsx +21 -9
  339. package/src/Chat/ChatComposerDrawer.doc.mjs +63 -5
  340. package/src/Chat/ChatComposerDrawer.spec.md +267 -0
  341. package/src/Chat/ChatComposerDrawer.test.tsx +81 -12
  342. package/src/Chat/ChatComposerDrawer.tsx +38 -9
  343. package/src/Chat/ChatComposerInput.doc.mjs +114 -26
  344. package/src/Chat/ChatComposerInput.spec.md +185 -0
  345. package/src/Chat/ChatComposerInput.test.tsx +113 -3
  346. package/src/Chat/ChatComposerInput.tsx +78 -13
  347. package/src/Chat/ChatComposerTokenElement.spec.md +152 -0
  348. package/src/Chat/ChatComposerTokenElement.test.tsx +85 -0
  349. package/src/Chat/ChatDictationButton.doc.mjs +3 -3
  350. package/src/Chat/ChatDictationButton.spec.md +160 -0
  351. package/src/Chat/ChatDictationButton.test.tsx +92 -27
  352. package/src/Chat/ChatDictationButton.tsx +8 -6
  353. package/src/Chat/ChatLayout.doc.mjs +12 -4
  354. package/src/Chat/ChatLayout.spec.md +271 -0
  355. package/src/Chat/ChatLayout.test.tsx +28 -0
  356. package/src/Chat/ChatLayout.tsx +19 -0
  357. package/src/Chat/ChatLayoutScrollButton.spec.md +338 -0
  358. package/src/Chat/ChatLayoutScrollButton.test.tsx +31 -0
  359. package/src/Chat/ChatLayoutScrollButton.tsx +31 -14
  360. package/src/Chat/ChatMessageBubble.doc.mjs +28 -15
  361. package/src/Chat/ChatMessageBubble.spec.md +263 -0
  362. package/src/Chat/ChatMessageBubble.test.tsx +93 -0
  363. package/src/Chat/ChatMessageBubble.tsx +8 -3
  364. package/src/Chat/ChatMessageList.spec.md +222 -0
  365. package/src/Chat/ChatMessageList.test.tsx +64 -2
  366. package/src/Chat/ChatMessageList.tsx +4 -3
  367. package/src/Chat/ChatMessageMetadata.doc.mjs +57 -3
  368. package/src/Chat/ChatMessageMetadata.spec.md +220 -0
  369. package/src/Chat/ChatMessageMetadata.test.tsx +34 -0
  370. package/src/Chat/ChatMessageMetadata.tsx +13 -13
  371. package/src/Chat/ChatSendButton.doc.mjs +32 -0
  372. package/src/Chat/ChatSendButton.spec.md +227 -0
  373. package/src/Chat/ChatSendButton.test.tsx +128 -8
  374. package/src/Chat/ChatSendButton.tsx +6 -4
  375. package/src/Chat/ChatSystemMessage.doc.mjs +115 -12
  376. package/src/Chat/ChatSystemMessage.spec.md +225 -0
  377. package/src/Chat/ChatSystemMessage.test.tsx +112 -20
  378. package/src/Chat/ChatSystemMessage.tsx +4 -6
  379. package/src/Chat/ChatTokenizedText.doc.mjs +96 -9
  380. package/src/Chat/ChatTokenizedText.spec.md +190 -0
  381. package/src/Chat/ChatTokenizedText.test.tsx +60 -1
  382. package/src/Chat/ChatTokenizedText.tsx +14 -8
  383. package/src/Chat/ChatToolCalls.doc.mjs +4 -1
  384. package/src/Chat/ChatToolCalls.spec.md +194 -0
  385. package/src/Chat/ChatToolCalls.test.tsx +83 -0
  386. package/src/Chat/ChatToolCalls.tsx +46 -21
  387. package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +514 -0
  388. package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +740 -0
  389. package/src/Chat/__tests__/ChatMessageBubble.a11y.chromium.spec.ts +457 -0
  390. package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.test.ts +91 -0
  391. package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.ts +91 -0
  392. package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +456 -0
  393. package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +413 -0
  394. package/src/Chat/__tests__/ChatSendButton.a11y.chromium.spec.ts +1522 -0
  395. package/src/Chat/__tests__/ChatSystemMessage.a11y.chromium.spec.ts +1004 -0
  396. package/src/Chat/__tests__/ChatTokenizedText.a11y.chromium.spec.ts +573 -0
  397. package/src/Chat/index.ts +1 -0
  398. package/src/CheckboxInput/CheckboxInput.doc.mjs +11 -0
  399. package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
  400. package/src/CheckboxInput/CheckboxInput.tsx +21 -1
  401. package/src/Citation/Citation.doc.mjs +2 -2
  402. package/src/Citation/Citation.test.tsx +17 -0
  403. package/src/Citation/Citation.tsx +4 -2
  404. package/src/ClickableCard/ClickableCard.doc.mjs +2 -2
  405. package/src/ClickableCard/ClickableCard.test.tsx +102 -5
  406. package/src/CodeBlock/highlightRanges.test.ts +143 -1
  407. package/src/CodeBlock/highlightRanges.ts +15 -5
  408. package/src/Collapsible/Collapsible.doc.mjs +11 -0
  409. package/src/Collapsible/Collapsible.test.tsx +21 -0
  410. package/src/Collapsible/Collapsible.tsx +5 -0
  411. package/src/CommandPalette/CommandPaletteInput.tsx +6 -1
  412. package/src/ComplexSelector/ComplexSelector.tsx +6 -1
  413. package/src/DateInput/DateInput.doc.mjs +38 -9
  414. package/src/DateInput/DateInput.tsx +59 -17
  415. package/src/DateInput/NativeDateField.tsx +24 -8
  416. package/src/DateInput/Presentation.test.tsx +121 -0
  417. package/src/DateInput/TouchDateField.tsx +6 -2
  418. package/src/DateInput/index.ts +1 -0
  419. package/src/DateRangeInput/DateRangeInput.tsx +6 -1
  420. package/src/DateTimeInput/DateTimeInput.doc.mjs +28 -12
  421. package/src/DateTimeInput/DateTimeInput.tsx +93 -37
  422. package/src/DateTimeInput/Presentation.test.tsx +89 -0
  423. package/src/DateTimeInput/TouchDateTimeField.tsx +6 -1
  424. package/src/DateTimeInput/index.ts +1 -0
  425. package/src/DateTimeInput/nativePickerSegmentStyles.ts +24 -8
  426. package/src/Dialog/Dialog.doc.mjs +2 -0
  427. package/src/Dialog/DialogHeader.doc.mjs +22 -0
  428. package/src/Dialog/DialogHeader.test.tsx +167 -3
  429. package/src/Dialog/DialogHeader.tsx +37 -6
  430. package/src/Dialog/modules/DialogHeader.spec.md +101 -42
  431. package/src/DropdownMenu/DropdownMenu.test.tsx +5 -2
  432. package/src/Field/InputClearButton.test.tsx +17 -3
  433. package/src/Field/InputClearButton.tsx +5 -2
  434. package/src/Field/PanelSearchInput.tsx +5 -2
  435. package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +1 -1
  436. package/src/FileInput/FileInput.tsx +11 -2
  437. package/src/Icon/Icon.doc.mjs +7 -5
  438. package/src/Icon/Icon.spec.md +81 -40
  439. package/src/Icon/Icon.test.tsx +6 -3
  440. package/src/Icon/Icon.tsx +20 -68
  441. package/src/Icon/IconDefaultSizeContext.ts +23 -0
  442. package/src/Icon/IconSize.stylex.ts +70 -0
  443. package/src/IconButton/IconButton.doc.mjs +3 -3
  444. package/src/IconButton/IconButton.test.tsx +40 -0
  445. package/src/Item/Item.doc.mjs +6 -2
  446. package/src/Item/Item.tsx +9 -3
  447. package/src/Kbd/Kbd.doc.mjs +3 -3
  448. package/src/Kbd/Kbd.test.tsx +57 -1
  449. package/src/Kbd/Kbd.tsx +57 -37
  450. package/src/Layout/LayoutFooter.doc.mjs +17 -0
  451. package/src/Link/Link.doc.mjs +17 -4
  452. package/src/Link/Link.test.tsx +24 -0
  453. package/src/Link/Link.tsx +5 -0
  454. package/src/Link/LinkProvider.doc.mjs +2 -2
  455. package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +261 -0
  456. package/src/Link/useLinkComponent.test.tsx +333 -0
  457. package/src/Link/useLinkComponent.ts +29 -57
  458. package/src/List/List.doc.mjs +6 -0
  459. package/src/List/List.spec.md +200 -0
  460. package/src/List/List.test.tsx +117 -1
  461. package/src/List/List.tsx +22 -2
  462. package/src/List/ListContext.tsx +3 -1
  463. package/src/List/ListItem.doc.mjs +2 -2
  464. package/src/List/ListItem.source-build.test.mjs +41 -0
  465. package/src/List/ListItem.tsx +26 -2
  466. package/src/Markdown/Markdown.doc.mjs +300 -2
  467. package/src/Markdown/Markdown.fr23.bench.ts +174 -0
  468. package/src/Markdown/Markdown.fr23.perf.test.ts +249 -0
  469. package/src/Markdown/Markdown.fr23.sampling.ts +49 -0
  470. package/src/Markdown/Markdown.helpers.perf.test.ts +489 -0
  471. package/src/Markdown/Markdown.public.test.ts +130 -3
  472. package/src/Markdown/Markdown.renderBoundary.test.tsx +72 -0
  473. package/src/Markdown/Markdown.spec.md +210 -45
  474. package/src/Markdown/Markdown.test.tsx +87 -3
  475. package/src/Markdown/Markdown.tsx +414 -135
  476. package/src/Markdown/ast.test.ts +307 -0
  477. package/src/Markdown/ast.ts +337 -0
  478. package/src/Markdown/incremental.test.ts +43 -0
  479. package/src/Markdown/index.ts +37 -1
  480. package/src/Markdown/modules/remark.spec.md +269 -0
  481. package/src/Markdown/modules/softBreaks.spec.md +137 -0
  482. package/src/Markdown/parser/index.ts +64 -0
  483. package/src/Markdown/parser.public.test.ts +103 -0
  484. package/src/Markdown/parser.test.ts +38 -6
  485. package/src/Markdown/parser.ts +1221 -242
  486. package/src/Markdown/plugins/frontmatter.test.tsx +125 -0
  487. package/src/Markdown/plugins/frontmatter.ts +198 -0
  488. package/src/Markdown/plugins/index.ts +54 -0
  489. package/src/Markdown/plugins/protocol.test.tsx +1022 -0
  490. package/src/Markdown/plugins/protocol.ts +1618 -0
  491. package/src/Markdown/plugins/semanticFence.test.tsx +546 -0
  492. package/src/Markdown/plugins/semanticFence.ts +424 -0
  493. package/src/Markdown/plugins/softBreaks.test.tsx +172 -0
  494. package/src/Markdown/plugins/softBreaks.ts +169 -0
  495. package/src/Markdown/plugins/sourceDecoration.test.tsx +799 -0
  496. package/src/Markdown/plugins/sourceDecoration.ts +539 -0
  497. package/src/Markdown/plugins/textTransform.test.ts +467 -0
  498. package/src/Markdown/plugins/textTransform.ts +554 -0
  499. package/src/Markdown/remark.test.tsx +1877 -0
  500. package/src/Markdown/remark.ts +1574 -0
  501. package/src/Markdown/url.ts +36 -0
  502. package/src/Markdown/utils.ts +13 -1
  503. package/src/MetadataList/MetadataList.test.tsx +4 -2
  504. package/src/MetadataList/MetadataList.tsx +3 -3
  505. package/src/MultiSelector/MultiSelector.test.tsx +1 -35
  506. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +128 -0
  507. package/src/NumberInput/NumberInput.tsx +6 -1
  508. package/src/Outline/Outline.doc.mjs +7 -5
  509. package/src/Outline/Outline.spec.md +1 -1
  510. package/src/Outline/index.ts +1 -0
  511. package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +142 -0
  512. package/src/Outline/parseOutlineFromMarkdown.ts +40 -10
  513. package/src/Outline/useOutlineFromMarkdown.ts +15 -3
  514. package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
  515. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +150 -1
  516. package/src/PowerSearch/PowerSearchEditPopover.tsx +51 -28
  517. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +51 -0
  518. package/src/PowerSearch/PowerSearchValueEditor.tsx +4 -0
  519. package/src/ProgressBar/ProgressBar.test.tsx +29 -11
  520. package/src/ProgressBar/ProgressBar.tsx +59 -72
  521. package/src/RadioList/RadioList.doc.mjs +11 -0
  522. package/src/RadioList/RadioList.test.tsx +32 -0
  523. package/src/RadioList/RadioListItem.tsx +25 -1
  524. package/src/ScrollableArea/ScrollableArea.tsx +1 -0
  525. package/src/ScrollableArea/modules/useScrollableArea.spec.md +50 -22
  526. package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
  527. package/src/SegmentedControl/SegmentedControl.test.tsx +61 -0
  528. package/src/SegmentedControl/SegmentedControl.tsx +2 -1
  529. package/src/SegmentedControl/SegmentedControlItem.tsx +6 -9
  530. package/src/Selector/Selector.doc.mjs +3 -3
  531. package/src/Selector/Selector.spec.md +51 -49
  532. package/src/Selector/Selector.test.tsx +61 -55
  533. package/src/Selector/Selector.tsx +34 -15
  534. package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +130 -0
  535. package/src/Selector/__tests__/Listbox.a11y.dom.ts +38 -0
  536. package/src/Selector/__tests__/Listbox.a11y.inventory.test.ts +63 -0
  537. package/src/Selector/__tests__/Listbox.a11y.known-failures.ts +37 -0
  538. package/src/Selector/__tests__/Listbox.a11y.states.ts +232 -0
  539. package/src/Selector/__tests__/Selector.a11y.chromium.spec.ts +45 -0
  540. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +121 -0
  541. package/src/SideNav/SideNav.doc.mjs +1 -1
  542. package/src/SideNav/SideNav.test.tsx +10 -0
  543. package/src/SideNav/SideNav.tsx +14 -2
  544. package/src/Slider/Slider.doc.mjs +17 -3
  545. package/src/Slider/Slider.test.tsx +221 -0
  546. package/src/Slider/Slider.tsx +40 -9
  547. package/src/Spinner/Spinner.test.tsx +4 -0
  548. package/src/Spinner/Spinner.tsx +31 -18
  549. package/src/Switch/Switch.doc.mjs +11 -0
  550. package/src/Switch/Switch.test.tsx +16 -0
  551. package/src/Switch/Switch.tsx +28 -0
  552. package/src/TabList/Tab.tsx +35 -7
  553. package/src/TabList/TabList.doc.mjs +11 -0
  554. package/src/TabList/TabList.spec.md +204 -0
  555. package/src/TabList/TabList.test.tsx +66 -0
  556. package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +1 -34
  557. package/src/Table/Table.doc.mjs +1 -1
  558. package/src/Table/Table.spec.md +54 -40
  559. package/src/Table/Table.test.tsx +83 -10
  560. package/src/Table/Table.tsx +30 -22
  561. package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +137 -0
  562. package/src/TextArea/TextArea.tsx +6 -1
  563. package/src/TextInput/TextInput.test.tsx +20 -1
  564. package/src/TextInput/TextInput.tsx +6 -1
  565. package/src/TimeInput/NativeTimeInput.test.tsx +36 -3
  566. package/src/TimeInput/Presentation.test.tsx +148 -0
  567. package/src/TimeInput/TimeInput.doc.mjs +21 -5
  568. package/src/TimeInput/TimeInput.tsx +102 -11
  569. package/src/TimeInput/TouchTimeField.tsx +572 -0
  570. package/src/TimeInput/index.ts +1 -0
  571. package/src/Timer/Timer.doc.mjs +183 -0
  572. package/src/Timer/Timer.spec.md +215 -0
  573. package/src/Timer/Timer.test.tsx +302 -0
  574. package/src/Timer/Timer.tsx +258 -0
  575. package/src/Timer/index.ts +11 -0
  576. package/src/ToggleButton/ToggleButton.doc.mjs +3 -3
  577. package/src/ToggleButton/ToggleButton.test.tsx +299 -4
  578. package/src/ToggleButton/ToggleButton.tsx +26 -33
  579. package/src/ToggleButton/ToggleButtonGroup.doc.mjs +3 -3
  580. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +209 -0
  581. package/src/Token/Token.doc.mjs +2 -2
  582. package/src/Tokenizer/Tokenizer.spec.md +142 -75
  583. package/src/TopNav/TopNavMenu.doc.mjs +2 -2
  584. package/src/TopNav/TopNavMenu.test.tsx +30 -0
  585. package/src/TopNav/TopNavMenu.tsx +7 -2
  586. package/src/TreeList/TreeList.doc.mjs +3 -3
  587. package/src/TreeList/TreeList.spec.md +123 -75
  588. package/src/TreeList/TreeList.test.tsx +29 -0
  589. package/src/TreeList/TreeList.tsx +3 -0
  590. package/src/TreeList/TreeListItem.tsx +15 -1
  591. package/src/TreeList/TreeListTypes.ts +11 -1
  592. package/src/Typeahead/BaseTypeahead.spec.md +4 -3
  593. package/src/Typeahead/BaseTypeahead.tsx +21 -7
  594. package/src/Typeahead/Typeahead.test.tsx +53 -0
  595. package/src/__tests__/PressedState.a11y.chromium.spec.ts +813 -0
  596. package/src/__tests__/pressState.ts +93 -0
  597. package/src/hooks/scrollKeyboardDelegation.test.ts +155 -0
  598. package/src/hooks/scrollKeyboardDelegation.ts +233 -0
  599. package/src/hooks/useClickableContainer.test.tsx +236 -0
  600. package/src/hooks/useClickableContainer.ts +20 -4
  601. package/src/hooks/useScrollableArea.doc.mjs +15 -3
  602. package/src/hooks/useScrollableArea.test.tsx +59 -1
  603. package/src/hooks/useScrollableArea.ts +34 -10
  604. package/src/index.ts +3 -0
  605. package/src/inputFontFloor.test.ts +106 -0
  606. package/src/tailwind-theme.css +0 -6
  607. package/src/theme/Theme.test.tsx +32 -0
  608. package/src/theme/declarationBoundary.test.ts +126 -0
  609. package/src/theme/declarationBoundary.ts +347 -0
  610. package/src/theme/defineTheme.ts +4 -0
  611. package/src/theme/derivedVarRegistry.test.ts +7 -0
  612. package/src/theme/derivedVarRegistry.ts +1 -0
  613. package/src/theme/generateThemeRules.test.ts +526 -1
  614. package/src/theme/generateThemeRules.ts +231 -50
  615. package/src/theme/themeAdaptations.test.ts +211 -1
  616. package/src/theme/themeAdaptations.ts +50 -4
  617. package/src/theme/tokenValueCompat.test.ts +4 -1
  618. package/src/utils/inputPresentation.ts +143 -0
  619. package/src/utils/interactionOverlay.stylex.ts +20 -0
  620. package/src/utils/safeUrl.test.ts +88 -0
  621. package/src/utils/safeUrl.ts +85 -0
@@ -0,0 +1,190 @@
1
+ ---
2
+ schema_version: 3
3
+ template_version: 6
4
+ kind: component
5
+ id: component:ChatTokenizedText
6
+ authority: draft
7
+ archive_reason: null
8
+ superseded_by: null
9
+ approved_by: null
10
+ approved_at: null
11
+ owners: [cixzhang]
12
+ review_triggers: [public-api, behavior, layout, theming, accessibility, testing]
13
+ verified_by:
14
+ [
15
+ packages/core/src/Chat/ChatTokenizedText.test.tsx,
16
+ packages/core/src/Chat/__tests__/ChatTokenizedText.a11y.chromium.spec.ts,
17
+ apps/storybook/stories/ChatTokenizedText.stories.tsx,
18
+ apps/storybook/rtl-audit/verified-not-applicable.json,
19
+ packages/core/src/theme/themingTargets.test.ts,
20
+ ]
21
+ modules: []
22
+ families: []
23
+ design_specs: []
24
+ architecture:
25
+ [
26
+ architecture:public-component-api,
27
+ architecture:component-theming-surface,
28
+ architecture:component-test-sufficiency,
29
+ architecture:react-component-runtime,
30
+ architecture:theme-tokens,
31
+ architecture:knowledge-contracts,
32
+ ]
33
+ contributing: []
34
+ system_specs: [spec:AST-002, spec:AST-020, spec:AST-029]
35
+ ---
36
+
37
+ # ChatTokenizedText component contract
38
+
39
+ ## Contract at a glance
40
+
41
+ | Area | Contract |
42
+ | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
43
+ | Public contract | The exported component accepts required plain-text children, optional composer token definitions, and supported root span props and ref. No prop, export, or theme target is added or removed. |
44
+ | Behavior | Unmatched text is preserved. Non-empty token values match literally from left to right. Structured tokens delegate to Badge and custom tokens to callers. |
45
+ | End-user impact | Tokenized messages finish rendering when a caller-supplied token definition has an empty serialized value. |
46
+ | Builder impact | Existing token arrays keep working, and empty serialized values are safely ignored instead of creating a non-advancing match. |
47
+ | Compatibility/readiness | Patch-compatible correctness repair and observational documentation. The pending inline-alignment change remains owned by its separate pull request. |
48
+ | Review checks | Reject zero-width matching, lost unmatched text, execution of custom renderers without a match, dropped root inputs, or claims about caller-owned content. |
49
+ | Governing rules | `architecture:public-component-api/INV1, INV5–INV6, INV8–INV9`; `architecture:component-test-sufficiency/INV1–INV7`; `spec:AST-029/FR3–FR7`; ECMAScript RegExp progress semantics. |
50
+
51
+ This table is a review projection. The draft body records verified current or
52
+ remediated behavior and creates no new token grammar or visual policy.
53
+
54
+ ## Intent
55
+
56
+ ChatTokenizedText projects serialized token values embedded in a plain chat message
57
+ into inline structured Badge content or caller-rendered content while preserving the
58
+ surrounding text.
59
+
60
+ ## Compatibility and migration
61
+
62
+ - Released default preserved: yes; messages without matching non-empty tokens remain plain text.
63
+ - Compatibility class: patch-compatible correctness repair for invalid zero-width matches.
64
+ - Controlled/uncontrolled behavior: not applicable; the component owns no state.
65
+ - Migration decision: none. No public type, prop, export, default, or theme target changes.
66
+
67
+ Consumer migration instructions belong in consumer docs and release notes.
68
+
69
+ ## Ownership boundary
70
+
71
+ **Owns**
72
+
73
+ - Literal matching of serialized token values against the supplied message text.
74
+ - Preserving unmatched text and source order.
75
+ - Choosing the existing structured Badge or custom-render branch for each match.
76
+ - The root span, its `chat-tokenized-text` target, accepted BaseProps composition, and ref.
77
+
78
+ **Does not own / non-goals**
79
+
80
+ - Token value grammar, identity, validation, or product semantics.
81
+ - Badge color, iconography, sizing, or accessibility semantics.
82
+ - Semantics and interaction inside caller-provided custom token content.
83
+ - Composer insertion, serialization, deletion, selection, or token-element alignment.
84
+ - The inline-alignment change proposed independently in pull request #6418.
85
+
86
+ ## Public concepts
87
+
88
+ | Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability | Invalid-value behavior |
89
+ | ------------ | ----------------------------------------------- | ------------------------------------------------------------------------- | ----------------------------------------- | -------- | ----------------------------------- | ------------------------- | ------------------------------------ |
90
+ | Message text | any string | Plain text whose literal token values may be projected inline. | Every render | required | `component:ChatTokenizedText` | released observed surface | Empty text renders an empty span. |
91
+ | Token set | omitted; empty; non-empty | Candidate serialized values and their structured or custom presentations. | Every render | omitted | caller and component | released observed surface | Empty token values are ignored. |
92
+ | Token form | structured Badge config; custom render function | Selects delegated Badge content or caller-rendered content. | Matching non-empty values | none | caller and delegated component | released observed surface | Type-invalid forms are rejected. |
93
+ | Root surface | ref; supported DOM/data/ARIA/class/style/xstyle | Extends the inline root without replacing its owned target. | Every render | omitted | `architecture:public-component-api` | released observed surface | Unsupported inputs stay unsupported. |
94
+
95
+ ## Behavioral and layout contract
96
+
97
+ | ID | Candidate invariant | Basis | Draft review state |
98
+ | --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ----------------------- |
99
+ | FR1 | The component MUST preserve unmatched text exactly and replace each matched non-empty serialized value at its original reading-order position. | Released consumer docs and implementation | verified |
100
+ | FR2 | Empty token values MUST be ignored so the renderer always makes progress and never enters a zero-width global-match loop. | Objective ECMAScript RegExp progress semantics and responsive rendering | remediated and verified |
101
+ | FR3 | Structured matches MUST delegate label, variant, and icon rendering to Badge; custom matches MUST invoke the caller renderer only for an actual match. | Released token type, source, docs, and tests | verified |
102
+ | FR4 | Supported ref, DOM/data/ARIA, className, style, and xstyle inputs MUST reach or compose on the root span while the `chat-tokenized-text` target remains intact. | `architecture:public-component-api/INV5–INV6, INV8` | verified |
103
+ | FR5 | The component MUST remain render-only, with no state, Effect, listener, observer, timer, or owned asynchronous resource. | Current source and `architecture:component-test-sufficiency` evidence boundary | verified |
104
+
105
+ ### Allowed variation
106
+
107
+ - **AV1 — Caller tokens.** Labels, variants, icons, custom content, and serialized values remain caller supplied.
108
+ - **AV2 — Caller styling.** Supported root styling inputs may extend the component without replacing its public target.
109
+ - **AV3 — Unmatched input.** Text with no matching non-empty value remains unchanged.
110
+
111
+ ### Representative states
112
+
113
+ | State | Required invariant | Allowed variation |
114
+ | -------------------- | ----------------------------------------------------------------------- | ------------------------------------- |
115
+ | Plain text | Exact text remains visible. | Any string content. |
116
+ | Structured match | Matching text is replaced by delegated Badge content. | Label, variant, and icon. |
117
+ | Custom match | Matching text is replaced by caller-rendered content. | Any caller-owned React node. |
118
+ | Repeated match | Every occurrence is replaced in reading order. | Number and position of occurrences. |
119
+ | Empty token value | The value is ignored and rendering terminates with text preserved. | Presence beside valid tokens. |
120
+ | Narrow / RTL context | Inline content remains readable and follows surrounding text direction. | Theme, direction, and message length. |
121
+
122
+ ### Transformation and precedence order
123
+
124
+ - **ORD1 — Normalize candidates.** Remove empty serialized values while preserving caller order.
125
+ - **ORD2 — Match literally.** Escape values for RegExp syntax and scan the message from left to right.
126
+ - **ORD3 — Render.** Preserve unmatched slices and delegate each matched token to Badge or the caller renderer.
127
+ - **ORD4 — Compose root.** Apply the component target and styles, then combine accepted consumer styling and root props.
128
+
129
+ ### Performance and resources
130
+
131
+ - **PR1 — Finite progress.** Every successful match consumes at least one UTF-16 code unit; empty values cannot enter the matcher.
132
+ - **PR2 — Render-only projection.** Matching allocates one candidate list, lookup map, and result list per render and owns no persistent resource.
133
+
134
+ ## Accessibility contract
135
+
136
+ - **AR1 — Reading order.** Unmatched text and token content remain in source reading order inside one inline text wrapper.
137
+ - **AR2 — Delegated content.** Structured token semantics remain owned by Badge; custom token semantics remain caller owned.
138
+ - **AR3 — Noninteractive root.** The component introduces no role, focus target, keyboard command, pointer action, or live-region behavior.
139
+
140
+ ## Design relationships
141
+
142
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
143
+ | ---------------- | -------------------------------------------- | -------------------------------- | -------------- | ------------------ |
144
+ | Tokenized text | Inline root preserves surrounding text flow. | Current source and released docs | supporting | FR1, FR5 |
145
+ | Rendered token | Delegates paint to Badge or caller content. | `component:Badge` or caller | supporting | FR4, AR2 |
146
+
147
+ This observational draft does not choose new spacing, alignment, token paint,
148
+ proportion, or state representation.
149
+
150
+ ### Theme ownership
151
+
152
+ The Chat family document owns the shared anatomy and target inventory inherited by
153
+ this subcomponent. The existing `chat-tokenized-text` target remains on the inline
154
+ root. Structured token paint delegates to Badge, while custom rendered token content
155
+ remains caller owned. This observational draft does not redefine the family map.
156
+
157
+ ## Family and system relationships
158
+
159
+ - `component:Badge` owns structured token paint, variants, iconography, and label semantics.
160
+ - `component:ChatComposerInput` owns token insertion, serialization, deletion, and composer selection behavior.
161
+ - `architecture:public-component-api` owns released exports, BaseProps reachability, styling composition, and refs.
162
+ - `architecture:component-theming-surface` owns the target/anatomy mapping.
163
+ - `architecture:component-test-sufficiency` owns bounded, mutation-sensitive evidence.
164
+ - `spec:AST-029` owns this observational audit backfill and closed evidence receipt.
165
+
166
+ ## Verification map
167
+
168
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
169
+ | -------------- | -------------------------------------------------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------- | ------------------------------------- |
170
+ | FR1–FR3, PR1 | `ChatTokenizedText.test.tsx` | plain, structured, custom, repeated, empty | Lost text, zero-width nontermination, or the wrong render branch fails. | `audit:ChatTokenizedText/behavior` |
171
+ | FR4 | focused root passthrough/ref checks, theming target guard | plain and tokenized roots | A supported root input or public target is dropped or replaced. | `audit:ChatTokenizedText/public-api` |
172
+ | FR5 | source inspection and strict lint | every render | Hidden state or an owned external resource triggers runtime review. | `audit:ChatTokenizedText/code-health` |
173
+ | RTL relation | source-hashed verified-N/A record | all existing stories | Component-owned directional behavior invalidates the record. | `audit:ChatTokenizedText/i18n-rtl` |
174
+ | Browser matrix | Storybook stories, exact-head visual gate, and scoped a11y | plain, multiple, mixed, edge, custom, narrow | Missing text/token content, overflow, visual regression, or an a11y violation fails. | `audit:ChatTokenizedText/rendered` |
175
+ | Docs / surface | docs, declarations, exports, `check:knowledge`, docs typecheck | public props, Chat subpath, target, draft record | Missing or stale docs, export, target map, or knowledge shape fails validation or review. | `audit:ChatTokenizedText/docs` |
176
+
177
+ ## Decision log
178
+
179
+ No component-local product decision is created by this observational draft. The
180
+ matching repair follows the component's released promise to replace supplied literal
181
+ token values while preserving surrounding text.
182
+
183
+ ## Open questions
184
+
185
+ None.
186
+
187
+ ## Content boundary
188
+
189
+ This file does not duplicate consumer examples, audit scores, screenshots, Badge
190
+ policy, token grammar, or composer editing behavior.
@@ -1,6 +1,7 @@
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
+ import {createRef} from 'react';
4
5
  import {render, screen} from '@testing-library/react';
5
6
  import {ChatTokenizedText} from './ChatTokenizedText';
6
7
 
@@ -79,6 +80,64 @@ describe('ChatTokenizedText', () => {
79
80
  expect(container.textContent).toContain('@Cindy Zhang');
80
81
  });
81
82
 
83
+ it('ignores empty token values instead of creating zero-width matches', () => {
84
+ render(
85
+ <ChatTokenizedText
86
+ tokens={[
87
+ {value: '', label: 'Empty'},
88
+ {value: '@alice', label: '@Alice'},
89
+ ]}>
90
+ Hello @alice
91
+ </ChatTokenizedText>,
92
+ );
93
+
94
+ expect(screen.getByText('@Alice')).toBeInTheDocument();
95
+ expect(screen.queryByText('Empty')).not.toBeInTheDocument();
96
+ });
97
+
98
+ it('renders plain text when every token value is empty', () => {
99
+ render(
100
+ <ChatTokenizedText
101
+ tokens={[
102
+ {value: '', label: 'First empty'},
103
+ {value: '', label: 'Second empty'},
104
+ ]}>
105
+ Hello world
106
+ </ChatTokenizedText>,
107
+ );
108
+
109
+ expect(screen.getByText('Hello world')).toBeInTheDocument();
110
+ expect(screen.queryByText('First empty')).not.toBeInTheDocument();
111
+ expect(screen.queryByText('Second empty')).not.toBeInTheDocument();
112
+ });
113
+
114
+ it('renders custom tokens only for actual matches', () => {
115
+ const renderCustom = vi.fn(() => <span>Custom token</span>);
116
+
117
+ const {rerender} = render(
118
+ <ChatTokenizedText tokens={[{value: '@custom', render: renderCustom}]}>
119
+ Hello @custom
120
+ </ChatTokenizedText>,
121
+ );
122
+ expect(screen.getByText('Custom token')).toBeInTheDocument();
123
+ expect(renderCustom).toHaveBeenCalledTimes(1);
124
+
125
+ rerender(
126
+ <ChatTokenizedText tokens={[{value: '@custom', render: renderCustom}]}>
127
+ Hello world
128
+ </ChatTokenizedText>,
129
+ );
130
+ expect(screen.queryByText('Custom token')).not.toBeInTheDocument();
131
+ expect(renderCustom).toHaveBeenCalledTimes(1);
132
+ });
133
+
134
+ it('forwards refs to the root span', () => {
135
+ const ref = createRef<HTMLSpanElement>();
136
+ render(<ChatTokenizedText ref={ref}>Plain text</ChatTokenizedText>);
137
+ expect(ref.current?.tagName).toBe('SPAN');
138
+ expect(ref.current?.textContent).toBe('Plain text');
139
+ });
140
+
82
141
  it('forwards rest props (data-*, id) to the root element', () => {
83
142
  render(
84
143
  <ChatTokenizedText data-testid="tokenized" data-custom="x" id="tok-1">
@@ -8,9 +8,9 @@
8
8
  * @output Exports ChatTokenizedText component
9
9
  * @position Utility component for rendering tokenized text in message bubbles
10
10
  *
11
- * Parses a plain text string and replaces token values with inline badges.
12
- * Accepts the same ChatComposerToken type used by the input triggers,
13
- * so the same token definitions work for both input and display.
11
+ * Parses a plain text string and replaces non-empty token values with inline
12
+ * token content. Accepts the same ChatComposerToken type used by the input
13
+ * triggers, so the same token definitions work for both input and display.
14
14
  *
15
15
  * SYNC: When modified, update:
16
16
  * - /packages/core/src/Chat/index.ts
@@ -51,8 +51,8 @@ export interface ChatTokenizedTextProps extends BaseProps<HTMLSpanElement> {
51
51
  children: string;
52
52
  /**
53
53
  * Token definitions — same type returned by trigger onSelect.
54
- * Each token's `value` is matched against the text and replaced
55
- * with its badge representation (label, variant, icon).
54
+ * Each non-empty token `value` is matched literally against the text and
55
+ * replaced with its Badge or custom representation. Empty values are ignored.
56
56
  *
57
57
  * @example
58
58
  * ```
@@ -88,7 +88,7 @@ function escapeRegExp(str: string): string {
88
88
  // =============================================================================
89
89
 
90
90
  /**
91
- * Renders text with token values replaced by inline badges.
91
+ * Renders text with token values replaced by inline token content.
92
92
  *
93
93
  * Accepts the same `ChatComposerToken` type used by input triggers,
94
94
  * so you can share a single token definition between input and display.
@@ -141,11 +141,17 @@ ChatTokenizedText.displayName = 'ChatTokenizedText';
141
141
  // =============================================================================
142
142
 
143
143
  function renderTokens(text: string, tokens: ChatComposerToken[]): ReactNode[] {
144
- const pattern = tokens.map(t => escapeRegExp(t.value)).join('|');
144
+ const matchableTokens = tokens.filter(token => token.value.length > 0);
145
+
146
+ if (matchableTokens.length === 0) {
147
+ return [text];
148
+ }
149
+
150
+ const pattern = matchableTokens.map(t => escapeRegExp(t.value)).join('|');
145
151
  const regex = new RegExp(`(${pattern})`, 'g');
146
152
 
147
153
  const tokenMap = new Map<string, ChatComposerToken>();
148
- for (const t of tokens) {
154
+ for (const t of matchableTokens) {
149
155
  tokenMap.set(t.value, t);
150
156
  }
151
157
 
@@ -16,6 +16,7 @@ export const docs = {
16
16
  bestPractices: [
17
17
  {guidance: true, description: 'Include a target string on every call so the user can see what the tool acted on: a file path, a shell command, or a search query.'},
18
18
  {guidance: true, description: 'Show a duration on completed calls so users can judge which tools are slow and understand why a response took time.'},
19
+ {guidance: true, description: 'Provide a group label when the automatic count does not explain what the calls represent.'},
19
20
  {guidance: true, description: 'Provide resultDetail with a code block for calls that produce output (diffs for edits, terminal output for shell commands) so users can inspect results inline.'},
20
21
  {guidance: true, description: 'Set a unique key on each call item when streaming so React can animate additions without re-mounting completed rows.'},
21
22
  {guidance: false, description: "Don't omit the status field. Without it the call defaults to complete, which is misleading for calls that are still running or have failed."},
@@ -54,7 +55,7 @@ export const docs = {
54
55
  name: 'label',
55
56
  type: 'string',
56
57
  description:
57
- 'Custom summary label for groups. Auto-generated from count if omitted.',
58
+ 'Custom summary label shown for an expanded group. The translated call count is used when omitted.',
58
59
  },
59
60
  {
60
61
  name: 'isExpanded',
@@ -90,6 +91,7 @@ export const docsZh = {
90
91
  bestPractices: [
91
92
  {guidance: true, description: 'Include a target string on every call so the user can see what the tool acted on: a file path, a shell command, or a search query.'},
92
93
  {guidance: true, description: 'Show a duration on completed calls so users can judge which tools are slow and understand why a response took time.'},
94
+ {guidance: true, description: 'Provide a group label when the automatic count does not explain what the calls represent.'},
93
95
  {guidance: true, description: 'Provide resultDetail with a code block for calls that produce output (diffs for edits, terminal output for shell commands) so users can inspect results inline.'},
94
96
  {guidance: true, description: 'Set a unique key on each call item when streaming so React can animate additions without re-mounting completed rows.'},
95
97
  {guidance: false, description: "Don't omit the status field. Without it the call defaults to complete, which is misleading for calls that are still running or have failed."},
@@ -115,6 +117,7 @@ export const docsDense = {
115
117
  bestPractices: [
116
118
  {guidance: true, description: 'Include target on every call: file path, command, or search query.'},
117
119
  {guidance: true, description: 'Show duration on completed calls so users understand timing.'},
120
+ {guidance: true, description: 'Provide group label when count alone is ambiguous.'},
118
121
  {guidance: true, description: 'Provide resultDetail with code blocks for calls that produce output.'},
119
122
  {guidance: true, description: 'Set unique key on each call item when streaming for stable animations.'},
120
123
  {guidance: false, description: "Don't omit status; defaults to complete, misleading for running/failed calls."},
@@ -0,0 +1,194 @@
1
+ ---
2
+ schema_version: 3
3
+ template_version: 6
4
+ kind: component
5
+ id: component:ChatToolCalls
6
+ authority: draft
7
+ archive_reason: null
8
+ superseded_by: null
9
+ approved_by: null
10
+ approved_at: null
11
+ owners: [cixzhang]
12
+ review_triggers: [public-api, behavior, layout, theming, accessibility, testing]
13
+ verified_by:
14
+ [
15
+ packages/core/src/Chat/ChatToolCalls.test.tsx,
16
+ apps/storybook/stories/ChatToolCalls.stories.tsx,
17
+ apps/storybook/rtl-audit/verified-not-applicable.json,
18
+ packages/core/src/theme/themingTargets.test.ts,
19
+ ]
20
+ modules: []
21
+ families: []
22
+ design_specs: []
23
+ architecture:
24
+ [
25
+ architecture:public-component-api,
26
+ architecture:component-theming-surface,
27
+ architecture:component-test-sufficiency,
28
+ architecture:react-component-runtime,
29
+ architecture:interaction-modality,
30
+ architecture:theme-tokens,
31
+ architecture:knowledge-contracts,
32
+ ]
33
+ contributing: []
34
+ system_specs: [spec:AST-009, spec:AST-029]
35
+ ---
36
+
37
+ # ChatToolCalls component contract
38
+
39
+ ## Contract at a glance
40
+
41
+ | Area | Contract |
42
+ | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
43
+ | Public contract | The exported component accepts a required call list, optional group label, controlled or uncontrolled expansion, a change callback, and supported root div props and ref. |
44
+ | Behavior | No calls render nothing; one call renders directly; multiple calls expose a disclosure whose collapsed surface shows the latest call and whose expanded surface shows every call. |
45
+ | End-user impact | Group labels appear as supplied, collapsed detail controls leave keyboard and accessibility navigation, and every disclosure has the shared visible focus treatment. |
46
+ | Builder impact | Existing calls keep their shape and defaults. Builders may rely on the released `label` prop and continue to omit it for the translated count. |
47
+ | Compatibility/readiness | Patch-compatible restoration of documented behavior and objective accessibility requirements. No prop, export, default, theme target, call ordering, or caller-content contract changes. |
48
+ | Review checks | Reject ignored labels, focusable descendants inside a collapsed group, lost keyboard activation, unreadable supporting text, dropped root inputs, or changed call ordering/defaults. |
49
+ | Governing rules | `architecture:public-component-api/INV5–INV6, INV8–INV9`; `architecture:interaction-modality`; `spec:AST-009/FR7`; `spec:AST-029/FR3–FR7`; WCAG 2.2 SC 1.4.3 and 2.4.7. |
50
+
51
+ This table is a review projection. The draft body records verified shipped or
52
+ remediated behavior and creates no new tool-call protocol or visual policy.
53
+
54
+ ## Intent
55
+
56
+ ChatToolCalls presents tool or function invocations inside an assistant message,
57
+ including execution status, optional metadata, and inspectable result details.
58
+
59
+ ## Compatibility and migration
60
+
61
+ - Released default preserved: yes; omitted status means complete and groups start collapsed unless `defaultIsExpanded` is true.
62
+ - Compatibility class: patch-compatible correctness and accessibility repair.
63
+ - Controlled/uncontrolled behavior: `isExpanded` remains authoritative when supplied; otherwise local state starts from `defaultIsExpanded ?? false`.
64
+ - Migration decision: none. No public type, prop, export, default, or theme target changes.
65
+
66
+ Consumer migration instructions belong in consumer docs and release notes.
67
+
68
+ ## Ownership boundary
69
+
70
+ **Owns**
71
+
72
+ - Projection of ordered call data into single-call or grouped presentation.
73
+ - Group and per-call disclosures, including keyboard operation and focus treatment.
74
+ - Status, metadata, duration, statistics, and result-detail placement.
75
+ - The root div, `chat-tool-calls` target, supported BaseProps composition, and ref.
76
+
77
+ **Does not own / non-goals**
78
+
79
+ - Tool execution, streaming transport, result parsing, or error recovery.
80
+ - Semantics and interaction inside caller-provided `stats` or `resultDetail` content.
81
+ - Badge, Icon, Spinner, or CodeBlock internals.
82
+ - Product policy for which tool calls may be shown.
83
+
84
+ ## Public concepts
85
+
86
+ | Concept | Closed values or states | Meaning | Availability | Default | Owner | Stability | Invalid-value behavior |
87
+ | ------------- | ----------------------------------------------------- | ------------------------------------------------------------ | ------------------- | --------- | ----------------------------------- | ------------------------- | ------------------------------------ |
88
+ | Call list | empty; single; multiple | Selects absent, direct-row, or grouped presentation. | Every render | required | `component:ChatToolCalls` | released observed surface | Empty renders nothing. |
89
+ | Status | pending; running; complete; error | Selects the visible and accessible execution state. | Every call | complete | `component:ChatToolCalls` | released observed surface | Type-invalid values reject. |
90
+ | Group label | omitted; supplied string | Names an expanded group; omission uses the translated count. | Multiple calls | omitted | caller and component | released observed surface | Supplied strings render verbatim. |
91
+ | Group state | controlled; uncontrolled collapsed; uncontrolled open | Controls whether grouped rows are exposed. | Multiple calls | collapsed | caller or component | released observed surface | Conflicting control is avoided. |
92
+ | Result detail | omitted; caller React node | Adds an independently operable per-call disclosure. | Any call | omitted | caller and component | released observed surface | Omitted content adds no control. |
93
+ | Root surface | ref; supported DOM/data/ARIA/class/style/xstyle | Extends the root without replacing its owned target. | Non-empty call list | omitted | `architecture:public-component-api` | released observed surface | Unsupported inputs stay unsupported. |
94
+
95
+ ## Behavioral and layout contract
96
+
97
+ | ID | Candidate invariant | Basis | Draft review state |
98
+ | --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------ |
99
+ | FR1 | An empty call list MUST render no root; one call MUST render directly; multiple calls MUST render one group disclosure and preserve caller order in its full list. | Released implementation, docs, stories, and tests | verified |
100
+ | FR2 | A supplied `label` MUST replace the translated count on the expanded group surface; omission MUST retain the translated count fallback. | Released public prop and consumer docs; public API INV5, INV9 | remediated and verified |
101
+ | FR3 | A collapsed group MUST keep its descendant call disclosures out of keyboard and accessibility navigation; expansion MUST restore them. | HTML `inert`, disclosure semantics, WCAG operability | remediated and verified |
102
+ | FR4 | Every component-owned disclosure MUST activate with Enter, Space, and pointer input, expose expansion state, and draw the shared keyboard focus ring. | Current interaction-modality architecture and WCAG 2.4.7 | remediated and verified |
103
+ | FR5 | Neutral supporting labels, targets, durations, and custom statistics MUST use the readable secondary foreground; signed addition/deletion counts retain their released semantic colors pending OQ2. | WCAG 2.2 SC 1.4.3 and current token architecture | partial remediation; OQ2 |
104
+ | FR6 | Supported root ref, DOM/data/ARIA, className, style, and xstyle inputs MUST reach or compose on the root while the public target remains intact. | `architecture:public-component-api/INV5–INV6, INV8` | verified |
105
+
106
+ ### Allowed variation
107
+
108
+ - **AV1 — Call content.** Tool names, targets, node names, durations, statistics, error messages, and result details remain caller supplied.
109
+ - **AV2 — Group control.** Callers may control expansion or supply only its initial uncontrolled value.
110
+ - **AV3 — Styling.** Supported root styling inputs may extend the component without replacing its public target.
111
+
112
+ ### Representative states
113
+
114
+ | State | Required invariant | Allowed variation |
115
+ | -------------------- | ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
116
+ | Empty | No root is rendered. | Empty array identity may vary. |
117
+ | Single | One row appears without group chrome. | Metadata and result detail may be absent. |
118
+ | Multiple, collapsed | Latest call and count appear; full rows are inert. | Call count and latest status may vary. |
119
+ | Multiple, expanded | Every call appears in source order; supplied label or translated count names the group. | Label text and row metadata may vary. |
120
+ | Detail closed/open | The row exposes its state and conditionally mounts the caller-owned detail. | Any caller React node. |
121
+ | Statuses | All statuses expose translated accessible text; complete and error also retain distinct semantic marks. | Theme may change semantic artwork; pending and running share a spinner pending OQ1. |
122
+ | Narrow / RTL context | Rows truncate without horizontal overflow and follow logical inline direction. | Content length, theme, and direction. |
123
+
124
+ ### Transformation and precedence order
125
+
126
+ - **ORD1 — Choose presentation.** Empty, single, and grouped branches are selected from list length.
127
+ - **ORD2 — Resolve state.** Controlled expansion wins; otherwise local state starts from the initial default.
128
+ - **ORD3 — Resolve label.** A supplied group label wins; otherwise use the translated count.
129
+ - **ORD4 — Compose rows.** Preserve call order, render status and metadata, then add caller-owned detail disclosure where present.
130
+ - **ORD5 — Compose root.** Apply the component target and styles, then combine supported consumer inputs.
131
+
132
+ ### Performance and resources
133
+
134
+ - **PR1 — Local state only.** The component owns disclosure state and no Effect, listener, observer, timer, or external resource.
135
+ - **PR2 — Linear projection.** Group rendering traverses the supplied call list once and does not mutate caller data.
136
+
137
+ ## Accessibility contract
138
+
139
+ - **AR1 — Disclosure operation.** Group and detail disclosures expose `aria-expanded`, operate with pointer, Enter, and Space, and use the shared visible focus ring.
140
+ - **AR2 — Collapsed ownership.** Collapsed group content is inert; hidden detail content is unmounted.
141
+ - **AR3 — Status meaning.** Every status exposes translated visually hidden text. Complete and error also use distinct semantic marks; pending and running currently share the same subtle spinner (OQ1). Error messages are exposed to assistive technology and echoed in the status icon's hover tooltip.
142
+ - **AR4 — Static evidence.** Focus appearance, keyboard behavior, inertness, color contrast, and DOM relationships use unit, axe, and real-browser evidence under `spec:AST-009/FR7`; this audit makes no AT-announcement claim.
143
+
144
+ ## Design relationships
145
+
146
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
147
+ | ---------------- | ---------------------------------------------------------------------------------------------- | --------------------------------- | -------------- | ------------------ |
148
+ | Call row | Compact inline status and metadata remain legible. | Current source and WCAG contrast | supporting | FR5, AR3 |
149
+ | Disclosure | Keyboard focus remains visible without changing layout. | Current interaction architecture | supporting | FR4, AR1 |
150
+ | Status | Translated hidden text preserves accessible meaning; complete and error retain semantic marks. | Current source and objective a11y | supporting | FR5, AR3 |
151
+
152
+ This observational draft does not choose new spacing, density, iconography,
153
+ proportion, status vocabulary, or motion.
154
+
155
+ ### Theme ownership
156
+
157
+ The existing `chat-tool-calls` target remains on the root. Badge, Icon, and Spinner
158
+ own their nested targets and paint. This observational draft does not add a public
159
+ theme target or redefine inherited Chat-family anatomy.
160
+
161
+ ## Family and system relationships
162
+
163
+ - `architecture:public-component-api` owns released exports, accepted inputs, styling composition, and refs.
164
+ - `architecture:component-theming-surface` owns the target and delegated anatomy contract.
165
+ - `architecture:interaction-modality` owns shared keyboard focus treatment.
166
+ - `architecture:component-test-sufficiency` owns bounded, mutation-sensitive evidence.
167
+ - `spec:AST-009` assigns these static semantics, keyboard, focus, and contrast claims to lower evidence layers rather than real AT.
168
+ - `spec:AST-029` owns this observational audit backfill and closed evidence receipt.
169
+
170
+ ## Verification map
171
+
172
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
173
+ | ---------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------- |
174
+ | FR1–FR4, AR1–AR2 | `ChatToolCalls.test.tsx` | empty, single, grouped, label, disclosures | Ignored label, wrong state, operable collapsed row, or missing ring fails. | `audit:ChatToolCalls/behavior` |
175
+ | FR5, AR3–AR4 | scoped Chromium axe plus existing-baseline visual comparisons | neutral metadata in light mode; existing visual states in light/dark | Reintroducing disabled-text contrast fails; semantic stats remain baselined under OQ2. | `audit:ChatToolCalls/accessibility` |
176
+ | FR6 | focused root passthrough/ref checks and theming target guard | single root | A supported input, ref, or public target is dropped or replaced. | `audit:ChatToolCalls/public-api` |
177
+ | RTL relation | source-hashed verified-N/A record | all checked-in stories | Component-owned directional behavior invalidates the record. | `audit:ChatToolCalls/i18n-rtl` |
178
+ | Browser matrix | existing visual baselines, scoped a11y, and required real-browser play guards | grouped focus and 320px narrow overflow; existing light/dark states | Missing focus, overflow, visual regressions, or new a11y violations fail. | `audit:ChatToolCalls/rendered` |
179
+ | Docs / surface | docs, declarations, exports, knowledge check, docs typecheck | public props, Chat subpath, draft record | Missing or stale docs, export, target, or knowledge shape fails. | `audit:ChatToolCalls/docs` |
180
+
181
+ ## Decision log
182
+
183
+ No component-local product decision is created by this observational draft. The
184
+ repairs restore released API behavior and objective accessibility requirements.
185
+
186
+ ## Open questions
187
+
188
+ - **OQ1 — Pending/running visual distinction.** Pending and running currently render the same subtle spinner and differ only in translated accessible text. Which approved visible treatment should distinguish them without inventing component-local status policy?
189
+ - **OQ2 — Semantic statistics contrast.** The released success/error foreground tokens for signed `+N`/`-N` statistics do not reach 4.5:1 in every shipped light/dark surface. Which system-level semantic text token should replace them while preserving addition/deletion meaning? The five affected axe baselines remain until that owner decision lands.
190
+
191
+ ## Content boundary
192
+
193
+ This file does not duplicate consumer examples, audit scores, screenshots, tool
194
+ execution policy, or delegated component contracts.