@ds-mo/ui 9.2.1 → 10.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 (302) hide show
  1. package/README.md +2 -2
  2. package/dist/.build-stamp +1 -1
  3. package/dist/agent-patterns.json +1 -1
  4. package/dist/agent.json +384 -135
  5. package/dist/angular/boolean-value-accessor.js +3 -3
  6. package/dist/angular/ds-agent-activity.js +3 -3
  7. package/dist/angular/ds-agent-response.js +3 -3
  8. package/dist/angular/ds-agent-source-list.js +3 -3
  9. package/dist/angular/ds-agent-tool-call.js +3 -3
  10. package/dist/angular/ds-app-shell.js +3 -3
  11. package/dist/angular/ds-attachment-list.js +3 -3
  12. package/dist/angular/ds-avatar.js +3 -3
  13. package/dist/angular/ds-badge.js +3 -3
  14. package/dist/angular/ds-bar-nav.js +3 -3
  15. package/dist/angular/ds-button-filled.js +3 -3
  16. package/dist/angular/ds-button-unfilled.js +3 -3
  17. package/dist/angular/ds-card-data-viz-donut.js +3 -3
  18. package/dist/angular/ds-card-setting.d.ts +5 -4
  19. package/dist/angular/ds-card-setting.js +6 -6
  20. package/dist/angular/ds-card-shell-data-viz.js +3 -3
  21. package/dist/angular/ds-chart-bar.js +3 -3
  22. package/dist/angular/ds-chart-donut.js +3 -3
  23. package/dist/angular/ds-chart-legend.js +3 -3
  24. package/dist/angular/ds-chart-line.js +3 -3
  25. package/dist/angular/ds-checkbox.js +3 -3
  26. package/dist/angular/ds-chip.js +3 -3
  27. package/dist/angular/ds-code-block.js +3 -3
  28. package/dist/angular/ds-conversation-list-item.js +3 -3
  29. package/dist/angular/ds-conversation-list-section.js +3 -3
  30. package/dist/angular/ds-conversation-list.js +3 -3
  31. package/dist/angular/ds-divider.js +3 -3
  32. package/dist/angular/ds-empty-state.js +3 -3
  33. package/dist/angular/ds-field.js +3 -3
  34. package/dist/angular/ds-icon.js +3 -3
  35. package/dist/angular/ds-input.js +3 -3
  36. package/dist/angular/ds-loader.js +3 -3
  37. package/dist/angular/ds-markdown.js +3 -3
  38. package/dist/angular/ds-menu.js +3 -3
  39. package/dist/angular/ds-message-bubble.js +3 -3
  40. package/dist/angular/ds-message-composer.js +3 -3
  41. package/dist/angular/ds-message-scroller.js +3 -3
  42. package/dist/angular/ds-message.js +3 -3
  43. package/dist/angular/ds-modal.d.ts +12 -3
  44. package/dist/angular/ds-modal.js +9 -6
  45. package/dist/angular/ds-panel-nav.js +3 -3
  46. package/dist/angular/ds-panel-sub-nav.js +3 -3
  47. package/dist/angular/ds-panel-tool-header.js +3 -3
  48. package/dist/angular/ds-panel-tool-search.js +3 -3
  49. package/dist/angular/ds-panel-tools.js +3 -3
  50. package/dist/angular/ds-radio.js +3 -3
  51. package/dist/angular/ds-select-multi.js +3 -3
  52. package/dist/angular/ds-select.js +3 -3
  53. package/dist/angular/ds-shell-gradient-picker.js +3 -3
  54. package/dist/angular/ds-shell-gradient-swatch.js +3 -3
  55. package/dist/angular/ds-skeleton.js +3 -3
  56. package/dist/angular/ds-slider.js +3 -3
  57. package/dist/angular/ds-swatch-picker.js +3 -3
  58. package/dist/angular/ds-switch.js +3 -3
  59. package/dist/angular/ds-tab-group.js +3 -3
  60. package/dist/angular/ds-tag.js +3 -3
  61. package/dist/angular/ds-text.js +3 -3
  62. package/dist/angular/ds-toast.d.ts +22 -0
  63. package/dist/angular/{ds-banner.js → ds-toast.js} +21 -15
  64. package/dist/angular/ds-tooltip-data-viz.js +3 -3
  65. package/dist/angular/ds-tooltip.js +3 -3
  66. package/dist/angular/index.d.ts +1 -1
  67. package/dist/angular/index.js +1 -2
  68. package/dist/angular/proxies.d.ts +1 -2
  69. package/dist/angular/proxies.js +1 -2
  70. package/dist/angular/radio-value-accessor.js +3 -3
  71. package/dist/angular/select-value-accessor.js +3 -3
  72. package/dist/angular/text-value-accessor.js +3 -3
  73. package/dist/angular/value-accessor.js +3 -3
  74. package/dist/components/ds-agent-activity.js +1 -1
  75. package/dist/components/ds-agent-response.js +1 -1
  76. package/dist/components/ds-agent-response.js.map +1 -1
  77. package/dist/components/ds-agent-source-list.js +1 -1
  78. package/dist/components/ds-agent-tool-call.js +1 -1
  79. package/dist/components/ds-app-shell.js +1 -1
  80. package/dist/components/ds-attachment-list.js +1 -1
  81. package/dist/components/ds-avatar.js +1 -1
  82. package/dist/components/ds-badge.js +1 -1
  83. package/dist/components/ds-bar-nav.js +1 -1
  84. package/dist/components/ds-button-filled.js +1 -1
  85. package/dist/components/ds-button-unfilled.js +1 -1
  86. package/dist/components/ds-card-data-viz-donut.js +1 -1
  87. package/dist/components/ds-card-data-viz-donut.js.map +1 -1
  88. package/dist/components/ds-card-setting.js +1 -1
  89. package/dist/components/ds-card-setting.js.map +1 -1
  90. package/dist/components/ds-card-shell-data-viz.js +1 -1
  91. package/dist/components/ds-chart-bar.js +1 -1
  92. package/dist/components/ds-chart-donut.js +1 -1
  93. package/dist/components/ds-chart-legend.js +1 -1
  94. package/dist/components/ds-chart-line.js +1 -1
  95. package/dist/components/ds-checkbox.js +1 -1
  96. package/dist/components/ds-chip.js +1 -1
  97. package/dist/components/ds-code-block.js +1 -1
  98. package/dist/components/ds-conversation-list-item.js +1 -1
  99. package/dist/components/ds-conversation-list-item.js.map +1 -1
  100. package/dist/components/ds-conversation-list-section.js +1 -1
  101. package/dist/components/ds-conversation-list.js +1 -1
  102. package/dist/components/ds-divider.js +1 -1
  103. package/dist/components/ds-empty-state.js +1 -1
  104. package/dist/components/ds-field.js +1 -1
  105. package/dist/components/ds-icon.js +1 -1
  106. package/dist/components/ds-input.js +1 -1
  107. package/dist/components/ds-markdown.js +1 -1
  108. package/dist/components/ds-menu.js +1 -1
  109. package/dist/components/ds-message-bubble.js +1 -1
  110. package/dist/components/ds-message-composer.js +1 -1
  111. package/dist/components/ds-message-composer.js.map +1 -1
  112. package/dist/components/ds-message-scroller.js +1 -1
  113. package/dist/components/ds-message-scroller.js.map +1 -1
  114. package/dist/components/ds-message.js +1 -1
  115. package/dist/components/ds-modal.js +1 -1
  116. package/dist/components/ds-modal.js.map +1 -1
  117. package/dist/components/ds-panel-nav.js +1 -1
  118. package/dist/components/ds-panel-sub-nav.js +1 -1
  119. package/dist/components/ds-panel-tool-header.js +1 -1
  120. package/dist/components/ds-panel-tool-search.js +1 -1
  121. package/dist/components/ds-panel-tools.js +1 -1
  122. package/dist/components/ds-radio.js +1 -1
  123. package/dist/components/ds-select-multi.js +1 -1
  124. package/dist/components/ds-select.js +1 -1
  125. package/dist/components/ds-shell-gradient-picker.js +1 -1
  126. package/dist/components/ds-shell-gradient-picker.js.map +1 -1
  127. package/dist/components/ds-shell-gradient-swatch.js +1 -1
  128. package/dist/components/ds-skeleton.js +1 -1
  129. package/dist/components/ds-slider.js +1 -1
  130. package/dist/components/ds-slider.js.map +1 -1
  131. package/dist/components/ds-swatch-picker.js +1 -1
  132. package/dist/components/ds-switch.js +1 -1
  133. package/dist/components/ds-tab-group.js +1 -1
  134. package/dist/components/ds-tag.js +1 -1
  135. package/dist/components/ds-text.js +1 -1
  136. package/dist/components/{ds-card.d.ts → ds-toast.d.ts} +4 -4
  137. package/dist/components/ds-toast.js +2 -0
  138. package/dist/components/ds-toast.js.map +1 -0
  139. package/dist/components/ds-tooltip-data-viz.js +1 -1
  140. package/dist/components/ds-tooltip.js +1 -1
  141. package/dist/components/{p-DnMCRAwx.js → p-0kEg-Z4f.js} +2 -2
  142. package/dist/components/{p-Cijzn3YQ.js → p-B4RQoNmL.js} +2 -2
  143. package/dist/components/p-B8C_yfLQ.js +2 -0
  144. package/dist/components/p-B8C_yfLQ.js.map +1 -0
  145. package/dist/components/{p-BHpWYKtP.js → p-BJUcsBHt.js} +2 -2
  146. package/dist/components/{p-DaQ0ZE_V.js → p-BTo4pNdp.js} +2 -2
  147. package/dist/components/p-Bet_UjML.js +2 -0
  148. package/dist/components/{p-CJlgONwR.js.map → p-Bet_UjML.js.map} +1 -1
  149. package/dist/components/{p-Ci_nVk5P.js → p-BkwBtZs3.js} +2 -2
  150. package/dist/components/{p-Dst-OliP.js → p-CKnoWZd9.js} +2 -2
  151. package/dist/components/{p-BRfOCc_h.js → p-CLn7QnE0.js} +2 -2
  152. package/dist/components/{p-kezp2_Xu.js → p-CPPAndX2.js} +2 -2
  153. package/dist/components/{p-xB0GPG3-.js → p-CS12e52R.js} +2 -2
  154. package/dist/components/{p-BSOZXagj.js → p-CZZYGqKz.js} +2 -2
  155. package/dist/components/p-C_0Q8Cnp.js +2 -0
  156. package/dist/components/p-C_0Q8Cnp.js.map +1 -0
  157. package/dist/components/{p-DiooIO2B.js → p-CxyjoTN1.js} +2 -2
  158. package/dist/components/p-CyoHRqy6.js +2 -0
  159. package/dist/components/p-CyoHRqy6.js.map +1 -0
  160. package/dist/components/p-DBJ2I3mH.js +2 -0
  161. package/dist/components/p-DBJ2I3mH.js.map +1 -0
  162. package/dist/components/p-DM-95BX1.js +2 -0
  163. package/dist/components/p-DM-95BX1.js.map +1 -0
  164. package/dist/components/{p-T0Mzhv3-.js → p-DZAtgSZo.js} +2 -2
  165. package/dist/components/{p-CeFBA7Dx.js → p-Dh4q5TSS.js} +2 -2
  166. package/dist/components/{p-Dj5MejHv.js → p-DhsO0939.js} +2 -2
  167. package/dist/components/{p-CiwdnKKp.js → p-DrDHC7V6.js} +2 -2
  168. package/dist/components/{p-CblAABEo.js → p-DsbhBb5F.js} +2 -2
  169. package/dist/components/p-DuNZGFkV.js +2 -0
  170. package/dist/components/p-DuNZGFkV.js.map +1 -0
  171. package/dist/components/{p-B1pWGQn1.js → p-P_4vE1ub.js} +2 -2
  172. package/dist/docs/components.json +447 -515
  173. package/dist/framework/select-multi-value-accessor.js +3 -3
  174. package/dist/lib/toast/index.d.ts +2 -0
  175. package/dist/lib/toast/index.js +158 -0
  176. package/dist/lib/toast/index.js.map +7 -0
  177. package/dist/lib/toast/toast-manager.d.ts +3 -0
  178. package/dist/lib/toast/toast-types.d.ts +85 -0
  179. package/dist/mcp-data/registry/agent-activity.json +1 -1
  180. package/dist/mcp-data/registry/agent-response.json +2 -2
  181. package/dist/mcp-data/registry/agent-source-list.json +1 -1
  182. package/dist/mcp-data/registry/agent-tool-call.json +1 -1
  183. package/dist/mcp-data/registry/app-shell.json +1 -1
  184. package/dist/mcp-data/registry/attachment-list.json +1 -1
  185. package/dist/mcp-data/registry/avatar.json +1 -1
  186. package/dist/mcp-data/registry/badge.json +1 -1
  187. package/dist/mcp-data/registry/bar-nav.json +1 -1
  188. package/dist/mcp-data/registry/button-filled.json +1 -1
  189. package/dist/mcp-data/registry/button-unfilled.json +1 -1
  190. package/dist/mcp-data/registry/card-data-viz-donut.json +2 -2
  191. package/dist/mcp-data/registry/card-setting.json +99 -13
  192. package/dist/mcp-data/registry/card-shell-data-viz.json +8 -8
  193. package/dist/mcp-data/registry/chart-bar.json +1 -1
  194. package/dist/mcp-data/registry/chart-donut.json +1 -1
  195. package/dist/mcp-data/registry/chart-legend.json +1 -1
  196. package/dist/mcp-data/registry/chart-line.json +1 -1
  197. package/dist/mcp-data/registry/checkbox.json +1 -1
  198. package/dist/mcp-data/registry/chip.json +1 -1
  199. package/dist/mcp-data/registry/code-block.json +1 -1
  200. package/dist/mcp-data/registry/conversation-list-item.json +4 -4
  201. package/dist/mcp-data/registry/conversation-list-section.json +1 -1
  202. package/dist/mcp-data/registry/conversation-list.json +1 -1
  203. package/dist/mcp-data/registry/divider.json +5 -5
  204. package/dist/mcp-data/registry/empty-state.json +1 -1
  205. package/dist/mcp-data/registry/field.json +1 -1
  206. package/dist/mcp-data/registry/icon.json +2 -2
  207. package/dist/mcp-data/registry/input.json +1 -1
  208. package/dist/mcp-data/registry/loader.json +1 -1
  209. package/dist/mcp-data/registry/markdown.json +1 -1
  210. package/dist/mcp-data/registry/menu.json +1 -1
  211. package/dist/mcp-data/registry/message-bubble.json +7 -7
  212. package/dist/mcp-data/registry/message-composer.json +2 -2
  213. package/dist/mcp-data/registry/message-scroller.json +1 -1
  214. package/dist/mcp-data/registry/message.json +7 -6
  215. package/dist/mcp-data/registry/modal.json +154 -24
  216. package/dist/mcp-data/registry/panel-nav.json +1 -1
  217. package/dist/mcp-data/registry/panel-sub-nav.json +2 -2
  218. package/dist/mcp-data/registry/panel-tool-header.json +1 -1
  219. package/dist/mcp-data/registry/panel-tool-search.json +1 -1
  220. package/dist/mcp-data/registry/panel-tools.json +1 -1
  221. package/dist/mcp-data/registry/radio.json +1 -1
  222. package/dist/mcp-data/registry/registry.json +387 -141
  223. package/dist/mcp-data/registry/select-multi.json +1 -1
  224. package/dist/mcp-data/registry/select.json +1 -1
  225. package/dist/mcp-data/registry/shell-gradient-picker.json +1 -1
  226. package/dist/mcp-data/registry/shell-gradient-swatch.json +1 -1
  227. package/dist/mcp-data/registry/skeleton.json +2 -2
  228. package/dist/mcp-data/registry/slider.json +1 -1
  229. package/dist/mcp-data/registry/swatch-picker.json +1 -1
  230. package/dist/mcp-data/registry/switch.json +1 -1
  231. package/dist/mcp-data/registry/tab-group.json +1 -1
  232. package/dist/mcp-data/registry/tag.json +2 -2
  233. package/dist/mcp-data/registry/text.json +2 -2
  234. package/dist/mcp-data/registry/toast.json +318 -0
  235. package/dist/mcp-data/registry/tooltip-data-viz.json +1 -1
  236. package/dist/mcp-data/registry/tooltip.json +1 -1
  237. package/dist/react/components.d.ts +1 -2
  238. package/dist/react/components.js +1 -2
  239. package/dist/react/ds-card-setting.d.ts +2 -2
  240. package/dist/react/ds-card-setting.js +1 -1
  241. package/dist/react/ds-modal.d.ts +3 -2
  242. package/dist/react/ds-modal.js +4 -1
  243. package/dist/react/ds-toast.d.ts +14 -0
  244. package/dist/react/ds-toast.js +16 -0
  245. package/dist/types/components/CardSetting/CardSetting.d.ts +9 -6
  246. package/dist/types/components/CardSetting/index.d.ts +1 -1
  247. package/dist/types/components/MessageBubble/MessageBubble.d.ts +1 -1
  248. package/dist/types/components/Modal/Modal.d.ts +21 -18
  249. package/dist/types/components/Toast/Toast.d.ts +106 -0
  250. package/dist/types/components/Toast/index.d.ts +2 -0
  251. package/dist/types/components.d.ts +136 -180
  252. package/dist/types/toast/index.d.ts +3 -0
  253. package/dist/types/toast/toast-manager.d.ts +4 -0
  254. package/dist/types/toast/toast-types.d.ts +86 -0
  255. package/package.json +12 -8
  256. package/dist/angular/ds-banner.d.ts +0 -15
  257. package/dist/angular/ds-card.d.ts +0 -12
  258. package/dist/angular/ds-card.js +0 -38
  259. package/dist/components/ds-banner.d.ts +0 -11
  260. package/dist/components/ds-banner.js +0 -2
  261. package/dist/components/ds-banner.js.map +0 -1
  262. package/dist/components/ds-card.js +0 -2
  263. package/dist/components/ds-card.js.map +0 -1
  264. package/dist/components/p-BO6C8abO.js +0 -2
  265. package/dist/components/p-BO6C8abO.js.map +0 -1
  266. package/dist/components/p-CBYuvZKM.js +0 -2
  267. package/dist/components/p-CBYuvZKM.js.map +0 -1
  268. package/dist/components/p-CJlgONwR.js +0 -2
  269. package/dist/components/p-CWNdl52Y.js +0 -2
  270. package/dist/components/p-CWNdl52Y.js.map +0 -1
  271. package/dist/components/p-CiKGqsA2.js +0 -2
  272. package/dist/components/p-CiKGqsA2.js.map +0 -1
  273. package/dist/components/p-DFxqk71w.js +0 -2
  274. package/dist/components/p-DFxqk71w.js.map +0 -1
  275. package/dist/components/p-drBA73M_.js +0 -2
  276. package/dist/components/p-drBA73M_.js.map +0 -1
  277. package/dist/mcp-data/registry/banner.json +0 -206
  278. package/dist/mcp-data/registry/card.json +0 -126
  279. package/dist/react/ds-banner.d.ts +0 -12
  280. package/dist/react/ds-banner.js +0 -12
  281. package/dist/react/ds-card.d.ts +0 -9
  282. package/dist/react/ds-card.js +0 -12
  283. package/dist/types/components/Banner/Banner.d.ts +0 -31
  284. package/dist/types/components/Card/Card.d.ts +0 -21
  285. package/dist/types/components/Card/index.d.ts +0 -2
  286. /package/dist/components/{p-DnMCRAwx.js.map → p-0kEg-Z4f.js.map} +0 -0
  287. /package/dist/components/{p-Cijzn3YQ.js.map → p-B4RQoNmL.js.map} +0 -0
  288. /package/dist/components/{p-BHpWYKtP.js.map → p-BJUcsBHt.js.map} +0 -0
  289. /package/dist/components/{p-DaQ0ZE_V.js.map → p-BTo4pNdp.js.map} +0 -0
  290. /package/dist/components/{p-Ci_nVk5P.js.map → p-BkwBtZs3.js.map} +0 -0
  291. /package/dist/components/{p-Dst-OliP.js.map → p-CKnoWZd9.js.map} +0 -0
  292. /package/dist/components/{p-BRfOCc_h.js.map → p-CLn7QnE0.js.map} +0 -0
  293. /package/dist/components/{p-kezp2_Xu.js.map → p-CPPAndX2.js.map} +0 -0
  294. /package/dist/components/{p-xB0GPG3-.js.map → p-CS12e52R.js.map} +0 -0
  295. /package/dist/components/{p-BSOZXagj.js.map → p-CZZYGqKz.js.map} +0 -0
  296. /package/dist/components/{p-DiooIO2B.js.map → p-CxyjoTN1.js.map} +0 -0
  297. /package/dist/components/{p-T0Mzhv3-.js.map → p-DZAtgSZo.js.map} +0 -0
  298. /package/dist/components/{p-CeFBA7Dx.js.map → p-Dh4q5TSS.js.map} +0 -0
  299. /package/dist/components/{p-Dj5MejHv.js.map → p-DhsO0939.js.map} +0 -0
  300. /package/dist/components/{p-CiwdnKKp.js.map → p-DrDHC7V6.js.map} +0 -0
  301. /package/dist/components/{p-CblAABEo.js.map → p-DsbhBb5F.js.map} +0 -0
  302. /package/dist/components/{p-B1pWGQn1.js.map → p-P_4vE1ub.js.map} +0 -0
@@ -721,7 +721,7 @@
721
721
  "peerDependencies": {
722
722
  "required": [
723
723
  "@ds-mo/tokens ^3.1.1",
724
- "@ds-mo/icons ^6.2.0"
724
+ "@ds-mo/icons ^6.3.0"
725
725
  ],
726
726
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
727
727
  }
@@ -707,7 +707,7 @@
707
707
  "peerDependencies": {
708
708
  "required": [
709
709
  "@ds-mo/tokens ^3.1.1",
710
- "@ds-mo/icons ^6.2.0"
710
+ "@ds-mo/icons ^6.3.0"
711
711
  ],
712
712
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
713
713
  }
@@ -167,7 +167,7 @@
167
167
  "peerDependencies": {
168
168
  "required": [
169
169
  "@ds-mo/tokens ^3.1.1",
170
- "@ds-mo/icons ^6.2.0"
170
+ "@ds-mo/icons ^6.3.0"
171
171
  ],
172
172
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
173
173
  }
@@ -184,7 +184,7 @@
184
184
  "peerDependencies": {
185
185
  "required": [
186
186
  "@ds-mo/tokens ^3.1.1",
187
- "@ds-mo/icons ^6.2.0"
187
+ "@ds-mo/icons ^6.3.0"
188
188
  ],
189
189
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
190
190
  }
@@ -43,7 +43,7 @@
43
43
  }
44
44
  ],
45
45
  "commonlyComposedWith": [
46
- "component:ds-card",
46
+ "component:ds-card-setting",
47
47
  "component:ds-text",
48
48
  "component:ds-icon"
49
49
  ],
@@ -256,7 +256,7 @@
256
256
  "peerDependencies": {
257
257
  "required": [
258
258
  "@ds-mo/tokens ^3.1.1",
259
- "@ds-mo/icons ^6.2.0"
259
+ "@ds-mo/icons ^6.3.0"
260
260
  ],
261
261
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
262
262
  }
@@ -629,7 +629,7 @@
629
629
  "peerDependencies": {
630
630
  "required": [
631
631
  "@ds-mo/tokens ^3.1.1",
632
- "@ds-mo/icons ^6.2.0"
632
+ "@ds-mo/icons ^6.3.0"
633
633
  ],
634
634
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
635
635
  }
@@ -200,7 +200,7 @@
200
200
  "peerDependencies": {
201
201
  "required": [
202
202
  "@ds-mo/tokens ^3.1.1",
203
- "@ds-mo/icons ^6.2.0"
203
+ "@ds-mo/icons ^6.3.0"
204
204
  ],
205
205
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
206
206
  }
@@ -335,7 +335,7 @@
335
335
  "peerDependencies": {
336
336
  "required": [
337
337
  "@ds-mo/tokens ^3.1.1",
338
- "@ds-mo/icons ^6.2.0"
338
+ "@ds-mo/icons ^6.3.0"
339
339
  ],
340
340
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
341
341
  }
@@ -219,7 +219,7 @@
219
219
  "peerDependencies": {
220
220
  "required": [
221
221
  "@ds-mo/tokens ^3.1.1",
222
- "@ds-mo/icons ^6.2.0"
222
+ "@ds-mo/icons ^6.3.0"
223
223
  ],
224
224
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
225
225
  }
@@ -45,7 +45,7 @@
45
45
  }
46
46
  ],
47
47
  "commonlyComposedWith": [
48
- "component:ds-card",
48
+ "component:ds-card-setting",
49
49
  "component:ds-text",
50
50
  "component:ds-icon",
51
51
  "component:ds-menu"
@@ -322,7 +322,7 @@
322
322
  "peerDependencies": {
323
323
  "required": [
324
324
  "@ds-mo/tokens ^3.1.1",
325
- "@ds-mo/icons ^6.2.0"
325
+ "@ds-mo/icons ^6.3.0"
326
326
  ],
327
327
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
328
328
  }
@@ -40,7 +40,7 @@
40
40
  ],
41
41
  "commonlyComposedWith": [
42
42
  "component:ds-icon",
43
- "component:ds-card",
43
+ "component:ds-card-setting",
44
44
  "component:ds-field",
45
45
  "component:ds-button-filled"
46
46
  ],
@@ -335,7 +335,7 @@
335
335
  "peerDependencies": {
336
336
  "required": [
337
337
  "@ds-mo/tokens ^3.1.1",
338
- "@ds-mo/icons ^6.2.0"
338
+ "@ds-mo/icons ^6.3.0"
339
339
  ],
340
340
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
341
341
  }
@@ -0,0 +1,318 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
+ "name": "toast",
4
+ "title": "Toast",
5
+ "description": "Application-level floating notification system with a global manager, queued bottom-end stack, anchored feedback, actions, promise states, priority announcements, pauseable timers, keyboard access, and swipe dismissal.",
6
+ "type": "registry:ui",
7
+ "meta": {
8
+ "library": "@ds-mo/ui",
9
+ "distribution": "npm",
10
+ "storybook": "https://zainadeel.github.io/compomo/?path=/story/toast",
11
+ "source": "src/wc/components/Toast/Toast.tsx",
12
+ "intentStatus": "complete",
13
+ "intent": {
14
+ "audience": "general",
15
+ "status": "stable",
16
+ "summary": "Application-level floating notification system with a global manager, queued bottom-end stack, anchored feedback, actions, promise states, priority announcements, pauseable timers, keyboard access, and swipe dismissal.",
17
+ "useWhen": [
18
+ "A completed or failed operation needs brief non-blocking feedback without moving page content.",
19
+ "An application needs one coordinated notification queue that can be triggered outside the current component tree.",
20
+ "A short-lived undo or recovery action belongs directly with transient feedback.",
21
+ "Contextual feedback such as Copy confirmation should appear near the control that caused it."
22
+ ],
23
+ "avoidWhen": [
24
+ "The message must remain visible as part of page content or contains information users need later.",
25
+ "The user must make a decision before continuing; use Modal for a blocking workflow.",
26
+ "Validation belongs to a specific field or form section; keep the error adjacent to that content.",
27
+ "The notification would contain long prose, several actions, navigation, or a complete workflow.",
28
+ "Repeated background events would create a noisy stream instead of one updated or deduplicated toast."
29
+ ],
30
+ "alternatives": [
31
+ {
32
+ "when": "The user must respond before continuing or an irreversible action needs confirmation.",
33
+ "component": "component:ds-modal",
34
+ "reason": "Modal owns blocking focus containment and explicit decision actions."
35
+ },
36
+ {
37
+ "when": "A form control needs persistent validation or supporting guidance.",
38
+ "component": "component:ds-field",
39
+ "reason": "Field keeps actionable feedback associated with the control that needs correction."
40
+ },
41
+ {
42
+ "when": "A compact status must remain visible in the page hierarchy.",
43
+ "component": "component:ds-tag",
44
+ "reason": "Tag represents persistent static metadata rather than transient feedback."
45
+ }
46
+ ],
47
+ "commonlyComposedWith": [
48
+ "component:ds-button-filled",
49
+ "component:ds-button-unfilled",
50
+ "component:ds-modal",
51
+ "component:ds-field"
52
+ ],
53
+ "accessibility": [
54
+ "Mount one ds-toast near the application root. New notifications never move focus.",
55
+ "Provide a concise title, description, or both. Do not place the only recovery instructions in an automatically expiring toast.",
56
+ "Use low priority for ordinary feedback. Reserve high priority for urgent interruptions that warrant assertive announcement.",
57
+ "F6 moves focus into the Notifications region; Escape dismisses the focused toast and focus returns to a surviving toast or the previous control.",
58
+ "Timers pause while users hover, focus, swipe, or leave the document, preserving the remaining reading time.",
59
+ "Use timeout 0 for feedback that must remain until explicitly dismissed. Keep action labels concise and uniquely understandable.",
60
+ "Anchored feedback supplements the triggering control but does not replace its accessible name, state, or persistent result.",
61
+ "Do not include secrets, customer PII, or sensitive operational details in transient notification text."
62
+ ],
63
+ "states": [
64
+ "The manager owns add, ID-based upsert, update, close, closeAll, and promise transitions. The component renders the manager snapshot.",
65
+ "Loading promise records remain persistent until the same id updates to success or error and begins its resulting timeout.",
66
+ "Only the newest records up to the limit are visible in the global stack. The collapsed trail insets each successive toast by 8px per side; hover or keyboard focus expands all visible records to full width. Older records remain mounted and inert until promoted.",
67
+ "All timers pause together on hover, focus, touch swipe, window blur, or hidden-document state and resume from their exact remainder.",
68
+ "Closing records remain rendered through exit motion before removal callbacks and dsToastRemove.",
69
+ "One optional bordered unfilled action sits below the text at bottom-left, emits dsToastAction, and runs the supplied callback without dismissing automatically.",
70
+ "Swipe state exposes movement and direction hooks; down and right are the default dismissal directions.",
71
+ "Anchored records use trigger-relative positioning and do not consume the global stack limit."
72
+ ],
73
+ "responsiveBehavior": [
74
+ "The global stack stays at the viewport bottom-end with token-based inset and never exceeds the available viewport width.",
75
+ "Anchored toasts flip on their placement axis and clamp to viewport padding when the preferred side does not fit.",
76
+ "The owner does not create separate mobile and desktop managers; one queue preserves ordering across responsive layouts.",
77
+ "Pointer swipe remains optional input. Close and action controls retain keyboard access through the notification region."
78
+ ],
79
+ "frameworkCaveats": {
80
+ "customElements": [
81
+ "Import ds-toast once and call toastManager from @ds-mo/ui/toast. Assign a custom manager and swipeDirections through JavaScript properties.",
82
+ "Mount one ds-toast per manager; a second connected viewport for the same manager remains inactive."
83
+ ],
84
+ "react": [
85
+ "Render one DsToast near the application root and import toastManager or createToastManager from @ds-mo/ui/toast.",
86
+ "Pass custom manager, action callbacks, data, positioner anchors, and swipe directions as properties rather than string attributes."
87
+ ],
88
+ "angular": [
89
+ "Import DsToast once near the application root and import toastManager or createToastManager from @ds-mo/ui/toast.",
90
+ "Use property binding for manager, action callbacks, data, positioner anchors, and swipeDirections."
91
+ ]
92
+ },
93
+ "references": [
94
+ {
95
+ "label": "Storybook examples",
96
+ "path": "src/wc/components/Toast/Toast.stories.ts"
97
+ },
98
+ {
99
+ "label": "Manager unit coverage",
100
+ "path": "tests/toast-manager.test.ts"
101
+ },
102
+ {
103
+ "label": "Cross-browser behavior coverage",
104
+ "path": "tests/e2e/toast.spec.ts"
105
+ }
106
+ ]
107
+ },
108
+ "api": {
109
+ "props": {
110
+ "closeLabel": {
111
+ "type": "string",
112
+ "resolvedType": "string",
113
+ "attribute": "close-label",
114
+ "default": "'Close notification'",
115
+ "required": false,
116
+ "mutable": false,
117
+ "description": "Localized accessible label for every toast close action."
118
+ },
119
+ "label": {
120
+ "type": "string",
121
+ "resolvedType": "string",
122
+ "attribute": "label",
123
+ "default": "'Notifications'",
124
+ "required": false,
125
+ "mutable": false,
126
+ "description": "Accessible label for the notification region."
127
+ },
128
+ "limit": {
129
+ "type": "number",
130
+ "resolvedType": "number",
131
+ "attribute": "limit",
132
+ "default": "3",
133
+ "required": false,
134
+ "mutable": false,
135
+ "description": "Maximum visible global-stack records. Limited records remain mounted and inert."
136
+ },
137
+ "manager": {
138
+ "type": "ToastManager",
139
+ "resolvedType": "ToastManager<unknown>",
140
+ "default": "defaultToastManager",
141
+ "required": false,
142
+ "mutable": false,
143
+ "description": "Manager that supplies toast records. Assign as a JavaScript property."
144
+ },
145
+ "swipeDirections": {
146
+ "type": "ToastSwipeDirection[]",
147
+ "resolvedType": "ToastSwipeDirection[]",
148
+ "default": "['down', 'right']",
149
+ "required": false,
150
+ "mutable": false,
151
+ "description": "Allowed swipe-to-dismiss directions. Assign as a JavaScript property."
152
+ },
153
+ "timeout": {
154
+ "type": "number | string",
155
+ "resolvedType": "number | string",
156
+ "attribute": "timeout",
157
+ "default": "TOKEN_DEFAULTS.animationDelayLong2",
158
+ "required": false,
159
+ "mutable": false,
160
+ "description": "Default auto-dismiss delay. Use 0 for persistent records."
161
+ }
162
+ },
163
+ "events": [
164
+ {
165
+ "name": "dsToastAction",
166
+ "detail": "ToastActionEventDetail",
167
+ "bubbles": true,
168
+ "cancelable": true,
169
+ "composed": true
170
+ },
171
+ {
172
+ "name": "dsToastClose",
173
+ "detail": "ToastCloseEventDetail",
174
+ "bubbles": true,
175
+ "cancelable": true,
176
+ "composed": true
177
+ },
178
+ {
179
+ "name": "dsToastRemove",
180
+ "detail": "ToastEventDetail",
181
+ "bubbles": true,
182
+ "cancelable": true,
183
+ "composed": true
184
+ }
185
+ ],
186
+ "methods": [],
187
+ "slots": []
188
+ },
189
+ "props": {
190
+ "closeLabel": {
191
+ "type": "string",
192
+ "resolvedType": "string",
193
+ "attribute": "close-label",
194
+ "default": "'Close notification'",
195
+ "required": false,
196
+ "mutable": false,
197
+ "description": "Localized accessible label for every toast close action."
198
+ },
199
+ "label": {
200
+ "type": "string",
201
+ "resolvedType": "string",
202
+ "attribute": "label",
203
+ "default": "'Notifications'",
204
+ "required": false,
205
+ "mutable": false,
206
+ "description": "Accessible label for the notification region."
207
+ },
208
+ "limit": {
209
+ "type": "number",
210
+ "resolvedType": "number",
211
+ "attribute": "limit",
212
+ "default": "3",
213
+ "required": false,
214
+ "mutable": false,
215
+ "description": "Maximum visible global-stack records. Limited records remain mounted and inert."
216
+ },
217
+ "manager": {
218
+ "type": "ToastManager",
219
+ "resolvedType": "ToastManager<unknown>",
220
+ "default": "defaultToastManager",
221
+ "required": false,
222
+ "mutable": false,
223
+ "description": "Manager that supplies toast records. Assign as a JavaScript property."
224
+ },
225
+ "swipeDirections": {
226
+ "type": "ToastSwipeDirection[]",
227
+ "resolvedType": "ToastSwipeDirection[]",
228
+ "default": "['down', 'right']",
229
+ "required": false,
230
+ "mutable": false,
231
+ "description": "Allowed swipe-to-dismiss directions. Assign as a JavaScript property."
232
+ },
233
+ "timeout": {
234
+ "type": "number | string",
235
+ "resolvedType": "number | string",
236
+ "attribute": "timeout",
237
+ "default": "TOKEN_DEFAULTS.animationDelayLong2",
238
+ "required": false,
239
+ "mutable": false,
240
+ "description": "Default auto-dismiss delay. Use 0 for persistent records."
241
+ }
242
+ },
243
+ "events": [
244
+ {
245
+ "name": "dsToastAction",
246
+ "detail": "ToastActionEventDetail",
247
+ "bubbles": true,
248
+ "cancelable": true,
249
+ "composed": true
250
+ },
251
+ {
252
+ "name": "dsToastClose",
253
+ "detail": "ToastCloseEventDetail",
254
+ "bubbles": true,
255
+ "cancelable": true,
256
+ "composed": true
257
+ },
258
+ {
259
+ "name": "dsToastRemove",
260
+ "detail": "ToastEventDetail",
261
+ "bubbles": true,
262
+ "cancelable": true,
263
+ "composed": true
264
+ }
265
+ ],
266
+ "methods": [],
267
+ "slots": [],
268
+ "exports": {
269
+ "customElement": "ds-toast",
270
+ "react": "DsToast",
271
+ "angular": "DsToast"
272
+ },
273
+ "consumption": {
274
+ "install": "npm install @ds-mo/ui @ds-mo/tokens @ds-mo/icons",
275
+ "cssSetup": "import '@ds-mo/tokens';\nimport '@ds-mo/tokens/reset';\nimport '@ds-mo/tokens/globals';",
276
+ "customElements": {
277
+ "import": "import '@ds-mo/ui/dist/components/ds-toast.js';",
278
+ "example": "<ds-toast></ds-toast>"
279
+ },
280
+ "react": {
281
+ "import": "import { DsToast } from '@ds-mo/ui/react';",
282
+ "example": "<DsToast />"
283
+ },
284
+ "angular": {
285
+ "import": "import { DsToast } from '@ds-mo/ui/angular/ds-toast';",
286
+ "example": "<ds-toast></ds-toast>"
287
+ },
288
+ "complexPropertyNote": "Assign these non-primitive values as JavaScript properties: manager, swipeDirections.",
289
+ "peerDependencies": {
290
+ "required": [
291
+ "@ds-mo/tokens ^3.1.1",
292
+ "@ds-mo/icons ^6.3.0"
293
+ ],
294
+ "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
295
+ }
296
+ }
297
+ },
298
+ "dependencies": [
299
+ "@ds-mo/ui",
300
+ "@ds-mo/tokens"
301
+ ],
302
+ "registryDependencies": [
303
+ "button-unfilled",
304
+ "text"
305
+ ],
306
+ "files": [
307
+ {
308
+ "path": "src/wc/components/Toast/Toast.css",
309
+ "content": ":host {\n display: contents;\n}\n\n.toast-region {\n position: fixed;\n inset: 0;\n z-index: var(--dimension-z-index-floating);\n pointer-events: none;\n outline: none;\n}\n\n.toast-viewport {\n position: absolute;\n right: var(--dimension-space-200);\n bottom: var(--dimension-space-200);\n display: grid;\n width: min(\n var(--dimension-card-width-sm),\n calc(100vw - 2 * var(--dimension-space-200))\n );\n}\n\n.toast-positioner {\n grid-area: 1 / 1;\n align-self: end;\n justify-self: center;\n width: 100%;\n pointer-events: auto;\n transform: translateY(\n calc(-1 * var(--toast-index) * var(--dimension-space-100))\n );\n transition:\n transform var(--effect-motion-short-3),\n width var(--effect-motion-short-3);\n}\n\n.toast-viewport:not([data-expanded]) .toast-positioner {\n width: calc(\n 100% - 2 * var(--toast-index) * var(--dimension-space-100)\n );\n}\n\n.toast-viewport[data-expanded] .toast-positioner {\n transform: translateY(calc(-1 * var(--toast-offset-y)));\n}\n\n.toast-positioner[data-limited] {\n visibility: hidden;\n pointer-events: none;\n}\n\n.toast-positioner--anchored {\n position: fixed;\n width: min(\n var(--dimension-card-width-sm),\n calc(100vw - 2 * var(--dimension-space-200))\n );\n transform: none;\n}\n\n.toast-positioner--anchored[data-positioned='false'] {\n visibility: hidden;\n}\n\n.toast-surface {\n position: relative;\n display: block;\n box-sizing: border-box;\n width: 100%;\n height: var(--toast-height, auto);\n padding: var(--dimension-space-200);\n overflow: hidden;\n color: var(--color-foreground-primary);\n background-color: var(--color-background-primary);\n border-radius: var(--dimension-radius-050);\n box-shadow: var(--effect-elevation-elevated-floating);\n transform: translate(\n var(--toast-swipe-movement-x),\n var(--toast-swipe-movement-y)\n );\n animation: toast-enter var(--effect-motion-short-2) both;\n}\n\n.toast-positioner--ending .toast-surface {\n animation: toast-exit var(--effect-motion-short-3) both;\n}\n\n.toast-surface--swiping {\n transition: none;\n user-select: none;\n}\n\n.toast-content {\n display: flex;\n flex-direction: column;\n min-width: 0;\n padding-inline-end: var(--dimension-size-500);\n transition: opacity var(--effect-motion-short-3);\n}\n\n.toast-copy {\n display: flex;\n flex-direction: column;\n min-width: 0;\n min-height: var(--typography-lineheight-md);\n margin-block: calc(-1 * var(--dimension-space-025));\n gap: var(--dimension-space-050);\n}\n\n.toast-title,\n.toast-description {\n min-width: 0;\n}\n\n.toast-action {\n align-self: start;\n margin-top: calc(\n var(--dimension-space-200) + var(--dimension-space-025)\n );\n}\n\n.toast-close {\n position: absolute;\n top: var(--dimension-space-100);\n right: var(--dimension-space-100);\n transition: opacity var(--effect-motion-short-3);\n}\n\n.toast-viewport:not([data-expanded]) .toast-positioner[data-behind] .toast-content,\n.toast-viewport:not([data-expanded]) .toast-positioner[data-behind] .toast-close {\n opacity: 0;\n}\n\n.toast-assertive-announcer {\n position: absolute;\n width: var(--dimension-size-100);\n height: var(--dimension-size-100);\n padding: 0;\n overflow: hidden;\n white-space: nowrap;\n clip-path: inset(50%);\n}\n\n@keyframes toast-enter {\n from {\n opacity: 0;\n transform: translateY(var(--dimension-space-100));\n }\n\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes toast-exit {\n from {\n opacity: 1;\n }\n\n to {\n opacity: 0;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .toast-positioner,\n .toast-surface,\n .toast-content,\n .toast-close,\n .toast-positioner--ending .toast-surface {\n transition: none;\n animation: none;\n }\n\n .toast-positioner--ending .toast-surface {\n opacity: 0;\n }\n}\n",
310
+ "type": "registry:ui"
311
+ },
312
+ {
313
+ "path": "src/wc/components/Toast/Toast.tsx",
314
+ "content": "import {\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Prop,\n State,\n Watch,\n} from '@stencil/core';\nimport {\n resolveCssLengthPx,\n resolveCssTimeMs,\n resolveMotionTimeMs,\n TOKEN_DEFAULTS,\n} from '../../utils';\nimport {\n toastManager as defaultToastManager,\n type ToastActionEventDetail,\n type ToastCloseContext,\n type ToastCloseEventDetail,\n type ToastEventDetail,\n type ToastManager,\n type ToastRecord,\n type ToastSwipeDirection,\n} from '../../toast';\nimport { computeTooltipPosition } from '../Tooltip/tooltip-position';\n\ninterface ToastTimer {\n timerKey: number;\n remaining: number;\n startedAt: number;\n handle: ReturnType<typeof setTimeout> | null;\n}\n\ninterface SwipeState {\n id: string;\n x: number;\n y: number;\n direction?: ToastSwipeDirection;\n}\n\ninterface AnchoredPosition {\n x: number;\n y: number;\n side: 'top' | 'right' | 'bottom' | 'left';\n}\n\ninterface ActiveSwipe {\n id: string;\n pointerId: number;\n pointerType: string;\n startX: number;\n startY: number;\n maxDistance: number;\n cancelled: boolean;\n axis: 'x' | 'y' | null;\n}\n\nconst SWIPE_THRESHOLD = 40;\nconst SWIPE_REVERSE_CANCEL_THRESHOLD = 10;\nconst GLOBAL_STACK_HOVER = '__global-stack__';\nconst INTERACTIVE_SWIPE_SELECTOR =\n 'button,a,input,textarea,select,[role=\"button\"],[data-ds-toast-swipe-ignore]';\n\nconst attachedManagers = new WeakMap<ToastManager, Toast>();\nconst connectedToastRegions = new Set<Toast>();\nlet activeToastRegion: Toast | null = null;\nlet toastInstanceCounter = 0;\n\n@Component({\n tag: 'ds-toast',\n styleUrl: 'Toast.css',\n scoped: true,\n})\nexport class Toast {\n @Element() el!: HTMLElement;\n\n /** Manager that supplies toast records. Assign as a JavaScript property. */\n @Prop() manager: ToastManager = defaultToastManager;\n /** Maximum visible global-stack records. Limited records remain mounted and inert. */\n @Prop() limit: number = 3;\n /** Default auto-dismiss delay. Use 0 for persistent records. */\n @Prop() timeout: number | string = TOKEN_DEFAULTS.animationDelayLong2;\n /** Accessible label for the notification region. */\n @Prop() label: string = 'Notifications';\n /** Localized accessible label for every toast close action. */\n @Prop() closeLabel: string = 'Close notification';\n /** Allowed swipe-to-dismiss directions. Assign as a JavaScript property. */\n @Prop() swipeDirections: ToastSwipeDirection[] = ['down', 'right'];\n\n @State() private records: readonly ToastRecord[] = [];\n @State() private expanded = false;\n @State() private keyboardActive = false;\n @State() private swipe: SwipeState | null = null;\n @State() private layoutVersion = 0;\n\n @Event() dsToastClose!: EventEmitter<ToastCloseEventDetail>;\n @Event() dsToastRemove!: EventEmitter<ToastEventDetail>;\n @Event() dsToastAction!: EventEmitter<ToastActionEventDetail>;\n\n private readonly instanceId = ++toastInstanceCounter;\n private readonly domIds = new Map<string, number>();\n private readonly timers = new Map<string, ToastTimer>();\n private readonly closeWatchdogs = new Map<string, ReturnType<typeof setTimeout>>();\n private readonly closeFrames = new Map<string, number>();\n private readonly closeEvents = new Set<string>();\n private readonly activationFrames = new Map<string, number>();\n private readonly pauseReasons = new Set<string>();\n private readonly hoveredIds = new Set<string>();\n private readonly heights = new Map<string, number>();\n private readonly measuredUpdateKeys = new Map<string, number>();\n private readonly anchoredPositions = new Map<string, AnchoredPosition>();\n private readonly dismissedSwipeDirections = new Map<string, ToastSwipeDirection>();\n private readonly observedElements = new Set<Element>();\n private readonly pendingRemovals: Array<{\n manager: ToastManager;\n context: ToastCloseContext;\n }> = [];\n\n private unsubscribe: (() => void) | null = null;\n private attachedManager: ToastManager | null = null;\n private previousFocus: HTMLElement | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private mutationObserver: MutationObserver | null = null;\n private layoutFrame: number | null = null;\n private activeSwipe: ActiveSwipe | null = null;\n private nextDomId = 0;\n private connected = false;\n private pendingHoverLeave = false;\n\n connectedCallback() {\n this.connect();\n }\n\n componentDidLoad() {\n this.connect();\n }\n\n private connect() {\n if (this.connected) return;\n this.connected = true;\n this.resizeObserver ??= new ResizeObserver(() => this.scheduleLayout());\n this.mutationObserver ??= new MutationObserver(() => this.scheduleLayout());\n this.mutationObserver.observe(document.body, { childList: true, subtree: true });\n if (!this.unsubscribe) this.attachManager(this.manager);\n window.addEventListener('blur', this.handleWindowBlur);\n window.addEventListener('focus', this.handleWindowFocus);\n window.addEventListener('resize', this.handleWindowResize);\n window.addEventListener('scroll', this.scheduleLayout, true);\n document.addEventListener('keydown', this.handleDocumentKeyDown);\n document.addEventListener('visibilitychange', this.handleVisibilityChange);\n connectedToastRegions.add(this);\n // eslint-disable-next-line @typescript-eslint/no-this-alias -- module coordinator tracks the active connected viewport\n if (!activeToastRegion) activeToastRegion = this;\n }\n\n componentDidRender() {\n this.syncObservedElements();\n this.flushPendingRemovals();\n this.scheduleLayout();\n }\n\n disconnectedCallback() {\n this.connected = false;\n this.flushPendingRemovals();\n this.detachManager();\n this.resetManagerState();\n this.resizeObserver?.disconnect();\n this.resizeObserver = null;\n this.mutationObserver?.disconnect();\n this.mutationObserver = null;\n this.observedElements.clear();\n if (this.layoutFrame !== null) cancelAnimationFrame(this.layoutFrame);\n this.layoutFrame = null;\n window.removeEventListener('blur', this.handleWindowBlur);\n window.removeEventListener('focus', this.handleWindowFocus);\n window.removeEventListener('resize', this.handleWindowResize);\n window.removeEventListener('scroll', this.scheduleLayout, true);\n document.removeEventListener('keydown', this.handleDocumentKeyDown);\n document.removeEventListener('visibilitychange', this.handleVisibilityChange);\n connectedToastRegions.delete(this);\n if (activeToastRegion === this) {\n const remaining = Array.from(connectedToastRegions);\n activeToastRegion = remaining[remaining.length - 1] ?? null;\n }\n }\n\n @Watch('manager')\n onManagerChange(next: ToastManager) {\n this.detachManager();\n this.resetManagerState();\n if (this.connected) this.attachManager(next);\n }\n\n @Watch('timeout')\n onTimeoutChange() {\n for (const timer of this.timers.values()) {\n if (timer.handle) clearTimeout(timer.handle);\n }\n this.timers.clear();\n this.syncTimers();\n }\n\n private attachManager(manager: ToastManager) {\n const attached = attachedManagers.get(manager);\n if (attached && attached !== this) {\n console.warn('[ds-toast] A manager can control only one connected ds-toast instance.');\n return;\n }\n attachedManagers.set(manager, this);\n this.attachedManager = manager;\n this.unsubscribe = manager.subscribe(records => {\n this.records = records;\n this.syncLifecycle(records);\n this.scheduleLayout();\n });\n }\n\n private detachManager() {\n this.unsubscribe?.();\n this.unsubscribe = null;\n if (this.attachedManager && attachedManagers.get(this.attachedManager) === this) {\n attachedManagers.delete(this.attachedManager);\n }\n this.attachedManager = null;\n }\n\n private resetManagerState() {\n this.flushPendingRemovals();\n if (this.el.contains(document.activeElement)) this.restorePreviousFocus();\n this.clearAllTimers();\n for (const frame of this.activationFrames.values()) cancelAnimationFrame(frame);\n for (const frame of this.closeFrames.values()) cancelAnimationFrame(frame);\n this.activationFrames.clear();\n this.closeFrames.clear();\n this.closeEvents.clear();\n this.pauseReasons.clear();\n this.hoveredIds.clear();\n this.pendingHoverLeave = false;\n this.heights.clear();\n this.measuredUpdateKeys.clear();\n this.anchoredPositions.clear();\n this.dismissedSwipeDirections.clear();\n this.domIds.clear();\n this.activeSwipe = null;\n this.swipe = null;\n this.expanded = false;\n this.keyboardActive = false;\n this.records = [];\n this.resizeObserver?.disconnect();\n this.observedElements.clear();\n }\n\n private syncObservedElements() {\n const next = new Set<Element>(\n this.el.querySelectorAll<HTMLElement>('.toast-positioner'),\n );\n for (const record of this.records) {\n if (!record.positioner) continue;\n const anchor = this.resolveAnchor(record.positioner.anchor);\n if (anchor) next.add(anchor);\n }\n\n for (const element of this.observedElements) {\n if (!next.has(element)) {\n this.resizeObserver?.unobserve(element);\n this.observedElements.delete(element);\n }\n }\n for (const element of next) {\n if (this.observedElements.has(element)) continue;\n this.resizeObserver?.observe(element);\n this.observedElements.add(element);\n }\n }\n\n private flushPendingRemovals() {\n for (const pending of this.pendingRemovals.splice(0)) {\n pending.manager.notifyRemove(pending.context);\n this.dsToastRemove.emit({\n id: pending.context.id,\n toast: pending.context.toast,\n });\n }\n }\n\n private syncLifecycle(records: readonly ToastRecord[]) {\n const recordIds = new Set(records.map(record => record.id));\n for (const id of this.hoveredIds) {\n if (id !== GLOBAL_STACK_HOVER && !recordIds.has(id)) this.hoveredIds.delete(id);\n }\n const hasEndingRecords = records.some(\n record => record.transitionStatus === 'ending',\n );\n if (this.pendingHoverLeave && !hasEndingRecords && !this.hoveredIds.size) {\n this.pendingHoverLeave = false;\n this.expanded = false;\n this.resumeTimers('hover');\n } else if (!this.hoveredIds.size && !this.pendingHoverLeave) {\n this.resumeTimers('hover');\n }\n\n for (const [id, timer] of this.timers) {\n if (recordIds.has(id)) continue;\n if (timer.handle) clearTimeout(timer.handle);\n this.timers.delete(id);\n }\n\n for (const [id, watchdog] of this.closeWatchdogs) {\n if (recordIds.has(id)) continue;\n clearTimeout(watchdog);\n this.closeWatchdogs.delete(id);\n }\n\n for (const [id, frame] of this.activationFrames) {\n if (recordIds.has(id)) continue;\n cancelAnimationFrame(frame);\n this.activationFrames.delete(id);\n }\n\n for (const [id, frame] of this.closeFrames) {\n if (recordIds.has(id)) continue;\n cancelAnimationFrame(frame);\n this.closeFrames.delete(id);\n }\n\n for (const id of this.domIds.keys()) {\n if (recordIds.has(id)) continue;\n this.closeEvents.delete(id);\n this.domIds.delete(id);\n this.heights.delete(id);\n this.measuredUpdateKeys.delete(id);\n this.anchoredPositions.delete(id);\n this.dismissedSwipeDirections.delete(id);\n }\n\n for (const record of records) {\n this.ensureDomId(record.id);\n if (\n record.transitionStatus === 'starting' &&\n !this.activationFrames.has(record.id)\n ) {\n const manager = this.attachedManager;\n const frame = requestAnimationFrame(() => {\n this.activationFrames.delete(record.id);\n manager?.activate(record.id);\n });\n this.activationFrames.set(record.id, frame);\n }\n\n if (record.transitionStatus === 'ending') {\n this.clearToastTimer(record.id);\n this.beginRemoval(record);\n } else {\n const watchdog = this.closeWatchdogs.get(record.id);\n if (watchdog) clearTimeout(watchdog);\n this.closeWatchdogs.delete(record.id);\n const closeFrame = this.closeFrames.get(record.id);\n if (closeFrame) cancelAnimationFrame(closeFrame);\n this.closeFrames.delete(record.id);\n this.closeEvents.delete(record.id);\n }\n }\n\n this.syncTimers();\n }\n\n private syncTimers() {\n const activeIds = new Set<string>();\n for (const record of this.records) {\n if (record.transitionStatus !== 'active') continue;\n activeIds.add(record.id);\n const duration = this.resolveToastTimeout(record);\n if (duration <= 0) {\n this.clearToastTimer(record.id);\n continue;\n }\n\n const existing = this.timers.get(record.id);\n if (!existing || existing.timerKey !== record.timerKey) {\n this.clearToastTimer(record.id);\n this.timers.set(record.id, {\n timerKey: record.timerKey,\n remaining: duration,\n startedAt: 0,\n handle: null,\n });\n }\n if (!this.isPaused) this.startToastTimer(record.id);\n }\n\n for (const id of this.timers.keys()) {\n if (!activeIds.has(id)) this.clearToastTimer(id);\n }\n }\n\n private resolveToastTimeout(record: ToastRecord): number {\n const value = record.timeout ?? this.timeout;\n if (typeof value === 'number') return Math.max(0, value);\n return resolveCssTimeMs(value, TOKEN_DEFAULTS.animationDelayLong2);\n }\n\n private startToastTimer(id: string) {\n const timer = this.timers.get(id);\n if (!timer || timer.handle || timer.remaining <= 0) return;\n timer.startedAt = Date.now();\n timer.handle = setTimeout(() => {\n timer.handle = null;\n timer.remaining = 0;\n this.manager.close(id, 'timeout');\n }, timer.remaining);\n }\n\n private pauseTimers(reason: string) {\n const wasPaused = this.isPaused;\n this.pauseReasons.add(reason);\n if (wasPaused) return;\n const now = Date.now();\n for (const timer of this.timers.values()) {\n if (!timer.handle) continue;\n clearTimeout(timer.handle);\n timer.handle = null;\n timer.remaining = Math.max(0, timer.remaining - (now - timer.startedAt));\n }\n }\n\n private resumeTimers(reason: string) {\n this.pauseReasons.delete(reason);\n if (this.isPaused) return;\n for (const id of this.timers.keys()) this.startToastTimer(id);\n }\n\n private get isPaused(): boolean {\n return this.pauseReasons.size > 0;\n }\n\n private clearToastTimer(id: string) {\n const timer = this.timers.get(id);\n if (timer?.handle) clearTimeout(timer.handle);\n this.timers.delete(id);\n }\n\n private clearAllTimers() {\n for (const timer of this.timers.values()) {\n if (timer.handle) clearTimeout(timer.handle);\n }\n for (const watchdog of this.closeWatchdogs.values()) clearTimeout(watchdog);\n this.timers.clear();\n this.closeWatchdogs.clear();\n }\n\n private beginRemoval(record: ToastRecord) {\n if (!this.closeEvents.has(record.id)) {\n this.closeEvents.add(record.id);\n this.dsToastClose.emit({\n id: record.id,\n reason: record.closeReason ?? 'programmatic',\n toast: record,\n });\n this.moveFocusAfterClose(record.id);\n }\n if (\n this.closeWatchdogs.has(record.id) ||\n this.closeFrames.has(record.id)\n ) return;\n\n const duration = resolveMotionTimeMs(\n TOKEN_DEFAULTS.motionShort3,\n TOKEN_DEFAULTS.animationDurationShort3,\n );\n if (duration <= 0) {\n queueMicrotask(() => this.completeRemoval(record));\n return;\n }\n const frame = requestAnimationFrame(() => {\n this.closeFrames.delete(record.id);\n const current = this.records.find(candidate => candidate.id === record.id);\n if (!current || current.transitionStatus !== 'ending') return;\n this.closeWatchdogs.set(\n record.id,\n setTimeout(() => this.completeRemoval(current), duration),\n );\n });\n this.closeFrames.set(record.id, frame);\n }\n\n private completeRemoval(record: ToastRecord) {\n const current = this.records.find(candidate => candidate.id === record.id);\n if (!current || current.transitionStatus !== 'ending') return;\n const watchdog = this.closeWatchdogs.get(record.id);\n if (watchdog) clearTimeout(watchdog);\n this.closeWatchdogs.delete(record.id);\n const closeFrame = this.closeFrames.get(record.id);\n if (closeFrame) cancelAnimationFrame(closeFrame);\n this.closeFrames.delete(record.id);\n const manager = this.attachedManager;\n const context = manager?.remove(record.id);\n if (manager && context) this.pendingRemovals.push({ manager, context });\n }\n\n private handleAnimationComplete(record: ToastRecord) {\n if (record.transitionStatus === 'ending') this.completeRemoval(record);\n }\n\n private bindAnimationCancel(element: HTMLDivElement | undefined, id: string) {\n if (!element || element.dataset['cancelBound'] === 'true') return;\n element.dataset['cancelBound'] = 'true';\n element.addEventListener('animationcancel', () => {\n const record = this.records.find(candidate => candidate.id === id);\n if (record) this.handleAnimationComplete(record);\n });\n }\n\n private handleWindowBlur = () => this.pauseTimers('window');\n private handleWindowFocus = () => this.resumeTimers('window');\n private handleVisibilityChange = () => {\n if (document.hidden) this.pauseTimers('document');\n else this.resumeTimers('document');\n };\n\n private handlePointerEnter(id: string) {\n // eslint-disable-next-line @typescript-eslint/no-this-alias -- pointer interaction selects the viewport that receives F6\n activeToastRegion = this;\n this.pendingHoverLeave = false;\n this.hoveredIds.add(id);\n this.expanded = true;\n this.pauseTimers('hover');\n }\n\n private handlePointerLeave(id: string) {\n this.hoveredIds.delete(id);\n if (this.hoveredIds.size) return;\n if (this.records.some(record => record.transitionStatus === 'ending')) {\n this.pendingHoverLeave = true;\n return;\n }\n this.expanded = false;\n this.resumeTimers('hover');\n }\n\n private handleFocusIn = () => {\n const active = document.activeElement;\n if (!(active instanceof HTMLElement) || !active.matches(':focus-visible')) return;\n // eslint-disable-next-line @typescript-eslint/no-this-alias -- module coordinator routes F6 to the last focused viewport\n activeToastRegion = this;\n this.keyboardActive = true;\n this.expanded = true;\n this.pauseTimers('focus');\n };\n\n private handleFocusOut = (event: FocusEvent) => {\n const next = event.relatedTarget;\n if (next instanceof Node && this.el.contains(next)) return;\n if (!this.keyboardActive) return;\n this.keyboardActive = false;\n this.expanded = this.hoveredIds.size > 0;\n this.resumeTimers('focus');\n };\n\n private handleDocumentKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'F6') return;\n const eligible = Array.from(connectedToastRegions).filter(\n region => region.activeRecords.length > 0,\n );\n const target =\n activeToastRegion && activeToastRegion.activeRecords.length\n ? activeToastRegion\n : eligible[eligible.length - 1];\n if (target !== this) return;\n event.preventDefault();\n if (!this.el.contains(document.activeElement)) {\n this.previousFocus = document.activeElement as HTMLElement | null;\n }\n this.keyboardActive = true;\n this.regionElement?.focus();\n };\n\n private handleRegionKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n const target = event.target as HTMLElement;\n const positioner = target.closest<HTMLElement>('.toast-positioner');\n const id = positioner?.dataset['toastId'] ?? this.activeRecords[0]?.id;\n if (id) {\n event.preventDefault();\n this.manager.close(id, 'escape');\n }\n return;\n }\n\n if (event.key === 'Tab' && event.shiftKey && event.target === this.regionElement) {\n event.preventDefault();\n this.restorePreviousFocus();\n }\n };\n\n private get regionElement(): HTMLElement | null {\n return this.el.querySelector<HTMLElement>('.toast-region');\n }\n\n private restorePreviousFocus() {\n this.previousFocus?.focus?.();\n this.previousFocus = null;\n this.keyboardActive = false;\n }\n\n private moveFocusAfterClose(id: string) {\n const active = document.activeElement;\n const closing = this.positionerElement(id);\n if (!active || !closing?.contains(active)) return;\n requestAnimationFrame(() => {\n const next = this.activeRecords.find(record => record.id !== id);\n const control = next\n ? this.positionerElement(next.id)?.querySelector<\n HTMLElement & { setFocus?: () => Promise<void> }\n >('ds-button-unfilled')\n : null;\n if (control?.setFocus) void control.setFocus();\n else if (next) this.regionElement?.focus();\n else this.restorePreviousFocus();\n });\n }\n\n private handleAction(record: ToastRecord, event: CustomEvent<MouseEvent>) {\n const detail: ToastActionEventDetail = {\n id: record.id,\n toast: record,\n originalEvent: event.detail,\n };\n this.dsToastAction.emit(detail);\n record.action?.onAction?.({\n id: record.id,\n data: record.data,\n manager: this.manager,\n originalEvent: event.detail,\n });\n }\n\n private handlePointerDown(record: ToastRecord, event: PointerEvent) {\n if (event.button !== 0) return;\n const target = event.target as Element;\n if (target.closest(INTERACTIVE_SWIPE_SELECTOR)) return;\n\n const surface = event.currentTarget as HTMLElement;\n surface.setPointerCapture(event.pointerId);\n this.activeSwipe = {\n id: record.id,\n pointerId: event.pointerId,\n pointerType: event.pointerType,\n startX: event.clientX,\n startY: event.clientY,\n maxDistance: 0,\n cancelled: false,\n axis: null,\n };\n this.swipe = { id: record.id, x: 0, y: 0 };\n if (event.pointerType === 'touch') this.pauseTimers('swipe');\n }\n\n private handlePointerMove(event: PointerEvent) {\n const active = this.activeSwipe;\n if (!active || active.pointerId !== event.pointerId || active.cancelled) return;\n const dx = event.clientX - active.startX;\n const dy = event.clientY - active.startY;\n if (!active.axis && Math.max(Math.abs(dx), Math.abs(dy)) > 1) {\n active.axis = Math.abs(dx) >= Math.abs(dy) ? 'x' : 'y';\n }\n if (!active.axis) return;\n const horizontal = active.axis === 'x';\n const direction: ToastSwipeDirection = horizontal\n ? dx >= 0 ? 'right' : 'left'\n : dy >= 0 ? 'down' : 'up';\n const allowed = this.swipeDirections.includes(direction);\n const rawDistance = horizontal ? Math.abs(dx) : Math.abs(dy);\n const distance = allowed ? rawDistance : Math.sqrt(rawDistance);\n const signed = (horizontal ? dx : dy) < 0 ? -distance : distance;\n const x = horizontal ? signed : 0;\n const y = horizontal ? 0 : signed;\n\n if (active.maxDistance - distance >= SWIPE_REVERSE_CANCEL_THRESHOLD) {\n active.cancelled = true;\n this.cancelSwipe();\n return;\n }\n active.maxDistance = Math.max(active.maxDistance, distance);\n if (rawDistance > 1) event.preventDefault();\n this.swipe = { id: active.id, x, y, direction: allowed ? direction : undefined };\n }\n\n private handlePointerUp(event: PointerEvent) {\n const active = this.activeSwipe;\n if (!active || active.pointerId !== event.pointerId) return;\n const swipe = this.swipe;\n const distance = swipe ? Math.max(Math.abs(swipe.x), Math.abs(swipe.y)) : 0;\n const shouldDismiss =\n !active.cancelled &&\n !!swipe?.direction &&\n distance >= SWIPE_THRESHOLD;\n const id = active.id;\n const wasTouch = active.pointerType === 'touch';\n this.activeSwipe = null;\n this.swipe = null;\n if (wasTouch) this.resumeTimers('swipe');\n if (shouldDismiss && swipe.direction) {\n this.dismissedSwipeDirections.set(id, swipe.direction);\n this.manager.close(id, 'swipe');\n }\n }\n\n private handlePointerCancel(event: PointerEvent) {\n if (this.activeSwipe?.pointerId !== event.pointerId) return;\n this.cancelSwipe();\n }\n\n private cancelSwipe() {\n const wasTouch = this.activeSwipe?.pointerType === 'touch';\n this.activeSwipe = null;\n this.swipe = null;\n if (wasTouch) this.resumeTimers('swipe');\n }\n\n private get touchAction(): string {\n const horizontal =\n this.swipeDirections.includes('left') || this.swipeDirections.includes('right');\n const vertical =\n this.swipeDirections.includes('up') || this.swipeDirections.includes('down');\n if (horizontal && vertical) return 'none';\n if (horizontal) return 'pan-y';\n if (vertical) return 'pan-x';\n return 'auto';\n }\n\n private handleWindowResize = () => {\n this.heights.clear();\n this.measuredUpdateKeys.clear();\n this.layoutVersion += 1;\n this.scheduleLayout();\n };\n\n private scheduleLayout = () => {\n if (this.layoutFrame !== null) return;\n this.layoutFrame = requestAnimationFrame(() => {\n this.layoutFrame = null;\n this.measureLayout();\n });\n };\n\n private measureNaturalHeight(element: HTMLElement, expandedWidth: boolean): number {\n const surface = element.querySelector<HTMLElement>('.toast-surface');\n if (!surface) return 0;\n const previousWidth = element.style.width;\n const previousTransition = element.style.transition;\n const previousHeight = surface.style.height;\n\n if (expandedWidth) {\n element.style.transition = 'none';\n element.style.width = '100%';\n }\n surface.style.height = 'auto';\n const height = surface.getBoundingClientRect().height;\n\n surface.style.height = previousHeight;\n if (expandedWidth) {\n element.style.width = previousWidth;\n element.getBoundingClientRect();\n element.style.transition = previousTransition;\n }\n return height;\n }\n\n private measureLayout() {\n let changed = false;\n for (const record of this.records) {\n const element = this.positionerElement(record.id);\n if (!element) continue;\n let height = this.heights.get(record.id) ?? 0;\n const needsHeightMeasurement =\n height <= 0 || this.measuredUpdateKeys.get(record.id) !== record.updateKey;\n if (needsHeightMeasurement) {\n height = this.measureNaturalHeight(element, !record.positioner);\n if (height > 0) {\n if (this.heights.get(record.id) !== height) changed = true;\n this.heights.set(record.id, height);\n this.measuredUpdateKeys.set(record.id, record.updateKey);\n }\n }\n\n if (!record.positioner) continue;\n const anchor = this.resolveAnchor(record.positioner.anchor);\n if (!anchor || height <= 0) {\n if (this.anchoredPositions.delete(record.id)) changed = true;\n continue;\n }\n const rect = element.getBoundingClientRect();\n const sideOffset = resolveCssLengthPx(\n record.positioner.sideOffset,\n TOKEN_DEFAULTS.space050,\n );\n const alignOffset = resolveCssLengthPx(record.positioner.alignOffset, 0);\n const position = computeTooltipPosition({\n anchorRect: anchor.getBoundingClientRect(),\n popupWidth: rect.width,\n popupHeight: height,\n side: record.positioner.side ?? 'top',\n align: record.positioner.align ?? 'center',\n sideOffsetPx: sideOffset,\n alignOffsetPx: alignOffset,\n viewportPadPx: resolveCssLengthPx(undefined, TOKEN_DEFAULTS.space200),\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n });\n const current = this.anchoredPositions.get(record.id);\n if (\n !current ||\n current.x !== position.x ||\n current.y !== position.y ||\n current.side !== position.resolvedSide\n ) {\n this.anchoredPositions.set(record.id, {\n x: position.x,\n y: position.y,\n side: position.resolvedSide,\n });\n changed = true;\n }\n }\n if (changed) this.layoutVersion += 1;\n }\n\n private resolveAnchor(anchor: HTMLElement | string): HTMLElement | null {\n return typeof anchor === 'string' ? document.getElementById(anchor) : anchor;\n }\n\n private positionerElement(id: string): HTMLElement | null {\n return (\n Array.from(this.el.querySelectorAll<HTMLElement>('.toast-positioner'))\n .find(element => element.dataset['toastId'] === id) ?? null\n );\n }\n\n private ensureDomId(id: string): number {\n const current = this.domIds.get(id);\n if (current) return current;\n const next = ++this.nextDomId;\n this.domIds.set(id, next);\n return next;\n }\n\n private get activeRecords(): ToastRecord[] {\n return this.records.filter(record => record.transitionStatus !== 'ending');\n }\n\n private globalLayout() {\n const globalRecords = this.records.filter(record => !record.positioner);\n let offset = 0;\n let visibleIndex = 0;\n const gap = resolveCssLengthPx(undefined, TOKEN_DEFAULTS.space200);\n const layouts = new Map<string, { index: number; offset: number; limited: boolean }>();\n\n globalRecords.forEach((record, domIndex) => {\n if (record.transitionStatus === 'ending') {\n layouts.set(record.id, { index: domIndex, offset, limited: false });\n return;\n }\n\n const limited = visibleIndex >= Math.max(1, this.limit);\n layouts.set(record.id, { index: visibleIndex, offset, limited });\n offset += (this.heights.get(record.id) ?? 0) + gap;\n visibleIndex += 1;\n });\n return layouts;\n }\n\n private renderToast(\n record: ToastRecord,\n layout: { index: number; offset: number; limited: boolean },\n ) {\n const domId = this.ensureDomId(record.id);\n const titleId = `ds-toast-${this.instanceId}-${domId}-title`;\n const descriptionId = `ds-toast-${this.instanceId}-${domId}-description`;\n const swipe = this.swipe?.id === record.id ? this.swipe : null;\n const swipeDirection = swipe?.direction ?? this.dismissedSwipeDirections.get(record.id);\n const anchored = !!record.positioner;\n const anchoredPosition = this.anchoredPositions.get(record.id);\n const hiddenHighPriority = record.priority === 'high' && !this.keyboardActive;\n const focusTabIndex = this.keyboardActive && !layout.limited ? 0 : -1;\n const toastHeight = this.heights.get(record.id);\n\n return (\n <div\n ref={(element?: HTMLDivElement) => this.bindAnimationCancel(element, record.id)}\n class={{\n 'toast-positioner': true,\n 'toast-positioner--anchored': anchored,\n 'toast-positioner--ending': record.transitionStatus === 'ending',\n }}\n data-toast-id={record.id}\n data-behind={!anchored && layout.index > 0 ? '' : undefined}\n data-limited={layout.limited ? '' : undefined}\n data-positioned={anchored ? String(!!anchoredPosition) : undefined}\n data-side={anchoredPosition?.side}\n inert={layout.limited ? true : undefined}\n aria-hidden={layout.limited ? 'true' : undefined}\n style={{\n '--toast-index': String(layout.index),\n '--toast-offset-y': `${layout.offset}px`,\n '--toast-height': toastHeight ? `${toastHeight}px` : undefined,\n zIndex: String(this.records.length - layout.index),\n left: anchoredPosition ? `${anchoredPosition.x}px` : undefined,\n top: anchoredPosition ? `${anchoredPosition.y}px` : undefined,\n }}\n onAnimationEnd={() => this.handleAnimationComplete(record)}\n >\n <div\n class={{\n 'toast-surface': true,\n 'toast-surface--swiping': !!swipe,\n }}\n role={record.priority === 'high' ? 'alertdialog' : 'dialog'}\n aria-modal=\"false\"\n aria-labelledby={\n record.title ? titleId : record.description ? descriptionId : undefined\n }\n aria-describedby={record.title && record.description ? descriptionId : undefined}\n aria-hidden={hiddenHighPriority ? 'true' : undefined}\n data-type={record.type}\n data-priority={record.priority}\n data-transition-status={record.transitionStatus}\n data-swiping={swipe ? '' : undefined}\n data-swipe-direction={swipeDirection}\n style={{\n '--toast-swipe-movement-x': `${swipe?.x ?? 0}px`,\n '--toast-swipe-movement-y': `${swipe?.y ?? 0}px`,\n touchAction: this.touchAction,\n }}\n onPointerDown={(event: PointerEvent) => this.handlePointerDown(record, event)}\n onPointerMove={(event: PointerEvent) => this.handlePointerMove(event)}\n onPointerUp={(event: PointerEvent) => this.handlePointerUp(event)}\n onPointerCancel={(event: PointerEvent) => this.handlePointerCancel(event)}\n onPointerEnter={\n anchored ? () => this.handlePointerEnter(record.id) : undefined\n }\n onPointerLeave={\n anchored ? () => this.handlePointerLeave(record.id) : undefined\n }\n >\n <div class=\"toast-content\">\n <div class=\"toast-copy\">\n {record.title && (\n <ds-text\n class=\"toast-title\"\n as=\"div\"\n variant=\"text-title-small\"\n color=\"primary\"\n textId={titleId}\n >\n {record.title}\n </ds-text>\n )}\n {record.description && (\n <ds-text\n class=\"toast-description\"\n as=\"div\"\n variant=\"text-body-medium\"\n color=\"secondary\"\n textId={descriptionId}\n >\n {record.description}\n </ds-text>\n )}\n </div>\n {record.action && (\n <ds-button-unfilled\n class=\"toast-action\"\n variant=\"label\"\n size=\"md\"\n type=\"button\"\n label={record.action.label}\n aria-label={record.action.ariaLabel}\n hasBorder\n focusTabIndex={focusTabIndex}\n aria-hidden={!this.keyboardActive ? 'true' : undefined}\n onDsClick={(event: CustomEvent<MouseEvent>) =>\n this.handleAction(record, event)\n }\n />\n )}\n </div>\n <ds-button-unfilled\n class=\"toast-close\"\n variant=\"icon\"\n size=\"md\"\n type=\"button\"\n icon=\"Cross\"\n aria-label={this.closeLabel}\n hasBorder={false}\n activeFill={false}\n focusTabIndex={focusTabIndex}\n aria-hidden={!this.keyboardActive ? 'true' : undefined}\n onDsClick={() => this.manager.close(record.id, 'close-button')}\n />\n </div>\n </div>\n );\n }\n\n render() {\n void this.layoutVersion;\n const globalLayouts = this.globalLayout();\n const globalRecords = this.records.filter(record => !record.positioner);\n const anchoredRecords = this.records.filter(record => !!record.positioner);\n const highPriority = this.records.filter(\n record =>\n record.priority === 'high' &&\n record.transitionStatus !== 'ending' &&\n !globalLayouts.get(record.id)?.limited,\n );\n\n return (\n <Host>\n <section\n class=\"toast-region\"\n role=\"region\"\n aria-label={this.label}\n aria-live=\"polite\"\n aria-atomic=\"false\"\n aria-relevant=\"additions text\"\n tabIndex={-1}\n onFocusin={this.handleFocusIn}\n onFocusout={(event: FocusEvent) => this.handleFocusOut(event)}\n onKeyDown={(event: KeyboardEvent) => this.handleRegionKeyDown(event)}\n >\n <div\n class=\"toast-viewport\"\n data-expanded={this.expanded ? '' : undefined}\n onPointerEnter={() => this.handlePointerEnter(GLOBAL_STACK_HOVER)}\n onPointerLeave={() => this.handlePointerLeave(GLOBAL_STACK_HOVER)}\n >\n {globalRecords.map(record =>\n this.renderToast(\n record,\n globalLayouts.get(record.id) ?? { index: 0, offset: 0, limited: false },\n )\n )}\n </div>\n <div class=\"toast-anchored-layer\">\n {anchoredRecords.map(record =>\n this.renderToast(record, { index: 0, offset: 0, limited: false })\n )}\n </div>\n <div class=\"toast-assertive-announcer\">\n {highPriority.map(record => (\n <div role=\"alert\" aria-atomic=\"true\">\n {[record.title, record.description].filter(Boolean).join('. ')}\n </div>\n ))}\n </div>\n </section>\n </Host>\n );\n }\n}\n",
315
+ "type": "registry:ui"
316
+ }
317
+ ]
318
+ }
@@ -130,7 +130,7 @@
130
130
  "peerDependencies": {
131
131
  "required": [
132
132
  "@ds-mo/tokens ^3.1.1",
133
- "@ds-mo/icons ^6.2.0"
133
+ "@ds-mo/icons ^6.3.0"
134
134
  ],
135
135
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
136
136
  }
@@ -278,7 +278,7 @@
278
278
  "peerDependencies": {
279
279
  "required": [
280
280
  "@ds-mo/tokens ^3.1.1",
281
- "@ds-mo/icons ^6.2.0"
281
+ "@ds-mo/icons ^6.3.0"
282
282
  ],
283
283
  "frameworks": "Custom Elements; React 18/19 wrappers; Angular 19-22 standalone adapters."
284
284
  }
@@ -10,14 +10,12 @@ export { DsAppShell } from "./ds-app-shell.js";
10
10
  export { DsAttachmentList } from "./ds-attachment-list.js";
11
11
  export { DsAvatar } from "./ds-avatar.js";
12
12
  export { DsBadge } from "./ds-badge.js";
13
- export { DsBanner } from "./ds-banner.js";
14
13
  export { DsBarNav } from "./ds-bar-nav.js";
15
14
  export { DsButtonFilled } from "./ds-button-filled.js";
16
15
  export { DsButtonUnfilled } from "./ds-button-unfilled.js";
17
16
  export { DsCardDataVizDonut } from "./ds-card-data-viz-donut.js";
18
17
  export { DsCardSetting } from "./ds-card-setting.js";
19
18
  export { DsCardShellDataViz } from "./ds-card-shell-data-viz.js";
20
- export { DsCard } from "./ds-card.js";
21
19
  export { DsChartBar } from "./ds-chart-bar.js";
22
20
  export { DsChartDonut } from "./ds-chart-donut.js";
23
21
  export { DsChartLegend } from "./ds-chart-legend.js";
@@ -58,5 +56,6 @@ export { DsSwitch } from "./ds-switch.js";
58
56
  export { DsTabGroup } from "./ds-tab-group.js";
59
57
  export { DsTag } from "./ds-tag.js";
60
58
  export { DsText } from "./ds-text.js";
59
+ export { DsToast } from "./ds-toast.js";
61
60
  export { DsTooltipDataViz } from "./ds-tooltip-data-viz.js";
62
61
  export { DsTooltip } from "./ds-tooltip.js";
@@ -11,14 +11,12 @@ export { DsAppShell } from "./ds-app-shell.js";
11
11
  export { DsAttachmentList } from "./ds-attachment-list.js";
12
12
  export { DsAvatar } from "./ds-avatar.js";
13
13
  export { DsBadge } from "./ds-badge.js";
14
- export { DsBanner } from "./ds-banner.js";
15
14
  export { DsBarNav } from "./ds-bar-nav.js";
16
15
  export { DsButtonFilled } from "./ds-button-filled.js";
17
16
  export { DsButtonUnfilled } from "./ds-button-unfilled.js";
18
17
  export { DsCardDataVizDonut } from "./ds-card-data-viz-donut.js";
19
18
  export { DsCardSetting } from "./ds-card-setting.js";
20
19
  export { DsCardShellDataViz } from "./ds-card-shell-data-viz.js";
21
- export { DsCard } from "./ds-card.js";
22
20
  export { DsChartBar } from "./ds-chart-bar.js";
23
21
  export { DsChartDonut } from "./ds-chart-donut.js";
24
22
  export { DsChartLegend } from "./ds-chart-legend.js";
@@ -59,5 +57,6 @@ export { DsSwitch } from "./ds-switch.js";
59
57
  export { DsTabGroup } from "./ds-tab-group.js";
60
58
  export { DsTag } from "./ds-tag.js";
61
59
  export { DsText } from "./ds-text.js";
60
+ export { DsToast } from "./ds-toast.js";
62
61
  export { DsTooltipDataViz } from "./ds-tooltip-data-viz.js";
63
62
  export { DsTooltip } from "./ds-tooltip.js";
@@ -3,10 +3,10 @@
3
3
  * Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
4
4
  */
5
5
  import type { EventName, StencilReactComponent } from '@stencil/react-output-target/runtime';
6
- import { type DsCardSettingCustomEvent } from "@ds-mo/ui";
6
+ import { type CardSettingActionDetail, type DsCardSettingCustomEvent } from "@ds-mo/ui";
7
7
  import type { Components } from "@ds-mo/ui/dist/components";
8
8
  import { DsCardSetting as DsCardSettingElement } from "@ds-mo/ui/dist/components/ds-card-setting.js";
9
9
  export type DsCardSettingEvents = {
10
- onDsEditingChange: EventName<DsCardSettingCustomEvent<boolean>>;
10
+ onDsAction: EventName<DsCardSettingCustomEvent<CardSettingActionDetail>>;
11
11
  };
12
12
  export declare const DsCardSetting: StencilReactComponent<DsCardSettingElement, DsCardSettingEvents, Components.DsCardSetting, 'heading'>;
@@ -7,6 +7,6 @@ export const DsCardSetting = /*@__PURE__*/ createComponent({
7
7
  elementClass: DsCardSettingElement,
8
8
  // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.
9
9
  react: React,
10
- events: { onDsEditingChange: 'dsEditingChange' },
10
+ events: { onDsAction: 'dsAction' },
11
11
  defineCustomElement: defineDsCardSetting
12
12
  });