@ds-mo/ui 9.1.0 → 9.2.1

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 (333) hide show
  1. package/README.md +0 -79
  2. package/dist/.build-stamp +1 -1
  3. package/dist/agent-patterns.json +165 -1
  4. package/dist/agent.json +2131 -639
  5. package/dist/angular/ds-agent-activity.d.ts +12 -0
  6. package/dist/angular/ds-agent-activity.js +38 -0
  7. package/dist/angular/ds-agent-response.d.ts +12 -0
  8. package/dist/angular/ds-agent-response.js +38 -0
  9. package/dist/angular/ds-agent-source-list.d.ts +12 -0
  10. package/dist/angular/ds-agent-source-list.js +38 -0
  11. package/dist/angular/ds-agent-tool-call.d.ts +12 -0
  12. package/dist/angular/ds-agent-tool-call.js +38 -0
  13. package/dist/angular/ds-attachment-list.d.ts +12 -0
  14. package/dist/angular/ds-attachment-list.js +38 -0
  15. package/dist/angular/ds-avatar.d.ts +12 -0
  16. package/dist/angular/ds-avatar.js +38 -0
  17. package/dist/angular/ds-code-block.d.ts +12 -0
  18. package/dist/angular/ds-code-block.js +38 -0
  19. package/dist/angular/ds-conversation-list-item.d.ts +19 -0
  20. package/dist/angular/ds-conversation-list-item.js +42 -0
  21. package/dist/angular/ds-conversation-list-section.d.ts +12 -0
  22. package/dist/angular/ds-conversation-list-section.js +38 -0
  23. package/dist/angular/ds-conversation-list.d.ts +12 -0
  24. package/dist/angular/ds-conversation-list.js +37 -0
  25. package/dist/angular/ds-markdown.d.ts +12 -0
  26. package/dist/angular/ds-markdown.js +38 -0
  27. package/dist/angular/ds-menu.d.ts +6 -1
  28. package/dist/angular/ds-menu.js +7 -4
  29. package/dist/angular/ds-message-bubble.d.ts +12 -0
  30. package/dist/angular/ds-message-bubble.js +38 -0
  31. package/dist/angular/ds-message-composer.d.ts +23 -0
  32. package/dist/angular/ds-message-composer.js +49 -0
  33. package/dist/angular/ds-message-scroller.d.ts +15 -0
  34. package/dist/angular/ds-message-scroller.js +43 -0
  35. package/dist/angular/ds-message.d.ts +12 -0
  36. package/dist/angular/ds-message.js +38 -0
  37. package/dist/angular/ds-panel-nav.d.ts +1 -1
  38. package/dist/angular/ds-panel-nav.js +3 -3
  39. package/dist/angular/ds-panel-tool-header.d.ts +25 -0
  40. package/dist/angular/ds-panel-tool-header.js +49 -0
  41. package/dist/angular/ds-panel-tool-search.d.ts +19 -0
  42. package/dist/angular/ds-panel-tool-search.js +49 -0
  43. package/dist/angular/ds-panel-tools.d.ts +30 -1
  44. package/dist/angular/ds-panel-tools.js +14 -5
  45. package/dist/angular/index.d.ts +1 -1
  46. package/dist/angular/index.js +17 -0
  47. package/dist/angular/proxies.d.ts +17 -0
  48. package/dist/angular/proxies.js +17 -0
  49. package/dist/components/ds-agent-activity.d.ts +11 -0
  50. package/dist/components/ds-agent-activity.js +2 -0
  51. package/dist/components/ds-agent-activity.js.map +1 -0
  52. package/dist/components/ds-agent-response.d.ts +11 -0
  53. package/dist/components/ds-agent-response.js +2 -0
  54. package/dist/components/ds-agent-response.js.map +1 -0
  55. package/dist/components/ds-agent-source-list.d.ts +11 -0
  56. package/dist/components/ds-agent-source-list.js +2 -0
  57. package/dist/components/ds-agent-source-list.js.map +1 -0
  58. package/dist/components/ds-agent-tool-call.d.ts +11 -0
  59. package/dist/components/ds-agent-tool-call.js +2 -0
  60. package/dist/components/ds-agent-tool-call.js.map +1 -0
  61. package/dist/components/ds-app-shell.js +1 -1
  62. package/dist/components/ds-app-shell.js.map +1 -1
  63. package/dist/components/ds-attachment-list.d.ts +11 -0
  64. package/dist/components/ds-attachment-list.js +2 -0
  65. package/dist/components/ds-attachment-list.js.map +1 -0
  66. package/dist/components/ds-avatar.d.ts +11 -0
  67. package/dist/components/ds-avatar.js +2 -0
  68. package/dist/components/ds-avatar.js.map +1 -0
  69. package/dist/components/ds-badge.js +1 -1
  70. package/dist/components/ds-banner.js +1 -1
  71. package/dist/components/ds-bar-nav.js +1 -1
  72. package/dist/components/ds-bar-nav.js.map +1 -1
  73. package/dist/components/ds-button-filled.js +1 -1
  74. package/dist/components/ds-button-unfilled.js +1 -1
  75. package/dist/components/ds-card-data-viz-donut.js +1 -1
  76. package/dist/components/ds-card-setting.js +1 -1
  77. package/dist/components/ds-card-shell-data-viz.js +1 -1
  78. package/dist/components/ds-card.js +1 -1
  79. package/dist/components/ds-chart-bar.js +1 -1
  80. package/dist/components/ds-chart-bar.js.map +1 -1
  81. package/dist/components/ds-chart-donut.js +1 -1
  82. package/dist/components/ds-chart-legend.js +1 -1
  83. package/dist/components/ds-chart-line.js +1 -1
  84. package/dist/components/ds-checkbox.js +1 -1
  85. package/dist/components/ds-chip.js +1 -1
  86. package/dist/components/ds-code-block.d.ts +11 -0
  87. package/dist/components/ds-code-block.js +2 -0
  88. package/dist/components/ds-code-block.js.map +1 -0
  89. package/dist/components/ds-conversation-list-item.d.ts +11 -0
  90. package/dist/components/ds-conversation-list-item.js +2 -0
  91. package/dist/components/ds-conversation-list-item.js.map +1 -0
  92. package/dist/components/ds-conversation-list-section.d.ts +11 -0
  93. package/dist/components/ds-conversation-list-section.js +2 -0
  94. package/dist/components/ds-conversation-list-section.js.map +1 -0
  95. package/dist/components/ds-conversation-list.d.ts +11 -0
  96. package/dist/components/ds-conversation-list.js +2 -0
  97. package/dist/components/ds-conversation-list.js.map +1 -0
  98. package/dist/components/ds-divider.js +1 -1
  99. package/dist/components/ds-divider.js.map +1 -1
  100. package/dist/components/ds-empty-state.js +1 -1
  101. package/dist/components/ds-field.js +1 -1
  102. package/dist/components/ds-icon.js +1 -1
  103. package/dist/components/ds-input.js +1 -1
  104. package/dist/components/ds-markdown.d.ts +11 -0
  105. package/dist/components/ds-markdown.js +2 -0
  106. package/dist/components/ds-markdown.js.map +1 -0
  107. package/dist/components/ds-menu.js +1 -1
  108. package/dist/components/ds-message-bubble.d.ts +11 -0
  109. package/dist/components/ds-message-bubble.js +2 -0
  110. package/dist/components/ds-message-bubble.js.map +1 -0
  111. package/dist/components/ds-message-composer.d.ts +11 -0
  112. package/dist/components/ds-message-composer.js +2 -0
  113. package/dist/components/ds-message-composer.js.map +1 -0
  114. package/dist/components/ds-message-scroller.d.ts +11 -0
  115. package/dist/components/ds-message-scroller.js +2 -0
  116. package/dist/components/ds-message-scroller.js.map +1 -0
  117. package/dist/components/ds-message.d.ts +11 -0
  118. package/dist/components/ds-message.js +2 -0
  119. package/dist/components/ds-message.js.map +1 -0
  120. package/dist/components/ds-modal.js +1 -1
  121. package/dist/components/ds-panel-nav.js +1 -1
  122. package/dist/components/ds-panel-nav.js.map +1 -1
  123. package/dist/components/ds-panel-sub-nav.js +1 -1
  124. package/dist/components/ds-panel-tool-header.d.ts +11 -0
  125. package/dist/components/ds-panel-tool-header.js +2 -0
  126. package/dist/components/ds-panel-tool-header.js.map +1 -0
  127. package/dist/components/ds-panel-tool-search.d.ts +11 -0
  128. package/dist/components/ds-panel-tool-search.js +2 -0
  129. package/dist/components/ds-panel-tool-search.js.map +1 -0
  130. package/dist/components/ds-panel-tools.js +1 -1
  131. package/dist/components/ds-panel-tools.js.map +1 -1
  132. package/dist/components/ds-radio.js +1 -1
  133. package/dist/components/ds-select-multi.js +1 -1
  134. package/dist/components/ds-select-multi.js.map +1 -1
  135. package/dist/components/ds-select.js +1 -1
  136. package/dist/components/ds-select.js.map +1 -1
  137. package/dist/components/ds-shell-gradient-picker.js +1 -1
  138. package/dist/components/ds-shell-gradient-picker.js.map +1 -1
  139. package/dist/components/ds-shell-gradient-swatch.js +1 -1
  140. package/dist/components/ds-skeleton.js +1 -1
  141. package/dist/components/ds-slider.js +1 -1
  142. package/dist/components/ds-slider.js.map +1 -1
  143. package/dist/components/ds-swatch-picker.js +1 -1
  144. package/dist/components/ds-switch.js +1 -1
  145. package/dist/components/ds-tab-group.js +1 -1
  146. package/dist/components/ds-tab-group.js.map +1 -1
  147. package/dist/components/ds-tag.js +1 -1
  148. package/dist/components/ds-tag.js.map +1 -1
  149. package/dist/components/ds-text.js +1 -1
  150. package/dist/components/ds-tooltip-data-viz.js +1 -1
  151. package/dist/components/ds-tooltip.js +1 -1
  152. package/dist/components/index.d.ts +14 -0
  153. package/dist/components/{p-HBIxvS5C.js → p-B1pWGQn1.js} +2 -2
  154. package/dist/components/p-BBu_Svz7.js +2 -0
  155. package/dist/components/p-BBu_Svz7.js.map +1 -0
  156. package/dist/components/p-BHpWYKtP.js +2 -0
  157. package/dist/components/p-BHpWYKtP.js.map +1 -0
  158. package/dist/components/{p-KRGBGTu5.js → p-BO6C8abO.js} +2 -2
  159. package/dist/components/p-BRfOCc_h.js +2 -0
  160. package/dist/components/p-BRfOCc_h.js.map +1 -0
  161. package/dist/components/{p-CbS_WWs2.js → p-BSOZXagj.js} +2 -2
  162. package/dist/components/p-BSOZXagj.js.map +1 -0
  163. package/dist/components/p-BhC1YyId.js +2 -0
  164. package/dist/components/p-BhC1YyId.js.map +1 -0
  165. package/dist/components/p-BjtXYFhw.js +2 -0
  166. package/dist/components/p-BjtXYFhw.js.map +1 -0
  167. package/dist/components/p-CBYuvZKM.js +2 -0
  168. package/dist/components/p-CBYuvZKM.js.map +1 -0
  169. package/dist/components/{p-CZ9wemOA.js → p-CJlgONwR.js} +2 -2
  170. package/dist/components/p-CKaJx0IX.js +2 -0
  171. package/dist/components/p-CKaJx0IX.js.map +1 -0
  172. package/dist/components/p-CWNdl52Y.js +2 -0
  173. package/dist/components/p-CWNdl52Y.js.map +1 -0
  174. package/dist/components/{p-DT2MK8Kt.js → p-CblAABEo.js} +2 -2
  175. package/dist/components/p-CeFBA7Dx.js +2 -0
  176. package/dist/components/p-CeFBA7Dx.js.map +1 -0
  177. package/dist/components/p-CiKGqsA2.js +2 -0
  178. package/dist/components/{p-BLzivrE3.js.map → p-CiKGqsA2.js.map} +1 -1
  179. package/dist/components/p-Ci_nVk5P.js +2 -0
  180. package/dist/components/p-Ci_nVk5P.js.map +1 -0
  181. package/dist/components/p-Cijzn3YQ.js +2 -0
  182. package/dist/components/p-Cijzn3YQ.js.map +1 -0
  183. package/dist/components/{p-BbV68F23.js → p-CiwdnKKp.js} +2 -2
  184. package/dist/components/p-DFxqk71w.js +2 -0
  185. package/dist/components/p-DFxqk71w.js.map +1 -0
  186. package/dist/components/p-DVsje4AY.js +2 -0
  187. package/dist/components/p-DVsje4AY.js.map +1 -0
  188. package/dist/components/p-DaQ0ZE_V.js +2 -0
  189. package/dist/components/p-DaQ0ZE_V.js.map +1 -0
  190. package/dist/components/p-DiooIO2B.js +2 -0
  191. package/dist/components/p-DiooIO2B.js.map +1 -0
  192. package/dist/components/p-Dj5MejHv.js +2 -0
  193. package/dist/components/p-Dj5MejHv.js.map +1 -0
  194. package/dist/components/{p-B-zhgAvL.js → p-DnMCRAwx.js} +2 -2
  195. package/dist/components/{p-DyZj3k9S.js → p-Dst-OliP.js} +2 -2
  196. package/dist/components/p-Dst-OliP.js.map +1 -0
  197. package/dist/components/p-T0Mzhv3-.js +2 -0
  198. package/dist/components/p-T0Mzhv3-.js.map +1 -0
  199. package/dist/components/p-a9nGf1s6.js +2 -0
  200. package/dist/components/p-a9nGf1s6.js.map +1 -0
  201. package/dist/components/p-gidVv1FX.js +2 -0
  202. package/dist/components/p-gidVv1FX.js.map +1 -0
  203. package/dist/components/p-kezp2_Xu.js +2 -0
  204. package/dist/components/p-kezp2_Xu.js.map +1 -0
  205. package/dist/components/p-rEe-3KR_.js +2 -0
  206. package/dist/components/p-rEe-3KR_.js.map +1 -0
  207. package/dist/components/{p-C7RObioO.js → p-xB0GPG3-.js} +2 -2
  208. package/dist/docs/components.json +8294 -4079
  209. package/dist/lib/components/Menu/menu-placement.d.ts +13 -0
  210. package/dist/lib/shell/index.d.ts +1 -1
  211. package/dist/lib/shell/index.js +8 -0
  212. package/dist/lib/shell/index.js.map +2 -2
  213. package/dist/mcp-data/registry/agent-activity.json +158 -0
  214. package/dist/mcp-data/registry/agent-response.json +211 -0
  215. package/dist/mcp-data/registry/agent-source-list.json +153 -0
  216. package/dist/mcp-data/registry/agent-tool-call.json +213 -0
  217. package/dist/mcp-data/registry/app-shell.json +2 -2
  218. package/dist/mcp-data/registry/attachment-list.json +137 -0
  219. package/dist/mcp-data/registry/avatar.json +154 -0
  220. package/dist/mcp-data/registry/bar-nav.json +2 -2
  221. package/dist/mcp-data/registry/button-unfilled.json +2 -2
  222. package/dist/mcp-data/registry/code-block.json +150 -0
  223. package/dist/mcp-data/registry/conversation-list-item.json +283 -0
  224. package/dist/mcp-data/registry/conversation-list-section.json +139 -0
  225. package/dist/mcp-data/registry/conversation-list.json +101 -0
  226. package/dist/mcp-data/registry/markdown.json +141 -0
  227. package/dist/mcp-data/registry/menu.json +43 -7
  228. package/dist/mcp-data/registry/message-bubble.json +119 -0
  229. package/dist/mcp-data/registry/message-composer.json +265 -0
  230. package/dist/mcp-data/registry/message-scroller.json +217 -0
  231. package/dist/mcp-data/registry/message.json +255 -0
  232. package/dist/mcp-data/registry/panel-nav.json +20 -2
  233. package/dist/mcp-data/registry/panel-tool-header.json +342 -0
  234. package/dist/mcp-data/registry/panel-tool-search.json +387 -0
  235. package/dist/mcp-data/registry/panel-tools.json +150 -10
  236. package/dist/mcp-data/registry/registry.json +2159 -616
  237. package/dist/mcp-data/registry/select.json +1 -1
  238. package/dist/mcp-data/registry/slider.json +4 -4
  239. package/dist/mcp-data/registry/switch.json +1 -1
  240. package/dist/mcp-data/registry/tab-group.json +2 -2
  241. package/dist/mcp-data/registry/tag.json +2 -2
  242. package/dist/mcp-data/registry/text.json +1 -1
  243. package/dist/react/components.d.ts +17 -0
  244. package/dist/react/components.js +17 -0
  245. package/dist/react/ds-agent-activity.d.ts +9 -0
  246. package/dist/react/ds-agent-activity.js +12 -0
  247. package/dist/react/ds-agent-response.d.ts +9 -0
  248. package/dist/react/ds-agent-response.js +12 -0
  249. package/dist/react/ds-agent-source-list.d.ts +9 -0
  250. package/dist/react/ds-agent-source-list.js +12 -0
  251. package/dist/react/ds-agent-tool-call.d.ts +9 -0
  252. package/dist/react/ds-agent-tool-call.js +12 -0
  253. package/dist/react/ds-attachment-list.d.ts +9 -0
  254. package/dist/react/ds-attachment-list.js +12 -0
  255. package/dist/react/ds-avatar.d.ts +9 -0
  256. package/dist/react/ds-avatar.js +12 -0
  257. package/dist/react/ds-code-block.d.ts +9 -0
  258. package/dist/react/ds-code-block.js +12 -0
  259. package/dist/react/ds-conversation-list-item.d.ts +14 -0
  260. package/dist/react/ds-conversation-list-item.js +12 -0
  261. package/dist/react/ds-conversation-list-section.d.ts +9 -0
  262. package/dist/react/ds-conversation-list-section.js +12 -0
  263. package/dist/react/ds-conversation-list.d.ts +9 -0
  264. package/dist/react/ds-conversation-list.js +12 -0
  265. package/dist/react/ds-markdown.d.ts +9 -0
  266. package/dist/react/ds-markdown.js +12 -0
  267. package/dist/react/ds-menu.d.ts +1 -0
  268. package/dist/react/ds-menu.js +1 -0
  269. package/dist/react/ds-message-bubble.d.ts +9 -0
  270. package/dist/react/ds-message-bubble.js +12 -0
  271. package/dist/react/ds-message-composer.d.ts +16 -0
  272. package/dist/react/ds-message-composer.js +16 -0
  273. package/dist/react/ds-message-scroller.d.ts +12 -0
  274. package/dist/react/ds-message-scroller.js +12 -0
  275. package/dist/react/ds-message.d.ts +9 -0
  276. package/dist/react/ds-message.js +12 -0
  277. package/dist/react/ds-panel-tool-header.d.ts +17 -0
  278. package/dist/react/ds-panel-tool-header.js +16 -0
  279. package/dist/react/ds-panel-tool-search.d.ts +14 -0
  280. package/dist/react/ds-panel-tool-search.js +16 -0
  281. package/dist/react/ds-panel-tools.d.ts +10 -0
  282. package/dist/react/ds-panel-tools.js +3 -0
  283. package/dist/types/components/AgentActivity/AgentActivity.d.ts +14 -0
  284. package/dist/types/components/AgentResponse/AgentResponse.d.ts +12 -0
  285. package/dist/types/components/AgentSourceList/AgentSourceList.d.ts +9 -0
  286. package/dist/types/components/AgentToolCall/AgentToolCall.d.ts +13 -0
  287. package/dist/types/components/AppShell/AppShell.d.ts +4 -0
  288. package/dist/types/components/AttachmentList/AttachmentList.d.ts +8 -0
  289. package/dist/types/components/Avatar/Avatar.d.ts +11 -0
  290. package/dist/types/components/BarNav/BarNav.d.ts +2 -0
  291. package/dist/types/components/ButtonUnfilled/ButtonUnfilled.d.ts +2 -0
  292. package/dist/types/components/CodeBlock/CodeBlock.d.ts +11 -0
  293. package/dist/types/components/ConversationList/ConversationList.d.ts +4 -0
  294. package/dist/types/components/ConversationListItem/ConversationListItem.d.ts +24 -0
  295. package/dist/types/components/ConversationListSection/ConversationListSection.d.ts +9 -0
  296. package/dist/types/components/Markdown/Markdown.d.ts +15 -0
  297. package/dist/types/components/Menu/Menu.d.ts +9 -0
  298. package/dist/types/components/Menu/menu-placement.d.ts +13 -0
  299. package/dist/types/components/Menu/menu-types.d.ts +1 -1
  300. package/dist/types/components/Message/Message.d.ts +17 -0
  301. package/dist/types/components/MessageBubble/MessageBubble.d.ts +6 -0
  302. package/dist/types/components/MessageComposer/MessageComposer.d.ts +29 -0
  303. package/dist/types/components/MessageScroller/MessageScroller.d.ts +41 -0
  304. package/dist/types/components/PanelNav/PanelNav.d.ts +5 -0
  305. package/dist/types/components/PanelToolHeader/PanelToolHeader.d.ts +34 -0
  306. package/dist/types/components/PanelToolSearch/PanelToolSearch.d.ts +35 -0
  307. package/dist/types/components/PanelTools/PanelTools.d.ts +40 -1
  308. package/dist/types/components/PanelTools/panel-tools-types.d.ts +20 -0
  309. package/dist/types/components/PanelTools/panel-tools-utils.d.ts +2 -0
  310. package/dist/types/components/Slider/Slider.d.ts +1 -1
  311. package/dist/types/components/conversation-types.d.ts +55 -0
  312. package/dist/types/components.d.ts +1229 -14
  313. package/dist/types/shell/index.d.ts +1 -1
  314. package/dist/types/utils/choice-list-parts.d.ts +4 -1
  315. package/package.json +11 -11
  316. package/dist/components/p-BLzivrE3.js +0 -2
  317. package/dist/components/p-C7UFYvsO.js +0 -2
  318. package/dist/components/p-C7UFYvsO.js.map +0 -1
  319. package/dist/components/p-CXF8yd-g.js +0 -2
  320. package/dist/components/p-CXF8yd-g.js.map +0 -1
  321. package/dist/components/p-CbS_WWs2.js.map +0 -1
  322. package/dist/components/p-DyZj3k9S.js.map +0 -1
  323. package/dist/components/p-VKIsOVza.js +0 -2
  324. package/dist/components/p-VKIsOVza.js.map +0 -1
  325. package/dist/components/p-tQ1QHeOE.js +0 -2
  326. package/dist/components/p-tQ1QHeOE.js.map +0 -1
  327. /package/dist/components/{p-HBIxvS5C.js.map → p-B1pWGQn1.js.map} +0 -0
  328. /package/dist/components/{p-KRGBGTu5.js.map → p-BO6C8abO.js.map} +0 -0
  329. /package/dist/components/{p-CZ9wemOA.js.map → p-CJlgONwR.js.map} +0 -0
  330. /package/dist/components/{p-DT2MK8Kt.js.map → p-CblAABEo.js.map} +0 -0
  331. /package/dist/components/{p-BbV68F23.js.map → p-CiwdnKKp.js.map} +0 -0
  332. /package/dist/components/{p-B-zhgAvL.js.map → p-DnMCRAwx.js.map} +0 -0
  333. /package/dist/components/{p-C7RObioO.js.map → p-xB0GPG3-.js.map} +0 -0
package/dist/agent.json CHANGED
@@ -1,9 +1,340 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
3
  "package": "@ds-mo/ui",
4
- "packageVersion": "9.1.0",
4
+ "packageVersion": "9.2.1",
5
5
  "kind": "components",
6
6
  "entries": [
7
+ {
8
+ "id": "component:ds-agent-activity",
9
+ "tag": "ds-agent-activity",
10
+ "name": "agent-activity",
11
+ "title": "AgentActivity",
12
+ "summary": "Collapsible, user-safe summary of agent work steps without private reasoning.",
13
+ "intentStatus": "complete",
14
+ "intent": {
15
+ "audience": "specialized",
16
+ "status": "experimental",
17
+ "summary": "Collapsible, user-safe summary of agent work steps without private reasoning.",
18
+ "useWhen": [
19
+ "An agent response benefits from concise progress or completion summaries."
20
+ ],
21
+ "avoidWhen": [
22
+ "The content would reveal private chain-of-thought, hidden prompts, secrets, or raw internal traces."
23
+ ],
24
+ "commonlyComposedWith": [
25
+ "component:ds-agent-response",
26
+ "component:ds-loader"
27
+ ],
28
+ "patterns": [
29
+ "pattern:agent-chat"
30
+ ],
31
+ "accessibility": [
32
+ "Each step has textual state and description; animation and color are supplementary.",
33
+ "The disclosure uses native keyboard and expanded-state semantics."
34
+ ],
35
+ "states": [
36
+ "While collapsed, the summary follows the current user-safe activity and shimmers only while active; while expanded, the heading becomes Activity and the ordered list exposes every step.",
37
+ "Pending, active, complete, and error describe user-safe workflow progress."
38
+ ],
39
+ "responsiveBehavior": [
40
+ "Steps wrap within the response width."
41
+ ],
42
+ "references": [
43
+ {
44
+ "label": "Storybook examples",
45
+ "path": "src/wc/components/MessageScroller/MessageScroller.stories.ts"
46
+ }
47
+ ]
48
+ },
49
+ "api": {
50
+ "props": {
51
+ "heading": {
52
+ "type": "string",
53
+ "required": false
54
+ },
55
+ "items": {
56
+ "type": "AgentActivityItem[]",
57
+ "required": false
58
+ },
59
+ "open": {
60
+ "type": "boolean",
61
+ "required": false
62
+ }
63
+ },
64
+ "events": [],
65
+ "slots": []
66
+ },
67
+ "exports": {
68
+ "customElement": "ds-agent-activity",
69
+ "react": "DsAgentActivity",
70
+ "angular": "DsAgentActivity"
71
+ },
72
+ "dependencies": [
73
+ "@ds-mo/ui",
74
+ "@ds-mo/tokens",
75
+ "@ds-mo/icons"
76
+ ],
77
+ "componentDependencies": [
78
+ "icon",
79
+ "loader",
80
+ "text"
81
+ ]
82
+ },
83
+ {
84
+ "id": "component:ds-agent-response",
85
+ "tag": "ds-agent-response",
86
+ "name": "agent-response",
87
+ "title": "AgentResponse",
88
+ "summary": "Ordered renderer for normalized immutable agent response parts inside a generic incoming message.",
89
+ "intentStatus": "complete",
90
+ "intent": {
91
+ "audience": "specialized",
92
+ "status": "experimental",
93
+ "summary": "Ordered renderer for normalized immutable agent response parts inside a generic incoming message.",
94
+ "useWhen": [
95
+ "An agent response combines Markdown, user-safe activity, display-only tools, attachments, and sources in authored order."
96
+ ],
97
+ "avoidWhen": [
98
+ "The component would be expected to own a model, transport, persistence, title generation, approval policy, or private reasoning."
99
+ ],
100
+ "commonlyComposedWith": [
101
+ "component:ds-message",
102
+ "component:ds-markdown",
103
+ "component:ds-agent-activity",
104
+ "component:ds-agent-tool-call",
105
+ "component:ds-agent-source-list"
106
+ ],
107
+ "patterns": [
108
+ "pattern:agent-chat"
109
+ ],
110
+ "accessibility": [
111
+ "Part order matches authored reading order and remains inside generic message semantics.",
112
+ "Streaming state supplements rather than replaces meaningful textual status."
113
+ ],
114
+ "states": [
115
+ "The owner replaces immutable part arrays as scripted or live output changes."
116
+ ],
117
+ "responsiveBehavior": [
118
+ "Rich content uses the wider ghost message treatment while respecting transcript constraints."
119
+ ],
120
+ "references": [
121
+ {
122
+ "label": "Storybook examples",
123
+ "path": "src/wc/components/MessageScroller/MessageScroller.stories.ts"
124
+ }
125
+ ]
126
+ },
127
+ "api": {
128
+ "props": {
129
+ "author": {
130
+ "type": "string",
131
+ "required": false
132
+ },
133
+ "messageId": {
134
+ "type": "string",
135
+ "required": false
136
+ },
137
+ "parts": {
138
+ "type": "AgentResponsePart[]",
139
+ "required": false
140
+ },
141
+ "showAuthor": {
142
+ "type": "boolean",
143
+ "required": false
144
+ },
145
+ "streaming": {
146
+ "type": "boolean",
147
+ "required": false
148
+ },
149
+ "timestamp": {
150
+ "type": "string",
151
+ "required": false
152
+ }
153
+ },
154
+ "events": [],
155
+ "slots": []
156
+ },
157
+ "exports": {
158
+ "customElement": "ds-agent-response",
159
+ "react": "DsAgentResponse",
160
+ "angular": "DsAgentResponse"
161
+ },
162
+ "dependencies": [
163
+ "@ds-mo/ui",
164
+ "@ds-mo/tokens"
165
+ ],
166
+ "componentDependencies": [
167
+ "agent-activity",
168
+ "agent-source-list",
169
+ "agent-tool-call",
170
+ "attachment-list",
171
+ "markdown",
172
+ "message",
173
+ "message-bubble"
174
+ ]
175
+ },
176
+ {
177
+ "id": "component:ds-agent-source-list",
178
+ "tag": "ds-agent-source-list",
179
+ "name": "agent-source-list",
180
+ "title": "AgentSourceList",
181
+ "summary": "Collapsible list of agent response sources with title, description, and validated external links.",
182
+ "intentStatus": "complete",
183
+ "intent": {
184
+ "audience": "specialized",
185
+ "status": "experimental",
186
+ "summary": "Collapsible list of agent response sources with title, description, and validated external links.",
187
+ "useWhen": [
188
+ "An agent response cites external material readers may inspect."
189
+ ],
190
+ "avoidWhen": [
191
+ "The links are ordinary body links or are not sources for the response."
192
+ ],
193
+ "commonlyComposedWith": [
194
+ "component:ds-agent-response",
195
+ "component:ds-markdown"
196
+ ],
197
+ "patterns": [
198
+ "pattern:agent-chat"
199
+ ],
200
+ "accessibility": [
201
+ "Each source uses descriptive linked text and visible supporting context.",
202
+ "Unsafe link schemes remain non-interactive text."
203
+ ],
204
+ "responsiveBehavior": [
205
+ "Source titles and descriptions wrap within the response width."
206
+ ],
207
+ "references": [
208
+ {
209
+ "label": "Storybook examples",
210
+ "path": "src/wc/components/MessageScroller/MessageScroller.stories.ts"
211
+ }
212
+ ]
213
+ },
214
+ "api": {
215
+ "props": {
216
+ "heading": {
217
+ "type": "string",
218
+ "required": false
219
+ },
220
+ "items": {
221
+ "type": "AgentSource[]",
222
+ "required": false
223
+ },
224
+ "open": {
225
+ "type": "boolean",
226
+ "required": false
227
+ }
228
+ },
229
+ "events": [],
230
+ "slots": []
231
+ },
232
+ "exports": {
233
+ "customElement": "ds-agent-source-list",
234
+ "react": "DsAgentSourceList",
235
+ "angular": "DsAgentSourceList"
236
+ },
237
+ "dependencies": [
238
+ "@ds-mo/ui",
239
+ "@ds-mo/tokens",
240
+ "@ds-mo/icons"
241
+ ],
242
+ "componentDependencies": [
243
+ "icon",
244
+ "text"
245
+ ]
246
+ },
247
+ {
248
+ "id": "component:ds-agent-tool-call",
249
+ "tag": "ds-agent-tool-call",
250
+ "name": "agent-tool-call",
251
+ "title": "AgentToolCall",
252
+ "summary": "Display-only disclosure for an agent tool call, its safe input or output, and execution status.",
253
+ "intentStatus": "complete",
254
+ "intent": {
255
+ "audience": "specialized",
256
+ "status": "experimental",
257
+ "summary": "Display-only disclosure for an agent tool call, its safe input or output, and execution status.",
258
+ "useWhen": [
259
+ "A prototype or agent product needs to expose user-safe tool execution detail."
260
+ ],
261
+ "avoidWhen": [
262
+ "A participant must approve, deny, edit, or retry the tool call; those are product controls outside this component."
263
+ ],
264
+ "commonlyComposedWith": [
265
+ "component:ds-agent-response",
266
+ "component:ds-code-block"
267
+ ],
268
+ "patterns": [
269
+ "pattern:agent-chat"
270
+ ],
271
+ "accessibility": [
272
+ "Queued, running, success, error, and denied states are available as text.",
273
+ "The disclosure uses native keyboard and expanded-state semantics."
274
+ ],
275
+ "states": [
276
+ "This component presents state but never executes a tool or owns approval policy."
277
+ ],
278
+ "responsiveBehavior": [
279
+ "Structured detail wraps and scrolls without widening the transcript."
280
+ ],
281
+ "references": [
282
+ {
283
+ "label": "Storybook examples",
284
+ "path": "src/wc/components/MessageScroller/MessageScroller.stories.ts"
285
+ }
286
+ ]
287
+ },
288
+ "api": {
289
+ "props": {
290
+ "error": {
291
+ "type": "string",
292
+ "required": false
293
+ },
294
+ "input": {
295
+ "type": "unknown",
296
+ "required": false
297
+ },
298
+ "label": {
299
+ "type": "string",
300
+ "required": false
301
+ },
302
+ "name": {
303
+ "type": "string",
304
+ "required": false
305
+ },
306
+ "open": {
307
+ "type": "boolean",
308
+ "required": false
309
+ },
310
+ "output": {
311
+ "type": "unknown",
312
+ "required": false
313
+ },
314
+ "state": {
315
+ "type": "AgentToolState",
316
+ "required": false
317
+ }
318
+ },
319
+ "events": [],
320
+ "slots": []
321
+ },
322
+ "exports": {
323
+ "customElement": "ds-agent-tool-call",
324
+ "react": "DsAgentToolCall",
325
+ "angular": "DsAgentToolCall"
326
+ },
327
+ "dependencies": [
328
+ "@ds-mo/ui",
329
+ "@ds-mo/tokens",
330
+ "@ds-mo/icons"
331
+ ],
332
+ "componentDependencies": [
333
+ "icon",
334
+ "loader",
335
+ "text"
336
+ ]
337
+ },
7
338
  {
8
339
  "id": "component:ds-app-shell",
9
340
  "tag": "ds-app-shell",
@@ -126,36 +457,170 @@
126
457
  "componentDependencies": []
127
458
  },
128
459
  {
129
- "id": "component:ds-badge",
130
- "tag": "ds-badge",
131
- "name": "badge",
132
- "title": "Badge",
133
- "summary": "Non-interactive brand counter or dot that supplements an owning control or label with unread notification information.",
460
+ "id": "component:ds-attachment-list",
461
+ "tag": "ds-attachment-list",
462
+ "name": "attachment-list",
463
+ "title": "AttachmentList",
464
+ "summary": "Channel-neutral list of message attachments with name, media type, size, and optional safe link.",
134
465
  "intentStatus": "complete",
135
466
  "intent": {
136
467
  "audience": "general",
137
- "status": "stable",
138
- "summary": "Non-interactive brand counter or dot that supplements an owning control or label with unread notification information.",
468
+ "status": "experimental",
469
+ "summary": "Channel-neutral list of message attachments with name, media type, size, and optional safe link.",
139
470
  "useWhen": [
140
- "An existing control, navigation item, or label needs a compact unread notification count.",
141
- "An owning element needs a small visual dot indicating that supplemental notification information exists.",
142
- "When the badge overlaps an icon or content, the immediate backing surface can be identified so its separation ring matches."
471
+ "A conversation message needs to display already-known attachment metadata."
143
472
  ],
144
473
  "avoidWhen": [
145
- "The status must stand alone without an owning label or control.",
146
- "The mark needs semantic positive, caution, negative, or neutral color; Badge intentionally uses one brand treatment.",
147
- "The compact content is metadata or taxonomy; use Tag or Chip according to whether it is removable.",
148
- "The badge itself would receive pointer or keyboard interaction; put interaction on the owning control."
474
+ "Users need to choose, upload, remove, or edit files; those controls belong to the product workflow."
149
475
  ],
150
- "alternatives": [
151
- {
152
- "when": "A compact static label communicates taxonomy or a semantic status.",
153
- "component": "component:ds-tag",
154
- "reason": "Tag owns static metadata labels and semantic intent coloring."
155
- },
156
- {
157
- "when": "A metadata value must be individually removable.",
158
- "component": "component:ds-chip",
476
+ "commonlyComposedWith": [
477
+ "component:ds-message",
478
+ "component:ds-message-bubble"
479
+ ],
480
+ "patterns": [
481
+ "pattern:conversation"
482
+ ],
483
+ "accessibility": [
484
+ "Attachment name remains visible and is the link text when a safe URL is available.",
485
+ "Media type and size are supporting metadata, never the only identifier."
486
+ ],
487
+ "responsiveBehavior": [
488
+ "Long names wrap or truncate without overflowing the message surface."
489
+ ],
490
+ "references": [
491
+ {
492
+ "label": "Storybook examples",
493
+ "path": "src/wc/components/MessageScroller/MessageScroller.stories.ts"
494
+ }
495
+ ]
496
+ },
497
+ "api": {
498
+ "props": {
499
+ "items": {
500
+ "type": "ConversationAttachment[]",
501
+ "required": false
502
+ },
503
+ "label": {
504
+ "type": "string",
505
+ "required": false
506
+ }
507
+ },
508
+ "events": [],
509
+ "slots": []
510
+ },
511
+ "exports": {
512
+ "customElement": "ds-attachment-list",
513
+ "react": "DsAttachmentList",
514
+ "angular": "DsAttachmentList"
515
+ },
516
+ "dependencies": [
517
+ "@ds-mo/ui",
518
+ "@ds-mo/tokens",
519
+ "@ds-mo/icons"
520
+ ],
521
+ "componentDependencies": [
522
+ "icon",
523
+ "text"
524
+ ]
525
+ },
526
+ {
527
+ "id": "component:ds-avatar",
528
+ "tag": "ds-avatar",
529
+ "name": "avatar",
530
+ "title": "Avatar",
531
+ "summary": "Compact icon avatar for visually identifying a person, group, channel, or conversation type.",
532
+ "intentStatus": "complete",
533
+ "intent": {
534
+ "audience": "general",
535
+ "status": "experimental",
536
+ "summary": "Compact icon avatar for visually identifying a person, group, channel, or conversation type.",
537
+ "useWhen": [
538
+ "A list or message composition needs a consistent 32px circular identity marker represented by an icon."
539
+ ],
540
+ "avoidWhen": [
541
+ "The identity has a supplied photograph, initials, presence state, or editable profile behavior; those variants are not part of this primitive."
542
+ ],
543
+ "commonlyComposedWith": [
544
+ "component:ds-conversation-list-item",
545
+ "component:ds-message"
546
+ ],
547
+ "accessibility": [
548
+ "Provide label only when the icon communicates meaning that surrounding text does not already convey.",
549
+ "Omit label when the owning row or message already provides an equivalent accessible name."
550
+ ],
551
+ "responsiveBehavior": [
552
+ "The avatar keeps its fixed 32px circle and 20px icon at every viewport size."
553
+ ],
554
+ "references": [
555
+ {
556
+ "label": "Storybook examples",
557
+ "path": "src/wc/components/Avatar/Avatar.stories.ts"
558
+ }
559
+ ]
560
+ },
561
+ "api": {
562
+ "props": {
563
+ "icon": {
564
+ "type": "string",
565
+ "required": false
566
+ },
567
+ "iconColor": {
568
+ "type": "IconColor",
569
+ "required": false
570
+ },
571
+ "label": {
572
+ "type": "string | undefined",
573
+ "required": false
574
+ }
575
+ },
576
+ "events": [],
577
+ "slots": []
578
+ },
579
+ "exports": {
580
+ "customElement": "ds-avatar",
581
+ "react": "DsAvatar",
582
+ "angular": "DsAvatar"
583
+ },
584
+ "dependencies": [
585
+ "@ds-mo/ui",
586
+ "@ds-mo/tokens",
587
+ "@ds-mo/icons"
588
+ ],
589
+ "componentDependencies": [
590
+ "icon"
591
+ ]
592
+ },
593
+ {
594
+ "id": "component:ds-badge",
595
+ "tag": "ds-badge",
596
+ "name": "badge",
597
+ "title": "Badge",
598
+ "summary": "Non-interactive brand counter or dot that supplements an owning control or label with unread notification information.",
599
+ "intentStatus": "complete",
600
+ "intent": {
601
+ "audience": "general",
602
+ "status": "stable",
603
+ "summary": "Non-interactive brand counter or dot that supplements an owning control or label with unread notification information.",
604
+ "useWhen": [
605
+ "An existing control, navigation item, or label needs a compact unread notification count.",
606
+ "An owning element needs a small visual dot indicating that supplemental notification information exists.",
607
+ "When the badge overlaps an icon or content, the immediate backing surface can be identified so its separation ring matches."
608
+ ],
609
+ "avoidWhen": [
610
+ "The status must stand alone without an owning label or control.",
611
+ "The mark needs semantic positive, caution, negative, or neutral color; Badge intentionally uses one brand treatment.",
612
+ "The compact content is metadata or taxonomy; use Tag or Chip according to whether it is removable.",
613
+ "The badge itself would receive pointer or keyboard interaction; put interaction on the owning control."
614
+ ],
615
+ "alternatives": [
616
+ {
617
+ "when": "A compact static label communicates taxonomy or a semantic status.",
618
+ "component": "component:ds-tag",
619
+ "reason": "Tag owns static metadata labels and semantic intent coloring."
620
+ },
621
+ {
622
+ "when": "A metadata value must be individually removable.",
623
+ "component": "component:ds-chip",
159
624
  "reason": "Chip owns dismissible metadata values."
160
625
  },
161
626
  {
@@ -1565,98 +2030,52 @@
1565
2030
  ]
1566
2031
  },
1567
2032
  {
1568
- "id": "component:ds-divider",
1569
- "tag": "ds-divider",
1570
- "name": "divider",
1571
- "title": "Divider",
1572
- "summary": "Horizontal or vertical separator between sibling content groups, decorative by default with optional structural semantics.",
2033
+ "id": "component:ds-code-block",
2034
+ "tag": "ds-code-block",
2035
+ "name": "code-block",
2036
+ "title": "CodeBlock",
2037
+ "summary": "Scrollable monospace code surface with optional language or filename context and copy action.",
1573
2038
  "intentStatus": "complete",
1574
2039
  "intent": {
1575
2040
  "audience": "general",
1576
- "status": "stable",
1577
- "summary": "Horizontal or vertical separator between sibling content groups, decorative by default with optional structural semantics.",
2041
+ "status": "experimental",
2042
+ "summary": "Scrollable monospace code surface with optional language or filename context and copy action.",
1578
2043
  "useWhen": [
1579
- "Related sibling content groups on one surface need stronger visual separation than spacing alone provides.",
1580
- "A list or panel needs an inset separator that does not define the outer edge of its container.",
1581
- "Meaningful document or group structure requires an explicit horizontal or vertical separator."
2044
+ "A message or document displays fenced code that readers may copy."
1582
2045
  ],
1583
2046
  "avoidWhen": [
1584
- "Spacing alone communicates the grouping clearly.",
1585
- "The line defines a container edge, control outline, or selected state; use the owning component's border treatment.",
1586
- "The divider would compensate for weak headings or unclear information hierarchy.",
1587
- "A decorative flourish does not clarify grouping."
1588
- ],
1589
- "alternatives": [
1590
- {
1591
- "when": "Content needs an enclosing surface and outer boundary.",
1592
- "component": "component:ds-card",
1593
- "reason": "Card owns container chrome, structure, and edge treatment."
1594
- },
1595
- {
1596
- "when": "A static compact label is being used to name a group.",
1597
- "component": "component:ds-text",
1598
- "reason": "Text communicates hierarchy directly instead of relying on a line."
1599
- }
2047
+ "A live editor, terminal, diff viewer, or syntax-highlighting environment is required."
1600
2048
  ],
1601
2049
  "commonlyComposedWith": [
1602
- "component:ds-card",
1603
- "component:ds-menu",
1604
- "component:ds-panel-sub-nav"
2050
+ "component:ds-markdown",
2051
+ "component:ds-button-unfilled"
1605
2052
  ],
1606
2053
  "accessibility": [
1607
- "Keep purely visual dividers hidden from assistive technology.",
1608
- "Expose separator semantics only when the line represents meaningful document or group structure.",
1609
- "Semantic orientation must match the divider's visual orientation.",
1610
- "Do not use a semantic divider as a substitute for headings, landmarks, or explicit group labels."
1611
- ],
1612
- "states": [
1613
- "Horizontal and vertical variants separate sibling groups along the parent's layout axis.",
1614
- "The omitted background context is for primary and secondary surfaces. Explicit faint documents a faint surface while using the same standard divider token.",
1615
- "Other background contexts select their matching divider token, including navigation where Divider is composed inside app chrome.",
1616
- "Inset is symmetric along the line axis. Explicit length is reserved for layout-specific separators; otherwise the line fills the available axis."
2054
+ "The copy action has explicit status wording and the code remains selectable text.",
2055
+ "Language and filename labels supplement rather than replace the code content."
1617
2056
  ],
1618
2057
  "responsiveBehavior": [
1619
- "The parent layout decides whether to change orientation, visibility, inset, or length at responsive breakpoints.",
1620
- "Divider does not infer layout direction or hide itself responsively."
2058
+ "Long lines scroll horizontally and do not widen the owning transcript."
1621
2059
  ],
1622
- "frameworkCaveats": {
1623
- "customElements": [
1624
- "Set semantic mode only from known document structure; presentation alone should remain hidden from assistive technology."
1625
- ],
1626
- "react": [
1627
- "Derive orientation and visibility from the parent layout rather than viewport logic inside Divider."
1628
- ],
1629
- "angular": [
1630
- "Derive orientation and visibility from the parent layout rather than viewport logic inside Divider."
1631
- ]
1632
- },
1633
2060
  "references": [
1634
2061
  {
1635
2062
  "label": "Storybook examples",
1636
- "path": "src/wc/components/Divider/Divider.stories.ts"
2063
+ "path": "src/wc/components/MessageScroller/MessageScroller.stories.ts"
1637
2064
  }
1638
2065
  ]
1639
2066
  },
1640
2067
  "api": {
1641
2068
  "props": {
1642
- "background": {
1643
- "type": "DividerBackground | undefined",
1644
- "required": false
1645
- },
1646
- "inset": {
1647
- "type": "DividerInset",
1648
- "required": false
1649
- },
1650
- "length": {
1651
- "type": "DividerLength",
2069
+ "code": {
2070
+ "type": "string",
1652
2071
  "required": false
1653
2072
  },
1654
- "orientation": {
1655
- "type": "DividerOrientation",
2073
+ "filename": {
2074
+ "type": "string",
1656
2075
  "required": false
1657
2076
  },
1658
- "semantic": {
1659
- "type": "boolean",
2077
+ "language": {
2078
+ "type": "string",
1660
2079
  "required": false
1661
2080
  }
1662
2081
  },
@@ -1664,344 +2083,230 @@
1664
2083
  "slots": []
1665
2084
  },
1666
2085
  "exports": {
1667
- "customElement": "ds-divider",
1668
- "react": "DsDivider",
1669
- "angular": "DsDivider"
2086
+ "customElement": "ds-code-block",
2087
+ "react": "DsCodeBlock",
2088
+ "angular": "DsCodeBlock"
1670
2089
  },
1671
2090
  "dependencies": [
1672
2091
  "@ds-mo/ui",
1673
2092
  "@ds-mo/tokens"
1674
2093
  ],
1675
- "componentDependencies": []
2094
+ "componentDependencies": [
2095
+ "button-unfilled",
2096
+ "text"
2097
+ ]
1676
2098
  },
1677
2099
  {
1678
- "id": "component:ds-empty-state",
1679
- "tag": "ds-empty-state",
1680
- "name": "empty-state",
1681
- "title": "EmptyState",
1682
- "summary": "Centered empty-content message composed as icon plus title plus body, title plus body, or compact body-only content.",
2100
+ "id": "component:ds-conversation-list",
2101
+ "tag": "ds-conversation-list",
2102
+ "name": "conversation-list",
2103
+ "title": "ConversationList",
2104
+ "summary": "Scrollable conversation-list region with dedicated empty and floating-action placement.",
1683
2105
  "intentStatus": "complete",
1684
2106
  "intent": {
1685
2107
  "audience": "general",
1686
- "status": "stable",
1687
- "summary": "Centered empty-content message composed as icon plus title plus body, title plus body, or compact body-only content.",
2108
+ "status": "experimental",
2109
+ "summary": "Scrollable conversation-list region with dedicated empty and floating-action placement.",
1688
2110
  "useWhen": [
1689
- "A bounded content area is in a first-use, no-content, filtered no-results, or no-access state and needs a calm explanatory message tailored to that cause.",
1690
- "A prominent empty region benefits from a decorative icon, visual title, and supporting body copy.",
1691
- "A compact owner such as a Select popup needs only centered body copy."
2111
+ "A messaging-like surface needs a reusable history list with empty and action regions."
1692
2112
  ],
1693
2113
  "avoidWhen": [
1694
- "Content is still loading; use Skeleton for predictable structure or Loader for an indeterminate operation.",
1695
- "The state is an error, warning, or confirmation that needs semantic intent and announcement from the owning workflow.",
1696
- "The state needs a recovery action, link, or other interactive content; the current EmptyState pattern is intentionally message-only.",
1697
- "A decorative illustration, arbitrary rich content, or custom layout is required."
1698
- ],
1699
- "alternatives": [
1700
- {
1701
- "when": "A content region is waiting for structured data.",
1702
- "component": "component:ds-skeleton",
1703
- "reason": "Skeleton preserves expected geometry while content is pending."
1704
- },
1705
- {
1706
- "when": "An operation is progressing without predictable content structure.",
1707
- "component": "component:ds-loader",
1708
- "reason": "Loader owns indeterminate progress rather than an empty outcome."
1709
- },
1710
- {
1711
- "when": "Only ordinary prose is needed without empty-state layout.",
1712
- "component": "component:ds-text",
1713
- "reason": "Text owns typography without adding centered empty-state composition."
1714
- }
2114
+ "The content is not a collection of conversations or threads."
1715
2115
  ],
1716
2116
  "commonlyComposedWith": [
1717
- "component:ds-select",
1718
- "component:ds-text",
1719
- "component:ds-icon"
2117
+ "component:ds-conversation-list-section",
2118
+ "component:ds-conversation-list-item",
2119
+ "component:ds-empty-state"
1720
2120
  ],
1721
- "accessibility": [
1722
- "The optional icon is decorative; the title and body provide all meaning in text.",
1723
- "EmptyState does not create a live region or alert automatically. The owner decides whether a dynamic transition requires announcement.",
1724
- "The visual title does not impose a document heading level because the correct hierarchy belongs to the consuming page or region.",
1725
- "Keep localized body copy concise and sufficient when using the body-only variant."
2121
+ "patterns": [
2122
+ "pattern:conversation"
1726
2123
  ],
1727
- "states": [
1728
- "Supported compositions are icon plus title plus body, title plus body, and body only; body copy is present in every supported composition.",
1729
- "The decorative icon renders at xl in the primary foreground with an 8px gap before the text group and only when a title is also provided.",
1730
- "The visual title uses title-small primary text; body uses body-medium secondary text with a 4px title-to-body gap.",
1731
- "All content is centered. The owner supplies container size and surrounding padding; do not compose actions into or immediately alongside the current EmptyState pattern.",
1732
- "First-use, no-content, no-results, and no-access states reuse this primitive with cause-specific localized messages rather than visual variants."
2124
+ "accessibility": [
2125
+ "Provide an accessible list label through the surrounding heading or region.",
2126
+ "Keep the empty message descriptive and the floating action explicitly named."
1733
2127
  ],
1734
2128
  "responsiveBehavior": [
1735
- "The owner controls available width and height; text wraps naturally while remaining centered.",
1736
- "EmptyState does not infer breakpoints or change composition automatically."
2129
+ "The list fills its owner, scrolls independently, and keeps its action at the lower end corner."
1737
2130
  ],
1738
- "frameworkCaveats": {
1739
- "customElements": [
1740
- "Pass canonical IcoMo icon names and localized heading/body strings through properties or attributes."
1741
- ],
1742
- "react": [
1743
- "Choose one supported composition by passing body with optional heading and icon props."
1744
- ],
1745
- "angular": [
1746
- "Choose one supported composition by binding body with optional heading and icon inputs."
1747
- ]
1748
- },
1749
2131
  "references": [
1750
2132
  {
1751
2133
  "label": "Storybook examples",
1752
- "path": "src/wc/components/EmptyState/EmptyState.stories.ts"
2134
+ "path": "src/wc/components/ConversationList/ConversationList.stories.ts"
1753
2135
  }
1754
2136
  ]
1755
2137
  },
1756
2138
  "api": {
1757
- "props": {
1758
- "body": {
1759
- "type": "string",
1760
- "required": false
1761
- },
1762
- "heading": {
1763
- "type": "string | undefined",
1764
- "required": false
1765
- },
1766
- "icon": {
1767
- "type": "string | undefined",
1768
- "required": false
1769
- }
1770
- },
2139
+ "props": {},
1771
2140
  "events": [],
1772
2141
  "slots": []
1773
2142
  },
1774
2143
  "exports": {
1775
- "customElement": "ds-empty-state",
1776
- "react": "DsEmptyState",
1777
- "angular": "DsEmptyState"
2144
+ "customElement": "ds-conversation-list",
2145
+ "react": "DsConversationList",
2146
+ "angular": "DsConversationList"
1778
2147
  },
1779
2148
  "dependencies": [
1780
2149
  "@ds-mo/ui",
1781
- "@ds-mo/tokens",
1782
- "@ds-mo/icons"
2150
+ "@ds-mo/tokens"
1783
2151
  ],
1784
- "componentDependencies": [
1785
- "icon",
1786
- "text"
1787
- ]
2152
+ "componentDependencies": []
1788
2153
  },
1789
2154
  {
1790
- "id": "component:ds-field",
1791
- "tag": "ds-field",
1792
- "name": "field",
1793
- "title": "Field",
1794
- "summary": "Accessible form-field composition that gives one Input or Select a persistent label, optional guidance, shared error presentation, stable IDs, and observable interaction state.",
2155
+ "id": "component:ds-conversation-list-item",
2156
+ "tag": "ds-conversation-list-item",
2157
+ "name": "conversation-list-item",
2158
+ "title": "ConversationListItem",
2159
+ "summary": "Selectable conversation row with one-line preview, recency, unread presence, generic busy or error status, and channel-owned accessory slots.",
1795
2160
  "intentStatus": "complete",
1796
2161
  "intent": {
1797
2162
  "audience": "general",
1798
- "status": "stable",
1799
- "summary": "Accessible form-field composition that gives one Input or Select a persistent label, optional guidance, shared error presentation, stable IDs, and observable interaction state.",
2163
+ "status": "experimental",
2164
+ "summary": "Selectable conversation row with one-line preview, recency, unread presence, generic busy or error status, and channel-owned accessory slots.",
1800
2165
  "useWhen": [
1801
- "An Input, Select, or SelectMulti needs a persistent visible label in a form.",
1802
- "Help text or an error message must be programmatically associated with one control.",
1803
- "A form layout needs one consistent label-control-message rhythm."
2166
+ "A conversation history needs a compact row that opens one thread."
1804
2167
  ],
1805
2168
  "avoidWhen": [
1806
- "The component already owns its visible label and complete selection semantics, such as Checkbox, Radio, or Switch.",
1807
- "Several controls belong to one question; use a semantic fieldset and legend instead.",
1808
- "Text describes a region or group rather than one form control."
1809
- ],
1810
- "alternatives": [
1811
- {
1812
- "when": "Several related controls answer one question.",
1813
- "component": "component:ds-text",
1814
- "reason": "Use native fieldset and legend semantics, then compose Text only for supporting content."
1815
- }
2169
+ "The row represents a command rather than a persisted conversation."
1816
2170
  ],
1817
2171
  "commonlyComposedWith": [
1818
- "component:ds-input",
1819
- "component:ds-select",
1820
- "component:ds-select-multi",
1821
- "component:ds-text"
2172
+ "component:ds-conversation-list-section",
2173
+ "component:ds-avatar",
2174
+ "component:ds-badge",
2175
+ "component:ds-loader"
2176
+ ],
2177
+ "patterns": [
2178
+ "pattern:conversation"
1822
2179
  ],
1823
2180
  "accessibility": [
1824
- "Slot exactly one form control. Field assigns its stable control ID and connects the visible label automatically.",
1825
- "The visible description or error ID is merged with any authored aria-describedby references; a rendered error replaces the description.",
1826
- "The error prop forwards aria-invalid and supported design-system control error styling; put visible error text on Field, not again on the child control.",
1827
- "Clicking the label focuses the slotted design-system control without opening a Select popup.",
1828
- "Do not use placeholder text as the only label. Keep label text concise and put format or consequence guidance in description."
2181
+ "The conversation surface is one button with its title as the primary accessible name; actions are sibling controls so buttons are never nested.",
2182
+ "An action in the actions slot remains keyboard-focusable and appears on row focus as well as pointer hover; touch layouts keep it visible.",
2183
+ "Status copy must make busy or error meaning available without relying on motion or color."
1829
2184
  ],
1830
2185
  "states": [
1831
- "Field exposes data-focused, data-filled, data-dirty, data-touched, data-invalid, data-disabled, and data-required hooks while the slotted control remains the source of value and interaction behavior.",
1832
- "A rendered error replaces the description; preserve essential guidance in the error message so users retain what they need to correct the field.",
1833
- "Field owns validation presentation but not validation timing; the form decides when to set error and errorMessage.",
1834
- "The label uses primary body-small emphasis, description uses secondary body-small text, and error uses negative body-small text."
2186
+ "Rows reuse the md choice-item label/subtext recipe used by Menu, including 6px row padding, 2px text inset, and the shared content gap. The enclosing conversation-list scroll region supplies the larger 8px outer container padding.",
2187
+ "Busy and error are generic channel-neutral states; the owning product supplies suitable status wording.",
2188
+ "Any positive unreadCount renders one dot on the title row rather than a visible counter; the accessible row name may still announce the exact unread quantity.",
2189
+ "Hover and press use the shared interaction hover and pressed overlays. Only the selected conversation uses the persistent active fill.",
2190
+ "The title uses body-medium emphasis, not title-small, and the body-small preview truncates after one line. Unread titles use primary foreground; read titles use secondary foreground.",
2191
+ "The actions slot overlays the row at an 8px right inset without changing title or preview measure, and paints above the row interaction wash while that wash remains active."
1835
2192
  ],
1836
2193
  "responsiveBehavior": [
1837
- "Field fills the width supplied by its parent and makes the slotted control fill that field width.",
1838
- "The form layout owns column count, wrapping, and responsive placement; Field keeps the vertical label-control-message composition intact."
2194
+ "Long titles and previews truncate without displacing trailing status."
1839
2195
  ],
1840
- "frameworkCaveats": {
1841
- "customElements": [
1842
- "Set fieldId only when another element must reference a predictable control ID; otherwise use the generated association.",
1843
- "Assign child component values and option arrays through their normal JavaScript properties."
1844
- ],
1845
- "react": [
1846
- "Compose one DsInput, DsSelect, or DsSelectMulti child and control validation timing in the form owner."
1847
- ],
1848
- "angular": [
1849
- "Compose the generated Field adapter around the control adapter and its matching Angular value accessor."
1850
- ]
1851
- },
1852
2196
  "references": [
1853
2197
  {
1854
2198
  "label": "Storybook examples",
1855
- "path": "src/wc/components/Field/Field.stories.ts"
1856
- },
1857
- {
1858
- "label": "Cross-browser form and accessibility coverage",
1859
- "path": "tests/e2e/forms.spec.ts"
2199
+ "path": "src/wc/components/ConversationList/ConversationList.stories.ts"
1860
2200
  }
1861
2201
  ]
1862
2202
  },
1863
2203
  "api": {
1864
2204
  "props": {
1865
- "description": {
1866
- "type": "string | undefined",
2205
+ "actionsOpen": {
2206
+ "type": "boolean",
1867
2207
  "required": false
1868
2208
  },
1869
- "error": {
2209
+ "conversationId": {
2210
+ "type": "string",
2211
+ "required": false
2212
+ },
2213
+ "conversationTitle": {
2214
+ "type": "string",
2215
+ "required": false
2216
+ },
2217
+ "preview": {
2218
+ "type": "string",
2219
+ "required": false
2220
+ },
2221
+ "selected": {
1870
2222
  "type": "boolean",
1871
2223
  "required": false
1872
2224
  },
1873
- "errorMessage": {
1874
- "type": "string | undefined",
2225
+ "state": {
2226
+ "type": "ConversationItemState",
1875
2227
  "required": false
1876
2228
  },
1877
- "fieldId": {
1878
- "type": "string | undefined",
2229
+ "statusLabel": {
2230
+ "type": "string",
1879
2231
  "required": false
1880
2232
  },
1881
- "label": {
2233
+ "unreadCount": {
2234
+ "type": "number",
2235
+ "required": false
2236
+ },
2237
+ "updatedAt": {
1882
2238
  "type": "string",
1883
- "required": true
2239
+ "required": false
1884
2240
  }
1885
2241
  },
1886
- "events": [],
2242
+ "events": [
2243
+ {
2244
+ "name": "dsSelect",
2245
+ "detail": "{ id: string }"
2246
+ }
2247
+ ],
1887
2248
  "slots": []
1888
2249
  },
1889
2250
  "exports": {
1890
- "customElement": "ds-field",
1891
- "react": "DsField",
1892
- "angular": "DsField"
2251
+ "customElement": "ds-conversation-list-item",
2252
+ "react": "DsConversationListItem",
2253
+ "angular": "DsConversationListItem"
1893
2254
  },
1894
2255
  "dependencies": [
1895
2256
  "@ds-mo/ui",
1896
2257
  "@ds-mo/tokens"
1897
2258
  ],
1898
2259
  "componentDependencies": [
2260
+ "badge",
2261
+ "loader",
1899
2262
  "text"
1900
2263
  ]
1901
2264
  },
1902
2265
  {
1903
- "id": "component:ds-icon",
1904
- "tag": "ds-icon",
1905
- "name": "icon",
1906
- "title": "Icon",
1907
- "summary": "Secure, lazily loaded renderer for canonical IcoMo system and flag glyphs, decorative by default with optional graphic semantics.",
2266
+ "id": "component:ds-conversation-list-section",
2267
+ "tag": "ds-conversation-list-section",
2268
+ "name": "conversation-list-section",
2269
+ "title": "ConversationListSection",
2270
+ "summary": "Semantically labelled section for grouping conversation rows by meaningful chronology or category.",
1908
2271
  "intentStatus": "complete",
1909
2272
  "intent": {
1910
2273
  "audience": "general",
1911
- "status": "stable",
1912
- "summary": "Secure, lazily loaded renderer for canonical IcoMo system and flag glyphs, decorative by default with optional graphic semantics.",
2274
+ "status": "experimental",
2275
+ "summary": "Semantically labelled section for grouping conversation rows by meaningful chronology or category.",
1913
2276
  "useWhen": [
1914
- "An approved IcoMo system glyph supplements visible text or control chrome.",
1915
- "A canonical flag glyph communicates a country or region with adjacent text or an explicit localized label.",
1916
- "A standalone non-interactive symbol conveys meaning that is unavailable from nearby text."
2277
+ "A conversation list needs visible groups such as Today, Yesterday, or Older."
1917
2278
  ],
1918
2279
  "avoidWhen": [
1919
- "The glyph itself must be clickable or keyboard interactive; use an appropriate button or link and compose Icon inside it.",
1920
- "The visual is an illustration, logo, chart, or arbitrary SVG artwork rather than a canonical IcoMo glyph.",
1921
- "An alias, guessed name, or case-insensitive lookup would be required; runtime lookup uses exact canonical export names.",
1922
- "A fallback glyph would be required when loading fails; Icon intentionally preserves an empty fixed-size box."
1923
- ],
1924
- "alternatives": [
1925
- {
1926
- "when": "The icon initiates an action or persistent toggle.",
1927
- "component": "component:ds-button-unfilled",
1928
- "reason": "ButtonUnfilled owns interaction, focus, naming, and toggle semantics."
1929
- },
1930
- {
1931
- "when": "The visual communicates indeterminate loading progress.",
1932
- "component": "component:ds-loader",
1933
- "reason": "Loader owns progress status and motion behavior."
1934
- },
1935
- {
1936
- "when": "The compact visual is an unread count or notification dot.",
1937
- "component": "component:ds-badge",
1938
- "reason": "Badge owns supplemental notification semantics."
1939
- }
2280
+ "A flat list is clearer or the proposed grouping has no meaning to readers."
1940
2281
  ],
1941
2282
  "commonlyComposedWith": [
1942
- "component:ds-button-filled",
1943
- "component:ds-button-unfilled",
1944
- "component:ds-menu",
1945
- "component:ds-panel-nav"
2283
+ "component:ds-conversation-list",
2284
+ "component:ds-conversation-list-item"
1946
2285
  ],
1947
- "accessibility": [
1948
- "Icons are decorative by default and remain hidden from assistive technology when visible text or an owning control already communicates the meaning.",
1949
- "The owning button, link, or composite control provides the accessible name; do not repeat that name on its nested Icon.",
1950
- "Provide an explicit label only when the non-interactive icon itself communicates otherwise unavailable meaning.",
1951
- "Tertiary and quaternary foregrounds are restricted to icons inside genuinely inactive or disabled UI, or to purely decorative icons; quaternary is the fainter tier, and informative icons and meaningful status graphics retain sufficient rendered contrast even when aria-hidden.",
1952
- "Informative flags require an explicit localized country or region label; never derive accessible text from the export name.",
1953
- "Icon never receives focus or owns interaction."
2286
+ "patterns": [
2287
+ "pattern:conversation"
1954
2288
  ],
1955
- "states": [
1956
- "Omitted color inherits currentColor from the owning context. Explicit semantic aliases and CSS-variable references are available when the icon has an independent color role.",
1957
- "Prefer the owning control's isInactive or native disabled state over manually selecting tertiary or quaternary so visual treatment and inactive semantics remain synchronized.",
1958
- "Built-in glyph lookup accepts exact canonical IcoMo export names only. Names beginning with Flag select the flag catalog automatically.",
1959
- "A cache miss lazy-loads into a fixed-size box without layout shift. Unknown names, failed loads, and rejected markup leave that box empty.",
1960
- "Critical first-paint glyphs may be pre-registered before rendering; all resolved glyphs share a global cache.",
1961
- "Every SVG is validated at the render boundary and injected as parsed DOM nodes so app-registered markup cannot bypass executable-content or external-reference checks."
2289
+ "accessibility": [
2290
+ "The visible heading labels the section and must describe the relationship shared by its rows."
1962
2291
  ],
1963
2292
  "responsiveBehavior": [
1964
- "The owning component or layout chooses icon size and any responsive changes.",
1965
- "Icon does not scale from viewport width or change glyphs automatically."
2293
+ "Rows remain full width while the heading stays visible in document order."
1966
2294
  ],
1967
- "frameworkCaveats": {
1968
- "customElements": [
1969
- "Import each canonical glyph as an SVG string and call registerIcons before first render when synchronous critical-icon paint is required."
1970
- ],
1971
- "react": [
1972
- "Keep nested control icons decorative and place the accessible name on the owning React control."
1973
- ],
1974
- "angular": [
1975
- "Keep nested control icons decorative and place the accessible name on the owning Angular control."
1976
- ]
1977
- },
1978
2295
  "references": [
1979
2296
  {
1980
2297
  "label": "Storybook examples",
1981
- "path": "src/wc/components/Icon/Icon.stories.ts"
1982
- },
1983
- {
1984
- "label": "Preload API guidance",
1985
- "path": "src/wc/components/Icon/icon-cache.ts"
2298
+ "path": "src/wc/components/ConversationList/ConversationList.stories.ts"
1986
2299
  }
1987
2300
  ]
1988
2301
  },
1989
2302
  "api": {
1990
2303
  "props": {
1991
- "color": {
1992
- "type": "IconColor",
1993
- "required": false
1994
- },
1995
- "label": {
1996
- "type": "string | undefined",
1997
- "required": false
1998
- },
1999
- "name": {
2304
+ "heading": {
2000
2305
  "type": "string",
2001
2306
  "required": false
2002
2307
  },
2003
- "size": {
2004
- "type": "IconSize",
2308
+ "sectionId": {
2309
+ "type": "string",
2005
2310
  "required": false
2006
2311
  }
2007
2312
  },
@@ -2009,324 +2314,1202 @@
2009
2314
  "slots": []
2010
2315
  },
2011
2316
  "exports": {
2012
- "customElement": "ds-icon",
2013
- "react": "DsIcon",
2014
- "angular": "DsIcon"
2317
+ "customElement": "ds-conversation-list-section",
2318
+ "react": "DsConversationListSection",
2319
+ "angular": "DsConversationListSection"
2015
2320
  },
2016
2321
  "dependencies": [
2017
2322
  "@ds-mo/ui",
2018
- "@ds-mo/tokens",
2019
- "@ds-mo/icons"
2323
+ "@ds-mo/tokens"
2020
2324
  ],
2021
- "componentDependencies": []
2325
+ "componentDependencies": [
2326
+ "text"
2327
+ ]
2022
2328
  },
2023
2329
  {
2024
- "id": "component:ds-input",
2025
- "tag": "ds-input",
2026
- "name": "input",
2027
- "title": "Input",
2028
- "summary": "Form-associated single-line text field for primary and secondary application backgrounds, with native text input behavior, three control densities, optional leading and trailing content, search clearing, and validation.",
2330
+ "id": "component:ds-divider",
2331
+ "tag": "ds-divider",
2332
+ "name": "divider",
2333
+ "title": "Divider",
2334
+ "summary": "Horizontal or vertical separator between sibling content groups, decorative by default with optional structural semantics.",
2029
2335
  "intentStatus": "complete",
2030
2336
  "intent": {
2031
2337
  "audience": "general",
2032
2338
  "status": "stable",
2033
- "summary": "Form-associated single-line text field for primary and secondary application backgrounds, with native text input behavior, three control densities, optional leading and trailing content, search clearing, and validation.",
2339
+ "summary": "Horizontal or vertical separator between sibling content groups, decorative by default with optional structural semantics.",
2034
2340
  "useWhen": [
2035
- "A user must enter or edit one line of text, an email address, telephone number, URL, search query, or password.",
2036
- "The value must participate in native, Angular, or React form state.",
2037
- "A compact filter or toolbar needs a single-line search field that follows the shared control-density recipe."
2341
+ "Related sibling content groups on one surface need stronger visual separation than spacing alone provides.",
2342
+ "A list or panel needs an inset separator that does not define the outer edge of its container.",
2343
+ "Meaningful document or group structure requires an explicit horizontal or vertical separator."
2038
2344
  ],
2039
2345
  "avoidWhen": [
2040
- "The user chooses from a finite set of known values.",
2041
- "The user must enter multiple paragraphs or formatted content.",
2042
- "The value is adjusted primarily by dragging within a numeric range."
2346
+ "Spacing alone communicates the grouping clearly.",
2347
+ "The line defines a container edge, control outline, or selected state; use the owning component's border treatment.",
2348
+ "The divider would compensate for weak headings or unclear information hierarchy.",
2349
+ "A decorative flourish does not clarify grouping."
2043
2350
  ],
2044
2351
  "alternatives": [
2045
2352
  {
2046
- "when": "The value comes from a finite set of known choices.",
2047
- "component": "component:ds-select",
2048
- "reason": "Select exposes the available values and owns listbox selection behavior."
2049
- },
2050
- {
2051
- "when": "The value is an immediate on/off setting.",
2052
- "component": "component:ds-switch",
2053
- "reason": "Switch communicates a binary setting instead of free text entry."
2353
+ "when": "Content needs an enclosing surface and outer boundary.",
2354
+ "component": "component:ds-card",
2355
+ "reason": "Card owns container chrome, structure, and edge treatment."
2054
2356
  },
2055
2357
  {
2056
- "when": "The value is chosen from a bounded numeric range.",
2057
- "component": "component:ds-slider",
2058
- "reason": "Slider supports direct range adjustment and communicates the current position."
2059
- }
2060
- ],
2358
+ "when": "A static compact label is being used to name a group.",
2359
+ "component": "component:ds-text",
2360
+ "reason": "Text communicates hierarchy directly instead of relying on a line."
2361
+ }
2362
+ ],
2363
+ "commonlyComposedWith": [
2364
+ "component:ds-card",
2365
+ "component:ds-menu",
2366
+ "component:ds-panel-sub-nav"
2367
+ ],
2368
+ "accessibility": [
2369
+ "Keep purely visual dividers hidden from assistive technology.",
2370
+ "Expose separator semantics only when the line represents meaningful document or group structure.",
2371
+ "Semantic orientation must match the divider's visual orientation.",
2372
+ "Do not use a semantic divider as a substitute for headings, landmarks, or explicit group labels."
2373
+ ],
2374
+ "states": [
2375
+ "Horizontal and vertical variants separate sibling groups along the parent's layout axis.",
2376
+ "The omitted background context is for primary and secondary surfaces. Explicit faint documents a faint surface while using the same standard divider token.",
2377
+ "Other background contexts select their matching divider token, including navigation where Divider is composed inside app chrome.",
2378
+ "Inset is symmetric along the line axis. Explicit length is reserved for layout-specific separators; otherwise the line fills the available axis."
2379
+ ],
2380
+ "responsiveBehavior": [
2381
+ "The parent layout decides whether to change orientation, visibility, inset, or length at responsive breakpoints.",
2382
+ "Divider does not infer layout direction or hide itself responsively."
2383
+ ],
2384
+ "frameworkCaveats": {
2385
+ "customElements": [
2386
+ "Set semantic mode only from known document structure; presentation alone should remain hidden from assistive technology."
2387
+ ],
2388
+ "react": [
2389
+ "Derive orientation and visibility from the parent layout rather than viewport logic inside Divider."
2390
+ ],
2391
+ "angular": [
2392
+ "Derive orientation and visibility from the parent layout rather than viewport logic inside Divider."
2393
+ ]
2394
+ },
2395
+ "references": [
2396
+ {
2397
+ "label": "Storybook examples",
2398
+ "path": "src/wc/components/Divider/Divider.stories.ts"
2399
+ }
2400
+ ]
2401
+ },
2402
+ "api": {
2403
+ "props": {
2404
+ "background": {
2405
+ "type": "DividerBackground | undefined",
2406
+ "required": false
2407
+ },
2408
+ "inset": {
2409
+ "type": "DividerInset",
2410
+ "required": false
2411
+ },
2412
+ "length": {
2413
+ "type": "DividerLength",
2414
+ "required": false
2415
+ },
2416
+ "orientation": {
2417
+ "type": "DividerOrientation",
2418
+ "required": false
2419
+ },
2420
+ "semantic": {
2421
+ "type": "boolean",
2422
+ "required": false
2423
+ }
2424
+ },
2425
+ "events": [],
2426
+ "slots": []
2427
+ },
2428
+ "exports": {
2429
+ "customElement": "ds-divider",
2430
+ "react": "DsDivider",
2431
+ "angular": "DsDivider"
2432
+ },
2433
+ "dependencies": [
2434
+ "@ds-mo/ui",
2435
+ "@ds-mo/tokens"
2436
+ ],
2437
+ "componentDependencies": []
2438
+ },
2439
+ {
2440
+ "id": "component:ds-empty-state",
2441
+ "tag": "ds-empty-state",
2442
+ "name": "empty-state",
2443
+ "title": "EmptyState",
2444
+ "summary": "Centered empty-content message composed as icon plus title plus body, title plus body, or compact body-only content.",
2445
+ "intentStatus": "complete",
2446
+ "intent": {
2447
+ "audience": "general",
2448
+ "status": "stable",
2449
+ "summary": "Centered empty-content message composed as icon plus title plus body, title plus body, or compact body-only content.",
2450
+ "useWhen": [
2451
+ "A bounded content area is in a first-use, no-content, filtered no-results, or no-access state and needs a calm explanatory message tailored to that cause.",
2452
+ "A prominent empty region benefits from a decorative icon, visual title, and supporting body copy.",
2453
+ "A compact owner such as a Select popup needs only centered body copy."
2454
+ ],
2455
+ "avoidWhen": [
2456
+ "Content is still loading; use Skeleton for predictable structure or Loader for an indeterminate operation.",
2457
+ "The state is an error, warning, or confirmation that needs semantic intent and announcement from the owning workflow.",
2458
+ "The state needs a recovery action, link, or other interactive content; the current EmptyState pattern is intentionally message-only.",
2459
+ "A decorative illustration, arbitrary rich content, or custom layout is required."
2460
+ ],
2461
+ "alternatives": [
2462
+ {
2463
+ "when": "A content region is waiting for structured data.",
2464
+ "component": "component:ds-skeleton",
2465
+ "reason": "Skeleton preserves expected geometry while content is pending."
2466
+ },
2467
+ {
2468
+ "when": "An operation is progressing without predictable content structure.",
2469
+ "component": "component:ds-loader",
2470
+ "reason": "Loader owns indeterminate progress rather than an empty outcome."
2471
+ },
2472
+ {
2473
+ "when": "Only ordinary prose is needed without empty-state layout.",
2474
+ "component": "component:ds-text",
2475
+ "reason": "Text owns typography without adding centered empty-state composition."
2476
+ }
2477
+ ],
2478
+ "commonlyComposedWith": [
2479
+ "component:ds-select",
2480
+ "component:ds-text",
2481
+ "component:ds-icon"
2482
+ ],
2483
+ "accessibility": [
2484
+ "The optional icon is decorative; the title and body provide all meaning in text.",
2485
+ "EmptyState does not create a live region or alert automatically. The owner decides whether a dynamic transition requires announcement.",
2486
+ "The visual title does not impose a document heading level because the correct hierarchy belongs to the consuming page or region.",
2487
+ "Keep localized body copy concise and sufficient when using the body-only variant."
2488
+ ],
2489
+ "states": [
2490
+ "Supported compositions are icon plus title plus body, title plus body, and body only; body copy is present in every supported composition.",
2491
+ "The decorative icon renders at xl in the primary foreground with an 8px gap before the text group and only when a title is also provided.",
2492
+ "The visual title uses title-small primary text; body uses body-medium secondary text with a 4px title-to-body gap.",
2493
+ "All content is centered. The owner supplies container size and surrounding padding; do not compose actions into or immediately alongside the current EmptyState pattern.",
2494
+ "First-use, no-content, no-results, and no-access states reuse this primitive with cause-specific localized messages rather than visual variants."
2495
+ ],
2496
+ "responsiveBehavior": [
2497
+ "The owner controls available width and height; text wraps naturally while remaining centered.",
2498
+ "EmptyState does not infer breakpoints or change composition automatically."
2499
+ ],
2500
+ "frameworkCaveats": {
2501
+ "customElements": [
2502
+ "Pass canonical IcoMo icon names and localized heading/body strings through properties or attributes."
2503
+ ],
2504
+ "react": [
2505
+ "Choose one supported composition by passing body with optional heading and icon props."
2506
+ ],
2507
+ "angular": [
2508
+ "Choose one supported composition by binding body with optional heading and icon inputs."
2509
+ ]
2510
+ },
2511
+ "references": [
2512
+ {
2513
+ "label": "Storybook examples",
2514
+ "path": "src/wc/components/EmptyState/EmptyState.stories.ts"
2515
+ }
2516
+ ]
2517
+ },
2518
+ "api": {
2519
+ "props": {
2520
+ "body": {
2521
+ "type": "string",
2522
+ "required": false
2523
+ },
2524
+ "heading": {
2525
+ "type": "string | undefined",
2526
+ "required": false
2527
+ },
2528
+ "icon": {
2529
+ "type": "string | undefined",
2530
+ "required": false
2531
+ }
2532
+ },
2533
+ "events": [],
2534
+ "slots": []
2535
+ },
2536
+ "exports": {
2537
+ "customElement": "ds-empty-state",
2538
+ "react": "DsEmptyState",
2539
+ "angular": "DsEmptyState"
2540
+ },
2541
+ "dependencies": [
2542
+ "@ds-mo/ui",
2543
+ "@ds-mo/tokens",
2544
+ "@ds-mo/icons"
2545
+ ],
2546
+ "componentDependencies": [
2547
+ "icon",
2548
+ "text"
2549
+ ]
2550
+ },
2551
+ {
2552
+ "id": "component:ds-field",
2553
+ "tag": "ds-field",
2554
+ "name": "field",
2555
+ "title": "Field",
2556
+ "summary": "Accessible form-field composition that gives one Input or Select a persistent label, optional guidance, shared error presentation, stable IDs, and observable interaction state.",
2557
+ "intentStatus": "complete",
2558
+ "intent": {
2559
+ "audience": "general",
2560
+ "status": "stable",
2561
+ "summary": "Accessible form-field composition that gives one Input or Select a persistent label, optional guidance, shared error presentation, stable IDs, and observable interaction state.",
2562
+ "useWhen": [
2563
+ "An Input, Select, or SelectMulti needs a persistent visible label in a form.",
2564
+ "Help text or an error message must be programmatically associated with one control.",
2565
+ "A form layout needs one consistent label-control-message rhythm."
2566
+ ],
2567
+ "avoidWhen": [
2568
+ "The component already owns its visible label and complete selection semantics, such as Checkbox, Radio, or Switch.",
2569
+ "Several controls belong to one question; use a semantic fieldset and legend instead.",
2570
+ "Text describes a region or group rather than one form control."
2571
+ ],
2572
+ "alternatives": [
2573
+ {
2574
+ "when": "Several related controls answer one question.",
2575
+ "component": "component:ds-text",
2576
+ "reason": "Use native fieldset and legend semantics, then compose Text only for supporting content."
2577
+ }
2578
+ ],
2579
+ "commonlyComposedWith": [
2580
+ "component:ds-input",
2581
+ "component:ds-select",
2582
+ "component:ds-select-multi",
2583
+ "component:ds-text"
2584
+ ],
2585
+ "accessibility": [
2586
+ "Slot exactly one form control. Field assigns its stable control ID and connects the visible label automatically.",
2587
+ "The visible description or error ID is merged with any authored aria-describedby references; a rendered error replaces the description.",
2588
+ "The error prop forwards aria-invalid and supported design-system control error styling; put visible error text on Field, not again on the child control.",
2589
+ "Clicking the label focuses the slotted design-system control without opening a Select popup.",
2590
+ "Do not use placeholder text as the only label. Keep label text concise and put format or consequence guidance in description."
2591
+ ],
2592
+ "states": [
2593
+ "Field exposes data-focused, data-filled, data-dirty, data-touched, data-invalid, data-disabled, and data-required hooks while the slotted control remains the source of value and interaction behavior.",
2594
+ "A rendered error replaces the description; preserve essential guidance in the error message so users retain what they need to correct the field.",
2595
+ "Field owns validation presentation but not validation timing; the form decides when to set error and errorMessage.",
2596
+ "The label uses primary body-small emphasis, description uses secondary body-small text, and error uses negative body-small text."
2597
+ ],
2598
+ "responsiveBehavior": [
2599
+ "Field fills the width supplied by its parent and makes the slotted control fill that field width.",
2600
+ "The form layout owns column count, wrapping, and responsive placement; Field keeps the vertical label-control-message composition intact."
2601
+ ],
2602
+ "frameworkCaveats": {
2603
+ "customElements": [
2604
+ "Set fieldId only when another element must reference a predictable control ID; otherwise use the generated association.",
2605
+ "Assign child component values and option arrays through their normal JavaScript properties."
2606
+ ],
2607
+ "react": [
2608
+ "Compose one DsInput, DsSelect, or DsSelectMulti child and control validation timing in the form owner."
2609
+ ],
2610
+ "angular": [
2611
+ "Compose the generated Field adapter around the control adapter and its matching Angular value accessor."
2612
+ ]
2613
+ },
2614
+ "references": [
2615
+ {
2616
+ "label": "Storybook examples",
2617
+ "path": "src/wc/components/Field/Field.stories.ts"
2618
+ },
2619
+ {
2620
+ "label": "Cross-browser form and accessibility coverage",
2621
+ "path": "tests/e2e/forms.spec.ts"
2622
+ }
2623
+ ]
2624
+ },
2625
+ "api": {
2626
+ "props": {
2627
+ "description": {
2628
+ "type": "string | undefined",
2629
+ "required": false
2630
+ },
2631
+ "error": {
2632
+ "type": "boolean",
2633
+ "required": false
2634
+ },
2635
+ "errorMessage": {
2636
+ "type": "string | undefined",
2637
+ "required": false
2638
+ },
2639
+ "fieldId": {
2640
+ "type": "string | undefined",
2641
+ "required": false
2642
+ },
2643
+ "label": {
2644
+ "type": "string",
2645
+ "required": true
2646
+ }
2647
+ },
2648
+ "events": [],
2649
+ "slots": []
2650
+ },
2651
+ "exports": {
2652
+ "customElement": "ds-field",
2653
+ "react": "DsField",
2654
+ "angular": "DsField"
2655
+ },
2656
+ "dependencies": [
2657
+ "@ds-mo/ui",
2658
+ "@ds-mo/tokens"
2659
+ ],
2660
+ "componentDependencies": [
2661
+ "text"
2662
+ ]
2663
+ },
2664
+ {
2665
+ "id": "component:ds-icon",
2666
+ "tag": "ds-icon",
2667
+ "name": "icon",
2668
+ "title": "Icon",
2669
+ "summary": "Secure, lazily loaded renderer for canonical IcoMo system and flag glyphs, decorative by default with optional graphic semantics.",
2670
+ "intentStatus": "complete",
2671
+ "intent": {
2672
+ "audience": "general",
2673
+ "status": "stable",
2674
+ "summary": "Secure, lazily loaded renderer for canonical IcoMo system and flag glyphs, decorative by default with optional graphic semantics.",
2675
+ "useWhen": [
2676
+ "An approved IcoMo system glyph supplements visible text or control chrome.",
2677
+ "A canonical flag glyph communicates a country or region with adjacent text or an explicit localized label.",
2678
+ "A standalone non-interactive symbol conveys meaning that is unavailable from nearby text."
2679
+ ],
2680
+ "avoidWhen": [
2681
+ "The glyph itself must be clickable or keyboard interactive; use an appropriate button or link and compose Icon inside it.",
2682
+ "The visual is an illustration, logo, chart, or arbitrary SVG artwork rather than a canonical IcoMo glyph.",
2683
+ "An alias, guessed name, or case-insensitive lookup would be required; runtime lookup uses exact canonical export names.",
2684
+ "A fallback glyph would be required when loading fails; Icon intentionally preserves an empty fixed-size box."
2685
+ ],
2686
+ "alternatives": [
2687
+ {
2688
+ "when": "The icon initiates an action or persistent toggle.",
2689
+ "component": "component:ds-button-unfilled",
2690
+ "reason": "ButtonUnfilled owns interaction, focus, naming, and toggle semantics."
2691
+ },
2692
+ {
2693
+ "when": "The visual communicates indeterminate loading progress.",
2694
+ "component": "component:ds-loader",
2695
+ "reason": "Loader owns progress status and motion behavior."
2696
+ },
2697
+ {
2698
+ "when": "The compact visual is an unread count or notification dot.",
2699
+ "component": "component:ds-badge",
2700
+ "reason": "Badge owns supplemental notification semantics."
2701
+ }
2702
+ ],
2703
+ "commonlyComposedWith": [
2704
+ "component:ds-button-filled",
2705
+ "component:ds-button-unfilled",
2706
+ "component:ds-menu",
2707
+ "component:ds-panel-nav"
2708
+ ],
2709
+ "accessibility": [
2710
+ "Icons are decorative by default and remain hidden from assistive technology when visible text or an owning control already communicates the meaning.",
2711
+ "The owning button, link, or composite control provides the accessible name; do not repeat that name on its nested Icon.",
2712
+ "Provide an explicit label only when the non-interactive icon itself communicates otherwise unavailable meaning.",
2713
+ "Tertiary and quaternary foregrounds are restricted to icons inside genuinely inactive or disabled UI, or to purely decorative icons; quaternary is the fainter tier, and informative icons and meaningful status graphics retain sufficient rendered contrast even when aria-hidden.",
2714
+ "Informative flags require an explicit localized country or region label; never derive accessible text from the export name.",
2715
+ "Icon never receives focus or owns interaction."
2716
+ ],
2717
+ "states": [
2718
+ "Omitted color inherits currentColor from the owning context. Explicit semantic aliases and CSS-variable references are available when the icon has an independent color role.",
2719
+ "Prefer the owning control's isInactive or native disabled state over manually selecting tertiary or quaternary so visual treatment and inactive semantics remain synchronized.",
2720
+ "Built-in glyph lookup accepts exact canonical IcoMo export names only. Names beginning with Flag select the flag catalog automatically.",
2721
+ "A cache miss lazy-loads into a fixed-size box without layout shift. Unknown names, failed loads, and rejected markup leave that box empty.",
2722
+ "Critical first-paint glyphs may be pre-registered before rendering; all resolved glyphs share a global cache.",
2723
+ "Every SVG is validated at the render boundary and injected as parsed DOM nodes so app-registered markup cannot bypass executable-content or external-reference checks."
2724
+ ],
2725
+ "responsiveBehavior": [
2726
+ "The owning component or layout chooses icon size and any responsive changes.",
2727
+ "Icon does not scale from viewport width or change glyphs automatically."
2728
+ ],
2729
+ "frameworkCaveats": {
2730
+ "customElements": [
2731
+ "Import each canonical glyph as an SVG string and call registerIcons before first render when synchronous critical-icon paint is required."
2732
+ ],
2733
+ "react": [
2734
+ "Keep nested control icons decorative and place the accessible name on the owning React control."
2735
+ ],
2736
+ "angular": [
2737
+ "Keep nested control icons decorative and place the accessible name on the owning Angular control."
2738
+ ]
2739
+ },
2740
+ "references": [
2741
+ {
2742
+ "label": "Storybook examples",
2743
+ "path": "src/wc/components/Icon/Icon.stories.ts"
2744
+ },
2745
+ {
2746
+ "label": "Preload API guidance",
2747
+ "path": "src/wc/components/Icon/icon-cache.ts"
2748
+ }
2749
+ ]
2750
+ },
2751
+ "api": {
2752
+ "props": {
2753
+ "color": {
2754
+ "type": "IconColor",
2755
+ "required": false
2756
+ },
2757
+ "label": {
2758
+ "type": "string | undefined",
2759
+ "required": false
2760
+ },
2761
+ "name": {
2762
+ "type": "string",
2763
+ "required": false
2764
+ },
2765
+ "size": {
2766
+ "type": "IconSize",
2767
+ "required": false
2768
+ }
2769
+ },
2770
+ "events": [],
2771
+ "slots": []
2772
+ },
2773
+ "exports": {
2774
+ "customElement": "ds-icon",
2775
+ "react": "DsIcon",
2776
+ "angular": "DsIcon"
2777
+ },
2778
+ "dependencies": [
2779
+ "@ds-mo/ui",
2780
+ "@ds-mo/tokens",
2781
+ "@ds-mo/icons"
2782
+ ],
2783
+ "componentDependencies": []
2784
+ },
2785
+ {
2786
+ "id": "component:ds-input",
2787
+ "tag": "ds-input",
2788
+ "name": "input",
2789
+ "title": "Input",
2790
+ "summary": "Form-associated single-line text field for primary and secondary application backgrounds, with native text input behavior, three control densities, optional leading and trailing content, search clearing, and validation.",
2791
+ "intentStatus": "complete",
2792
+ "intent": {
2793
+ "audience": "general",
2794
+ "status": "stable",
2795
+ "summary": "Form-associated single-line text field for primary and secondary application backgrounds, with native text input behavior, three control densities, optional leading and trailing content, search clearing, and validation.",
2796
+ "useWhen": [
2797
+ "A user must enter or edit one line of text, an email address, telephone number, URL, search query, or password.",
2798
+ "The value must participate in native, Angular, or React form state.",
2799
+ "A compact filter or toolbar needs a single-line search field that follows the shared control-density recipe."
2800
+ ],
2801
+ "avoidWhen": [
2802
+ "The user chooses from a finite set of known values.",
2803
+ "The user must enter multiple paragraphs or formatted content.",
2804
+ "The value is adjusted primarily by dragging within a numeric range."
2805
+ ],
2806
+ "alternatives": [
2807
+ {
2808
+ "when": "The value comes from a finite set of known choices.",
2809
+ "component": "component:ds-select",
2810
+ "reason": "Select exposes the available values and owns listbox selection behavior."
2811
+ },
2812
+ {
2813
+ "when": "The value is an immediate on/off setting.",
2814
+ "component": "component:ds-switch",
2815
+ "reason": "Switch communicates a binary setting instead of free text entry."
2816
+ },
2817
+ {
2818
+ "when": "The value is chosen from a bounded numeric range.",
2819
+ "component": "component:ds-slider",
2820
+ "reason": "Slider supports direct range adjustment and communicates the current position."
2821
+ }
2822
+ ],
2823
+ "commonlyComposedWith": [
2824
+ "component:ds-field",
2825
+ "component:ds-icon",
2826
+ "component:ds-text"
2827
+ ],
2828
+ "accessibility": [
2829
+ "Provide a persistent visible label through the owning field or an external native label; placeholder text is guidance and must not be the field's only label.",
2830
+ "Choose the native input type that matches the value so browsers and assistive technology can provide appropriate semantics and keyboards.",
2831
+ "Error text is associated with the native input and announced as an alert when the invalid state is rendered.",
2832
+ "Read-only fields remain focusable and submittable while preventing edits; inactive or disabled fields leave the tab order and are omitted from form submission.",
2833
+ "Suffix content must not carry information that is otherwise absent from the field's visible label, value, or description."
2834
+ ],
2835
+ "states": [
2836
+ "The normal field boundary uses the shared secondary inset border. Focus promotes it to the thicker bold-brand inset stroke, while error uses the thicker bold-negative inset stroke without changing geometry.",
2837
+ "Placeholder text is secondary at rest and quaternary while the editable field is focused because it becomes decorative once typing begins.",
2838
+ "Entered values use the parent surface's primary foreground; prefix icons, suffix content, and resting placeholder text use its secondary foreground.",
2839
+ "Search fields show a standard borderless CrossCircle icon action only while they contain a value. Clearing emits the empty value and restores focus to the native field.",
2840
+ "The suffix slot is for compact units or decorations. The optional leading icon is decorative and does not replace the field label.",
2841
+ "Use autoComplete, inputMode, and enterKeyHint to provide browser and virtual-keyboard hints without changing the value's semantic type.",
2842
+ "The host exposes focused, filled, dirty, touched, invalid, disabled, read-only, and required data attributes for Field integration and diagnostics.",
2843
+ "Use Input only on primary or secondary application backgrounds. It intentionally does not expose alternate surface contexts."
2844
+ ],
2845
+ "responsiveBehavior": [
2846
+ "Form fields normally fill their parent; use hug width only in a compact toolbar or filter layout with an explicit width constraint.",
2847
+ "Choose density from the containing layout: md for ordinary forms, sm or xs only where the surrounding controls use the same compact recipe.",
2848
+ "The owner supplies layout constraints and decides when a compact field moves to its own row."
2849
+ ],
2850
+ "frameworkCaveats": {
2851
+ "customElements": [
2852
+ "Listen for dsChange for user edits and dsClear for the search clear action.",
2853
+ "Use the form attribute on the host when associating an input rendered outside its owning form."
2854
+ ],
2855
+ "react": [
2856
+ "Use DsInput, bind value for controlled application state, and handle onDsChange and onDsClear."
2857
+ ],
2858
+ "angular": [
2859
+ "Import DsInput with TextValueAccessor when integrating with Angular Forms."
2860
+ ]
2861
+ },
2862
+ "references": [
2863
+ {
2864
+ "label": "Storybook examples",
2865
+ "path": "src/wc/components/Input/Input.stories.ts"
2866
+ },
2867
+ {
2868
+ "label": "Cross-browser form and accessibility coverage",
2869
+ "path": "tests/e2e/forms.spec.ts"
2870
+ }
2871
+ ]
2872
+ },
2873
+ "api": {
2874
+ "props": {
2875
+ "ariaDescribedby": {
2876
+ "type": "string | undefined",
2877
+ "required": false
2878
+ },
2879
+ "ariaLabel": {
2880
+ "type": "string | null",
2881
+ "required": false
2882
+ },
2883
+ "ariaLabelledby": {
2884
+ "type": "string | undefined",
2885
+ "required": false
2886
+ },
2887
+ "autoComplete": {
2888
+ "type": "string | undefined",
2889
+ "required": false
2890
+ },
2891
+ "autoFocus": {
2892
+ "type": "boolean",
2893
+ "required": false
2894
+ },
2895
+ "clearLabel": {
2896
+ "type": "string",
2897
+ "required": false
2898
+ },
2899
+ "disabled": {
2900
+ "type": "boolean",
2901
+ "required": false
2902
+ },
2903
+ "enterKeyHint": {
2904
+ "type": "string",
2905
+ "required": false
2906
+ },
2907
+ "error": {
2908
+ "type": "boolean",
2909
+ "required": false
2910
+ },
2911
+ "errorMessage": {
2912
+ "type": "string | undefined",
2913
+ "required": false
2914
+ },
2915
+ "form": {
2916
+ "type": "string | undefined",
2917
+ "required": false
2918
+ },
2919
+ "hasBorder": {
2920
+ "type": "boolean",
2921
+ "required": false
2922
+ },
2923
+ "icon": {
2924
+ "type": "string | undefined",
2925
+ "required": false
2926
+ },
2927
+ "inputId": {
2928
+ "type": "string | undefined",
2929
+ "required": false
2930
+ },
2931
+ "inputMode": {
2932
+ "type": "string",
2933
+ "required": false
2934
+ },
2935
+ "isInactive": {
2936
+ "type": "boolean",
2937
+ "required": false
2938
+ },
2939
+ "name": {
2940
+ "type": "string | undefined",
2941
+ "required": false
2942
+ },
2943
+ "placeholder": {
2944
+ "type": "string | undefined",
2945
+ "required": false
2946
+ },
2947
+ "readOnly": {
2948
+ "type": "boolean",
2949
+ "required": false
2950
+ },
2951
+ "required": {
2952
+ "type": "boolean",
2953
+ "required": false
2954
+ },
2955
+ "requiredMessage": {
2956
+ "type": "string",
2957
+ "required": false
2958
+ },
2959
+ "size": {
2960
+ "type": "InputSize",
2961
+ "required": false
2962
+ },
2963
+ "type": {
2964
+ "type": "InputType",
2965
+ "required": false
2966
+ },
2967
+ "value": {
2968
+ "type": "string",
2969
+ "required": false
2970
+ },
2971
+ "width": {
2972
+ "type": "InputWidth",
2973
+ "required": false
2974
+ }
2975
+ },
2976
+ "events": [
2977
+ {
2978
+ "name": "dsChange",
2979
+ "detail": "string"
2980
+ },
2981
+ {
2982
+ "name": "dsClear",
2983
+ "detail": "void"
2984
+ }
2985
+ ],
2986
+ "slots": []
2987
+ },
2988
+ "exports": {
2989
+ "customElement": "ds-input",
2990
+ "react": "DsInput",
2991
+ "angular": "DsInput"
2992
+ },
2993
+ "dependencies": [
2994
+ "@ds-mo/ui",
2995
+ "@ds-mo/tokens",
2996
+ "@ds-mo/icons"
2997
+ ],
2998
+ "componentDependencies": [
2999
+ "button-unfilled",
3000
+ "icon",
3001
+ "text"
3002
+ ]
3003
+ },
3004
+ {
3005
+ "id": "component:ds-loader",
3006
+ "tag": "ds-loader",
3007
+ "name": "loader",
3008
+ "title": "Loader",
3009
+ "summary": "Indeterminate progress glyph for ongoing operations, inheriting owner color and optionally exposing standalone polite status text.",
3010
+ "intentStatus": "complete",
3011
+ "intent": {
3012
+ "audience": "general",
3013
+ "status": "stable",
3014
+ "summary": "Indeterminate progress glyph for ongoing operations, inheriting owner color and optionally exposing standalone polite status text.",
3015
+ "useWhen": [
3016
+ "An action or operation is in progress and its remaining duration cannot be quantified.",
3017
+ "A button, field, or bounded workflow needs a compact visual busy indicator owned by that control or region.",
3018
+ "A standalone operation needs a visible spinner with contextual polite status text."
3019
+ ],
3020
+ "avoidWhen": [
3021
+ "Pending content has a predictable structure; use Skeleton to preserve that layout.",
3022
+ "Progress is measurable; use an appropriate determinate progress pattern.",
3023
+ "The UI needs a blocking overlay or automatic centering; the owning layout must provide that structure.",
3024
+ "Success, failure, retry, or completion must be communicated; the owning workflow handles outcomes."
3025
+ ],
3026
+ "alternatives": [
3027
+ {
3028
+ "when": "A content region is waiting for structured data.",
3029
+ "component": "component:ds-skeleton",
3030
+ "reason": "Skeleton preserves the expected content geometry while data loads."
3031
+ },
3032
+ {
3033
+ "when": "A static visual symbol is needed without progress semantics.",
3034
+ "component": "component:ds-icon",
3035
+ "reason": "Icon owns non-progress system and flag glyphs."
3036
+ }
3037
+ ],
3038
+ "commonlyComposedWith": [
3039
+ "component:ds-button-filled",
3040
+ "component:ds-button-unfilled",
3041
+ "component:ds-input",
3042
+ "component:ds-select"
3043
+ ],
3044
+ "accessibility": [
3045
+ "When Loader is nested in a busy button, field, or region, keep it unnamed and expose busy state from the owner.",
3046
+ "Standalone Loader requires contextual status text that explains what is loading; do not rely on a generic visual spinner alone.",
3047
+ "Loader is an informative progress graphic and must retain sufficient rendered contrast; tertiary and quaternary are not supported standalone or informative Loader treatments.",
3048
+ "Avoid duplicate announcements from both Loader and its owning busy region.",
3049
+ "Reduced motion stops rotation while keeping the glyph and status semantics visible."
3050
+ ],
3051
+ "states": [
3052
+ "Loader communicates indeterminate progress only and does not emit completion or failure events.",
3053
+ "Omitted color inherits currentColor. Explicit semantic aliases and CSS-variable references match Icon when an independent progress color is required.",
3054
+ "Nested Loader inherits a readable color from its owning busy control or region rather than selecting tertiary or quaternary directly.",
3055
+ "The owner decides whether to delay Loader visibility for short operations and removes it when the operation settles.",
3056
+ "The owner reserves space and supplies centering or overlay layout so Loader never causes unexpected layout movement."
3057
+ ],
3058
+ "responsiveBehavior": [
3059
+ "The owning component or layout chooses Loader size, placement, and any responsive changes.",
3060
+ "Loader does not infer container size or viewport breakpoints."
3061
+ ],
3062
+ "frameworkCaveats": {
3063
+ "customElements": [
3064
+ "Use the label only for standalone status; nested usage should synchronize aria-busy on the owning element."
3065
+ ],
3066
+ "react": [
3067
+ "Derive Loader visibility and the owner's busy state from the same operation state."
3068
+ ],
3069
+ "angular": [
3070
+ "Derive Loader visibility and the owner's busy state from the same operation state."
3071
+ ]
3072
+ },
3073
+ "references": [
3074
+ {
3075
+ "label": "Storybook examples",
3076
+ "path": "src/wc/components/Loader/Loader.stories.ts"
3077
+ }
3078
+ ]
3079
+ },
3080
+ "api": {
3081
+ "props": {
3082
+ "color": {
3083
+ "type": "LoaderColor",
3084
+ "required": false
3085
+ },
3086
+ "label": {
3087
+ "type": "string | undefined",
3088
+ "required": false
3089
+ },
3090
+ "size": {
3091
+ "type": "LoaderSize",
3092
+ "required": false
3093
+ }
3094
+ },
3095
+ "events": [],
3096
+ "slots": []
3097
+ },
3098
+ "exports": {
3099
+ "customElement": "ds-loader",
3100
+ "react": "DsLoader",
3101
+ "angular": "DsLoader"
3102
+ },
3103
+ "dependencies": [
3104
+ "@ds-mo/ui",
3105
+ "@ds-mo/tokens"
3106
+ ],
3107
+ "componentDependencies": []
3108
+ },
3109
+ {
3110
+ "id": "component:ds-markdown",
3111
+ "tag": "ds-markdown",
3112
+ "name": "markdown",
3113
+ "title": "Markdown",
3114
+ "summary": "Safe CommonMark and GFM renderer built from parsed nodes without raw HTML injection.",
3115
+ "intentStatus": "complete",
3116
+ "intent": {
3117
+ "audience": "specialized",
3118
+ "status": "experimental",
3119
+ "summary": "Safe CommonMark and GFM renderer built from parsed nodes without raw HTML injection.",
3120
+ "useWhen": [
3121
+ "Trusted or untrusted message text needs headings, lists, links, tables, tasks, quotes, and code."
3122
+ ],
3123
+ "avoidWhen": [
3124
+ "The application needs arbitrary HTML, custom plugins, or a full document CMS renderer."
3125
+ ],
2061
3126
  "commonlyComposedWith": [
2062
- "component:ds-field",
2063
- "component:ds-icon",
2064
- "component:ds-text"
3127
+ "component:ds-code-block",
3128
+ "component:ds-message-bubble"
3129
+ ],
3130
+ "patterns": [
3131
+ "pattern:conversation",
3132
+ "pattern:agent-chat"
2065
3133
  ],
2066
3134
  "accessibility": [
2067
- "Provide a persistent visible label through the owning field or an external native label; placeholder text is guidance and must not be the field's only label.",
2068
- "Choose the native input type that matches the value so browsers and assistive technology can provide appropriate semantics and keyboards.",
2069
- "Error text is associated with the native input and announced as an alert when the invalid state is rendered.",
2070
- "Read-only fields remain focusable and submittable while preventing edits; inactive or disabled fields leave the tab order and are omitted from form submission.",
2071
- "Suffix content must not carry information that is otherwise absent from the field's visible label, value, or description."
3135
+ "Semantic parsed elements preserve heading, list, table, quote, and code relationships.",
3136
+ "Raw HTML is ignored and unsafe link schemes are not made interactive.",
3137
+ "Link text must remain descriptive in authored content."
2072
3138
  ],
2073
3139
  "states": [
2074
- "The normal field boundary uses the shared secondary inset border. Focus promotes it to the thicker bold-brand inset stroke, while error uses the thicker bold-negative inset stroke without changing geometry.",
2075
- "Placeholder text is secondary at rest and quaternary while the editable field is focused because it becomes decorative once typing begins.",
2076
- "Entered values use the parent surface's primary foreground; prefix icons, suffix content, and resting placeholder text use its secondary foreground.",
2077
- "Search fields show a standard borderless CrossCircle icon action only while they contain a value. Clearing emits the empty value and restores focus to the native field.",
2078
- "The suffix slot is for compact units or decorations. The optional leading icon is decorative and does not replace the field label.",
2079
- "Use autoComplete, inputMode, and enterKeyHint to provide browser and virtual-keyboard hints without changing the value's semantic type.",
2080
- "The host exposes focused, filled, dirty, touched, invalid, disabled, read-only, and required data attributes for Field integration and diagnostics.",
2081
- "Use Input only on primary or secondary application backgrounds. It intentionally does not expose alternate surface contexts."
3140
+ "Streaming updates are coalesced to one parse and render per animation frame."
2082
3141
  ],
2083
3142
  "responsiveBehavior": [
2084
- "Form fields normally fill their parent; use hug width only in a compact toolbar or filter layout with an explicit width constraint.",
2085
- "Choose density from the containing layout: md for ordinary forms, sm or xs only where the surrounding controls use the same compact recipe.",
2086
- "The owner supplies layout constraints and decides when a compact field moves to its own row."
3143
+ "Tables and code scroll horizontally instead of forcing the transcript wider."
3144
+ ],
3145
+ "references": [
3146
+ {
3147
+ "label": "Storybook examples",
3148
+ "path": "src/wc/components/MessageScroller/MessageScroller.stories.ts"
3149
+ }
3150
+ ]
3151
+ },
3152
+ "api": {
3153
+ "props": {
3154
+ "content": {
3155
+ "type": "string",
3156
+ "required": false
3157
+ },
3158
+ "streaming": {
3159
+ "type": "boolean",
3160
+ "required": false
3161
+ }
3162
+ },
3163
+ "events": [],
3164
+ "slots": []
3165
+ },
3166
+ "exports": {
3167
+ "customElement": "ds-markdown",
3168
+ "react": "DsMarkdown",
3169
+ "angular": "DsMarkdown"
3170
+ },
3171
+ "dependencies": [
3172
+ "@ds-mo/ui",
3173
+ "@ds-mo/tokens"
3174
+ ],
3175
+ "componentDependencies": [
3176
+ "code-block"
3177
+ ]
3178
+ },
3179
+ {
3180
+ "id": "component:ds-menu",
3181
+ "tag": "ds-menu",
3182
+ "name": "menu",
3183
+ "title": "Menu",
3184
+ "summary": "Anchored action menu with flat commands, grouped sections, single-selection radio choices, supplemental notification dots, switches, and destructive actions.",
3185
+ "intentStatus": "complete",
3186
+ "intent": {
3187
+ "audience": "general",
3188
+ "status": "stable",
3189
+ "summary": "Anchored action menu with flat commands, grouped sections, single-selection radio choices, supplemental notification dots, switches, and destructive actions.",
3190
+ "useWhen": [
3191
+ "A trigger reveals a short contextual list of commands or state-changing actions.",
3192
+ "Actions need grouping, mutually exclusive selected state, supplemental notification dots, switch rows, or destructive treatment."
3193
+ ],
3194
+ "avoidWhen": [
3195
+ "The user is selecting a value for a form field.",
3196
+ "The content requires rich dialog interaction or a multi-step workflow.",
3197
+ "The actions should remain persistently visible."
3198
+ ],
3199
+ "alternatives": [
3200
+ {
3201
+ "when": "The choice is a form value with a label, validation, and submitted value.",
3202
+ "component": "component:ds-select",
3203
+ "reason": "Select provides form-control semantics and value ownership."
3204
+ },
3205
+ {
3206
+ "when": "Several form values may be selected.",
3207
+ "component": "component:ds-select-multi",
3208
+ "reason": "SelectMulti provides multi-select listbox semantics, array value ownership, and count presentation."
3209
+ },
3210
+ {
3211
+ "when": "The interaction needs substantial content, confirmation, or a form.",
3212
+ "component": "component:ds-modal",
3213
+ "reason": "Modal owns focus containment and dialog-level interaction."
3214
+ }
3215
+ ],
3216
+ "commonlyComposedWith": [
3217
+ "component:ds-button-unfilled",
3218
+ "component:ds-panel-nav",
3219
+ "component:ds-switch",
3220
+ "component:ds-swatch-picker"
3221
+ ],
3222
+ "patterns": [
3223
+ "pattern:menu-trigger"
3224
+ ],
3225
+ "accessibility": [
3226
+ "Anchor the menu to the control that opens it and return focus to that control when the menu closes.",
3227
+ "Open with visible initial focus only when the trigger was activated from the keyboard.",
3228
+ "Keep disabled items discoverable only when their unavailable state is meaningful.",
3229
+ "Switch rows use menuitemcheckbox semantics on the row; the nested ds-switch is an aria-hidden md presentation indicator.",
3230
+ "Single-selection menus use menuitemradio semantics and aria-checked on each row; the leading radio mark is presentation-only.",
3231
+ "A swatch-picker section changes the popup to a non-modal dialog so its radio group and ordinary preference buttons keep valid nested semantics; Tab moves between its controls, then leaves and closes at the popup boundary.",
3232
+ "Use notification dots only as supplemental status and not as the sole indication of important information."
3233
+ ],
3234
+ "states": [
3235
+ "The host owns open state and responds to selection and close events.",
3236
+ "Use either flat items or sections, not both.",
3237
+ "After dsSelect from a switch row, update switchValue in the items property so the controlled indicator reflects the new state.",
3238
+ "For selectionMode single, keep exactly one item isSelected and update the items property after dsSelect.",
3239
+ "Arrays, objects, and element anchors must be assigned as JavaScript properties.",
3240
+ "Use a swatch-picker section for a small curated visual preference and apply dsSwatchSelect immediately without closing the popup; the legacy gradient-picker section and dsGradientSelect remain compatibility-only."
3241
+ ],
3242
+ "responsiveBehavior": [
3243
+ "Keep the default choice-cell anchor alignment so the first or last interactive row edge aligns with its trigger, matching Select; use popup-frame only for deliberate custom frame geometry.",
3244
+ "Choose placement relative to the trigger and allow the component to clamp the popup to the viewport.",
3245
+ "Avoid fixed widths that exceed narrow viewports."
2087
3246
  ],
2088
3247
  "frameworkCaveats": {
2089
3248
  "customElements": [
2090
- "Listen for dsChange for user edits and dsClear for the search clear action.",
2091
- "Use the form attribute on the host when associating an input rendered outside its owning form."
3249
+ "Assign items, sections, and HTMLElement anchors as properties after the element is defined."
2092
3250
  ],
2093
3251
  "react": [
2094
- "Use DsInput, bind value for controlled application state, and handle onDsChange and onDsClear."
3252
+ "Pass arrays and objects as wrapper props and handle generated onDsSelect and onDsClose event props."
2095
3253
  ],
2096
3254
  "angular": [
2097
- "Import DsInput with TextValueAccessor when integrating with Angular Forms."
3255
+ "Use property bindings for arrays, objects, and anchors and event bindings for dsSelect and dsClose."
2098
3256
  ]
2099
3257
  },
2100
3258
  "references": [
2101
3259
  {
2102
3260
  "label": "Storybook examples",
2103
- "path": "src/wc/components/Input/Input.stories.ts"
3261
+ "path": "src/wc/components/Menu/Menu.stories.ts"
2104
3262
  },
2105
3263
  {
2106
- "label": "Cross-browser form and accessibility coverage",
2107
- "path": "tests/e2e/forms.spec.ts"
3264
+ "label": "Framework integration",
3265
+ "path": "docs/framework-integration.md"
2108
3266
  }
2109
3267
  ]
2110
3268
  },
2111
3269
  "api": {
2112
3270
  "props": {
2113
- "ariaDescribedby": {
2114
- "type": "string | undefined",
3271
+ "align": {
3272
+ "type": "MenuAlign",
2115
3273
  "required": false
2116
3274
  },
2117
- "ariaLabel": {
2118
- "type": "string | null",
3275
+ "alignOffset": {
3276
+ "type": "number | string",
2119
3277
  "required": false
2120
3278
  },
2121
- "ariaLabelledby": {
2122
- "type": "string | undefined",
3279
+ "anchor": {
3280
+ "type": "HTMLElement | undefined",
2123
3281
  "required": false
2124
3282
  },
2125
- "autoComplete": {
3283
+ "anchorAlignment": {
3284
+ "type": "ChoicePopupAnchorAlignment",
3285
+ "required": false
3286
+ },
3287
+ "anchorId": {
2126
3288
  "type": "string | undefined",
2127
3289
  "required": false
2128
3290
  },
2129
- "autoFocus": {
3291
+ "initialFocusVisible": {
2130
3292
  "type": "boolean",
2131
3293
  "required": false
2132
3294
  },
2133
- "clearLabel": {
3295
+ "items": {
3296
+ "type": "MenuItemData[]",
3297
+ "required": false
3298
+ },
3299
+ "menuLabel": {
2134
3300
  "type": "string",
2135
3301
  "required": false
2136
3302
  },
2137
- "disabled": {
2138
- "type": "boolean",
3303
+ "menuWidth": {
3304
+ "type": "string | undefined",
2139
3305
  "required": false
2140
3306
  },
2141
- "enterKeyHint": {
2142
- "type": "string",
3307
+ "minWidth": {
3308
+ "type": "string | undefined",
2143
3309
  "required": false
2144
3310
  },
2145
- "error": {
3311
+ "open": {
2146
3312
  "type": "boolean",
2147
3313
  "required": false
2148
3314
  },
2149
- "errorMessage": {
2150
- "type": "string | undefined",
3315
+ "sections": {
3316
+ "type": "MenuSection[]",
2151
3317
  "required": false
2152
3318
  },
2153
- "form": {
2154
- "type": "string | undefined",
3319
+ "selectionMode": {
3320
+ "type": "MenuSelectionMode",
3321
+ "required": false
3322
+ },
3323
+ "side": {
3324
+ "type": "MenuSide",
3325
+ "required": false
3326
+ },
3327
+ "sideOffset": {
3328
+ "type": "number | string",
3329
+ "required": false
3330
+ }
3331
+ },
3332
+ "events": [
3333
+ {
3334
+ "name": "dsAfterClose",
3335
+ "detail": "void"
3336
+ },
3337
+ {
3338
+ "name": "dsClose",
3339
+ "detail": "void"
3340
+ },
3341
+ {
3342
+ "name": "dsGradientSelect",
3343
+ "detail": "ShellGradientPreset"
3344
+ },
3345
+ {
3346
+ "name": "dsSelect",
3347
+ "detail": "MenuItemData"
3348
+ },
3349
+ {
3350
+ "name": "dsSwatchSelect",
3351
+ "detail": "string"
3352
+ }
3353
+ ],
3354
+ "slots": []
3355
+ },
3356
+ "exports": {
3357
+ "customElement": "ds-menu",
3358
+ "react": "DsMenu",
3359
+ "angular": "DsMenu"
3360
+ },
3361
+ "dependencies": [
3362
+ "@ds-mo/ui",
3363
+ "@ds-mo/tokens"
3364
+ ],
3365
+ "componentDependencies": [
3366
+ "badge",
3367
+ "swatch-picker",
3368
+ "switch",
3369
+ "text"
3370
+ ]
3371
+ },
3372
+ {
3373
+ "id": "component:ds-message",
3374
+ "tag": "ds-message",
3375
+ "name": "message",
3376
+ "title": "Message",
3377
+ "summary": "Channel-neutral message row owning direction, grouping, author, time, delivery metadata, and accessory regions.",
3378
+ "intentStatus": "complete",
3379
+ "intent": {
3380
+ "audience": "general",
3381
+ "status": "experimental",
3382
+ "summary": "Channel-neutral message row owning direction, grouping, author, time, delivery metadata, and accessory regions.",
3383
+ "useWhen": [
3384
+ "A transcript contains messages that need consistent incoming, outgoing, or system layout."
3385
+ ],
3386
+ "avoidWhen": [
3387
+ "Content is not an authored message in a conversation."
3388
+ ],
3389
+ "commonlyComposedWith": [
3390
+ "component:ds-message-bubble",
3391
+ "component:ds-message-scroller"
3392
+ ],
3393
+ "patterns": [
3394
+ "pattern:conversation"
3395
+ ],
3396
+ "accessibility": [
3397
+ "Author and time metadata remain textual when they are necessary to interpret the transcript.",
3398
+ "Delivery failure must be expressed in text rather than color alone."
3399
+ ],
3400
+ "states": [
3401
+ "Pass an ISO timestamp. Message keeps the full value in dateTime and formats the visible value as a localized time; applications must not render a raw ISO string as visible transcript metadata.",
3402
+ "Grouping joins adjacent bubble corners, shows the incoming author only at the start, and shows delivery/time metadata only at the end. Outgoing author remains in the accessible message label without repeating a visible You label.",
3403
+ "Set showAuthor false only when the product makes participant and assistant roles visually self-evident; continue passing author so the accessible message label remains specific."
3404
+ ],
3405
+ "responsiveBehavior": [
3406
+ "Outgoing and incoming rows adapt to available width while preserving their directional alignment."
3407
+ ],
3408
+ "references": [
3409
+ {
3410
+ "label": "Storybook examples",
3411
+ "path": "src/wc/components/MessageScroller/MessageScroller.stories.ts"
3412
+ }
3413
+ ]
3414
+ },
3415
+ "api": {
3416
+ "props": {
3417
+ "author": {
3418
+ "type": "string",
2155
3419
  "required": false
2156
3420
  },
2157
- "hasBorder": {
2158
- "type": "boolean",
3421
+ "deliveryState": {
3422
+ "type": "MessageDeliveryState | undefined",
2159
3423
  "required": false
2160
3424
  },
2161
- "icon": {
2162
- "type": "string | undefined",
3425
+ "direction": {
3426
+ "type": "MessageDirection",
2163
3427
  "required": false
2164
3428
  },
2165
- "inputId": {
2166
- "type": "string | undefined",
3429
+ "groupPosition": {
3430
+ "type": "MessageGroupPosition",
2167
3431
  "required": false
2168
3432
  },
2169
- "inputMode": {
3433
+ "messageId": {
2170
3434
  "type": "string",
2171
3435
  "required": false
2172
3436
  },
2173
- "isInactive": {
3437
+ "scrollAnchor": {
2174
3438
  "type": "boolean",
2175
3439
  "required": false
2176
3440
  },
2177
- "name": {
2178
- "type": "string | undefined",
2179
- "required": false
2180
- },
2181
- "placeholder": {
2182
- "type": "string | undefined",
2183
- "required": false
2184
- },
2185
- "readOnly": {
3441
+ "showAuthor": {
2186
3442
  "type": "boolean",
2187
3443
  "required": false
2188
3444
  },
2189
- "required": {
3445
+ "streaming": {
2190
3446
  "type": "boolean",
2191
3447
  "required": false
2192
3448
  },
2193
- "requiredMessage": {
2194
- "type": "string",
2195
- "required": false
2196
- },
2197
- "size": {
2198
- "type": "InputSize",
2199
- "required": false
2200
- },
2201
- "type": {
2202
- "type": "InputType",
2203
- "required": false
2204
- },
2205
- "value": {
3449
+ "timestamp": {
2206
3450
  "type": "string",
2207
3451
  "required": false
2208
- },
2209
- "width": {
2210
- "type": "InputWidth",
2211
- "required": false
2212
3452
  }
2213
3453
  },
2214
- "events": [
2215
- {
2216
- "name": "dsChange",
2217
- "detail": "string"
2218
- },
2219
- {
2220
- "name": "dsClear",
2221
- "detail": "void"
2222
- }
2223
- ],
3454
+ "events": [],
2224
3455
  "slots": []
2225
3456
  },
2226
3457
  "exports": {
2227
- "customElement": "ds-input",
2228
- "react": "DsInput",
2229
- "angular": "DsInput"
3458
+ "customElement": "ds-message",
3459
+ "react": "DsMessage",
3460
+ "angular": "DsMessage"
2230
3461
  },
2231
3462
  "dependencies": [
2232
3463
  "@ds-mo/ui",
2233
- "@ds-mo/tokens",
2234
- "@ds-mo/icons"
3464
+ "@ds-mo/tokens"
2235
3465
  ],
2236
3466
  "componentDependencies": [
2237
- "button-unfilled",
2238
- "icon",
2239
3467
  "text"
2240
3468
  ]
2241
3469
  },
2242
3470
  {
2243
- "id": "component:ds-loader",
2244
- "tag": "ds-loader",
2245
- "name": "loader",
2246
- "title": "Loader",
2247
- "summary": "Indeterminate progress glyph for ongoing operations, inheriting owner color and optionally exposing standalone polite status text.",
3471
+ "id": "component:ds-message-bubble",
3472
+ "tag": "ds-message-bubble",
3473
+ "name": "message-bubble",
3474
+ "title": "MessageBubble",
3475
+ "summary": "Visible message content surface with a body-medium default, separated from message-row direction and metadata.",
2248
3476
  "intentStatus": "complete",
2249
3477
  "intent": {
2250
3478
  "audience": "general",
2251
- "status": "stable",
2252
- "summary": "Indeterminate progress glyph for ongoing operations, inheriting owner color and optionally exposing standalone polite status text.",
3479
+ "status": "experimental",
3480
+ "summary": "Visible message content surface with a body-medium default, separated from message-row direction and metadata.",
2253
3481
  "useWhen": [
2254
- "An action or operation is in progress and its remaining duration cannot be quantified.",
2255
- "A button, field, or bounded workflow needs a compact visual busy indicator owned by that control or region.",
2256
- "A standalone operation needs a visible spinner with contextual polite status text."
3482
+ "Message content needs a primary, secondary, ghost, or error surface within a Message row.",
3483
+ "Plain incoming or outgoing message copy should use the shared body-medium regular typography recipe without application styling."
2257
3484
  ],
2258
3485
  "avoidWhen": [
2259
- "Pending content has a predictable structure; use Skeleton to preserve that layout.",
2260
- "Progress is measurable; use an appropriate determinate progress pattern.",
2261
- "The UI needs a blocking overlay or automatic centering; the owning layout must provide that structure.",
2262
- "Success, failure, retry, or completion must be communicated; the owning workflow handles outcomes."
2263
- ],
2264
- "alternatives": [
2265
- {
2266
- "when": "A content region is waiting for structured data.",
2267
- "component": "component:ds-skeleton",
2268
- "reason": "Skeleton preserves the expected content geometry while data loads."
2269
- },
2270
- {
2271
- "when": "A static visual symbol is needed without progress semantics.",
2272
- "component": "component:ds-icon",
2273
- "reason": "Icon owns non-progress system and flag glyphs."
2274
- }
3486
+ "The surface is a general card, callout, or form container.",
3487
+ "The application wants to promote ordinary conversation copy to body-large; message typography stays body-medium unless a distinct authored rich-content element owns its own complete type recipe."
2275
3488
  ],
2276
3489
  "commonlyComposedWith": [
2277
- "component:ds-button-filled",
2278
- "component:ds-button-unfilled",
2279
- "component:ds-input",
2280
- "component:ds-select"
3490
+ "component:ds-message",
3491
+ "component:ds-markdown"
2281
3492
  ],
2282
- "accessibility": [
2283
- "When Loader is nested in a busy button, field, or region, keep it unnamed and expose busy state from the owner.",
2284
- "Standalone Loader requires contextual status text that explains what is loading; do not rely on a generic visual spinner alone.",
2285
- "Loader is an informative progress graphic and must retain sufficient rendered contrast; tertiary and quaternary are not supported standalone or informative Loader treatments.",
2286
- "Avoid duplicate announcements from both Loader and its owning busy region.",
2287
- "Reduced motion stops rotation while keeping the glyph and status semantics visible."
3493
+ "patterns": [
3494
+ "pattern:conversation"
2288
3495
  ],
2289
- "states": [
2290
- "Loader communicates indeterminate progress only and does not emit completion or failure events.",
2291
- "Omitted color inherits currentColor. Explicit semantic aliases and CSS-variable references match Icon when an independent progress color is required.",
2292
- "Nested Loader inherits a readable color from its owning busy control or region rather than selecting tertiary or quaternary directly.",
2293
- "The owner decides whether to delay Loader visibility for short operations and removes it when the operation settles.",
2294
- "The owner reserves space and supplies centering or overlay layout so Loader never causes unexpected layout movement."
3496
+ "accessibility": [
3497
+ "Surface styling does not add semantics; meaningful error or status copy belongs in message content or metadata."
2295
3498
  ],
2296
3499
  "responsiveBehavior": [
2297
- "The owning component or layout chooses Loader size, placement, and any responsive changes.",
2298
- "Loader does not infer container size or viewport breakpoints."
3500
+ "The bubble wraps content and allows wide ghost responses to use more transcript width."
2299
3501
  ],
2300
- "frameworkCaveats": {
2301
- "customElements": [
2302
- "Use the label only for standalone status; nested usage should synchronize aria-busy on the owning element."
2303
- ],
2304
- "react": [
2305
- "Derive Loader visibility and the owner's busy state from the same operation state."
2306
- ],
2307
- "angular": [
2308
- "Derive Loader visibility and the owner's busy state from the same operation state."
2309
- ]
2310
- },
2311
3502
  "references": [
2312
3503
  {
2313
3504
  "label": "Storybook examples",
2314
- "path": "src/wc/components/Loader/Loader.stories.ts"
3505
+ "path": "src/wc/components/MessageScroller/MessageScroller.stories.ts"
2315
3506
  }
2316
3507
  ]
2317
3508
  },
2318
3509
  "api": {
2319
3510
  "props": {
2320
- "color": {
2321
- "type": "LoaderColor",
2322
- "required": false
2323
- },
2324
- "label": {
2325
- "type": "string | undefined",
2326
- "required": false
2327
- },
2328
- "size": {
2329
- "type": "LoaderSize",
3511
+ "variant": {
3512
+ "type": "MessageBubbleVariant",
2330
3513
  "required": false
2331
3514
  }
2332
3515
  },
@@ -2334,9 +3517,9 @@
2334
3517
  "slots": []
2335
3518
  },
2336
3519
  "exports": {
2337
- "customElement": "ds-loader",
2338
- "react": "DsLoader",
2339
- "angular": "DsLoader"
3520
+ "customElement": "ds-message-bubble",
3521
+ "react": "DsMessageBubble",
3522
+ "angular": "DsMessageBubble"
2340
3523
  },
2341
3524
  "dependencies": [
2342
3525
  "@ds-mo/ui",
@@ -2345,186 +3528,193 @@
2345
3528
  "componentDependencies": []
2346
3529
  },
2347
3530
  {
2348
- "id": "component:ds-menu",
2349
- "tag": "ds-menu",
2350
- "name": "menu",
2351
- "title": "Menu",
2352
- "summary": "Anchored action menu with flat commands, grouped sections, selected command state, supplemental notification dots, switches, and destructive actions.",
3531
+ "id": "component:ds-message-composer",
3532
+ "tag": "ds-message-composer",
3533
+ "name": "message-composer",
3534
+ "title": "MessageComposer",
3535
+ "summary": "Two-line auto-growing conversation textarea with submit, stop, error, and extensible leading-tool or trailing-action regions.",
2353
3536
  "intentStatus": "complete",
2354
3537
  "intent": {
2355
3538
  "audience": "general",
2356
- "status": "stable",
2357
- "summary": "Anchored action menu with flat commands, grouped sections, selected command state, supplemental notification dots, switches, and destructive actions.",
3539
+ "status": "experimental",
3540
+ "summary": "Two-line auto-growing conversation textarea with submit, stop, error, and extensible leading-tool or trailing-action regions.",
2358
3541
  "useWhen": [
2359
- "A trigger reveals a short contextual list of commands or state-changing actions.",
2360
- "Actions need grouping, selected state, supplemental notification dots, switch rows, or destructive treatment."
3542
+ "A conversation accepts multi-line text and needs Enter-to-submit with a streaming stop action."
2361
3543
  ],
2362
3544
  "avoidWhen": [
2363
- "The user is selecting a value for a form field.",
2364
- "The content requires rich dialog interaction or a multi-step workflow.",
2365
- "The actions should remain persistently visible."
2366
- ],
2367
- "alternatives": [
2368
- {
2369
- "when": "The choice is a form value with a label, validation, and submitted value.",
2370
- "component": "component:ds-select",
2371
- "reason": "Select provides form-control semantics and value ownership."
2372
- },
2373
- {
2374
- "when": "Several form values may be selected.",
2375
- "component": "component:ds-select-multi",
2376
- "reason": "SelectMulti provides multi-select listbox semantics, array value ownership, and count presentation."
2377
- },
2378
- {
2379
- "when": "The interaction needs substantial content, confirmation, or a form.",
2380
- "component": "component:ds-modal",
2381
- "reason": "Modal owns focus containment and dialog-level interaction."
2382
- }
3545
+ "The text is a conventional form field submitted with unrelated fields."
2383
3546
  ],
2384
3547
  "commonlyComposedWith": [
2385
- "component:ds-button-unfilled",
2386
- "component:ds-panel-nav",
2387
- "component:ds-switch",
2388
- "component:ds-swatch-picker"
3548
+ "component:ds-message-scroller",
3549
+ "component:ds-button-filled",
3550
+ "component:ds-button-unfilled"
2389
3551
  ],
2390
3552
  "patterns": [
2391
- "pattern:menu-trigger"
3553
+ "pattern:conversation"
2392
3554
  ],
2393
3555
  "accessibility": [
2394
- "Anchor the menu to the control that opens it and return focus to that control when the menu closes.",
2395
- "Open with visible initial focus only when the trigger was activated from the keyboard.",
2396
- "Keep disabled items discoverable only when their unavailable state is meaningful.",
2397
- "Switch rows use menuitemcheckbox semantics on the row; the nested ds-switch is an aria-hidden md presentation indicator.",
2398
- "A swatch-picker section changes the popup to a non-modal dialog so its radio group and ordinary preference buttons keep valid nested semantics; Tab moves between its controls, then leaves and closes at the popup boundary.",
2399
- "Use notification dots only as supplemental status and not as the sole indication of important information."
3556
+ "Always provide a localized textarea label and submit or stop action names.",
3557
+ "Shift plus Enter inserts a newline while Enter submits non-empty content.",
3558
+ "Streaming and error states remain perceivable without relying on icon shape alone."
2400
3559
  ],
2401
3560
  "states": [
2402
- "The host owns open state and responds to selection and close events.",
2403
- "Use either flat items or sections, not both.",
2404
- "After dsSelect from a switch row, update switchValue in the items property so the controlled indicator reflects the new state.",
2405
- "Arrays, objects, and element anchors must be assigned as JavaScript properties.",
2406
- "Use a swatch-picker section for a small curated visual preference and apply dsSwatchSelect immediately without closing the popup; the legacy gradient-picker section and dsGradientSelect remain compatibility-only."
3561
+ "The owner controls draft value and transport state; the composer emits intent without performing transport.",
3562
+ "Use the tools slot for leading actions such as add and the actions slot for trailing actions such as dictation; the built-in submit or stop action remains last.",
3563
+ "The submit action defaults to brand for both agent and person-to-person conversations; change submitIntent only when the action consequence has a different semantic intent."
2407
3564
  ],
2408
3565
  "responsiveBehavior": [
2409
- "Keep the default choice-cell anchor alignment so the first or last interactive row edge aligns with its trigger, matching Select; use popup-frame only for deliberate custom frame geometry.",
2410
- "Choose placement relative to the trigger and allow the component to clamp the popup to the viewport.",
2411
- "Avoid fixed widths that exceed narrow viewports."
3566
+ "The textarea begins at two body-medium lines, grows one line at a time through six lines, and then scrolls internally."
2412
3567
  ],
2413
- "frameworkCaveats": {
2414
- "customElements": [
2415
- "Assign items, sections, and HTMLElement anchors as properties after the element is defined."
2416
- ],
2417
- "react": [
2418
- "Pass arrays and objects as wrapper props and handle generated onDsSelect and onDsClose event props."
2419
- ],
2420
- "angular": [
2421
- "Use property bindings for arrays, objects, and anchors and event bindings for dsSelect and dsClose."
2422
- ]
2423
- },
2424
3568
  "references": [
2425
3569
  {
2426
3570
  "label": "Storybook examples",
2427
- "path": "src/wc/components/Menu/Menu.stories.ts"
3571
+ "path": "src/wc/components/MessageComposer/MessageComposer.stories.ts"
2428
3572
  },
2429
3573
  {
2430
- "label": "Framework integration",
2431
- "path": "docs/framework-integration.md"
3574
+ "label": "Scroller overlay composition",
3575
+ "path": "src/wc/components/MessageScroller/MessageScroller.stories.ts"
2432
3576
  }
2433
3577
  ]
2434
3578
  },
2435
3579
  "api": {
2436
3580
  "props": {
2437
- "align": {
2438
- "type": "MenuAlign",
3581
+ "isInactive": {
3582
+ "type": "boolean",
2439
3583
  "required": false
2440
3584
  },
2441
- "alignOffset": {
2442
- "type": "number | string",
3585
+ "label": {
3586
+ "type": "string",
2443
3587
  "required": false
2444
3588
  },
2445
- "anchor": {
2446
- "type": "HTMLElement | undefined",
3589
+ "placeholder": {
3590
+ "type": "string",
2447
3591
  "required": false
2448
3592
  },
2449
- "anchorAlignment": {
2450
- "type": "ChoicePopupAnchorAlignment",
3593
+ "status": {
3594
+ "type": "MessageComposerStatus",
2451
3595
  "required": false
2452
3596
  },
2453
- "anchorId": {
2454
- "type": "string | undefined",
3597
+ "submitIntent": {
3598
+ "type": "ButtonFilledIntent",
2455
3599
  "required": false
2456
3600
  },
2457
- "initialFocusVisible": {
3601
+ "value": {
3602
+ "type": "string",
3603
+ "required": false
3604
+ }
3605
+ },
3606
+ "events": [
3607
+ {
3608
+ "name": "dsInput",
3609
+ "detail": "string"
3610
+ },
3611
+ {
3612
+ "name": "dsStop",
3613
+ "detail": "void"
3614
+ },
3615
+ {
3616
+ "name": "dsSubmit",
3617
+ "detail": "{ text: string }"
3618
+ }
3619
+ ],
3620
+ "slots": []
3621
+ },
3622
+ "exports": {
3623
+ "customElement": "ds-message-composer",
3624
+ "react": "DsMessageComposer",
3625
+ "angular": "DsMessageComposer"
3626
+ },
3627
+ "dependencies": [
3628
+ "@ds-mo/ui",
3629
+ "@ds-mo/tokens"
3630
+ ],
3631
+ "componentDependencies": [
3632
+ "button-filled"
3633
+ ]
3634
+ },
3635
+ {
3636
+ "id": "component:ds-message-scroller",
3637
+ "tag": "ds-message-scroller",
3638
+ "name": "message-scroller",
3639
+ "title": "MessageScroller",
3640
+ "summary": "Focusable transcript scroller that follows the live edge only while the reader remains there.",
3641
+ "intentStatus": "complete",
3642
+ "intent": {
3643
+ "audience": "general",
3644
+ "status": "experimental",
3645
+ "summary": "Focusable transcript scroller that follows the live edge only while the reader remains there.",
3646
+ "useWhen": [
3647
+ "Messages can append or stream and transcript position must remain respectful of reader intent."
3648
+ ],
3649
+ "avoidWhen": [
3650
+ "Content is static prose without message navigation or live updates."
3651
+ ],
3652
+ "commonlyComposedWith": [
3653
+ "component:ds-message",
3654
+ "component:ds-message-composer"
3655
+ ],
3656
+ "patterns": [
3657
+ "pattern:conversation"
3658
+ ],
3659
+ "accessibility": [
3660
+ "Give each transcript a concise localized label.",
3661
+ "New content is exposed through log semantics without stealing focus.",
3662
+ "The scroll-to-latest control remains keyboard accessible when follow behavior is released."
3663
+ ],
3664
+ "states": [
3665
+ "Selection and transcript interaction release automatic following.",
3666
+ "Opening saved history, message jumps, and prepended history preserve deliberate position.",
3667
+ "The scroll-to-latest action is absent at the live edge, appears only after the reader moves away, and disappears again after returning to the newest message.",
3668
+ "Place a composer container in the overlay slot so messages scroll behind it; the scroller measures its live height, reserves matching transcript clearance, and keeps scroll-to-latest above it."
3669
+ ],
3670
+ "responsiveBehavior": [
3671
+ "Transcript width is readable while the scroll region fills available height."
3672
+ ],
3673
+ "references": [
3674
+ {
3675
+ "label": "Storybook examples",
3676
+ "path": "src/wc/components/MessageScroller/MessageScroller.stories.ts"
3677
+ }
3678
+ ]
3679
+ },
3680
+ "api": {
3681
+ "props": {
3682
+ "autoFollow": {
2458
3683
  "type": "boolean",
2459
3684
  "required": false
2460
3685
  },
2461
- "items": {
2462
- "type": "MenuItemData[]",
2463
- "required": false
2464
- },
2465
- "menuLabel": {
2466
- "type": "string",
2467
- "required": false
2468
- },
2469
- "menuWidth": {
2470
- "type": "string | undefined",
2471
- "required": false
2472
- },
2473
- "minWidth": {
2474
- "type": "string | undefined",
2475
- "required": false
2476
- },
2477
- "open": {
3686
+ "busy": {
2478
3687
  "type": "boolean",
2479
3688
  "required": false
2480
3689
  },
2481
- "sections": {
2482
- "type": "MenuSection[]",
2483
- "required": false
2484
- },
2485
- "side": {
2486
- "type": "MenuSide",
3690
+ "defaultPosition": {
3691
+ "type": "MessageScrollerPosition",
2487
3692
  "required": false
2488
3693
  },
2489
- "sideOffset": {
2490
- "type": "number | string",
3694
+ "messagesLabel": {
3695
+ "type": "string",
2491
3696
  "required": false
2492
3697
  }
2493
3698
  },
2494
3699
  "events": [
2495
3700
  {
2496
- "name": "dsClose",
3701
+ "name": "dsReachStart",
2497
3702
  "detail": "void"
2498
- },
2499
- {
2500
- "name": "dsGradientSelect",
2501
- "detail": "ShellGradientPreset"
2502
- },
2503
- {
2504
- "name": "dsSelect",
2505
- "detail": "MenuItemData"
2506
- },
2507
- {
2508
- "name": "dsSwatchSelect",
2509
- "detail": "string"
2510
3703
  }
2511
3704
  ],
2512
3705
  "slots": []
2513
3706
  },
2514
3707
  "exports": {
2515
- "customElement": "ds-menu",
2516
- "react": "DsMenu",
2517
- "angular": "DsMenu"
3708
+ "customElement": "ds-message-scroller",
3709
+ "react": "DsMessageScroller",
3710
+ "angular": "DsMessageScroller"
2518
3711
  },
2519
3712
  "dependencies": [
2520
3713
  "@ds-mo/ui",
2521
3714
  "@ds-mo/tokens"
2522
3715
  ],
2523
3716
  "componentDependencies": [
2524
- "badge",
2525
- "swatch-picker",
2526
- "switch",
2527
- "text"
3717
+ "button-unfilled"
2528
3718
  ]
2529
3719
  },
2530
3720
  {
@@ -2686,6 +3876,10 @@
2686
3876
  "type": "string",
2687
3877
  "required": false
2688
3878
  },
3879
+ "accountMenuExpanded": {
3880
+ "type": "boolean",
3881
+ "required": false
3882
+ },
2689
3883
  "activeId": {
2690
3884
  "type": "string",
2691
3885
  "required": false
@@ -2930,6 +4124,264 @@
2930
4124
  "text"
2931
4125
  ]
2932
4126
  },
4127
+ {
4128
+ "id": "component:ds-panel-tool-header",
4129
+ "tag": "ds-panel-tool-header",
4130
+ "name": "panel-tool-header",
4131
+ "title": "PanelToolHeader",
4132
+ "summary": "Canonical left-aligned PanelTools header with an optional leading navigation or dismiss action and application-owned trailing icon actions.",
4133
+ "intentStatus": "complete",
4134
+ "intent": {
4135
+ "audience": "general",
4136
+ "status": "experimental",
4137
+ "summary": "Canonical left-aligned PanelTools header with an optional leading navigation or dismiss action and application-owned trailing icon actions.",
4138
+ "useWhen": [
4139
+ "PanelTools needs its one shared root or detail header.",
4140
+ "A tool header needs a title with optional Back or Close navigation, menu, fullscreen, or other compact icon actions."
4141
+ ],
4142
+ "avoidWhen": [
4143
+ "Rendering inside a PanelTools tool body; PanelTools already composes this canonical header above the body.",
4144
+ "The header belongs to page content."
4145
+ ],
4146
+ "commonlyComposedWith": [
4147
+ "component:ds-button-unfilled"
4148
+ ],
4149
+ "accessibility": [
4150
+ "Leading navigation or dismiss actions and trailing icon actions require concise localized names.",
4151
+ "The visible heading names the active panel or subview."
4152
+ ],
4153
+ "states": [
4154
+ "The title remains left aligned whether the header has no actions, Back, one trailing action, or several trailing actions.",
4155
+ "Leading and trailing control zones never shrink; only the title consumes and truncates within the remaining width, with a fixed 4px gap between zones.",
4156
+ "Header chrome text is not selectable; actions remain keyboard focusable and interactive.",
4157
+ "Adjacent trailing actions keep the shared 4px control gap in drawer and fullscreen presentations.",
4158
+ "When fullscreen and overflow actions appear together, author fullscreen before overflow so Ellipses remains the rightmost action.",
4159
+ "PanelTools supplies application-owned actions and relays their ids through its shared dsHeaderAction event."
4160
+ ],
4161
+ "responsiveBehavior": [
4162
+ "The title truncates between optional leading navigation and trailing action zones."
4163
+ ],
4164
+ "references": [
4165
+ {
4166
+ "label": "Standalone examples",
4167
+ "path": "src/wc/components/PanelToolHeader/PanelToolHeader.stories.ts"
4168
+ }
4169
+ ]
4170
+ },
4171
+ "api": {
4172
+ "props": {
4173
+ "actions": {
4174
+ "type": "PanelToolsHeaderAction[]",
4175
+ "required": false
4176
+ },
4177
+ "backAriaLabel": {
4178
+ "type": "string",
4179
+ "required": false
4180
+ },
4181
+ "backIcon": {
4182
+ "type": "string",
4183
+ "required": false
4184
+ },
4185
+ "heading": {
4186
+ "type": "string",
4187
+ "required": false
4188
+ },
4189
+ "menuAriaLabel": {
4190
+ "type": "string",
4191
+ "required": false
4192
+ },
4193
+ "menuControls": {
4194
+ "type": "string | undefined",
4195
+ "required": false
4196
+ },
4197
+ "menuExpanded": {
4198
+ "type": "boolean",
4199
+ "required": false
4200
+ },
4201
+ "menuTriggerId": {
4202
+ "type": "string",
4203
+ "required": false
4204
+ },
4205
+ "showBack": {
4206
+ "type": "boolean",
4207
+ "required": false
4208
+ },
4209
+ "showMenu": {
4210
+ "type": "boolean",
4211
+ "required": false
4212
+ }
4213
+ },
4214
+ "events": [
4215
+ {
4216
+ "name": "dsAction",
4217
+ "detail": "{ id: string; originalEvent: MouseEvent }"
4218
+ },
4219
+ {
4220
+ "name": "dsBack",
4221
+ "detail": "MouseEvent"
4222
+ },
4223
+ {
4224
+ "name": "dsMenuToggle",
4225
+ "detail": "MouseEvent"
4226
+ }
4227
+ ],
4228
+ "slots": []
4229
+ },
4230
+ "exports": {
4231
+ "customElement": "ds-panel-tool-header",
4232
+ "react": "DsPanelToolHeader",
4233
+ "angular": "DsPanelToolHeader"
4234
+ },
4235
+ "dependencies": [
4236
+ "@ds-mo/ui",
4237
+ "@ds-mo/tokens"
4238
+ ],
4239
+ "componentDependencies": [
4240
+ "button-unfilled",
4241
+ "text"
4242
+ ]
4243
+ },
4244
+ {
4245
+ "id": "component:ds-panel-tool-search",
4246
+ "tag": "ds-panel-tool-search",
4247
+ "name": "panel-tool-search",
4248
+ "title": "PanelToolSearch",
4249
+ "summary": "Transparent search row for the top of a PanelTools product view, with a fixed 48px allocation around the standard md search control and an optional filter-menu trigger.",
4250
+ "intentStatus": "complete",
4251
+ "intent": {
4252
+ "audience": "general",
4253
+ "status": "experimental",
4254
+ "summary": "Transparent search row for the top of a PanelTools product view, with a fixed 48px allocation around the standard md search control and an optional filter-menu trigger.",
4255
+ "useWhen": [
4256
+ "A PanelTools base view filters or searches the tool's own content.",
4257
+ "Several tool products need the same search-row geometry directly below the shared PanelTools header.",
4258
+ "The product needs a compact filter menu next to search while keeping its filter choices and matching policy application-owned."
4259
+ ],
4260
+ "avoidWhen": [
4261
+ "The search belongs inside a Select or SelectMulti popup; use that component's searchable behavior.",
4262
+ "A form needs a labelled standalone field; compose ds-input inside ds-field instead."
4263
+ ],
4264
+ "commonlyComposedWith": [
4265
+ "component:ds-panel-tools",
4266
+ "component:ds-conversation-list",
4267
+ "component:ds-input"
4268
+ ],
4269
+ "accessibility": [
4270
+ "Provide an aria-label that names the searched domain, such as Search agent chats or Search messages.",
4271
+ "The standard search clear action restores focus and emits both the empty query and dsClear.",
4272
+ "When showFilter is enabled, provide stable filterTriggerId and filterControls values, synchronize filterExpanded with the controlled menu, and restore focus after selection."
4273
+ ],
4274
+ "states": [
4275
+ "The row is always 48px high with 8px outer padding and a complete md search recipe: 32px control, text-body-medium at 14px/20px, and a 20px md search icon.",
4276
+ "The search icon stays foreground-secondary at rest, hover, focus, active, and while the query is filled.",
4277
+ "The row and control surface remain transparent so the AppShell chrome wash is visible behind them.",
4278
+ "The row divider remains the same tertiary 1px boundary while the input is focused because it belongs to the 48px container rather than the input control.",
4279
+ "With filtering enabled, the md search control, decorative vertical divider, and borderless md Filter action are separated by 8px; filterActive promotes only the trigger foreground without adding a selected fill."
4280
+ ],
4281
+ "responsiveBehavior": [
4282
+ "The row fills the available drawer or fullscreen width, allows its search region to shrink inside a 300px drawer without pushing the filter trigger under the tool rail, and does not reduce its control below md density."
4283
+ ],
4284
+ "frameworkCaveats": {
4285
+ "customElements": [
4286
+ "Listen for dsChange to receive the current string query and dsClear when the clear action is used.",
4287
+ "Listen for dsFilterToggle and pair the trigger with an externally controlled ds-menu; product-specific filter labels and filtering remain outside this component."
4288
+ ],
4289
+ "react": [
4290
+ "Use DsPanelToolSearch, bind value for controlled state, and handle onDsChange.",
4291
+ "Bind the optional filter trigger state and connect onDsFilterToggle to a controlled DsMenu."
4292
+ ],
4293
+ "angular": [
4294
+ "Import DsPanelToolSearch and bind value as a property; this search composition is not a form value accessor.",
4295
+ "Bind showFilter, filterExpanded, and filterActive, then connect dsFilterToggle to a product-owned ds-menu."
4296
+ ]
4297
+ },
4298
+ "references": [
4299
+ {
4300
+ "label": "Storybook examples",
4301
+ "path": "src/wc/components/PanelToolSearch/PanelToolSearch.stories.ts"
4302
+ }
4303
+ ]
4304
+ },
4305
+ "api": {
4306
+ "props": {
4307
+ "ariaLabel": {
4308
+ "type": "string",
4309
+ "required": false
4310
+ },
4311
+ "controls": {
4312
+ "type": "string | undefined",
4313
+ "required": false
4314
+ },
4315
+ "filterActive": {
4316
+ "type": "boolean",
4317
+ "required": false
4318
+ },
4319
+ "filterAriaLabel": {
4320
+ "type": "string",
4321
+ "required": false
4322
+ },
4323
+ "filterControls": {
4324
+ "type": "string | undefined",
4325
+ "required": false
4326
+ },
4327
+ "filterExpanded": {
4328
+ "type": "boolean",
4329
+ "required": false
4330
+ },
4331
+ "filterTriggerId": {
4332
+ "type": "string",
4333
+ "required": false
4334
+ },
4335
+ "isInactive": {
4336
+ "type": "boolean",
4337
+ "required": false
4338
+ },
4339
+ "placeholder": {
4340
+ "type": "string",
4341
+ "required": false
4342
+ },
4343
+ "showFilter": {
4344
+ "type": "boolean",
4345
+ "required": false
4346
+ },
4347
+ "value": {
4348
+ "type": "string",
4349
+ "required": false
4350
+ }
4351
+ },
4352
+ "events": [
4353
+ {
4354
+ "name": "dsChange",
4355
+ "detail": "string"
4356
+ },
4357
+ {
4358
+ "name": "dsClear",
4359
+ "detail": "void"
4360
+ },
4361
+ {
4362
+ "name": "dsFilterToggle",
4363
+ "detail": "MouseEvent"
4364
+ }
4365
+ ],
4366
+ "slots": []
4367
+ },
4368
+ "exports": {
4369
+ "customElement": "ds-panel-tool-search",
4370
+ "react": "DsPanelToolSearch",
4371
+ "angular": "DsPanelToolSearch"
4372
+ },
4373
+ "dependencies": [
4374
+ "@ds-mo/ui",
4375
+ "@ds-mo/tokens",
4376
+ "@ds-mo/icons"
4377
+ ],
4378
+ "componentDependencies": [
4379
+ "button-unfilled",
4380
+ "divider",
4381
+ "icon",
4382
+ "text"
4383
+ ]
4384
+ },
2933
4385
  {
2934
4386
  "id": "component:ds-panel-tools",
2935
4387
  "tag": "ds-panel-tools",
@@ -2994,21 +4446,32 @@
2994
4446
  "The drawer starts closed, remains open across ordinary route changes, and retains every mounted tool's independent conversation, query, scroll, and work state.",
2995
4447
  "When storageKey is set, persist only the last active tool in this browser and still restore the drawer closed after reload.",
2996
4448
  "The application owns unread state; opening Messages, Agents, Stacks, or Activity does not automatically clear its notification dot.",
4449
+ "PanelTools owns the one visible header above every drawer tool view and above fullscreen views using the default shared header mode. Slotted tool content must not render a second header unless the conversation product explicitly opts into split fullscreen headers.",
4450
+ "PanelTools composes ds-panel-tool-header as its canonical left-aligned header implementation so standalone header stories and shell rendering cannot diverge.",
4451
+ "Each tool supplies its current header title, base-versus-detail Back state, and right-side actions through the headers property. Base views omit Back; deeper views expose Back and update the same header in place.",
4452
+ "Header Back and action events express intent only; the owning tool changes product navigation, menus, and data state. PanelTools keeps the final header action exactly 8px from the drawer edge.",
4453
+ "Menus opened from a right-side header action use PANEL_TOOLS_HEADER_MENU_PLACEMENT: bottom/end choice-cell alignment and a 12px side offset, placing the popup 4px below the 48px header while aligning the final menu item edge with the trigger.",
4454
+ "Tool view roots stay transparent so AppShell's chrome wash remains visible; only explicitly designed child surfaces introduce a fill.",
4455
+ "Tools with search compose ds-panel-tool-search immediately below the shared header. Its 48px row always contains the md search control and must not be reduced to sm or xs.",
2997
4456
  "If an active optional tool becomes unavailable, PanelTools closes the drawer, clears activeTool, and emits its deselection.",
2998
4457
  "Use isInactive only for a temporarily unavailable visible tool; omit tools the user is not authorized to access.",
2999
- "The application owns slotted tool products and data while PanelTools owns rail ordering, drawer selection, open state, motion, and shell events."
4458
+ "The application owns slotted tool products and data while PanelTools owns rail ordering, drawer selection, open state, motion, and shell events.",
4459
+ "Opening and closing clip an already-rendered fixed-width surface. Header and tool content remain fully opaque and retained during width motion; transition completion is accepted only at the measured terminal clip width, after which the closed surface becomes inert and paint-skipped.",
4460
+ "Entering and exiting fullscreen snaps without borrowing the drawer open or close animation.",
4461
+ "When fullscreenHeaderMode is split, PanelTools suppresses only its fullscreen shared header. The application renders exactly two canonical ds-panel-tool-header instances: a tool-title/list-actions header over the 300px history pane and a chat-title/Exit-fullscreen/chat-actions header over the detail pane. The detail header omits Back because the list remains visible."
3000
4462
  ],
3001
4463
  "responsiveBehavior": [
3002
- "On desktop at 1200px and wider, the open drawer reduces main-content width and uses --dimension-panel-width-sm (400px).",
3003
- "On tablet from 768px through 1199px, the open drawer also reduces main-content width and uses --dimension-panel-width-xs (300px).",
3004
- "AppShell owns the responsive drawer-width variable and fixed breakpoint policy; consumers must not hardcode alternate drawer widths.",
4464
+ "The open drawer reduces main-content width and uses --dimension-panel-width-xs (300px) on every supported desktop and tablet viewport.",
4465
+ "AppShell owns the fixed drawer-width variable; consumers must not hardcode alternate drawer widths.",
3005
4466
  "Below 768px, do not reuse desktop PanelTools: future AppShell mobile composition uses a bottom bar for Search, Agents, Notifications, and Stacks, while Help moves into mobile primary navigation.",
3006
4467
  "Keep named-slot content mounted while tools switch or the drawer closes so users can return to in-progress global work.",
4468
+ "Conversation products may use fullscreenHeaderMode split for a 300px history rail beside a flexible detail pane, each with its own canonical header; the application owns that internal split layout.",
3007
4469
  "Use fixed drawer widths for now; do not add user resizing or width persistence."
3008
4470
  ],
3009
4471
  "frameworkCaveats": {
3010
4472
  "customElements": [
3011
4473
  "Assign items as a JavaScript property for structured data; items-json is the string fallback.",
4474
+ "Assign headers as a JavaScript property and replace its object identity whenever an active tool changes title, depth, or actions.",
3012
4475
  "Keep PanelTools mounted at AppShell scope across route changes and provide each product through its matching named slot."
3013
4476
  ],
3014
4477
  "react": [
@@ -3017,6 +4480,7 @@
3017
4480
  ],
3018
4481
  "angular": [
3019
4482
  "Import DsPanelTools from @ds-mo/ui/angular/ds-panel-tools and bind items as a property.",
4483
+ "Bind headers as a replaced object and route dsHeaderBack and dsHeaderAction to the active tool owner.",
3020
4484
  "Keep the component in the persistent shell layout rather than recreating it in routed page components."
3021
4485
  ]
3022
4486
  },
@@ -3041,6 +4505,18 @@
3041
4505
  "type": "PanelToolsToolId | ''",
3042
4506
  "required": false
3043
4507
  },
4508
+ "fullscreenHeaderMode": {
4509
+ "type": "'shared' | 'split'",
4510
+ "required": false
4511
+ },
4512
+ "headers": {
4513
+ "type": "PanelToolsHeaders",
4514
+ "required": false
4515
+ },
4516
+ "headersJson": {
4517
+ "type": "string",
4518
+ "required": false
4519
+ },
3044
4520
  "items": {
3045
4521
  "type": "PanelToolsItem[]",
3046
4522
  "required": false
@@ -3053,6 +4529,10 @@
3053
4529
  "type": "boolean",
3054
4530
  "required": false
3055
4531
  },
4532
+ "presentation": {
4533
+ "type": "'drawer' | 'fullscreen'",
4534
+ "required": false
4535
+ },
3056
4536
  "storageKey": {
3057
4537
  "type": "string",
3058
4538
  "required": false
@@ -3075,6 +4555,18 @@
3075
4555
  "name": "dsChromeTransitionStart",
3076
4556
  "detail": "ChromeTransitionDetail"
3077
4557
  },
4558
+ {
4559
+ "name": "dsHeaderAction",
4560
+ "detail": "{\n tool: PanelToolsToolId;\n id: string;\n }"
4561
+ },
4562
+ {
4563
+ "name": "dsHeaderBack",
4564
+ "detail": "{\n tool: PanelToolsToolId;\n }"
4565
+ },
4566
+ {
4567
+ "name": "dsPresentationChange",
4568
+ "detail": "{\n presentation: 'drawer' | 'fullscreen';\n }"
4569
+ },
3078
4570
  {
3079
4571
  "name": "dsToolChange",
3080
4572
  "detail": "{\n id: PanelToolsToolId;\n selected: boolean;\n }"
@@ -3093,7 +4585,7 @@
3093
4585
  ],
3094
4586
  "componentDependencies": [
3095
4587
  "button-unfilled",
3096
- "text",
4588
+ "panel-tool-header",
3097
4589
  "tooltip"
3098
4590
  ]
3099
4591
  },