@ds-mo/ui 9.1.0 → 9.2.0

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