@ds-mo/ui 14.36.0 → 15.0.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 (479) hide show
  1. package/dist/.package-ready.json +1 -1
  2. package/dist/agent-patterns.json +1 -1
  3. package/dist/agent.json +5083 -4924
  4. package/dist/angular/ds-conversation-list.d.ts +1 -1
  5. package/dist/angular/ds-conversation-list.js +3 -4
  6. package/dist/angular/ds-data-customize.d.ts +18 -0
  7. package/dist/angular/ds-data-customize.js +46 -0
  8. package/dist/angular/ds-data-filter.d.ts +50 -0
  9. package/dist/angular/{ds-table-filter.js → ds-data-filter.js} +10 -10
  10. package/dist/angular/ds-data-group.d.ts +29 -0
  11. package/dist/angular/{ds-table-group.js → ds-data-group.js} +10 -10
  12. package/dist/angular/ds-data-preferences.d.ts +39 -0
  13. package/dist/angular/{ds-table-preferences.js → ds-data-preferences.js} +15 -15
  14. package/dist/angular/ds-data-saved-views.d.ts +49 -0
  15. package/dist/angular/{ds-table-saved-views.js → ds-data-saved-views.js} +10 -10
  16. package/dist/angular/ds-data-search.d.ts +20 -0
  17. package/dist/angular/{ds-table-search.js → ds-data-search.js} +12 -12
  18. package/dist/angular/ds-data-sort.d.ts +16 -0
  19. package/dist/angular/{ds-table-sort.js → ds-data-sort.js} +12 -12
  20. package/dist/angular/ds-data-toolbar.d.ts +12 -0
  21. package/dist/angular/{ds-table-toolbar.js → ds-data-toolbar.js} +10 -10
  22. package/dist/angular/ds-table.d.ts +7 -7
  23. package/dist/angular/ds-table.js +6 -6
  24. package/dist/angular/index.d.ts +1 -1
  25. package/dist/angular/index.js +8 -7
  26. package/dist/angular/proxies.d.ts +8 -7
  27. package/dist/angular/proxies.js +8 -7
  28. package/dist/components/ds-agent-activity.js +1 -1
  29. package/dist/components/ds-agent-questionnaire.js +1 -1
  30. package/dist/components/ds-agent-response.js +1 -1
  31. package/dist/components/ds-agent-source-list.js +1 -1
  32. package/dist/components/ds-agent-tool-call.js +1 -1
  33. package/dist/components/ds-attachment-list.js +1 -1
  34. package/dist/components/ds-avatar.js +1 -1
  35. package/dist/components/ds-badge.js +1 -1
  36. package/dist/components/ds-banner.js +1 -1
  37. package/dist/components/ds-bar-action.js +1 -1
  38. package/dist/components/ds-bar-nav.js +1 -1
  39. package/dist/components/ds-bar-page-title.js +1 -1
  40. package/dist/components/ds-bar-title.js +1 -1
  41. package/dist/components/ds-bar-workflow.js +1 -1
  42. package/dist/components/ds-breadcrumb.js +1 -1
  43. package/dist/components/ds-button-filled.js +1 -1
  44. package/dist/components/ds-button-inverted.js +1 -1
  45. package/dist/components/ds-button-unfilled.js +1 -1
  46. package/dist/components/ds-calendar.js +1 -1
  47. package/dist/components/ds-card-action-center.js +1 -1
  48. package/dist/components/ds-card-chart.js +1 -1
  49. package/dist/components/ds-card-navigation.js +1 -1
  50. package/dist/components/ds-card-overview.js +1 -1
  51. package/dist/components/ds-card-setting.js +1 -1
  52. package/dist/components/ds-card-settings-scope.js +1 -1
  53. package/dist/components/ds-chart-legend.js +1 -1
  54. package/dist/components/ds-chart.js +1 -1
  55. package/dist/components/ds-checkbox.js +1 -1
  56. package/dist/components/ds-chip.js +1 -1
  57. package/dist/components/ds-code-block.js +1 -1
  58. package/dist/components/ds-conversation-list-item.js +1 -1
  59. package/dist/components/ds-conversation-list-section.js +1 -1
  60. package/dist/components/ds-conversation-list.js +1 -1
  61. package/dist/components/ds-conversation-list.js.map +1 -1
  62. package/dist/components/ds-data-customize.d.ts +11 -0
  63. package/dist/components/ds-data-customize.js +2 -0
  64. package/dist/components/ds-data-customize.js.map +1 -0
  65. package/dist/components/{ds-table-group.d.ts → ds-data-filter.d.ts} +4 -4
  66. package/dist/components/ds-data-filter.js +2 -0
  67. package/dist/components/ds-data-filter.js.map +1 -0
  68. package/dist/components/{ds-table-sort.d.ts → ds-data-group.d.ts} +4 -4
  69. package/dist/components/ds-data-group.js +2 -0
  70. package/dist/components/{ds-table-saved-views.d.ts → ds-data-preferences.d.ts} +4 -4
  71. package/dist/components/ds-data-preferences.js +2 -0
  72. package/dist/components/ds-data-preferences.js.map +1 -0
  73. package/dist/components/ds-data-saved-views.d.ts +11 -0
  74. package/dist/components/ds-data-saved-views.js +2 -0
  75. package/dist/components/ds-data-saved-views.js.map +1 -0
  76. package/dist/components/{ds-table-search.d.ts → ds-data-search.d.ts} +4 -4
  77. package/dist/components/ds-data-search.js +2 -0
  78. package/dist/components/ds-data-search.js.map +1 -0
  79. package/dist/components/ds-data-sort.d.ts +11 -0
  80. package/dist/components/ds-data-sort.js +2 -0
  81. package/dist/components/ds-data-sort.js.map +1 -0
  82. package/dist/components/{ds-table-filter.d.ts → ds-data-toolbar.d.ts} +4 -4
  83. package/dist/components/ds-data-toolbar.js +2 -0
  84. package/dist/components/ds-data-toolbar.js.map +1 -0
  85. package/dist/components/ds-divider.js +1 -1
  86. package/dist/components/ds-empty-state.js +1 -1
  87. package/dist/components/ds-field.js +1 -1
  88. package/dist/components/ds-filter-menu.js +1 -1
  89. package/dist/components/ds-icon.js +1 -1
  90. package/dist/components/ds-input-date.js +1 -1
  91. package/dist/components/ds-input-time.js +1 -1
  92. package/dist/components/ds-input-time.js.map +1 -1
  93. package/dist/components/ds-input.js +1 -1
  94. package/dist/components/ds-markdown.js +1 -1
  95. package/dist/components/ds-menu.js +1 -1
  96. package/dist/components/ds-message-actions.js +1 -1
  97. package/dist/components/ds-message-bubble.js +1 -1
  98. package/dist/components/ds-message-composer.js +1 -1
  99. package/dist/components/ds-message-composer.js.map +1 -1
  100. package/dist/components/ds-message-scroller.js +1 -1
  101. package/dist/components/ds-message.js +1 -1
  102. package/dist/components/ds-mobile-bar-nav.js +1 -1
  103. package/dist/components/ds-mobile-header.js +1 -1
  104. package/dist/components/ds-mobile-section-switcher.js +1 -1
  105. package/dist/components/ds-mobile-sheet-nav.js +1 -1
  106. package/dist/components/ds-modal.js +1 -1
  107. package/dist/components/ds-pagination.js +1 -1
  108. package/dist/components/ds-panel-nav.js +1 -1
  109. package/dist/components/ds-panel-sub-nav.js +1 -1
  110. package/dist/components/ds-panel-tool-header.js +1 -1
  111. package/dist/components/ds-panel-tool-search.js +1 -1
  112. package/dist/components/ds-panel-tools.js +1 -1
  113. package/dist/components/ds-paper-texture.js +1 -1
  114. package/dist/components/ds-radio.js +1 -1
  115. package/dist/components/ds-score.js +1 -1
  116. package/dist/components/ds-scroll-overlay.js +1 -1
  117. package/dist/components/ds-select.js +1 -1
  118. package/dist/components/ds-shell-app.js +1 -1
  119. package/dist/components/ds-shell-page.js +1 -1
  120. package/dist/components/ds-shell-tools.js +1 -1
  121. package/dist/components/ds-skeleton.js +1 -1
  122. package/dist/components/ds-slider.js +1 -1
  123. package/dist/components/ds-swatch-picker.js +1 -1
  124. package/dist/components/ds-switch.js +1 -1
  125. package/dist/components/ds-tab-group.js +1 -1
  126. package/dist/components/ds-table.js +1 -1
  127. package/dist/components/ds-table.js.map +1 -1
  128. package/dist/components/ds-tag.js +1 -1
  129. package/dist/components/ds-text.js +1 -1
  130. package/dist/components/ds-textarea.js +1 -1
  131. package/dist/components/ds-time-picker.js +1 -1
  132. package/dist/components/ds-toast.js +1 -1
  133. package/dist/components/ds-tooltip-chart.js +1 -1
  134. package/dist/components/ds-tooltip.js +1 -1
  135. package/dist/components/ds-typing-indicator.js +1 -1
  136. package/dist/components/index.d.ts +5 -5
  137. package/dist/components/{p-D8rpKod8.js → p-0FYD2bev.js} +2 -2
  138. package/dist/components/p-0qY_HDId.js +2 -0
  139. package/dist/components/{p-C0CE2v5D.js.map → p-0qY_HDId.js.map} +1 -1
  140. package/dist/components/{p-DK9Ex3aY.js → p-5URekSny.js} +2 -2
  141. package/dist/components/{p-Ds51RgCi.js → p-7V1AhetH.js} +2 -2
  142. package/dist/components/{p-C2JnoaWI.js → p-8yBdCXCn.js} +2 -2
  143. package/dist/components/{p-CQIh2yRP.js → p-BKZdqJQB.js} +2 -2
  144. package/dist/components/p-BKZdqJQB.js.map +1 -0
  145. package/dist/components/p-BYrBU_U9.js +2 -0
  146. package/dist/components/p-BYrBU_U9.js.map +1 -0
  147. package/dist/components/{p-su6y4hLK.js → p-BciTtTwx.js} +2 -2
  148. package/dist/components/{p-DgG9W9N4.js → p-BeNa6tw5.js} +2 -2
  149. package/dist/components/{p-DgG9W9N4.js.map → p-BeNa6tw5.js.map} +1 -1
  150. package/dist/components/p-BgQMEHRa.js +2 -0
  151. package/dist/components/{p-D7yBIPB6.js.map → p-BgQMEHRa.js.map} +1 -1
  152. package/dist/components/{p-CQ5RwY2C.js → p-BhJXmuRA.js} +2 -2
  153. package/dist/components/{p-neWTRxmf.js → p-Bm7rqs3C.js} +2 -2
  154. package/dist/components/{p-BV5T1hzN.js → p-Bn8I7iw6.js} +2 -2
  155. package/dist/components/{p-PmcUwTQ_.js → p-Bpd6YCo4.js} +2 -2
  156. package/dist/components/p-C-3YqeTb.js +2 -0
  157. package/dist/components/{p-TjXGRPik.js.map → p-C-3YqeTb.js.map} +1 -1
  158. package/dist/components/{p-C4m8y9ki.js → p-CD4DZPy_.js} +2 -2
  159. package/dist/components/{p-B27_chI7.js → p-CElUM-xU.js} +2 -2
  160. package/dist/components/{p-CuwopElg.js → p-CGidq1iC.js} +2 -2
  161. package/dist/components/{p-CWog26I_.js → p-CNxvnQ6A.js} +2 -2
  162. package/dist/components/{p-2GVGhrh0.js → p-CUcUHwI3.js} +2 -2
  163. package/dist/components/{p-CbSUyv5B.js → p-CYzFfFcH.js} +2 -2
  164. package/dist/components/p-CdgOLWX9.js +2 -0
  165. package/dist/components/p-CdgOLWX9.js.map +1 -0
  166. package/dist/components/{p-Jaqdfw4E.js → p-CiH4GG6r.js} +2 -2
  167. package/dist/components/{p-Cl9phSf0.js → p-CiJ1WR11.js} +2 -2
  168. package/dist/components/{p-Cus1Sigh.js → p-CmexIVnE.js} +2 -2
  169. package/dist/components/{p-DLXXGgmf.js → p-CzIpquvw.js} +2 -2
  170. package/dist/components/{p-tNQ0YulU.js → p-D0y7Sja6.js} +2 -2
  171. package/dist/components/{p-x1wf38q3.js → p-D1vQGJzc.js} +2 -2
  172. package/dist/components/{p-x1wf38q3.js.map → p-D1vQGJzc.js.map} +1 -1
  173. package/dist/components/{p-Dryt3COt.js → p-D6Wl3dRO.js} +2 -2
  174. package/dist/components/{p-ji09W9el.js → p-D922f6Tb.js} +2 -2
  175. package/dist/components/{p-CaNCGKEJ.js → p-DHICPS4n.js} +2 -2
  176. package/dist/components/{p-Cga6Ex0E.js → p-DOAybCp0.js} +2 -2
  177. package/dist/components/{p-CWPT3aOB.js → p-DVINzOoK.js} +2 -2
  178. package/dist/components/{p-CWPT3aOB.js.map → p-DVINzOoK.js.map} +1 -1
  179. package/dist/components/{p-7O-2D29W.js → p-DVOjjuXc.js} +2 -2
  180. package/dist/components/{p-DkikNSSO.js → p-Di5FH7eh.js} +2 -2
  181. package/dist/components/{p-DkikNSSO.js.map → p-Di5FH7eh.js.map} +1 -1
  182. package/dist/components/p-DjkUFlDW.js +2 -0
  183. package/dist/components/p-DjkUFlDW.js.map +1 -0
  184. package/dist/components/{p-DVd1TIxi.js → p-Dn9QHL4O.js} +2 -2
  185. package/dist/components/{p-C-dHtQMi.js → p-Do2FJd1y.js} +2 -2
  186. package/dist/components/{p-BWfzaSc3.js → p-DpoTwJAR.js} +2 -2
  187. package/dist/components/{p-ClJhuG5Y.js → p-Dpr2y6_S.js} +2 -2
  188. package/dist/components/{p-ClJhuG5Y.js.map → p-Dpr2y6_S.js.map} +1 -1
  189. package/dist/components/p-Dw9sE6Iw.js +2 -0
  190. package/dist/components/p-Dw9sE6Iw.js.map +1 -0
  191. package/dist/components/{p-BgLI9JoT.js → p-DwbcNDJF.js} +2 -2
  192. package/dist/components/p-Dzndkdx5.js +2 -0
  193. package/dist/components/{p-BOhpMUwO.js.map → p-Dzndkdx5.js.map} +1 -1
  194. package/dist/components/{p-DvzI2A_M.js → p-E5W27Fu_.js} +2 -2
  195. package/dist/components/{p-DkfM55x8.js → p-FIBCluwV.js} +2 -2
  196. package/dist/components/{p-CMQUuGvl.js → p-IEq_06J0.js} +2 -2
  197. package/dist/components/{p-CMQUuGvl.js.map → p-IEq_06J0.js.map} +1 -1
  198. package/dist/components/{p-8oRkhvjy.js → p-MG4lcN0D.js} +2 -2
  199. package/dist/components/{p-DtkLtKY0.js → p-Nc76seSq.js} +2 -2
  200. package/dist/components/p-Nc76seSq.js.map +1 -0
  201. package/dist/components/{p-DBwa1OXP.js → p-ZhP2tVmM.js} +2 -2
  202. package/dist/components/p-aD5cw_m2.js +2 -0
  203. package/dist/components/p-aD5cw_m2.js.map +1 -0
  204. package/dist/components/{p-J5x-QtlD.js → p-etifxiDc.js} +2 -2
  205. package/dist/components/p-kDZ0sEII.js +2 -0
  206. package/dist/components/p-kDZ0sEII.js.map +1 -0
  207. package/dist/components/{p-rYePOPbJ.js → p-ljbw3UMZ.js} +2 -2
  208. package/dist/components/{p-DZ58Sg5a.js → p-vfCu7XSc.js} +2 -2
  209. package/dist/components/{p-Ce4zy8q1.js → p-xdmJCPCg.js} +2 -2
  210. package/dist/components/{p-CDJ2Ntcq.js → p-xtGGIZmU.js} +2 -2
  211. package/dist/docs/components.json +13115 -12615
  212. package/dist/lib/components/Icon/flag-icon-catalog.d.ts +2 -0
  213. package/dist/lib/components/Icon/icon-cache.d.ts +36 -4
  214. package/dist/lib/components/Icon/map-icon-catalog.d.ts +2 -0
  215. package/dist/lib/shell/index.js +2 -2
  216. package/dist/lib/shell/index.js.map +1 -1
  217. package/dist/lib/utils/index.js +68 -5
  218. package/dist/lib/utils/index.js.map +3 -3
  219. package/dist/mcp-data/registry/agent-activity.json +2 -2
  220. package/dist/mcp-data/registry/agent-questionnaire.json +2 -2
  221. package/dist/mcp-data/registry/agent-response.json +1 -1
  222. package/dist/mcp-data/registry/agent-source-list.json +1 -1
  223. package/dist/mcp-data/registry/agent-tool-call.json +2 -2
  224. package/dist/mcp-data/registry/attachment-list.json +1 -1
  225. package/dist/mcp-data/registry/avatar.json +1 -1
  226. package/dist/mcp-data/registry/badge.json +1 -1
  227. package/dist/mcp-data/registry/banner.json +1 -1
  228. package/dist/mcp-data/registry/bar-action.json +1 -1
  229. package/dist/mcp-data/registry/bar-nav.json +1 -1
  230. package/dist/mcp-data/registry/bar-page-title.json +1 -1
  231. package/dist/mcp-data/registry/bar-title.json +1 -1
  232. package/dist/mcp-data/registry/bar-workflow.json +1 -1
  233. package/dist/mcp-data/registry/breadcrumb.json +1 -1
  234. package/dist/mcp-data/registry/button-filled.json +1 -1
  235. package/dist/mcp-data/registry/button-inverted.json +1 -1
  236. package/dist/mcp-data/registry/button-unfilled.json +1 -1
  237. package/dist/mcp-data/registry/calendar.json +1 -1
  238. package/dist/mcp-data/registry/card-action-center.json +1 -1
  239. package/dist/mcp-data/registry/card-chart.json +1 -1
  240. package/dist/mcp-data/registry/card-navigation.json +1 -1
  241. package/dist/mcp-data/registry/card-overview.json +1 -1
  242. package/dist/mcp-data/registry/card-setting.json +1 -1
  243. package/dist/mcp-data/registry/card-settings-scope.json +1 -1
  244. package/dist/mcp-data/registry/chart-legend.json +1 -1
  245. package/dist/mcp-data/registry/chart.json +1 -1
  246. package/dist/mcp-data/registry/checkbox.json +1 -1
  247. package/dist/mcp-data/registry/chip.json +1 -1
  248. package/dist/mcp-data/registry/code-block.json +1 -1
  249. package/dist/mcp-data/registry/conversation-list-item.json +1 -1
  250. package/dist/mcp-data/registry/conversation-list-section.json +1 -1
  251. package/dist/mcp-data/registry/conversation-list.json +10 -32
  252. package/dist/mcp-data/registry/data-customize.json +374 -0
  253. package/dist/mcp-data/registry/{table-filter.json → data-filter.json} +33 -33
  254. package/dist/mcp-data/registry/data-group.json +358 -0
  255. package/dist/mcp-data/registry/data-preferences.json +566 -0
  256. package/dist/mcp-data/registry/data-saved-views.json +433 -0
  257. package/dist/mcp-data/registry/data-search.json +367 -0
  258. package/dist/mcp-data/registry/data-sort.json +254 -0
  259. package/dist/mcp-data/registry/data-toolbar.json +181 -0
  260. package/dist/mcp-data/registry/divider.json +1 -1
  261. package/dist/mcp-data/registry/empty-state.json +1 -1
  262. package/dist/mcp-data/registry/field.json +1 -1
  263. package/dist/mcp-data/registry/filter-menu.json +3 -3
  264. package/dist/mcp-data/registry/icon.json +13 -7
  265. package/dist/mcp-data/registry/input-date.json +1 -1
  266. package/dist/mcp-data/registry/input-time.json +1 -1
  267. package/dist/mcp-data/registry/input.json +2 -2
  268. package/dist/mcp-data/registry/loader.json +1 -1
  269. package/dist/mcp-data/registry/markdown.json +1 -1
  270. package/dist/mcp-data/registry/menu.json +3 -3
  271. package/dist/mcp-data/registry/message-actions.json +1 -1
  272. package/dist/mcp-data/registry/message-bubble.json +1 -1
  273. package/dist/mcp-data/registry/message-composer.json +2 -2
  274. package/dist/mcp-data/registry/message-scroller.json +1 -1
  275. package/dist/mcp-data/registry/message.json +1 -1
  276. package/dist/mcp-data/registry/mobile-bar-nav.json +2 -2
  277. package/dist/mcp-data/registry/mobile-header.json +1 -1
  278. package/dist/mcp-data/registry/mobile-section-switcher.json +1 -1
  279. package/dist/mcp-data/registry/mobile-sheet-nav.json +2 -2
  280. package/dist/mcp-data/registry/modal.json +1 -1
  281. package/dist/mcp-data/registry/pagination.json +1 -1
  282. package/dist/mcp-data/registry/panel-nav.json +1 -1
  283. package/dist/mcp-data/registry/panel-sub-nav.json +1 -1
  284. package/dist/mcp-data/registry/panel-tool-header.json +1 -1
  285. package/dist/mcp-data/registry/panel-tool-search.json +1 -1
  286. package/dist/mcp-data/registry/panel-tools.json +3 -3
  287. package/dist/mcp-data/registry/paper-texture.json +1 -1
  288. package/dist/mcp-data/registry/radio.json +1 -1
  289. package/dist/mcp-data/registry/registry.json +5026 -4864
  290. package/dist/mcp-data/registry/score.json +1 -1
  291. package/dist/mcp-data/registry/scroll-overlay.json +1 -1
  292. package/dist/mcp-data/registry/select.json +1 -1
  293. package/dist/mcp-data/registry/shell-app.json +1 -1
  294. package/dist/mcp-data/registry/shell-page.json +1 -1
  295. package/dist/mcp-data/registry/shell-tools.json +1 -1
  296. package/dist/mcp-data/registry/skeleton.json +1 -1
  297. package/dist/mcp-data/registry/slider.json +1 -1
  298. package/dist/mcp-data/registry/swatch-picker.json +1 -1
  299. package/dist/mcp-data/registry/switch.json +1 -1
  300. package/dist/mcp-data/registry/tab-group.json +1 -1
  301. package/dist/mcp-data/registry/table.json +71 -71
  302. package/dist/mcp-data/registry/tag.json +1 -1
  303. package/dist/mcp-data/registry/text.json +1 -1
  304. package/dist/mcp-data/registry/textarea.json +1 -1
  305. package/dist/mcp-data/registry/time-picker.json +1 -1
  306. package/dist/mcp-data/registry/toast.json +1 -1
  307. package/dist/mcp-data/registry/tooltip-chart.json +1 -1
  308. package/dist/mcp-data/registry/tooltip.json +1 -1
  309. package/dist/mcp-data/registry/typing-indicator.json +1 -1
  310. package/dist/react/components.d.ts +8 -7
  311. package/dist/react/components.js +8 -7
  312. package/dist/react/ds-data-customize.d.ts +13 -0
  313. package/dist/react/ds-data-customize.js +15 -0
  314. package/dist/react/ds-data-filter.d.ts +18 -0
  315. package/dist/react/{ds-table-filter.js → ds-data-filter.js} +5 -5
  316. package/dist/react/ds-data-group.d.ts +14 -0
  317. package/dist/react/{ds-table-group.js → ds-data-group.js} +5 -5
  318. package/dist/react/ds-data-preferences.d.ts +21 -0
  319. package/dist/react/{ds-table-preferences.js → ds-data-preferences.js} +6 -6
  320. package/dist/react/ds-data-saved-views.d.ts +17 -0
  321. package/dist/react/{ds-table-saved-views.js → ds-data-saved-views.js} +5 -5
  322. package/dist/react/ds-data-search.d.ts +14 -0
  323. package/dist/react/{ds-table-search.js → ds-data-search.js} +5 -5
  324. package/dist/react/ds-data-sort.d.ts +12 -0
  325. package/dist/react/ds-data-sort.js +12 -0
  326. package/dist/react/{ds-table-toolbar.d.ts → ds-data-toolbar.d.ts} +3 -3
  327. package/dist/react/ds-data-toolbar.js +12 -0
  328. package/dist/react/ds-table.d.ts +3 -3
  329. package/dist/react/ds-table.js +1 -1
  330. package/dist/styles/table.css +11 -11
  331. package/dist/types/components/ConversationList/ConversationList.d.ts +0 -7
  332. package/dist/types/components/DataCustomize/DataCustomize.d.ts +67 -0
  333. package/dist/types/components/{TableFilter/TableFilter.d.ts → DataFilter/DataFilter.d.ts} +2 -2
  334. package/dist/types/components/{TableGroup/TableGroup.d.ts → DataGroup/DataGroup.d.ts} +8 -8
  335. package/dist/types/components/{TablePreferences/TablePreferences.d.ts → DataPreferences/DataPreferences.d.ts} +29 -13
  336. package/dist/types/components/{TableSavedViews/TableSavedViews.d.ts → DataSavedViews/DataSavedViews.d.ts} +10 -10
  337. package/dist/types/components/DataSavedViews/data-saved-views-types.d.ts +24 -0
  338. package/dist/types/components/DataSavedViews/index.d.ts +2 -0
  339. package/dist/types/components/{TableSearch/TableSearch.d.ts → DataSearch/DataSearch.d.ts} +6 -6
  340. package/dist/types/components/{TableSearch/table-search-model.d.ts → DataSearch/data-search-model.d.ts} +6 -6
  341. package/dist/types/components/{TableSearch/table-search-types.d.ts → DataSearch/data-search-types.d.ts} +3 -3
  342. package/dist/types/components/{TableSort/TableSort.d.ts → DataSort/DataSort.d.ts} +7 -6
  343. package/dist/types/components/DataSort/data-sort-menu.d.ts +15 -0
  344. package/dist/types/components/{TableToolbar/TableToolbar.d.ts → DataToolbar/DataToolbar.d.ts} +3 -3
  345. package/dist/types/components/Icon/icon-cache.d.ts +36 -4
  346. package/dist/types/components/Icon/map-icon-catalog.d.ts +3 -0
  347. package/dist/types/components/PanelTools/PanelTools.d.ts +1 -1
  348. package/dist/types/components/Table/Table.d.ts +9 -9
  349. package/dist/types/components/Table/index.d.ts +1 -1
  350. package/dist/types/components/Table/table-action-menu.d.ts +1 -1
  351. package/dist/types/components/Table/table-body-renderer.d.ts +2 -2
  352. package/dist/types/components/Table/table-column-customizer.d.ts +9 -9
  353. package/dist/types/components/Table/table-group-load-controller.d.ts +2 -2
  354. package/dist/types/components/Table/table-model.d.ts +7 -7
  355. package/dist/types/components/Table/table-render-model.d.ts +3 -3
  356. package/dist/types/components/Table/table-types.d.ts +17 -36
  357. package/dist/types/components/Table/table-virtual-model.d.ts +2 -2
  358. package/dist/types/components.d.ts +3837 -3640
  359. package/dist/types/utils/data-field.d.ts +38 -0
  360. package/dist/types/utils/list-customizer.d.ts +38 -0
  361. package/dist/types/utils/table-caption-compact.d.ts +1 -1
  362. package/dist/vue/components.d.ts +8 -7
  363. package/dist/vue/components.js +8 -7
  364. package/dist/vue/ds-conversation-list.js +1 -3
  365. package/dist/vue/ds-data-customize.d.ts +3 -0
  366. package/dist/vue/ds-data-customize.js +23 -0
  367. package/dist/vue/{ds-table-group.d.ts → ds-data-filter.d.ts} +1 -1
  368. package/dist/vue/{ds-table-filter.js → ds-data-filter.js} +2 -2
  369. package/dist/vue/{ds-table-sort.d.ts → ds-data-group.d.ts} +1 -1
  370. package/dist/vue/{ds-table-group.js → ds-data-group.js} +2 -2
  371. package/dist/vue/{ds-table-saved-views.d.ts → ds-data-preferences.d.ts} +1 -1
  372. package/dist/vue/{ds-table-preferences.js → ds-data-preferences.js} +10 -7
  373. package/dist/vue/ds-data-saved-views.d.ts +3 -0
  374. package/dist/vue/{ds-table-saved-views.js → ds-data-saved-views.js} +2 -2
  375. package/dist/vue/{ds-table-filter.d.ts → ds-data-search.d.ts} +1 -1
  376. package/dist/vue/{ds-table-search.js → ds-data-search.js} +3 -3
  377. package/dist/vue/{ds-table-search.d.ts → ds-data-sort.d.ts} +1 -1
  378. package/dist/vue/{ds-table-sort.js → ds-data-sort.js} +3 -3
  379. package/dist/vue/ds-data-toolbar.d.ts +3 -0
  380. package/dist/vue/ds-data-toolbar.js +9 -0
  381. package/dist/vue/ds-table.js +4 -4
  382. package/package.json +3 -3
  383. package/dist/angular/ds-table-filter.d.ts +0 -50
  384. package/dist/angular/ds-table-group.d.ts +0 -29
  385. package/dist/angular/ds-table-preferences.d.ts +0 -39
  386. package/dist/angular/ds-table-saved-views.d.ts +0 -49
  387. package/dist/angular/ds-table-search.d.ts +0 -20
  388. package/dist/angular/ds-table-sort.d.ts +0 -16
  389. package/dist/angular/ds-table-toolbar.d.ts +0 -12
  390. package/dist/components/ds-table-filter.js +0 -2
  391. package/dist/components/ds-table-filter.js.map +0 -1
  392. package/dist/components/ds-table-group.js +0 -2
  393. package/dist/components/ds-table-preferences.d.ts +0 -11
  394. package/dist/components/ds-table-preferences.js +0 -2
  395. package/dist/components/ds-table-preferences.js.map +0 -1
  396. package/dist/components/ds-table-saved-views.js +0 -2
  397. package/dist/components/ds-table-saved-views.js.map +0 -1
  398. package/dist/components/ds-table-search.js +0 -2
  399. package/dist/components/ds-table-search.js.map +0 -1
  400. package/dist/components/ds-table-sort.js +0 -2
  401. package/dist/components/ds-table-sort.js.map +0 -1
  402. package/dist/components/ds-table-toolbar.d.ts +0 -11
  403. package/dist/components/ds-table-toolbar.js +0 -2
  404. package/dist/components/ds-table-toolbar.js.map +0 -1
  405. package/dist/components/p-BOhpMUwO.js +0 -2
  406. package/dist/components/p-C0CE2v5D.js +0 -2
  407. package/dist/components/p-CKarsuR2.js +0 -2
  408. package/dist/components/p-CKarsuR2.js.map +0 -1
  409. package/dist/components/p-CQIh2yRP.js.map +0 -1
  410. package/dist/components/p-Cea7rROU.js +0 -2
  411. package/dist/components/p-Cea7rROU.js.map +0 -1
  412. package/dist/components/p-D7yBIPB6.js +0 -2
  413. package/dist/components/p-DtkLtKY0.js.map +0 -1
  414. package/dist/components/p-KBrC9IG4.js +0 -2
  415. package/dist/components/p-KBrC9IG4.js.map +0 -1
  416. package/dist/components/p-MQ36mEgn.js +0 -2
  417. package/dist/components/p-MQ36mEgn.js.map +0 -1
  418. package/dist/components/p-TjXGRPik.js +0 -2
  419. package/dist/components/p-bM3LH3kc.js +0 -2
  420. package/dist/components/p-bM3LH3kc.js.map +0 -1
  421. package/dist/mcp-data/registry/table-group.json +0 -358
  422. package/dist/mcp-data/registry/table-preferences.json +0 -511
  423. package/dist/mcp-data/registry/table-saved-views.json +0 -433
  424. package/dist/mcp-data/registry/table-search.json +0 -366
  425. package/dist/mcp-data/registry/table-sort.json +0 -253
  426. package/dist/mcp-data/registry/table-toolbar.json +0 -180
  427. package/dist/react/ds-table-filter.d.ts +0 -18
  428. package/dist/react/ds-table-group.d.ts +0 -14
  429. package/dist/react/ds-table-preferences.d.ts +0 -21
  430. package/dist/react/ds-table-saved-views.d.ts +0 -17
  431. package/dist/react/ds-table-search.d.ts +0 -14
  432. package/dist/react/ds-table-sort.d.ts +0 -12
  433. package/dist/react/ds-table-sort.js +0 -12
  434. package/dist/react/ds-table-toolbar.js +0 -12
  435. package/dist/types/components/TableSavedViews/index.d.ts +0 -2
  436. package/dist/types/components/TableSavedViews/table-saved-views-types.d.ts +0 -24
  437. package/dist/types/components/TableSort/table-sort-menu.d.ts +0 -15
  438. package/dist/vue/ds-table-preferences.d.ts +0 -3
  439. package/dist/vue/ds-table-toolbar.d.ts +0 -3
  440. package/dist/vue/ds-table-toolbar.js +0 -9
  441. /package/dist/components/{ds-table-group.js.map → ds-data-group.js.map} +0 -0
  442. /package/dist/components/{p-D8rpKod8.js.map → p-0FYD2bev.js.map} +0 -0
  443. /package/dist/components/{p-DK9Ex3aY.js.map → p-5URekSny.js.map} +0 -0
  444. /package/dist/components/{p-Ds51RgCi.js.map → p-7V1AhetH.js.map} +0 -0
  445. /package/dist/components/{p-C2JnoaWI.js.map → p-8yBdCXCn.js.map} +0 -0
  446. /package/dist/components/{p-su6y4hLK.js.map → p-BciTtTwx.js.map} +0 -0
  447. /package/dist/components/{p-CQ5RwY2C.js.map → p-BhJXmuRA.js.map} +0 -0
  448. /package/dist/components/{p-neWTRxmf.js.map → p-Bm7rqs3C.js.map} +0 -0
  449. /package/dist/components/{p-BV5T1hzN.js.map → p-Bn8I7iw6.js.map} +0 -0
  450. /package/dist/components/{p-PmcUwTQ_.js.map → p-Bpd6YCo4.js.map} +0 -0
  451. /package/dist/components/{p-C4m8y9ki.js.map → p-CD4DZPy_.js.map} +0 -0
  452. /package/dist/components/{p-B27_chI7.js.map → p-CElUM-xU.js.map} +0 -0
  453. /package/dist/components/{p-CuwopElg.js.map → p-CGidq1iC.js.map} +0 -0
  454. /package/dist/components/{p-CWog26I_.js.map → p-CNxvnQ6A.js.map} +0 -0
  455. /package/dist/components/{p-2GVGhrh0.js.map → p-CUcUHwI3.js.map} +0 -0
  456. /package/dist/components/{p-CbSUyv5B.js.map → p-CYzFfFcH.js.map} +0 -0
  457. /package/dist/components/{p-Jaqdfw4E.js.map → p-CiH4GG6r.js.map} +0 -0
  458. /package/dist/components/{p-Cl9phSf0.js.map → p-CiJ1WR11.js.map} +0 -0
  459. /package/dist/components/{p-Cus1Sigh.js.map → p-CmexIVnE.js.map} +0 -0
  460. /package/dist/components/{p-DLXXGgmf.js.map → p-CzIpquvw.js.map} +0 -0
  461. /package/dist/components/{p-tNQ0YulU.js.map → p-D0y7Sja6.js.map} +0 -0
  462. /package/dist/components/{p-Dryt3COt.js.map → p-D6Wl3dRO.js.map} +0 -0
  463. /package/dist/components/{p-ji09W9el.js.map → p-D922f6Tb.js.map} +0 -0
  464. /package/dist/components/{p-CaNCGKEJ.js.map → p-DHICPS4n.js.map} +0 -0
  465. /package/dist/components/{p-Cga6Ex0E.js.map → p-DOAybCp0.js.map} +0 -0
  466. /package/dist/components/{p-7O-2D29W.js.map → p-DVOjjuXc.js.map} +0 -0
  467. /package/dist/components/{p-DVd1TIxi.js.map → p-Dn9QHL4O.js.map} +0 -0
  468. /package/dist/components/{p-C-dHtQMi.js.map → p-Do2FJd1y.js.map} +0 -0
  469. /package/dist/components/{p-BWfzaSc3.js.map → p-DpoTwJAR.js.map} +0 -0
  470. /package/dist/components/{p-BgLI9JoT.js.map → p-DwbcNDJF.js.map} +0 -0
  471. /package/dist/components/{p-DvzI2A_M.js.map → p-E5W27Fu_.js.map} +0 -0
  472. /package/dist/components/{p-DkfM55x8.js.map → p-FIBCluwV.js.map} +0 -0
  473. /package/dist/components/{p-8oRkhvjy.js.map → p-MG4lcN0D.js.map} +0 -0
  474. /package/dist/components/{p-DBwa1OXP.js.map → p-ZhP2tVmM.js.map} +0 -0
  475. /package/dist/components/{p-J5x-QtlD.js.map → p-etifxiDc.js.map} +0 -0
  476. /package/dist/components/{p-rYePOPbJ.js.map → p-ljbw3UMZ.js.map} +0 -0
  477. /package/dist/components/{p-DZ58Sg5a.js.map → p-vfCu7XSc.js.map} +0 -0
  478. /package/dist/components/{p-Ce4zy8q1.js.map → p-xdmJCPCg.js.map} +0 -0
  479. /package/dist/components/{p-CDJ2Ntcq.js.map → p-xtGGIZmU.js.map} +0 -0
@@ -132,7 +132,7 @@
132
132
  "peerDependencies": {
133
133
  "required": [
134
134
  "@ds-mo/tokens ^6.5.1",
135
- "@ds-mo/icons ^7.0.0"
135
+ "@ds-mo/icons ^8.1.0"
136
136
  ],
137
137
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
138
138
  }
@@ -156,7 +156,7 @@
156
156
  },
157
157
  {
158
158
  "path": "src/wc/components/AgentActivity/AgentActivity.tsx",
159
- "content": "import { Component, Prop, State, Watch, h, Host } from '@stencil/core';\nimport type { AgentActivityItem } from '../conversation-types';\n\n@Component({\n tag: 'ds-agent-activity',\n styleUrl: 'AgentActivity.css',\n scoped: true,\n})\nexport class AgentActivity {\n @Prop() items: AgentActivityItem[] = [];\n @Prop() heading: string = 'Activity';\n @Prop() open: boolean = false;\n\n @State() private expanded: boolean = false;\n\n componentWillLoad() {\n this.expanded = this.open;\n }\n\n @Watch('open')\n handleOpenChange(open: boolean) {\n this.expanded = open;\n }\n\n private get currentItem(): AgentActivityItem | undefined {\n return (\n this.items.find(item => item.state === 'active') ??\n this.items.find(item => item.state === 'error') ??\n [...this.items].reverse().find(item => item.state === 'complete') ??\n this.items.find(item => item.state === 'pending')\n );\n }\n\n private handleToggle = (event: Event) => {\n this.expanded = (event.currentTarget as HTMLDetailsElement).open;\n };\n\n private stateLabel(item: AgentActivityItem): string {\n if (item.state === 'active') return 'In progress';\n if (item.state === 'complete') return 'Complete';\n if (item.state === 'error') return 'Error';\n return 'Pending';\n }\n\n render() {\n return (\n <Host>\n <details class=\"agent-activity\" open={this.open} onToggle={this.handleToggle}>\n <summary>\n <ds-icon name=\"ChevronRight\" size=\"xs\" color=\"inherit\" />\n <ds-text\n class=\"agent-activity__summary-label\"\n variant=\"text-body-small\"\n shimmer={!this.expanded && this.currentItem?.state === 'active'}\n >\n {this.expanded ? this.heading : (this.currentItem?.label ?? this.heading)}\n </ds-text>\n </summary>\n <ol>\n {this.items.map(item => (\n <li class={`agent-activity__item agent-activity__item--${item.state}`}>\n <span class=\"agent-activity__marker\" aria-hidden=\"true\">\n {item.state === 'active' ? (\n <ds-loader size=\"xs\" color=\"inherit\" />\n ) : item.state === 'pending' ? (\n <span class=\"agent-activity__pending-dot\" />\n ) : (\n <ds-icon\n name={item.state === 'error' ? 'ErrorTriangle' : 'Check'}\n size=\"xs\"\n color=\"inherit\"\n />\n )}\n </span>\n <span>\n <ds-text variant=\"text-body-small\" shimmer={item.state === 'active'}>\n {item.label}\n </ds-text>\n {item.detail ? (\n <ds-text variant=\"text-caption\" color=\"secondary\">\n {item.detail}\n </ds-text>\n ) : null}\n <span class=\"agent-activity__state ds-visually-hidden\">\n {this.stateLabel(item)}\n </span>\n </span>\n </li>\n ))}\n </ol>\n </details>\n </Host>\n );\n }\n}\n",
159
+ "content": "import { Component, Prop, State, Watch, h, Host } from '@stencil/core';\nimport type { AgentActivityItem } from '../conversation-types';\n\n@Component({\n tag: 'ds-agent-activity',\n styleUrl: 'AgentActivity.css',\n scoped: true,\n})\nexport class AgentActivity {\n @Prop() items: AgentActivityItem[] = [];\n @Prop() heading: string = 'Activity';\n @Prop() open: boolean = false;\n\n @State() private expanded: boolean = false;\n\n componentWillLoad() {\n this.expanded = this.open;\n }\n\n @Watch('open')\n handleOpenChange(open: boolean) {\n this.expanded = open;\n }\n\n private get currentItem(): AgentActivityItem | undefined {\n return (\n this.items.find(item => item.state === 'active') ??\n this.items.find(item => item.state === 'error') ??\n [...this.items].reverse().find(item => item.state === 'complete') ??\n this.items.find(item => item.state === 'pending')\n );\n }\n\n private handleToggle = (event: Event) => {\n this.expanded = (event.currentTarget as HTMLDetailsElement).open;\n };\n\n private stateLabel(item: AgentActivityItem): string {\n if (item.state === 'active') return 'In progress';\n if (item.state === 'complete') return 'Complete';\n if (item.state === 'error') return 'Error';\n return 'Pending';\n }\n\n render() {\n return (\n <Host>\n <details class=\"agent-activity\" open={this.open} onToggle={this.handleToggle}>\n <summary>\n <ds-icon name=\"ChevronRight\" size=\"xs\" color=\"inherit\" />\n <ds-text\n class=\"agent-activity__summary-label\"\n variant=\"text-body-small\"\n shimmer={!this.expanded && this.currentItem?.state === 'active'}\n >\n {this.expanded ? this.heading : (this.currentItem?.label ?? this.heading)}\n </ds-text>\n </summary>\n <ol>\n {this.items.map(item => (\n <li class={`agent-activity__item agent-activity__item--${item.state}`}>\n <span class=\"agent-activity__marker\" aria-hidden=\"true\">\n {item.state === 'active' ? (\n <ds-loader size=\"xs\" color=\"inherit\" />\n ) : item.state === 'pending' ? (\n <span class=\"agent-activity__pending-dot\" />\n ) : (\n <ds-icon\n name={item.state === 'error' ? 'ExclamationTriangle' : 'Check'}\n size=\"xs\"\n color=\"inherit\"\n />\n )}\n </span>\n <span>\n <ds-text variant=\"text-body-small\" shimmer={item.state === 'active'}>\n {item.label}\n </ds-text>\n {item.detail ? (\n <ds-text variant=\"text-caption\" color=\"secondary\">\n {item.detail}\n </ds-text>\n ) : null}\n <span class=\"agent-activity__state ds-visually-hidden\">\n {this.stateLabel(item)}\n </span>\n </span>\n </li>\n ))}\n </ol>\n </details>\n </Host>\n );\n }\n}\n",
160
160
  "type": "registry:ui"
161
161
  }
162
162
  ]
@@ -237,7 +237,7 @@
237
237
  "peerDependencies": {
238
238
  "required": [
239
239
  "@ds-mo/tokens ^6.5.1",
240
- "@ds-mo/icons ^7.0.0"
240
+ "@ds-mo/icons ^8.1.0"
241
241
  ],
242
242
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
243
243
  }
@@ -266,7 +266,7 @@
266
266
  },
267
267
  {
268
268
  "path": "src/wc/components/AgentQuestionnaire/AgentQuestionnaire.tsx",
269
- "content": "import {\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Method,\n Prop,\n State,\n Watch,\n} from '@stencil/core';\nimport type {\n AgentQuestion,\n AgentQuestionAnswer,\n AgentQuestionnaireAnswerEventDetail,\n AgentQuestionnaireCancelEventDetail,\n AgentQuestionnaireLabels,\n AgentQuestionnaireStatus,\n} from '../conversation-types';\nimport {\n createQuestionnaireDrafts,\n formatQuestionAnswer,\n normalizeQuestionAnswer,\n validateQuestionDraft,\n} from './agent-questionnaire-model';\nimport type { AgentQuestionDraft, AgentQuestionDrafts } from './agent-questionnaire-model';\n\nconst DEFAULT_LABELS: AgentQuestionnaireLabels = {\n progress: 'Question {current} of {total}',\n previous: 'Previous',\n next: 'Next',\n answer: 'Answer',\n skip: 'Skip',\n cancel: 'Cancel',\n other: 'Other',\n otherPlaceholder: 'Enter another answer',\n preparing: 'Preparing questions…',\n};\n\nlet questionnaireId = 0;\n\n@Component({\n tag: 'ds-agent-questionnaire',\n styleUrl: 'AgentQuestionnaire.css',\n scoped: true,\n})\nexport class AgentQuestionnaire {\n @Element() el!: HTMLElement;\n\n @Prop() requestId!: string;\n @Prop() questions!: AgentQuestion[];\n @Prop() answers: AgentQuestionAnswer[] = [];\n @Prop() status: AgentQuestionnaireStatus = 'ready';\n @Prop() errorMessage?: string;\n @Prop() allowCancel: boolean = false;\n @Prop() labels?: Partial<AgentQuestionnaireLabels>;\n\n @Event() dsAnswer!: EventEmitter<AgentQuestionnaireAnswerEventDetail>;\n @Event() dsCancel!: EventEmitter<AgentQuestionnaireCancelEventDetail>;\n\n @State() private currentStep = 0;\n @State() private drafts: AgentQuestionDrafts = {};\n @State() private validation: Record<string, string> = {};\n\n private readonly instanceId = ++questionnaireId;\n private readonly otherValue = `__ds-agent-questionnaire-other-${this.instanceId}`;\n private answerPending = false;\n private resetScheduled = false;\n private draftRequestId?: string;\n private answersSnapshot: AgentQuestionAnswer[] = [];\n private waitingForRequestAnswers = false;\n\n componentWillLoad() {\n this.draftRequestId = this.requestId;\n this.answersSnapshot = this.answers;\n this.resetDraft();\n }\n\n @Watch('requestId')\n @Watch('questions')\n @Watch('answers')\n handleQuestionnaireInputChange() {\n this.scheduleDraftReset();\n }\n\n @Watch('status')\n handleStatusChange(status: AgentQuestionnaireStatus) {\n if (status !== 'submitting') this.answerPending = false;\n }\n\n @Method()\n async setFocus(): Promise<void> {\n this.focusCurrentControl();\n }\n\n private get copy(): AgentQuestionnaireLabels {\n return { ...DEFAULT_LABELS, ...this.labels };\n }\n\n private get disabled(): boolean {\n return this.status === 'submitting';\n }\n\n private resetDraft(answers = this.answers) {\n this.currentStep = 0;\n this.drafts = createQuestionnaireDrafts(this.questions ?? [], answers ?? []);\n this.validation = {};\n this.answerPending = false;\n }\n\n private scheduleDraftReset() {\n if (this.resetScheduled) return;\n this.resetScheduled = true;\n queueMicrotask(() => {\n this.resetScheduled = false;\n const requestChanged = this.requestId !== this.draftRequestId;\n const answersChanged = this.answers !== this.answersSnapshot;\n if (requestChanged && !answersChanged) {\n this.waitingForRequestAnswers = true;\n } else if (answersChanged) {\n this.waitingForRequestAnswers = false;\n }\n this.resetDraft(this.waitingForRequestAnswers ? [] : this.answers);\n this.draftRequestId = this.requestId;\n this.answersSnapshot = this.answers;\n });\n }\n\n private focusCurrentControl(preferInvalid = false) {\n const focus = () => {\n const invalidControl = preferInvalid\n ? this.el.querySelector<HTMLElement>(\n '[data-question-control][aria-invalid=\"true\"]:not([disabled])'\n )\n : null;\n const control =\n invalidControl ??\n this.el.querySelector<HTMLElement>(\n '[data-question-control]:not([disabled]):not([is-inactive])'\n );\n const action = this.el.querySelector<HTMLElement>(\n '[data-question-action]:not([is-inactive]):not([is-loading])'\n );\n const target = (control ?? action) as\n | (HTMLElement & { setFocus?: () => Promise<void> })\n | null;\n if (target?.setFocus) void target.setFocus();\n else target?.focus();\n };\n focus();\n requestAnimationFrame(focus);\n setTimeout(focus, 0);\n }\n\n private updateDraft(questionId: string, update: Partial<AgentQuestionDraft>) {\n const previous = this.drafts[questionId] ?? {\n value: '',\n otherSelected: false,\n otherText: '',\n skipped: false,\n };\n this.drafts = {\n ...this.drafts,\n [questionId]: { ...previous, ...update, skipped: false },\n };\n if (this.validation[questionId]) {\n const { [questionId]: _removed, ...rest } = this.validation;\n this.validation = rest;\n }\n }\n\n private validate(question: AgentQuestion): boolean {\n const message = validateQuestionDraft(question, this.drafts[question.id]);\n if (!message) return true;\n this.validation = { ...this.validation, [question.id]: message };\n this.focusCurrentControl(true);\n return false;\n }\n\n private move(step: number) {\n this.currentStep = Math.min(Math.max(step, 0), this.questions.length - 1);\n this.focusCurrentControl();\n }\n\n private next(question: AgentQuestion) {\n if (!this.validate(question)) return;\n this.move(this.currentStep + 1);\n }\n\n private skip(question: AgentQuestion) {\n if (question.required) return;\n this.drafts = {\n ...this.drafts,\n [question.id]: {\n ...(this.drafts[question.id] ?? {\n value: '',\n otherSelected: false,\n otherText: '',\n }),\n skipped: true,\n },\n };\n if (this.currentStep < this.questions.length - 1) this.move(this.currentStep + 1);\n else this.submit();\n }\n\n private submit() {\n if (this.disabled || this.answerPending) return;\n const invalidIndex = this.questions.findIndex(question => !this.validateWithoutFocus(question));\n if (invalidIndex >= 0) {\n this.currentStep = invalidIndex;\n this.focusCurrentControl(true);\n return;\n }\n\n this.answerPending = true;\n this.dsAnswer.emit({\n requestId: this.requestId,\n answers: this.questions.map(question =>\n normalizeQuestionAnswer(question, this.drafts[question.id])\n ),\n });\n }\n\n private validateWithoutFocus(question: AgentQuestion): boolean {\n const message = validateQuestionDraft(question, this.drafts[question.id]);\n if (!message) return true;\n this.validation = { ...this.validation, [question.id]: message };\n return false;\n }\n\n private progressLabel(): string {\n return this.copy.progress\n .split('{current}')\n .join(String(this.currentStep + 1))\n .split('{total}')\n .join(String(this.questions.length));\n }\n\n private selectSingle(question: AgentQuestion, value: string) {\n const otherSelected = value === this.otherValue;\n this.updateDraft(question.id, {\n value: otherSelected ? '' : value,\n otherSelected,\n });\n if (otherSelected) {\n requestAnimationFrame(() =>\n this.el.querySelector<HTMLInputElement>('[data-question-other-input]')?.focus()\n );\n }\n }\n\n private renderSingleChoice(question: AgentQuestion, promptId: string, errorId: string) {\n const draft = this.drafts[question.id];\n const value = draft.otherSelected\n ? this.otherValue\n : typeof draft.value === 'string'\n ? draft.value\n : '';\n const options = [\n ...(question.choices ?? []),\n ...(question.allowOther ? [{ value: this.otherValue, label: this.copy.other }] : []),\n ];\n return (\n <div class=\"questionnaire__single-choice\">\n <ds-radio\n data-question-control\n size=\"lg\"\n options={options}\n value={value}\n disabled={this.disabled}\n form={`ds-agent-questionnaire-detached-${this.instanceId}`}\n ariaLabelledby={promptId}\n aria-describedby={this.validation[question.id] ? errorId : undefined}\n onDsChange={(event: CustomEvent<string>) => this.selectSingle(question, event.detail)}\n />\n {draft.otherSelected ? this.renderOtherInput(question, errorId) : null}\n </div>\n );\n }\n\n private renderMultipleChoice(question: AgentQuestion, errorId: string) {\n const draft = this.drafts[question.id];\n const values = Array.isArray(draft.value) ? draft.value : [];\n const detachedForm = `ds-agent-questionnaire-detached-${this.instanceId}`;\n return (\n <div class=\"questionnaire__multiple-choice\">\n {question.choices?.map(choice => (\n <ds-checkbox\n key={choice.value}\n data-question-control\n size=\"lg\"\n label={choice.label}\n description={choice.description}\n value={choice.value}\n checked={values.includes(choice.value)}\n disabled={this.disabled}\n form={detachedForm}\n onDsChange={(event: CustomEvent<boolean>) => {\n this.updateDraft(question.id, {\n value: event.detail\n ? [...values, choice.value]\n : values.filter(value => value !== choice.value),\n });\n }}\n />\n ))}\n {question.allowOther ? (\n <div class=\"questionnaire__other-choice\">\n <ds-checkbox\n data-question-control\n size=\"lg\"\n label={this.copy.other}\n checked={draft.otherSelected}\n disabled={this.disabled}\n form={detachedForm}\n onDsChange={(event: CustomEvent<boolean>) => {\n this.updateDraft(question.id, { otherSelected: event.detail });\n if (event.detail) {\n requestAnimationFrame(() =>\n this.el.querySelector<HTMLInputElement>('[data-question-other-input]')?.focus()\n );\n }\n }}\n />\n {draft.otherSelected ? this.renderOtherInput(question, errorId) : null}\n </div>\n ) : null}\n </div>\n );\n }\n\n private renderOtherInput(question: AgentQuestion, errorId: string) {\n const draft = this.drafts[question.id];\n return (\n <input\n class=\"questionnaire__other-input\"\n data-question-control\n data-question-other-input\n type=\"text\"\n form={`ds-agent-questionnaire-detached-${this.instanceId}`}\n value={draft.otherText}\n placeholder={this.copy.otherPlaceholder}\n aria-label={this.copy.other}\n aria-invalid={this.validation[question.id] ? 'true' : undefined}\n aria-describedby={this.validation[question.id] ? errorId : undefined}\n disabled={this.disabled}\n onInput={(event: Event) =>\n this.updateDraft(question.id, {\n otherText: (event.target as HTMLInputElement).value,\n })\n }\n />\n );\n }\n\n private renderQuestion(question: AgentQuestion) {\n const draft = this.drafts[question.id];\n const errorId = `ds-agent-questionnaire-${this.instanceId}-${this.currentStep}-error`;\n const promptId = `ds-agent-questionnaire-${this.instanceId}-${this.currentStep}-prompt`;\n return (\n <div class=\"questionnaire__body\">\n <div class=\"questionnaire__prompt\">\n <ds-text as=\"h2\" variant=\"text-title-small\" textId={promptId}>\n {question.question}\n </ds-text>\n {question.description ? (\n <ds-text variant=\"text-body-small\" color=\"secondary\">\n {question.description}\n </ds-text>\n ) : null}\n </div>\n {question.type === 'text' ? (\n <textarea\n class=\"questionnaire__text-input\"\n data-question-control\n value={typeof draft.value === 'string' ? draft.value : ''}\n form={`ds-agent-questionnaire-detached-${this.instanceId}`}\n placeholder={question.placeholder}\n aria-label={question.question}\n aria-invalid={this.validation[question.id] ? 'true' : undefined}\n aria-describedby={this.validation[question.id] ? errorId : undefined}\n disabled={this.disabled}\n rows={4}\n onInput={(event: Event) =>\n this.updateDraft(question.id, {\n value: (event.target as HTMLTextAreaElement).value,\n })\n }\n />\n ) : (\n <fieldset\n class=\"questionnaire__choices\"\n aria-describedby={this.validation[question.id] ? errorId : undefined}\n >\n <legend class=\"ds-visually-hidden\">{question.question}</legend>\n {question.type === 'single'\n ? this.renderSingleChoice(question, promptId, errorId)\n : this.renderMultipleChoice(question, errorId)}\n </fieldset>\n )}\n {this.validation[question.id] ? (\n <div id={errorId} class=\"questionnaire__error\" role=\"alert\">\n <ds-icon name=\"ErrorTriangle\" size=\"xs\" color=\"inherit\" />\n <ds-text variant=\"text-body-small\" color=\"negative\">\n {this.validation[question.id]}\n </ds-text>\n </div>\n ) : null}\n </div>\n );\n }\n\n private renderAnswered() {\n return (\n <div class=\"questionnaire questionnaire--answered\">\n <ol class=\"questionnaire__summary\">\n {this.questions.map(question => (\n <li>\n <ds-text variant=\"text-body-small\" emphasis>\n {question.question}\n </ds-text>\n <ds-text variant=\"text-body-small\" color=\"secondary\">\n {formatQuestionAnswer(\n question,\n this.answers.find(answer => answer.questionId === question.id)\n )}\n </ds-text>\n </li>\n ))}\n </ol>\n </div>\n );\n }\n\n render() {\n if (this.status === 'preparing') {\n return (\n <Host>\n <div class=\"questionnaire questionnaire--preparing\" role=\"status\">\n <ds-loader size=\"sm\" />\n <ds-text variant=\"text-body-medium\">{this.copy.preparing}</ds-text>\n </div>\n </Host>\n );\n }\n if (!this.questions?.length) return null;\n if (this.status === 'answered') return <Host>{this.renderAnswered()}</Host>;\n\n const question = this.questions[this.currentStep];\n const last = this.currentStep === this.questions.length - 1;\n const canSkip = Boolean(question.skippable && !question.required);\n return (\n <Host>\n <section\n class={{\n questionnaire: true,\n 'questionnaire--submitting': this.disabled,\n 'questionnaire--error': this.status === 'error',\n }}\n aria-busy={this.disabled ? 'true' : undefined}\n aria-label={question.question}\n >\n <header class=\"questionnaire__header\">\n <ds-text variant=\"text-caption\" color=\"secondary\">\n {this.progressLabel()}\n </ds-text>\n {this.allowCancel ? (\n <ds-tooltip label={this.copy.cancel} side=\"top\" size=\"sm\">\n <ds-button-unfilled\n data-question-action\n variant=\"icon\"\n icon=\"Cross\"\n size=\"sm\"\n aria-label={this.copy.cancel}\n hasBorder={false}\n isInactive={this.disabled}\n onDsClick={() => this.dsCancel.emit({ requestId: this.requestId })}\n />\n </ds-tooltip>\n ) : null}\n </header>\n {this.renderQuestion(question)}\n {this.status === 'error' && this.errorMessage ? (\n <div class=\"questionnaire__submission-error\" role=\"alert\">\n <ds-icon name=\"ErrorTriangle\" size=\"xs\" color=\"inherit\" />\n <ds-text variant=\"text-body-small\" color=\"negative\">\n {this.errorMessage}\n </ds-text>\n </div>\n ) : null}\n <footer class=\"questionnaire__actions\">\n <div class=\"questionnaire__actions-leading\">\n {this.currentStep > 0 ? (\n <div class=\"questionnaire__action-item\">\n <ds-button-unfilled\n data-question-action\n label={this.copy.previous}\n size=\"sm\"\n width=\"fill\"\n isInactive={this.disabled}\n onDsClick={() => this.move(this.currentStep - 1)}\n />\n </div>\n ) : null}\n {canSkip ? (\n <div class=\"questionnaire__action-item\">\n <ds-button-unfilled\n data-question-action\n label={this.copy.skip}\n size=\"sm\"\n width=\"fill\"\n hasBorder={false}\n isInactive={this.disabled}\n onDsClick={() => this.skip(question)}\n />\n </div>\n ) : null}\n </div>\n <div class=\"questionnaire__action-item questionnaire__action-item--primary\">\n <ds-button-filled\n data-question-action\n label={last ? this.copy.answer : this.copy.next}\n size=\"sm\"\n width=\"fill\"\n isLoading={this.disabled}\n onDsClick={() => (last ? this.submit() : this.next(question))}\n />\n </div>\n </footer>\n </section>\n </Host>\n );\n }\n}\n",
269
+ "content": "import {\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Method,\n Prop,\n State,\n Watch,\n} from '@stencil/core';\nimport type {\n AgentQuestion,\n AgentQuestionAnswer,\n AgentQuestionnaireAnswerEventDetail,\n AgentQuestionnaireCancelEventDetail,\n AgentQuestionnaireLabels,\n AgentQuestionnaireStatus,\n} from '../conversation-types';\nimport {\n createQuestionnaireDrafts,\n formatQuestionAnswer,\n normalizeQuestionAnswer,\n validateQuestionDraft,\n} from './agent-questionnaire-model';\nimport type { AgentQuestionDraft, AgentQuestionDrafts } from './agent-questionnaire-model';\n\nconst DEFAULT_LABELS: AgentQuestionnaireLabels = {\n progress: 'Question {current} of {total}',\n previous: 'Previous',\n next: 'Next',\n answer: 'Answer',\n skip: 'Skip',\n cancel: 'Cancel',\n other: 'Other',\n otherPlaceholder: 'Enter another answer',\n preparing: 'Preparing questions…',\n};\n\nlet questionnaireId = 0;\n\n@Component({\n tag: 'ds-agent-questionnaire',\n styleUrl: 'AgentQuestionnaire.css',\n scoped: true,\n})\nexport class AgentQuestionnaire {\n @Element() el!: HTMLElement;\n\n @Prop() requestId!: string;\n @Prop() questions!: AgentQuestion[];\n @Prop() answers: AgentQuestionAnswer[] = [];\n @Prop() status: AgentQuestionnaireStatus = 'ready';\n @Prop() errorMessage?: string;\n @Prop() allowCancel: boolean = false;\n @Prop() labels?: Partial<AgentQuestionnaireLabels>;\n\n @Event() dsAnswer!: EventEmitter<AgentQuestionnaireAnswerEventDetail>;\n @Event() dsCancel!: EventEmitter<AgentQuestionnaireCancelEventDetail>;\n\n @State() private currentStep = 0;\n @State() private drafts: AgentQuestionDrafts = {};\n @State() private validation: Record<string, string> = {};\n\n private readonly instanceId = ++questionnaireId;\n private readonly otherValue = `__ds-agent-questionnaire-other-${this.instanceId}`;\n private answerPending = false;\n private resetScheduled = false;\n private draftRequestId?: string;\n private answersSnapshot: AgentQuestionAnswer[] = [];\n private waitingForRequestAnswers = false;\n\n componentWillLoad() {\n this.draftRequestId = this.requestId;\n this.answersSnapshot = this.answers;\n this.resetDraft();\n }\n\n @Watch('requestId')\n @Watch('questions')\n @Watch('answers')\n handleQuestionnaireInputChange() {\n this.scheduleDraftReset();\n }\n\n @Watch('status')\n handleStatusChange(status: AgentQuestionnaireStatus) {\n if (status !== 'submitting') this.answerPending = false;\n }\n\n @Method()\n async setFocus(): Promise<void> {\n this.focusCurrentControl();\n }\n\n private get copy(): AgentQuestionnaireLabels {\n return { ...DEFAULT_LABELS, ...this.labels };\n }\n\n private get disabled(): boolean {\n return this.status === 'submitting';\n }\n\n private resetDraft(answers = this.answers) {\n this.currentStep = 0;\n this.drafts = createQuestionnaireDrafts(this.questions ?? [], answers ?? []);\n this.validation = {};\n this.answerPending = false;\n }\n\n private scheduleDraftReset() {\n if (this.resetScheduled) return;\n this.resetScheduled = true;\n queueMicrotask(() => {\n this.resetScheduled = false;\n const requestChanged = this.requestId !== this.draftRequestId;\n const answersChanged = this.answers !== this.answersSnapshot;\n if (requestChanged && !answersChanged) {\n this.waitingForRequestAnswers = true;\n } else if (answersChanged) {\n this.waitingForRequestAnswers = false;\n }\n this.resetDraft(this.waitingForRequestAnswers ? [] : this.answers);\n this.draftRequestId = this.requestId;\n this.answersSnapshot = this.answers;\n });\n }\n\n private focusCurrentControl(preferInvalid = false) {\n const focus = () => {\n const invalidControl = preferInvalid\n ? this.el.querySelector<HTMLElement>(\n '[data-question-control][aria-invalid=\"true\"]:not([disabled])'\n )\n : null;\n const control =\n invalidControl ??\n this.el.querySelector<HTMLElement>(\n '[data-question-control]:not([disabled]):not([is-inactive])'\n );\n const action = this.el.querySelector<HTMLElement>(\n '[data-question-action]:not([is-inactive]):not([is-loading])'\n );\n const target = (control ?? action) as\n | (HTMLElement & { setFocus?: () => Promise<void> })\n | null;\n if (target?.setFocus) void target.setFocus();\n else target?.focus();\n };\n focus();\n requestAnimationFrame(focus);\n setTimeout(focus, 0);\n }\n\n private updateDraft(questionId: string, update: Partial<AgentQuestionDraft>) {\n const previous = this.drafts[questionId] ?? {\n value: '',\n otherSelected: false,\n otherText: '',\n skipped: false,\n };\n this.drafts = {\n ...this.drafts,\n [questionId]: { ...previous, ...update, skipped: false },\n };\n if (this.validation[questionId]) {\n const { [questionId]: _removed, ...rest } = this.validation;\n this.validation = rest;\n }\n }\n\n private validate(question: AgentQuestion): boolean {\n const message = validateQuestionDraft(question, this.drafts[question.id]);\n if (!message) return true;\n this.validation = { ...this.validation, [question.id]: message };\n this.focusCurrentControl(true);\n return false;\n }\n\n private move(step: number) {\n this.currentStep = Math.min(Math.max(step, 0), this.questions.length - 1);\n this.focusCurrentControl();\n }\n\n private next(question: AgentQuestion) {\n if (!this.validate(question)) return;\n this.move(this.currentStep + 1);\n }\n\n private skip(question: AgentQuestion) {\n if (question.required) return;\n this.drafts = {\n ...this.drafts,\n [question.id]: {\n ...(this.drafts[question.id] ?? {\n value: '',\n otherSelected: false,\n otherText: '',\n }),\n skipped: true,\n },\n };\n if (this.currentStep < this.questions.length - 1) this.move(this.currentStep + 1);\n else this.submit();\n }\n\n private submit() {\n if (this.disabled || this.answerPending) return;\n const invalidIndex = this.questions.findIndex(question => !this.validateWithoutFocus(question));\n if (invalidIndex >= 0) {\n this.currentStep = invalidIndex;\n this.focusCurrentControl(true);\n return;\n }\n\n this.answerPending = true;\n this.dsAnswer.emit({\n requestId: this.requestId,\n answers: this.questions.map(question =>\n normalizeQuestionAnswer(question, this.drafts[question.id])\n ),\n });\n }\n\n private validateWithoutFocus(question: AgentQuestion): boolean {\n const message = validateQuestionDraft(question, this.drafts[question.id]);\n if (!message) return true;\n this.validation = { ...this.validation, [question.id]: message };\n return false;\n }\n\n private progressLabel(): string {\n return this.copy.progress\n .split('{current}')\n .join(String(this.currentStep + 1))\n .split('{total}')\n .join(String(this.questions.length));\n }\n\n private selectSingle(question: AgentQuestion, value: string) {\n const otherSelected = value === this.otherValue;\n this.updateDraft(question.id, {\n value: otherSelected ? '' : value,\n otherSelected,\n });\n if (otherSelected) {\n requestAnimationFrame(() =>\n this.el.querySelector<HTMLInputElement>('[data-question-other-input]')?.focus()\n );\n }\n }\n\n private renderSingleChoice(question: AgentQuestion, promptId: string, errorId: string) {\n const draft = this.drafts[question.id];\n const value = draft.otherSelected\n ? this.otherValue\n : typeof draft.value === 'string'\n ? draft.value\n : '';\n const options = [\n ...(question.choices ?? []),\n ...(question.allowOther ? [{ value: this.otherValue, label: this.copy.other }] : []),\n ];\n return (\n <div class=\"questionnaire__single-choice\">\n <ds-radio\n data-question-control\n size=\"lg\"\n options={options}\n value={value}\n disabled={this.disabled}\n form={`ds-agent-questionnaire-detached-${this.instanceId}`}\n ariaLabelledby={promptId}\n aria-describedby={this.validation[question.id] ? errorId : undefined}\n onDsChange={(event: CustomEvent<string>) => this.selectSingle(question, event.detail)}\n />\n {draft.otherSelected ? this.renderOtherInput(question, errorId) : null}\n </div>\n );\n }\n\n private renderMultipleChoice(question: AgentQuestion, errorId: string) {\n const draft = this.drafts[question.id];\n const values = Array.isArray(draft.value) ? draft.value : [];\n const detachedForm = `ds-agent-questionnaire-detached-${this.instanceId}`;\n return (\n <div class=\"questionnaire__multiple-choice\">\n {question.choices?.map(choice => (\n <ds-checkbox\n key={choice.value}\n data-question-control\n size=\"lg\"\n label={choice.label}\n description={choice.description}\n value={choice.value}\n checked={values.includes(choice.value)}\n disabled={this.disabled}\n form={detachedForm}\n onDsChange={(event: CustomEvent<boolean>) => {\n this.updateDraft(question.id, {\n value: event.detail\n ? [...values, choice.value]\n : values.filter(value => value !== choice.value),\n });\n }}\n />\n ))}\n {question.allowOther ? (\n <div class=\"questionnaire__other-choice\">\n <ds-checkbox\n data-question-control\n size=\"lg\"\n label={this.copy.other}\n checked={draft.otherSelected}\n disabled={this.disabled}\n form={detachedForm}\n onDsChange={(event: CustomEvent<boolean>) => {\n this.updateDraft(question.id, { otherSelected: event.detail });\n if (event.detail) {\n requestAnimationFrame(() =>\n this.el.querySelector<HTMLInputElement>('[data-question-other-input]')?.focus()\n );\n }\n }}\n />\n {draft.otherSelected ? this.renderOtherInput(question, errorId) : null}\n </div>\n ) : null}\n </div>\n );\n }\n\n private renderOtherInput(question: AgentQuestion, errorId: string) {\n const draft = this.drafts[question.id];\n return (\n <input\n class=\"questionnaire__other-input\"\n data-question-control\n data-question-other-input\n type=\"text\"\n form={`ds-agent-questionnaire-detached-${this.instanceId}`}\n value={draft.otherText}\n placeholder={this.copy.otherPlaceholder}\n aria-label={this.copy.other}\n aria-invalid={this.validation[question.id] ? 'true' : undefined}\n aria-describedby={this.validation[question.id] ? errorId : undefined}\n disabled={this.disabled}\n onInput={(event: Event) =>\n this.updateDraft(question.id, {\n otherText: (event.target as HTMLInputElement).value,\n })\n }\n />\n );\n }\n\n private renderQuestion(question: AgentQuestion) {\n const draft = this.drafts[question.id];\n const errorId = `ds-agent-questionnaire-${this.instanceId}-${this.currentStep}-error`;\n const promptId = `ds-agent-questionnaire-${this.instanceId}-${this.currentStep}-prompt`;\n return (\n <div class=\"questionnaire__body\">\n <div class=\"questionnaire__prompt\">\n <ds-text as=\"h2\" variant=\"text-title-small\" textId={promptId}>\n {question.question}\n </ds-text>\n {question.description ? (\n <ds-text variant=\"text-body-small\" color=\"secondary\">\n {question.description}\n </ds-text>\n ) : null}\n </div>\n {question.type === 'text' ? (\n <textarea\n class=\"questionnaire__text-input\"\n data-question-control\n value={typeof draft.value === 'string' ? draft.value : ''}\n form={`ds-agent-questionnaire-detached-${this.instanceId}`}\n placeholder={question.placeholder}\n aria-label={question.question}\n aria-invalid={this.validation[question.id] ? 'true' : undefined}\n aria-describedby={this.validation[question.id] ? errorId : undefined}\n disabled={this.disabled}\n rows={4}\n onInput={(event: Event) =>\n this.updateDraft(question.id, {\n value: (event.target as HTMLTextAreaElement).value,\n })\n }\n />\n ) : (\n <fieldset\n class=\"questionnaire__choices\"\n aria-describedby={this.validation[question.id] ? errorId : undefined}\n >\n <legend class=\"ds-visually-hidden\">{question.question}</legend>\n {question.type === 'single'\n ? this.renderSingleChoice(question, promptId, errorId)\n : this.renderMultipleChoice(question, errorId)}\n </fieldset>\n )}\n {this.validation[question.id] ? (\n <div id={errorId} class=\"questionnaire__error\" role=\"alert\">\n <ds-icon name=\"ExclamationTriangle\" size=\"xs\" color=\"inherit\" />\n <ds-text variant=\"text-body-small\" color=\"negative\">\n {this.validation[question.id]}\n </ds-text>\n </div>\n ) : null}\n </div>\n );\n }\n\n private renderAnswered() {\n return (\n <div class=\"questionnaire questionnaire--answered\">\n <ol class=\"questionnaire__summary\">\n {this.questions.map(question => (\n <li>\n <ds-text variant=\"text-body-small\" emphasis>\n {question.question}\n </ds-text>\n <ds-text variant=\"text-body-small\" color=\"secondary\">\n {formatQuestionAnswer(\n question,\n this.answers.find(answer => answer.questionId === question.id)\n )}\n </ds-text>\n </li>\n ))}\n </ol>\n </div>\n );\n }\n\n render() {\n if (this.status === 'preparing') {\n return (\n <Host>\n <div class=\"questionnaire questionnaire--preparing\" role=\"status\">\n <ds-loader size=\"sm\" />\n <ds-text variant=\"text-body-medium\">{this.copy.preparing}</ds-text>\n </div>\n </Host>\n );\n }\n if (!this.questions?.length) return null;\n if (this.status === 'answered') return <Host>{this.renderAnswered()}</Host>;\n\n const question = this.questions[this.currentStep];\n const last = this.currentStep === this.questions.length - 1;\n const canSkip = Boolean(question.skippable && !question.required);\n return (\n <Host>\n <section\n class={{\n questionnaire: true,\n 'questionnaire--submitting': this.disabled,\n 'questionnaire--error': this.status === 'error',\n }}\n aria-busy={this.disabled ? 'true' : undefined}\n aria-label={question.question}\n >\n <header class=\"questionnaire__header\">\n <ds-text variant=\"text-caption\" color=\"secondary\">\n {this.progressLabel()}\n </ds-text>\n {this.allowCancel ? (\n <ds-tooltip label={this.copy.cancel} side=\"top\" size=\"sm\">\n <ds-button-unfilled\n data-question-action\n variant=\"icon\"\n icon=\"Cross\"\n size=\"sm\"\n aria-label={this.copy.cancel}\n hasBorder={false}\n isInactive={this.disabled}\n onDsClick={() => this.dsCancel.emit({ requestId: this.requestId })}\n />\n </ds-tooltip>\n ) : null}\n </header>\n {this.renderQuestion(question)}\n {this.status === 'error' && this.errorMessage ? (\n <div class=\"questionnaire__submission-error\" role=\"alert\">\n <ds-icon name=\"ExclamationTriangle\" size=\"xs\" color=\"inherit\" />\n <ds-text variant=\"text-body-small\" color=\"negative\">\n {this.errorMessage}\n </ds-text>\n </div>\n ) : null}\n <footer class=\"questionnaire__actions\">\n <div class=\"questionnaire__actions-leading\">\n {this.currentStep > 0 ? (\n <div class=\"questionnaire__action-item\">\n <ds-button-unfilled\n data-question-action\n label={this.copy.previous}\n size=\"sm\"\n width=\"fill\"\n isInactive={this.disabled}\n onDsClick={() => this.move(this.currentStep - 1)}\n />\n </div>\n ) : null}\n {canSkip ? (\n <div class=\"questionnaire__action-item\">\n <ds-button-unfilled\n data-question-action\n label={this.copy.skip}\n size=\"sm\"\n width=\"fill\"\n hasBorder={false}\n isInactive={this.disabled}\n onDsClick={() => this.skip(question)}\n />\n </div>\n ) : null}\n </div>\n <div class=\"questionnaire__action-item questionnaire__action-item--primary\">\n <ds-button-filled\n data-question-action\n label={last ? this.copy.answer : this.copy.next}\n size=\"sm\"\n width=\"fill\"\n isLoading={this.disabled}\n onDsClick={() => (last ? this.submit() : this.next(question))}\n />\n </div>\n </footer>\n </section>\n </Host>\n );\n }\n}\n",
270
270
  "type": "registry:ui"
271
271
  },
272
272
  {
@@ -229,7 +229,7 @@
229
229
  "peerDependencies": {
230
230
  "required": [
231
231
  "@ds-mo/tokens ^6.5.1",
232
- "@ds-mo/icons ^7.0.0"
232
+ "@ds-mo/icons ^8.1.0"
233
233
  ],
234
234
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
235
235
  }
@@ -148,7 +148,7 @@
148
148
  "peerDependencies": {
149
149
  "required": [
150
150
  "@ds-mo/tokens ^6.5.1",
151
- "@ds-mo/icons ^7.0.0"
151
+ "@ds-mo/icons ^8.1.0"
152
152
  ],
153
153
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
154
154
  }
@@ -228,7 +228,7 @@
228
228
  "peerDependencies": {
229
229
  "required": [
230
230
  "@ds-mo/tokens ^6.5.1",
231
- "@ds-mo/icons ^7.0.0"
231
+ "@ds-mo/icons ^8.1.0"
232
232
  ],
233
233
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
234
234
  }
@@ -252,7 +252,7 @@
252
252
  },
253
253
  {
254
254
  "path": "src/wc/components/AgentToolCall/AgentToolCall.tsx",
255
- "content": "import { Component, Element, Event, EventEmitter, h, Host, Prop, State } from '@stencil/core';\nimport type { AgentToolState } from '../conversation-types';\n\nconst STATUS_LABELS: Record<AgentToolState, string> = {\n preparing: 'Preparing',\n queued: 'Queued',\n running: 'Running',\n 'waiting-for-user': 'Waiting for your response',\n success: 'Completed',\n error: 'Failed',\n denied: 'Permission denied',\n canceled: 'Canceled',\n};\n\n@Component({ tag: 'ds-agent-tool-call', styleUrl: 'AgentToolCall.css', scoped: true })\nexport class AgentToolCall {\n @Element() el!: HTMLElement;\n\n @Prop() name: string = '';\n @Prop() label: string = '';\n @Prop() state: AgentToolState = 'queued';\n @Prop() statusLabel?: string;\n @Prop() input?: unknown;\n @Prop() output?: unknown;\n @Prop() error?: string;\n @Prop() open: boolean = false;\n\n @Event() dsOpenChange!: EventEmitter<{ open: boolean }>;\n\n @State() private hasSummary = false;\n @State() private hasResult = false;\n @State() private hasPlainTextResult = false;\n @State() private hasDetails = false;\n\n private slotObserver?: MutationObserver;\n\n componentWillLoad() {\n this.syncSlots();\n }\n\n componentDidLoad() {\n this.syncSlots();\n this.slotObserver = new MutationObserver(() => this.syncSlots());\n this.slotObserver.observe(this.el, {\n childList: true,\n subtree: false,\n attributes: true,\n attributeFilter: ['slot'],\n });\n }\n\n disconnectedCallback() {\n this.slotObserver?.disconnect();\n }\n\n private syncSlots() {\n this.hasSummary = Boolean(this.el.querySelector('[slot=\"summary\"]'));\n const result = this.el.querySelector<HTMLElement>('[slot=\"result\"]');\n this.hasResult = Boolean(result);\n this.hasPlainTextResult = Boolean(\n result && result.childElementCount === 0 && result.textContent?.trim()\n );\n this.hasDetails = Boolean(this.el.querySelector('[slot=\"details\"]'));\n }\n\n private serialize(value: unknown) {\n if (value === undefined) return '';\n if (typeof value === 'string') return value;\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n }\n\n private get active(): boolean {\n return ['preparing', 'queued', 'running'].includes(this.state);\n }\n\n private get expandable(): boolean {\n return (\n this.hasDetails ||\n this.input !== undefined ||\n this.output !== undefined ||\n Boolean(this.error)\n );\n }\n\n private renderStatusIcon() {\n if (this.active) return <ds-loader size=\"xs\" color=\"inherit\" />;\n if (this.state === 'success') {\n return <ds-icon name=\"Check\" size=\"xs\" color=\"inherit\" />;\n }\n if (this.state === 'waiting-for-user') {\n return <ds-icon name=\"Clock\" size=\"xs\" color=\"inherit\" />;\n }\n return <ds-icon name=\"ErrorTriangle\" size=\"xs\" color=\"inherit\" />;\n }\n\n private renderSummary(expandable: boolean) {\n return (\n <span class=\"agent-tool__summary-content\">\n <span class=\"agent-tool__status-icon\" aria-hidden=\"true\">\n {this.renderStatusIcon()}\n </span>\n <span class=\"agent-tool__title\">\n {this.hasSummary ? (\n <slot name=\"summary\" />\n ) : (\n <ds-text as=\"span\" variant=\"text-body-small\" emphasis>\n {this.label || this.name}\n </ds-text>\n )}\n <ds-text\n class=\"agent-tool__state-label\"\n as=\"span\"\n variant=\"text-caption\"\n color={['error', 'denied'].includes(this.state) ? 'negative' : 'secondary'}\n >\n {this.statusLabel ?? STATUS_LABELS[this.state]}\n </ds-text>\n </span>\n {expandable ? (\n <ds-icon class=\"agent-tool__chevron\" name=\"ChevronRight\" size=\"xs\" color=\"inherit\" />\n ) : null}\n </span>\n );\n }\n\n private renderGenericDetails() {\n return (\n <div class=\"agent-tool__diagnostics\">\n {this.input !== undefined ? (\n <section>\n <ds-text variant=\"text-caption\" emphasis>\n Input\n </ds-text>\n <pre>{this.serialize(this.input)}</pre>\n </section>\n ) : null}\n {this.output !== undefined ? (\n <section>\n <ds-text variant=\"text-caption\" emphasis>\n Output\n </ds-text>\n <pre>{this.serialize(this.output)}</pre>\n </section>\n ) : null}\n {this.error ? (\n <section>\n <ds-text variant=\"text-caption\" emphasis>\n Error\n </ds-text>\n <pre>{this.error}</pre>\n </section>\n ) : null}\n </div>\n );\n }\n\n private handleToggle = (event: Event) => {\n this.dsOpenChange.emit({ open: (event.currentTarget as HTMLDetailsElement).open });\n };\n\n render() {\n const expandable = this.expandable;\n return (\n <Host>\n <div class={`agent-tool agent-tool--${this.state}`}>\n {expandable ? (\n <details open={this.open} onToggle={this.handleToggle}>\n <summary>{this.renderSummary(true)}</summary>\n <div class=\"agent-tool__details\">\n {this.hasDetails ? <slot name=\"details\" /> : this.renderGenericDetails()}\n </div>\n </details>\n ) : (\n <div class=\"agent-tool__row\">{this.renderSummary(false)}</div>\n )}\n {this.hasResult ? (\n <div\n class={{\n 'agent-tool__result': true,\n 'agent-tool__result--plain-text': this.hasPlainTextResult,\n }}\n >\n <slot name=\"result\" />\n </div>\n ) : null}\n </div>\n </Host>\n );\n }\n}\n",
255
+ "content": "import { Component, Element, Event, EventEmitter, h, Host, Prop, State } from '@stencil/core';\nimport type { AgentToolState } from '../conversation-types';\n\nconst STATUS_LABELS: Record<AgentToolState, string> = {\n preparing: 'Preparing',\n queued: 'Queued',\n running: 'Running',\n 'waiting-for-user': 'Waiting for your response',\n success: 'Completed',\n error: 'Failed',\n denied: 'Permission denied',\n canceled: 'Canceled',\n};\n\n@Component({ tag: 'ds-agent-tool-call', styleUrl: 'AgentToolCall.css', scoped: true })\nexport class AgentToolCall {\n @Element() el!: HTMLElement;\n\n @Prop() name: string = '';\n @Prop() label: string = '';\n @Prop() state: AgentToolState = 'queued';\n @Prop() statusLabel?: string;\n @Prop() input?: unknown;\n @Prop() output?: unknown;\n @Prop() error?: string;\n @Prop() open: boolean = false;\n\n @Event() dsOpenChange!: EventEmitter<{ open: boolean }>;\n\n @State() private hasSummary = false;\n @State() private hasResult = false;\n @State() private hasPlainTextResult = false;\n @State() private hasDetails = false;\n\n private slotObserver?: MutationObserver;\n\n componentWillLoad() {\n this.syncSlots();\n }\n\n componentDidLoad() {\n this.syncSlots();\n this.slotObserver = new MutationObserver(() => this.syncSlots());\n this.slotObserver.observe(this.el, {\n childList: true,\n subtree: false,\n attributes: true,\n attributeFilter: ['slot'],\n });\n }\n\n disconnectedCallback() {\n this.slotObserver?.disconnect();\n }\n\n private syncSlots() {\n this.hasSummary = Boolean(this.el.querySelector('[slot=\"summary\"]'));\n const result = this.el.querySelector<HTMLElement>('[slot=\"result\"]');\n this.hasResult = Boolean(result);\n this.hasPlainTextResult = Boolean(\n result && result.childElementCount === 0 && result.textContent?.trim()\n );\n this.hasDetails = Boolean(this.el.querySelector('[slot=\"details\"]'));\n }\n\n private serialize(value: unknown) {\n if (value === undefined) return '';\n if (typeof value === 'string') return value;\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n }\n\n private get active(): boolean {\n return ['preparing', 'queued', 'running'].includes(this.state);\n }\n\n private get expandable(): boolean {\n return (\n this.hasDetails ||\n this.input !== undefined ||\n this.output !== undefined ||\n Boolean(this.error)\n );\n }\n\n private renderStatusIcon() {\n if (this.active) return <ds-loader size=\"xs\" color=\"inherit\" />;\n if (this.state === 'success') {\n return <ds-icon name=\"Check\" size=\"xs\" color=\"inherit\" />;\n }\n if (this.state === 'waiting-for-user') {\n return <ds-icon name=\"Clock\" size=\"xs\" color=\"inherit\" />;\n }\n return <ds-icon name=\"ExclamationTriangle\" size=\"xs\" color=\"inherit\" />;\n }\n\n private renderSummary(expandable: boolean) {\n return (\n <span class=\"agent-tool__summary-content\">\n <span class=\"agent-tool__status-icon\" aria-hidden=\"true\">\n {this.renderStatusIcon()}\n </span>\n <span class=\"agent-tool__title\">\n {this.hasSummary ? (\n <slot name=\"summary\" />\n ) : (\n <ds-text as=\"span\" variant=\"text-body-small\" emphasis>\n {this.label || this.name}\n </ds-text>\n )}\n <ds-text\n class=\"agent-tool__state-label\"\n as=\"span\"\n variant=\"text-caption\"\n color={['error', 'denied'].includes(this.state) ? 'negative' : 'secondary'}\n >\n {this.statusLabel ?? STATUS_LABELS[this.state]}\n </ds-text>\n </span>\n {expandable ? (\n <ds-icon class=\"agent-tool__chevron\" name=\"ChevronRight\" size=\"xs\" color=\"inherit\" />\n ) : null}\n </span>\n );\n }\n\n private renderGenericDetails() {\n return (\n <div class=\"agent-tool__diagnostics\">\n {this.input !== undefined ? (\n <section>\n <ds-text variant=\"text-caption\" emphasis>\n Input\n </ds-text>\n <pre>{this.serialize(this.input)}</pre>\n </section>\n ) : null}\n {this.output !== undefined ? (\n <section>\n <ds-text variant=\"text-caption\" emphasis>\n Output\n </ds-text>\n <pre>{this.serialize(this.output)}</pre>\n </section>\n ) : null}\n {this.error ? (\n <section>\n <ds-text variant=\"text-caption\" emphasis>\n Error\n </ds-text>\n <pre>{this.error}</pre>\n </section>\n ) : null}\n </div>\n );\n }\n\n private handleToggle = (event: Event) => {\n this.dsOpenChange.emit({ open: (event.currentTarget as HTMLDetailsElement).open });\n };\n\n render() {\n const expandable = this.expandable;\n return (\n <Host>\n <div class={`agent-tool agent-tool--${this.state}`}>\n {expandable ? (\n <details open={this.open} onToggle={this.handleToggle}>\n <summary>{this.renderSummary(true)}</summary>\n <div class=\"agent-tool__details\">\n {this.hasDetails ? <slot name=\"details\" /> : this.renderGenericDetails()}\n </div>\n </details>\n ) : (\n <div class=\"agent-tool__row\">{this.renderSummary(false)}</div>\n )}\n {this.hasResult ? (\n <div\n class={{\n 'agent-tool__result': true,\n 'agent-tool__result--plain-text': this.hasPlainTextResult,\n }}\n >\n <slot name=\"result\" />\n </div>\n ) : null}\n </div>\n </Host>\n );\n }\n}\n",
256
256
  "type": "registry:ui"
257
257
  }
258
258
  ]
@@ -112,7 +112,7 @@
112
112
  "peerDependencies": {
113
113
  "required": [
114
114
  "@ds-mo/tokens ^6.5.1",
115
- "@ds-mo/icons ^7.0.0"
115
+ "@ds-mo/icons ^8.1.0"
116
116
  ],
117
117
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
118
118
  }
@@ -149,7 +149,7 @@
149
149
  "peerDependencies": {
150
150
  "required": [
151
151
  "@ds-mo/tokens ^6.5.1",
152
- "@ds-mo/icons ^7.0.0"
152
+ "@ds-mo/icons ^8.1.0"
153
153
  ],
154
154
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
155
155
  }
@@ -264,7 +264,7 @@
264
264
  "peerDependencies": {
265
265
  "required": [
266
266
  "@ds-mo/tokens ^6.5.1",
267
- "@ds-mo/icons ^7.0.0"
267
+ "@ds-mo/icons ^8.1.0"
268
268
  ],
269
269
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
270
270
  }
@@ -309,7 +309,7 @@
309
309
  "peerDependencies": {
310
310
  "required": [
311
311
  "@ds-mo/tokens ^6.5.1",
312
- "@ds-mo/icons ^7.0.0"
312
+ "@ds-mo/icons ^8.1.0"
313
313
  ],
314
314
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
315
315
  }
@@ -214,7 +214,7 @@
214
214
  "peerDependencies": {
215
215
  "required": [
216
216
  "@ds-mo/tokens ^6.5.1",
217
- "@ds-mo/icons ^7.0.0"
217
+ "@ds-mo/icons ^8.1.0"
218
218
  ],
219
219
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
220
220
  }
@@ -287,7 +287,7 @@
287
287
  "peerDependencies": {
288
288
  "required": [
289
289
  "@ds-mo/tokens ^6.5.1",
290
- "@ds-mo/icons ^7.0.0"
290
+ "@ds-mo/icons ^8.1.0"
291
291
  ],
292
292
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
293
293
  }
@@ -399,7 +399,7 @@
399
399
  "peerDependencies": {
400
400
  "required": [
401
401
  "@ds-mo/tokens ^6.5.1",
402
- "@ds-mo/icons ^7.0.0"
402
+ "@ds-mo/icons ^8.1.0"
403
403
  ],
404
404
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
405
405
  }
@@ -540,7 +540,7 @@
540
540
  "peerDependencies": {
541
541
  "required": [
542
542
  "@ds-mo/tokens ^6.5.1",
543
- "@ds-mo/icons ^7.0.0"
543
+ "@ds-mo/icons ^8.1.0"
544
544
  ],
545
545
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
546
546
  }
@@ -357,7 +357,7 @@
357
357
  "peerDependencies": {
358
358
  "required": [
359
359
  "@ds-mo/tokens ^6.5.1",
360
- "@ds-mo/icons ^7.0.0"
360
+ "@ds-mo/icons ^8.1.0"
361
361
  ],
362
362
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
363
363
  }
@@ -177,7 +177,7 @@
177
177
  "peerDependencies": {
178
178
  "required": [
179
179
  "@ds-mo/tokens ^6.5.1",
180
- "@ds-mo/icons ^7.0.0"
180
+ "@ds-mo/icons ^8.1.0"
181
181
  ],
182
182
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
183
183
  }
@@ -629,7 +629,7 @@
629
629
  "peerDependencies": {
630
630
  "required": [
631
631
  "@ds-mo/tokens ^6.5.1",
632
- "@ds-mo/icons ^7.0.0"
632
+ "@ds-mo/icons ^8.1.0"
633
633
  ],
634
634
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
635
635
  }
@@ -548,7 +548,7 @@
548
548
  "peerDependencies": {
549
549
  "required": [
550
550
  "@ds-mo/tokens ^6.5.1",
551
- "@ds-mo/icons ^7.0.0"
551
+ "@ds-mo/icons ^8.1.0"
552
552
  ],
553
553
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
554
554
  }
@@ -711,7 +711,7 @@
711
711
  "peerDependencies": {
712
712
  "required": [
713
713
  "@ds-mo/tokens ^6.5.1",
714
- "@ds-mo/icons ^7.0.0"
714
+ "@ds-mo/icons ^8.1.0"
715
715
  ],
716
716
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
717
717
  }
@@ -239,7 +239,7 @@
239
239
  "peerDependencies": {
240
240
  "required": [
241
241
  "@ds-mo/tokens ^6.5.1",
242
- "@ds-mo/icons ^7.0.0"
242
+ "@ds-mo/icons ^8.1.0"
243
243
  ],
244
244
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
245
245
  }
@@ -176,7 +176,7 @@
176
176
  "peerDependencies": {
177
177
  "required": [
178
178
  "@ds-mo/tokens ^6.5.1",
179
- "@ds-mo/icons ^7.0.0"
179
+ "@ds-mo/icons ^8.1.0"
180
180
  ],
181
181
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
182
182
  }
@@ -214,7 +214,7 @@
214
214
  "peerDependencies": {
215
215
  "required": [
216
216
  "@ds-mo/tokens ^6.5.1",
217
- "@ds-mo/icons ^7.0.0"
217
+ "@ds-mo/icons ^8.1.0"
218
218
  ],
219
219
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
220
220
  }
@@ -227,7 +227,7 @@
227
227
  "peerDependencies": {
228
228
  "required": [
229
229
  "@ds-mo/tokens ^6.5.1",
230
- "@ds-mo/icons ^7.0.0"
230
+ "@ds-mo/icons ^8.1.0"
231
231
  ],
232
232
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
233
233
  }
@@ -352,7 +352,7 @@
352
352
  "peerDependencies": {
353
353
  "required": [
354
354
  "@ds-mo/tokens ^6.5.1",
355
- "@ds-mo/icons ^7.0.0"
355
+ "@ds-mo/icons ^8.1.0"
356
356
  ],
357
357
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
358
358
  }
@@ -255,7 +255,7 @@
255
255
  "peerDependencies": {
256
256
  "required": [
257
257
  "@ds-mo/tokens ^6.5.1",
258
- "@ds-mo/icons ^7.0.0"
258
+ "@ds-mo/icons ^8.1.0"
259
259
  ],
260
260
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
261
261
  }
@@ -304,7 +304,7 @@
304
304
  "peerDependencies": {
305
305
  "required": [
306
306
  "@ds-mo/tokens ^6.5.1",
307
- "@ds-mo/icons ^7.0.0"
307
+ "@ds-mo/icons ^8.1.0"
308
308
  ],
309
309
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
310
310
  }
@@ -273,7 +273,7 @@
273
273
  "peerDependencies": {
274
274
  "required": [
275
275
  "@ds-mo/tokens ^6.5.1",
276
- "@ds-mo/icons ^7.0.0"
276
+ "@ds-mo/icons ^8.1.0"
277
277
  ],
278
278
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
279
279
  }
@@ -235,7 +235,7 @@
235
235
  "peerDependencies": {
236
236
  "required": [
237
237
  "@ds-mo/tokens ^6.5.1",
238
- "@ds-mo/icons ^7.0.0"
238
+ "@ds-mo/icons ^8.1.0"
239
239
  ],
240
240
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
241
241
  }
@@ -358,7 +358,7 @@
358
358
  "peerDependencies": {
359
359
  "required": [
360
360
  "@ds-mo/tokens ^6.5.1",
361
- "@ds-mo/icons ^7.0.0"
361
+ "@ds-mo/icons ^8.1.0"
362
362
  ],
363
363
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
364
364
  }
@@ -289,7 +289,7 @@
289
289
  "peerDependencies": {
290
290
  "required": [
291
291
  "@ds-mo/tokens ^6.5.1",
292
- "@ds-mo/icons ^7.0.0"
292
+ "@ds-mo/icons ^8.1.0"
293
293
  ],
294
294
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
295
295
  }
@@ -134,7 +134,7 @@
134
134
  "peerDependencies": {
135
135
  "required": [
136
136
  "@ds-mo/tokens ^6.5.1",
137
- "@ds-mo/icons ^7.0.0"
137
+ "@ds-mo/icons ^8.1.0"
138
138
  ],
139
139
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
140
140
  }
@@ -259,7 +259,7 @@
259
259
  "peerDependencies": {
260
260
  "required": [
261
261
  "@ds-mo/tokens ^6.5.1",
262
- "@ds-mo/icons ^7.0.0"
262
+ "@ds-mo/icons ^8.1.0"
263
263
  ],
264
264
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
265
265
  }
@@ -116,7 +116,7 @@
116
116
  "peerDependencies": {
117
117
  "required": [
118
118
  "@ds-mo/tokens ^6.5.1",
119
- "@ds-mo/icons ^7.0.0"
119
+ "@ds-mo/icons ^8.1.0"
120
120
  ],
121
121
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
122
122
  }
@@ -23,8 +23,7 @@
23
23
  "commonlyComposedWith": [
24
24
  "component:ds-conversation-list-section",
25
25
  "component:ds-conversation-list-item",
26
- "component:ds-empty-state",
27
- "component:ds-scroll-overlay"
26
+ "component:ds-empty-state"
28
27
  ],
29
28
  "patterns": [
30
29
  "pattern:conversation"
@@ -34,14 +33,13 @@
34
33
  "Keep the empty message descriptive and every persistent action explicitly named."
35
34
  ],
36
35
  "states": [
37
- "The default floating action stays at the lower end corner.",
38
- "actionLayout footer stretches a long action between 8px side and bottom insets.",
39
- "Both action layouts share the always-active scroll-overlay fade controller, reserve measured end clearance, and begin fading 8px before the visible action.",
40
- "ConversationList paints its measured fade on a separate surface-aware layer so contextual row actions retain a real backdrop for blur; hovered, focused, and menu-open rows rise above that decorative fade.",
36
+ "The action stays at the lower end corner, inset 16px from both edges.",
37
+ "Slot an icon-only rounded button; the corner action is the single supported placement, so a full-width labelled action no longer has a layout to sit in.",
38
+ "Rows scroll beneath the action. The list reserves no end clearance and paints no fade, so it keeps its full height whether or not an action is slotted.",
41
39
  "The persistent action wrapper splits its md outer shadow from a top inset-highlight overlay so opaque filled actions keep the complete TokoMo elevation; slotted buttons disable optional resting borders and the press-scale modifier moves the button and elevated surface as one unit."
42
40
  ],
43
41
  "responsiveBehavior": [
44
- "The list fills its owner, scrolls independently, and keeps its persistent action above scrolling rows."
42
+ "The list fills its owner, scrolls independently, and floats its corner action above scrolling rows."
45
43
  ],
46
44
  "references": [
47
45
  {
@@ -51,32 +49,12 @@
51
49
  ]
52
50
  },
53
51
  "api": {
54
- "props": {
55
- "actionLayout": {
56
- "type": "ConversationListActionLayout",
57
- "resolvedType": "\"floating\" | \"footer\"",
58
- "attribute": "action-layout",
59
- "default": "'floating'",
60
- "required": false,
61
- "mutable": false,
62
- "description": "Corner icon action or full-width persistent footer action."
63
- }
64
- },
52
+ "props": {},
65
53
  "events": [],
66
54
  "methods": [],
67
55
  "slots": []
68
56
  },
69
- "props": {
70
- "actionLayout": {
71
- "type": "ConversationListActionLayout",
72
- "resolvedType": "\"floating\" | \"footer\"",
73
- "attribute": "action-layout",
74
- "default": "'floating'",
75
- "required": false,
76
- "mutable": false,
77
- "description": "Corner icon action or full-width persistent footer action."
78
- }
79
- },
57
+ "props": {},
80
58
  "events": [],
81
59
  "methods": [],
82
60
  "slots": [],
@@ -108,7 +86,7 @@
108
86
  "peerDependencies": {
109
87
  "required": [
110
88
  "@ds-mo/tokens ^6.5.1",
111
- "@ds-mo/icons ^7.0.0"
89
+ "@ds-mo/icons ^8.1.0"
112
90
  ],
113
91
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
114
92
  }
@@ -122,12 +100,12 @@
122
100
  "files": [
123
101
  {
124
102
  "path": "src/wc/components/ConversationList/ConversationList.css",
125
- "content": "@import '../../styles/control-elevation.css';\n\n:host {\n display: block;\n position: relative;\n width: 100%;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n -webkit-user-select: none;\n user-select: none;\n}\n\n.conversation-list {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n}\n\n.conversation-list__viewport {\n position: relative;\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n box-sizing: border-box;\n}\n\n.conversation-list__content {\n position: relative;\n min-height: 100%;\n padding: var(--dimension-space-100);\n padding-bottom: calc(var(--dimension-space-100) + var(--ds-scroll-overlay-block-size, 0px));\n box-sizing: border-box;\n}\n\n.conversation-list__fade {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1;\n height: var(--ds-scroll-overlay-fade-block-size, 0);\n pointer-events: none;\n background-color: var(\n --ds-scroll-overlay-surface-color,\n var(--_shell-chrome-bg, var(--color-background-primary))\n );\n --ds-scroll-edge-fade-size: 100%;\n}\n\n.conversation-list__fade::before {\n content: '';\n position: absolute;\n inset: 0;\n background-image: var(--ds-scroll-overlay-surface-image, var(--ds-shell-gradient-image, none));\n background-position: var(--ds-scroll-overlay-surface-position, 0 0);\n background-attachment: fixed;\n background-size: var(--ds-scroll-overlay-surface-size, var(--ds-shell-gradient-size, auto));\n background-repeat: no-repeat;\n opacity: var(--ds-scroll-overlay-surface-image-opacity, var(--ds-shell-gradient-opacity, 1));\n}\n\n.conversation-list__empty {\n position: absolute;\n inset-block: 0 var(--ds-scroll-overlay-block-size, 0);\n inset-inline: 0;\n box-sizing: border-box;\n}\n\n/* The named slot itself keeps this wrapper from matching :empty. Only create\n its full-size hit area when assigned empty-state content is actually here. */\n.conversation-list__empty:not(:has([slot='empty'])) {\n display: none;\n}\n\n.conversation-list__actions {\n position: absolute;\n right: 0;\n bottom: 0;\n z-index: var(--dimension-z-index-floating);\n padding: 0 var(--dimension-space-200) var(--dimension-space-200) 0;\n}\n\n.conversation-list__actions--footer {\n left: 0;\n padding: 0 var(--dimension-space-100) var(--dimension-space-100);\n}\n\n.conversation-list__actions-surface {\n display: flex;\n border-radius: var(--dimension-radius-half);\n}\n\n.conversation-list__actions--footer .conversation-list__actions-surface {\n width: 100%;\n}\n\n.conversation-list__actions-surface:empty {\n display: none;\n}\n",
103
+ "content": "@import '../../styles/control-elevation.css';\n\n:host {\n display: block;\n position: relative;\n width: 100%;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n -webkit-user-select: none;\n user-select: none;\n}\n\n.conversation-list {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-height: 0;\n box-sizing: border-box;\n}\n\n.conversation-list__viewport {\n position: relative;\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n box-sizing: border-box;\n}\n\n.conversation-list__content {\n position: relative;\n min-height: 100%;\n padding: var(--dimension-space-100);\n box-sizing: border-box;\n}\n\n.conversation-list__empty {\n position: absolute;\n inset: 0;\n box-sizing: border-box;\n}\n\n/* The named slot itself keeps this wrapper from matching :empty. Only create\n its full-size hit area when assigned empty-state content is actually here. */\n.conversation-list__empty:not(:has([slot='empty'])) {\n display: none;\n}\n\n/* Corner action. Rows scroll beneath it — there is no reserved clearance and no\n fade, so the list keeps its full height whether or not an action is slotted. */\n.conversation-list__actions {\n position: absolute;\n right: 0;\n bottom: 0;\n z-index: var(--dimension-z-index-floating);\n padding: 0 var(--dimension-space-200) var(--dimension-space-200) 0;\n}\n\n.conversation-list__actions-surface {\n display: flex;\n border-radius: var(--dimension-radius-half);\n}\n\n.conversation-list__actions-surface:empty {\n display: none;\n}\n",
126
104
  "type": "registry:ui"
127
105
  },
128
106
  {
129
107
  "path": "src/wc/components/ConversationList/ConversationList.tsx",
130
- "content": "import { Component, Element, h, Host, Prop } from '@stencil/core';\nimport { ScrollOverlayController } from '../../utils/scroll-overlay-controller';\n\nexport type ConversationListActionLayout = 'floating' | 'footer';\n\n@Component({\n tag: 'ds-conversation-list',\n styleUrl: 'ConversationList.css',\n styleUrls: ['../../utils/scroll-edge-fade.css'],\n scoped: true,\n})\nexport class ConversationList {\n @Element() el!: HTMLElement;\n\n /** Corner icon action or full-width persistent footer action. */\n @Prop() actionLayout: ConversationListActionLayout = 'floating';\n\n private viewport?: HTMLElement;\n private content?: HTMLElement;\n private empty?: HTMLElement;\n private overlay?: HTMLElement;\n private scrollOverlayController?: ScrollOverlayController;\n private emptySlotObserver?: MutationObserver;\n\n componentDidLoad(): void {\n if (!this.viewport || !this.content || !this.overlay) return;\n this.scrollOverlayController = new ScrollOverlayController({\n host: this.el,\n viewport: this.viewport,\n content: this.content,\n overlay: this.overlay,\n overlayContentSelector: '[slot=\"actions\"]',\n });\n this.scrollOverlayController.connect();\n this.syncEmptyStateLayout();\n this.emptySlotObserver = new MutationObserver(this.syncEmptyStateLayout);\n this.emptySlotObserver.observe(this.el, { childList: true, subtree: true });\n }\n\n disconnectedCallback(): void {\n this.scrollOverlayController?.disconnect();\n this.emptySlotObserver?.disconnect();\n }\n\n private syncEmptyStateLayout = (): void => {\n const emptyState = this.el.querySelector<HTMLElement>('[slot=\"empty\"]');\n if (emptyState && !this.empty?.contains(emptyState)) {\n // Stencil's scoped-slot runtime does not relocate nodes appended after\n // hydration. Keep that dynamic fallback aligned with the CSS-owned\n // wrapper used by declarative slot content.\n emptyState.style.setProperty('position', 'absolute');\n emptyState.style.setProperty('inset-block-start', '0');\n emptyState.style.setProperty('inset-inline', '0');\n emptyState.style.setProperty('inset-block-end', 'var(--ds-scroll-overlay-block-size, 0)');\n emptyState.style.setProperty('height', 'auto');\n emptyState.style.setProperty('box-sizing', 'border-box');\n }\n this.scrollOverlayController?.sync();\n };\n\n render() {\n return (\n <Host>\n <div class=\"conversation-list\">\n <div\n class=\"conversation-list__viewport\"\n ref={element => {\n this.viewport = element;\n }}\n onScroll={() => this.scrollOverlayController?.sync()}\n >\n <div\n class=\"conversation-list__content\"\n ref={element => {\n this.content = element;\n }}\n >\n <slot />\n <div\n class=\"conversation-list__empty\"\n ref={element => {\n this.empty = element;\n }}\n >\n <slot name=\"empty\" />\n </div>\n </div>\n </div>\n <div\n class=\"conversation-list__fade scroll-edge-fade scroll-edge-fade--top\"\n aria-hidden=\"true\"\n />\n <div\n class={{\n 'conversation-list__actions': true,\n 'conversation-list__actions--footer': this.actionLayout === 'footer',\n }}\n ref={element => {\n this.overlay = element;\n }}\n >\n <div class=\"conversation-list__actions-surface ds-control-elevation ds-control-elevation--md ds-control-elevation--press-scale\">\n <slot name=\"actions\" />\n </div>\n </div>\n </div>\n </Host>\n );\n }\n}\n",
108
+ "content": "import { Component, Element, h, Host } from '@stencil/core';\n\n@Component({\n tag: 'ds-conversation-list',\n styleUrl: 'ConversationList.css',\n scoped: true,\n})\nexport class ConversationList {\n @Element() el!: HTMLElement;\n\n private empty?: HTMLElement;\n private emptySlotObserver?: MutationObserver;\n\n componentDidLoad(): void {\n this.syncEmptyStateLayout();\n this.emptySlotObserver = new MutationObserver(this.syncEmptyStateLayout);\n this.emptySlotObserver.observe(this.el, { childList: true, subtree: true });\n }\n\n disconnectedCallback(): void {\n this.emptySlotObserver?.disconnect();\n }\n\n private syncEmptyStateLayout = (): void => {\n const emptyState = this.el.querySelector<HTMLElement>('[slot=\"empty\"]');\n if (emptyState && !this.empty?.contains(emptyState)) {\n // Stencil's scoped-slot runtime does not relocate nodes appended after\n // hydration. Keep that dynamic fallback aligned with the CSS-owned\n // wrapper used by declarative slot content.\n emptyState.style.setProperty('position', 'absolute');\n emptyState.style.setProperty('inset-block-start', '0');\n emptyState.style.setProperty('inset-inline', '0');\n emptyState.style.setProperty('inset-block-end', '0');\n emptyState.style.setProperty('height', 'auto');\n emptyState.style.setProperty('box-sizing', 'border-box');\n }\n };\n\n render() {\n return (\n <Host>\n <div class=\"conversation-list\">\n <div class=\"conversation-list__viewport\">\n <div class=\"conversation-list__content\">\n <slot />\n <div\n class=\"conversation-list__empty\"\n ref={element => {\n this.empty = element;\n }}\n >\n <slot name=\"empty\" />\n </div>\n </div>\n </div>\n <div class=\"conversation-list__actions\">\n <div class=\"conversation-list__actions-surface ds-control-elevation ds-control-elevation--md ds-control-elevation--press-scale\">\n <slot name=\"actions\" />\n </div>\n </div>\n </div>\n </Host>\n );\n }\n}\n",
131
109
  "type": "registry:ui"
132
110
  }
133
111
  ]