@maggioli-design-system/magma-react 2.9.0 → 2.11.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 (618) hide show
  1. package/AGENTS.md +10 -7
  2. package/CHANGELOG.md +109 -0
  3. package/README.md +38 -0
  4. package/agents/assets.md +2 -2
  5. package/agents/color.md +7 -5
  6. package/agents/components.md +2 -2
  7. package/agents/conventions.md +1 -1
  8. package/agents/mcp.md +78 -8
  9. package/agents/{anti-patterns.md → mistakes.md} +2 -2
  10. package/agents/patterns/actions.md +393 -0
  11. package/agents/patterns/app-shell.md +223 -0
  12. package/agents/patterns/choose-items.md +18 -0
  13. package/agents/patterns/concurrent-editing.md +17 -0
  14. package/agents/patterns/confirm-action.md +216 -0
  15. package/agents/patterns/consent-and-legal.md +16 -0
  16. package/agents/patterns/density.md +236 -0
  17. package/agents/patterns/empty-state.md +201 -0
  18. package/agents/patterns/error-recovery.md +237 -0
  19. package/agents/patterns/form-and-validation.md +16 -0
  20. package/agents/patterns/item-list.md +214 -0
  21. package/agents/patterns/labels-and-values.md +184 -0
  22. package/agents/patterns/list-with-filters.md +282 -0
  23. package/agents/patterns/loading.md +221 -0
  24. package/agents/patterns/message-placement.md +304 -0
  25. package/agents/patterns/notification-center.md +18 -0
  26. package/agents/patterns/page-header.md +201 -0
  27. package/agents/patterns/permissions.md +17 -0
  28. package/agents/patterns/previews/actions/banner.html +21 -0
  29. package/agents/patterns/previews/actions/confirm.html +11 -0
  30. package/agents/patterns/previews/actions/danger-zone.html +22 -0
  31. package/agents/patterns/previews/actions/destructive-in-menu.html +19 -0
  32. package/agents/patterns/previews/actions/dismiss-message.html +15 -0
  33. package/agents/patterns/previews/actions/dismiss.html +25 -0
  34. package/agents/patterns/previews/actions/more-in-menu.html +21 -0
  35. package/agents/patterns/previews/actions/part-primary.html +28 -0
  36. package/agents/patterns/previews/actions/primary.html +20 -0
  37. package/agents/patterns/previews/actions/remove.html +44 -0
  38. package/agents/patterns/previews/actions/secondary.html +20 -0
  39. package/agents/patterns/previews/actions/stacked.html +17 -0
  40. package/agents/patterns/previews/actions/toast.html +10 -0
  41. package/agents/patterns/previews/app-shell/back-office.html +41 -0
  42. package/agents/patterns/previews/app-shell/many-sections.html +45 -0
  43. package/agents/patterns/previews/app-shell/public-service.html +31 -0
  44. package/agents/patterns/previews/confirm-action/act-then-undo.html +44 -0
  45. package/agents/patterns/previews/confirm-action/ask-before-sending.html +25 -0
  46. package/agents/patterns/previews/confirm-action/ask-first-many.html +11 -0
  47. package/agents/patterns/previews/confirm-action/ask-first.html +14 -0
  48. package/agents/patterns/previews/confirm-action/make-reversible.html +54 -0
  49. package/agents/patterns/previews/confirm-action/send-as-shown.html +57 -0
  50. package/agents/patterns/previews/empty-state/add-the-first.html +19 -0
  51. package/agents/patterns/previews/empty-state/all-done.html +15 -0
  52. package/agents/patterns/previews/empty-state/clear-filters.html +35 -0
  53. package/agents/patterns/previews/empty-state/filled-by-others.html +15 -0
  54. package/agents/patterns/previews/empty-state/not-found.html +38 -0
  55. package/agents/patterns/previews/empty-state/one-line.html +12 -0
  56. package/agents/patterns/previews/error-recovery/action-another-way.html +35 -0
  57. package/agents/patterns/previews/error-recovery/changed-meanwhile.html +26 -0
  58. package/agents/patterns/previews/error-recovery/check-or-repeat.html +38 -0
  59. package/agents/patterns/previews/error-recovery/content-another-way.html +12 -0
  60. package/agents/patterns/previews/error-recovery/partial.html +29 -0
  61. package/agents/patterns/previews/error-recovery/retry-action.html +35 -0
  62. package/agents/patterns/previews/error-recovery/retry-content.html +40 -0
  63. package/agents/patterns/previews/error-recovery/sign-in-again.html +44 -0
  64. package/agents/patterns/previews/item-list/documents-of-a-request.html +12 -0
  65. package/agents/patterns/previews/item-list/queue-of-a-desk.html +109 -0
  66. package/agents/patterns/previews/item-list/requests-of-an-office.html +74 -0
  67. package/agents/patterns/previews/item-list/requests-to-assign.html +80 -0
  68. package/agents/patterns/previews/labels-and-values/data-of-a-contact.html +31 -0
  69. package/agents/patterns/previews/labels-and-values/payment-before-paying.html +21 -0
  70. package/agents/patterns/previews/labels-and-values/what-is-sent.html +25 -0
  71. package/agents/patterns/previews/list-with-filters/act-on-many.html +121 -0
  72. package/agents/patterns/previews/list-with-filters/find-and-open.html +109 -0
  73. package/agents/patterns/previews/list-with-filters/show-new-items.html +132 -0
  74. package/agents/patterns/previews/loading/await-and-say.html +41 -0
  75. package/agents/patterns/previews/loading/await-the-control.html +28 -0
  76. package/agents/patterns/previews/loading/first-load.html +10 -0
  77. package/agents/patterns/previews/loading/keep-while-reloading.html +80 -0
  78. package/agents/patterns/previews/loading/long-load-measured.html +16 -0
  79. package/agents/patterns/previews/loading/long-load.html +12 -0
  80. package/agents/patterns/previews/loading/progress-in-place.html +52 -0
  81. package/agents/patterns/previews/loading/run-in-background.html +24 -0
  82. package/agents/patterns/previews/message-placement/action-done-elsewhere.html +38 -0
  83. package/agents/patterns/previews/message-placement/action-done-in-page.html +53 -0
  84. package/agents/patterns/previews/message-placement/action-done-in-part.html +42 -0
  85. package/agents/patterns/previews/message-placement/action-failed-elsewhere.html +40 -0
  86. package/agents/patterns/previews/message-placement/action-failed-in-place.html +31 -0
  87. package/agents/patterns/previews/message-placement/action-later.html +24 -0
  88. package/agents/patterns/previews/message-placement/action-partial-elsewhere.html +33 -0
  89. package/agents/patterns/previews/message-placement/action-partial-in-place.html +51 -0
  90. package/agents/patterns/previews/message-placement/action-taken.html +25 -0
  91. package/agents/patterns/previews/message-placement/app-deadline.html +20 -0
  92. package/agents/patterns/previews/message-placement/app-failed.html +48 -0
  93. package/agents/patterns/previews/message-placement/app-info.html +39 -0
  94. package/agents/patterns/previews/message-placement/decision.html +49 -0
  95. package/agents/patterns/previews/message-placement/field-error.html +28 -0
  96. package/agents/patterns/previews/message-placement/field-hint.html +30 -0
  97. package/agents/patterns/previews/message-placement/field-valid.html +11 -0
  98. package/agents/patterns/previews/message-placement/region-failed.html +31 -0
  99. package/agents/patterns/previews/message-placement/region-info.html +16 -0
  100. package/agents/patterns/previews/page-header/contact-being-edited.html +25 -0
  101. package/agents/patterns/previews/page-header/members-of-a-group.html +18 -0
  102. package/agents/patterns/previews/page-header/own-profile.html +17 -0
  103. package/agents/patterns/previews/page-header/request-from-the-list.html +33 -0
  104. package/agents/patterns/previews/page-header/requests-of-an-office.html +16 -0
  105. package/agents/patterns/previews/record-detail/ask-for-words.html +72 -0
  106. package/agents/patterns/previews/record-detail/edit-data.html +104 -0
  107. package/agents/patterns/previews/record-detail/read-the-data.html +80 -0
  108. package/agents/patterns/previews/record-detail/record-changed.html +87 -0
  109. package/agents/patterns/previews/record-detail/run-at-once.html +88 -0
  110. package/agents/patterns/previews/record-detail/work-on-it.html +106 -0
  111. package/agents/patterns/previews/rhythm/between-containers.html +29 -0
  112. package/agents/patterns/previews/rhythm/between-fields.html +14 -0
  113. package/agents/patterns/previews/rhythm/between-groups.html +23 -0
  114. package/agents/patterns/previews/rhythm/between-sections.html +17 -0
  115. package/agents/patterns/previews/rhythm/content-actions.html +14 -0
  116. package/agents/patterns/previews/rhythm/inline.html +12 -0
  117. package/agents/patterns/previews/rhythm/inset.html +11 -0
  118. package/agents/patterns/previews/rhythm/label-control.html +8 -0
  119. package/agents/patterns/previews/rhythm/title-content.html +10 -0
  120. package/agents/patterns/previews/surfaces/band.html +73 -0
  121. package/agents/patterns/previews/surfaces/canvas.html +66 -0
  122. package/agents/patterns/previews/surfaces/card.html +30 -0
  123. package/agents/patterns/previews/surfaces/dialog.html +28 -0
  124. package/agents/patterns/previews/surfaces/edit-actions.html +35 -0
  125. package/agents/patterns/previews/surfaces/section.html +35 -0
  126. package/agents/patterns/previews/titles/dialog.html +18 -0
  127. package/agents/patterns/previews/titles/group.html +14 -0
  128. package/agents/patterns/previews/titles/page.html +25 -0
  129. package/agents/patterns/previews/titles/part.html +24 -0
  130. package/agents/patterns/previews/titles/section.html +14 -0
  131. package/agents/patterns/previews/widths/dialog.html +33 -0
  132. package/agents/patterns/previews/widths/field.html +20 -0
  133. package/agents/patterns/previews/widths/form.html +27 -0
  134. package/agents/patterns/previews/widths/page.html +49 -0
  135. package/agents/patterns/previews/widths/reading.html +15 -0
  136. package/agents/patterns/record-detail.md +268 -0
  137. package/agents/patterns/rhythm.md +212 -0
  138. package/agents/patterns/surfaces.md +212 -0
  139. package/agents/patterns/titles.md +208 -0
  140. package/agents/patterns/widths.md +202 -0
  141. package/agents/patterns.md +121 -0
  142. package/agents/reporting.md +6 -3
  143. package/agents/theming.md +36 -12
  144. package/agents/typography.md +27 -2
  145. package/agents/variants.md +1 -1
  146. package/dist/components.js +117 -117
  147. package/dist/components.server.js +117 -117
  148. package/dist/mds-accordion-item.js +8 -3
  149. package/dist/mds-accordion-item.server.js +7 -2
  150. package/dist/mds-accordion-timer-item.js +8 -3
  151. package/dist/mds-accordion-timer-item.server.js +7 -2
  152. package/dist/mds-accordion-timer.js +11 -4
  153. package/dist/mds-accordion-timer.server.js +7 -2
  154. package/dist/mds-accordion.js +11 -4
  155. package/dist/mds-accordion.server.js +7 -2
  156. package/dist/mds-author.js +8 -3
  157. package/dist/mds-author.server.js +7 -2
  158. package/dist/mds-avatar-stack-item.js +8 -3
  159. package/dist/mds-avatar-stack-item.server.js +7 -2
  160. package/dist/mds-avatar-stack.js +8 -3
  161. package/dist/mds-avatar-stack.server.js +7 -2
  162. package/dist/mds-avatar.js +8 -3
  163. package/dist/mds-avatar.server.js +7 -2
  164. package/dist/mds-badge.js +8 -3
  165. package/dist/mds-badge.server.js +7 -2
  166. package/dist/mds-banner.js +11 -4
  167. package/dist/mds-banner.server.js +7 -2
  168. package/dist/mds-benchmark-bar.js +8 -3
  169. package/dist/mds-benchmark-bar.server.js +7 -2
  170. package/dist/mds-bibliography.js +8 -3
  171. package/dist/mds-bibliography.server.js +7 -2
  172. package/dist/mds-book.js +8 -3
  173. package/dist/mds-book.server.js +7 -2
  174. package/dist/mds-breadcrumb-item.js +11 -4
  175. package/dist/mds-breadcrumb-item.server.js +7 -2
  176. package/dist/mds-breadcrumb.js +11 -4
  177. package/dist/mds-breadcrumb.server.js +10 -3
  178. package/dist/mds-button-dropdown.js +11 -4
  179. package/dist/mds-button-dropdown.server.js +7 -2
  180. package/dist/mds-button-group.js +8 -3
  181. package/dist/mds-button-group.server.js +7 -2
  182. package/dist/mds-button.js +8 -3
  183. package/dist/mds-button.server.js +7 -2
  184. package/dist/mds-calendar-cell.js +8 -3
  185. package/dist/mds-calendar-cell.server.js +7 -2
  186. package/dist/mds-calendar.js +8 -3
  187. package/dist/mds-calendar.server.js +7 -2
  188. package/dist/mds-card-content.js +8 -3
  189. package/dist/mds-card-content.server.js +7 -2
  190. package/dist/mds-card-footer.js +8 -3
  191. package/dist/mds-card-footer.server.js +7 -2
  192. package/dist/mds-card-header.js +8 -3
  193. package/dist/mds-card-header.server.js +7 -2
  194. package/dist/mds-card-media.js +8 -3
  195. package/dist/mds-card-media.server.js +7 -2
  196. package/dist/mds-card.js +8 -3
  197. package/dist/mds-card.server.js +10 -3
  198. package/dist/mds-chip.js +8 -3
  199. package/dist/mds-chip.server.js +7 -2
  200. package/dist/mds-details.js +11 -4
  201. package/dist/mds-details.server.js +10 -3
  202. package/dist/mds-dropdown.js +8 -3
  203. package/dist/mds-dropdown.server.js +7 -2
  204. package/dist/mds-emoji.js +8 -3
  205. package/dist/mds-emoji.server.js +10 -3
  206. package/dist/mds-entity.js +8 -3
  207. package/dist/mds-entity.server.js +7 -2
  208. package/dist/mds-file-preview.js +8 -3
  209. package/dist/mds-file-preview.server.js +7 -2
  210. package/dist/mds-file.js +11 -4
  211. package/dist/mds-file.server.js +7 -2
  212. package/dist/mds-filter-item.js +11 -4
  213. package/dist/mds-filter-item.server.js +7 -2
  214. package/dist/mds-filter.js +11 -4
  215. package/dist/mds-filter.server.js +7 -2
  216. package/dist/mds-header-bar.js +11 -4
  217. package/dist/mds-header-bar.server.js +7 -2
  218. package/dist/mds-header.js +8 -3
  219. package/dist/mds-header.server.js +7 -2
  220. package/dist/mds-help.js +8 -3
  221. package/dist/mds-help.server.js +7 -2
  222. package/dist/mds-horizontal-scroll.js +8 -3
  223. package/dist/mds-horizontal-scroll.server.js +7 -2
  224. package/dist/mds-hr.js +8 -3
  225. package/dist/mds-hr.server.js +7 -2
  226. package/dist/mds-icon.js +8 -3
  227. package/dist/mds-icon.server.js +10 -3
  228. package/dist/mds-img.js +8 -3
  229. package/dist/mds-img.server.js +7 -2
  230. package/dist/mds-input-date-range-preselection.js +8 -3
  231. package/dist/mds-input-date-range-preselection.server.js +7 -2
  232. package/dist/mds-input-date-range.js +11 -4
  233. package/dist/mds-input-date-range.server.js +7 -2
  234. package/dist/mds-input-date.js +8 -3
  235. package/dist/mds-input-date.server.js +7 -2
  236. package/dist/mds-input-field.js +8 -3
  237. package/dist/mds-input-field.server.js +8 -2
  238. package/dist/mds-input-otp.js +8 -3
  239. package/dist/mds-input-otp.server.js +7 -2
  240. package/dist/mds-input-range.js +11 -4
  241. package/dist/mds-input-range.server.js +7 -2
  242. package/dist/mds-input-select.js +11 -4
  243. package/dist/mds-input-select.server.js +7 -2
  244. package/dist/mds-input-switch.js +11 -4
  245. package/dist/mds-input-switch.server.js +7 -2
  246. package/dist/mds-input-tip-item.js +8 -3
  247. package/dist/mds-input-tip-item.server.js +7 -2
  248. package/dist/mds-input-tip.js +8 -3
  249. package/dist/mds-input-tip.server.js +7 -2
  250. package/dist/mds-input-upload.js +11 -4
  251. package/dist/mds-input-upload.server.js +7 -2
  252. package/dist/mds-input.js +8 -3
  253. package/dist/mds-input.server.js +7 -2
  254. package/dist/mds-keyboard-key.js +8 -3
  255. package/dist/mds-keyboard-key.server.js +7 -2
  256. package/dist/mds-keyboard.js +8 -3
  257. package/dist/mds-keyboard.server.js +7 -2
  258. package/dist/mds-kpi-item.js +8 -3
  259. package/dist/mds-kpi-item.server.js +7 -2
  260. package/dist/mds-kpi.js +8 -3
  261. package/dist/mds-kpi.server.js +7 -2
  262. package/dist/mds-label.js +11 -4
  263. package/dist/mds-label.server.js +7 -2
  264. package/dist/mds-link.js +8 -3
  265. package/dist/mds-link.server.js +7 -2
  266. package/dist/mds-list-item.js +8 -3
  267. package/dist/mds-list-item.server.js +7 -2
  268. package/dist/mds-list.js +8 -3
  269. package/dist/mds-list.server.js +7 -2
  270. package/dist/mds-mention.js +11 -4
  271. package/dist/mds-mention.server.js +7 -2
  272. package/dist/mds-modal.js +8 -3
  273. package/dist/mds-modal.server.js +7 -2
  274. package/dist/mds-note.js +11 -4
  275. package/dist/mds-note.server.js +7 -2
  276. package/dist/mds-notification.js +8 -3
  277. package/dist/mds-notification.server.js +10 -3
  278. package/dist/mds-paginator-item.js +8 -3
  279. package/dist/mds-paginator-item.server.js +7 -2
  280. package/dist/mds-paginator.js +11 -4
  281. package/dist/mds-paginator.server.js +7 -2
  282. package/dist/mds-policy-ai.js +8 -3
  283. package/dist/mds-policy-ai.server.js +7 -2
  284. package/dist/mds-pref-animation.js +11 -4
  285. package/dist/mds-pref-animation.server.js +7 -2
  286. package/dist/mds-pref-consumption.js +11 -4
  287. package/dist/mds-pref-consumption.server.js +7 -2
  288. package/dist/mds-pref-contrast.js +11 -4
  289. package/dist/mds-pref-contrast.server.js +7 -2
  290. package/dist/mds-pref-language-item.js +11 -4
  291. package/dist/mds-pref-language-item.server.js +7 -2
  292. package/dist/mds-pref-language.js +8 -3
  293. package/dist/mds-pref-language.server.js +7 -2
  294. package/dist/mds-pref-mode.js +11 -4
  295. package/dist/mds-pref-mode.server.js +7 -2
  296. package/dist/mds-pref-theme-item.js +11 -4
  297. package/dist/mds-pref-theme-item.server.js +7 -2
  298. package/dist/mds-pref-theme.js +8 -3
  299. package/dist/mds-pref-theme.server.js +7 -2
  300. package/dist/mds-pref.js +8 -3
  301. package/dist/mds-pref.server.js +7 -2
  302. package/dist/mds-price-table-features-cell.js +8 -3
  303. package/dist/mds-price-table-features-cell.server.js +10 -3
  304. package/dist/mds-price-table-features-row.js +8 -3
  305. package/dist/mds-price-table-features-row.server.js +7 -2
  306. package/dist/mds-price-table-features.js +8 -3
  307. package/dist/mds-price-table-features.server.js +10 -3
  308. package/dist/mds-price-table-header.js +8 -3
  309. package/dist/mds-price-table-header.server.js +7 -2
  310. package/dist/mds-price-table-list-item.js +8 -3
  311. package/dist/mds-price-table-list-item.server.js +7 -2
  312. package/dist/mds-price-table-list.js +8 -3
  313. package/dist/mds-price-table-list.server.js +7 -2
  314. package/dist/mds-price-table.js +8 -3
  315. package/dist/mds-price-table.server.js +7 -2
  316. package/dist/mds-progress.js +8 -3
  317. package/dist/mds-progress.server.js +7 -2
  318. package/dist/mds-push-notification-item.js +11 -4
  319. package/dist/mds-push-notification-item.server.js +7 -2
  320. package/dist/mds-push-notification.js +8 -3
  321. package/dist/mds-push-notification.server.js +7 -2
  322. package/dist/mds-quote.js +8 -3
  323. package/dist/mds-quote.server.js +7 -2
  324. package/dist/mds-radial-menu-item.js +8 -3
  325. package/dist/mds-radial-menu-item.server.js +7 -2
  326. package/dist/mds-radial-menu.js +8 -3
  327. package/dist/mds-radial-menu.server.js +7 -2
  328. package/dist/mds-radial-progress.js +8 -3
  329. package/dist/mds-radial-progress.server.js +7 -2
  330. package/dist/mds-separator.js +8 -3
  331. package/dist/mds-separator.server.js +7 -2
  332. package/dist/mds-spinner.js +8 -3
  333. package/dist/mds-spinner.server.js +10 -3
  334. package/dist/mds-status-bar.js +8 -3
  335. package/dist/mds-status-bar.server.js +7 -2
  336. package/dist/mds-stepper-bar-item.js +11 -4
  337. package/dist/mds-stepper-bar-item.server.js +7 -2
  338. package/dist/mds-stepper-bar.js +11 -4
  339. package/dist/mds-stepper-bar.server.js +7 -2
  340. package/dist/mds-tab-bar-item.js +11 -4
  341. package/dist/mds-tab-bar-item.server.js +7 -2
  342. package/dist/mds-tab-bar.js +11 -4
  343. package/dist/mds-tab-bar.server.js +7 -2
  344. package/dist/mds-tab-item.js +8 -3
  345. package/dist/mds-tab-item.server.js +7 -2
  346. package/dist/mds-tab.js +11 -4
  347. package/dist/mds-tab.server.js +7 -2
  348. package/dist/mds-table-body.js +8 -3
  349. package/dist/mds-table-body.server.js +7 -2
  350. package/dist/mds-table-cell.js +8 -3
  351. package/dist/mds-table-cell.server.js +10 -3
  352. package/dist/mds-table-footer.js +8 -3
  353. package/dist/mds-table-footer.server.js +10 -3
  354. package/dist/mds-table-header-cell.js +11 -4
  355. package/dist/mds-table-header-cell.server.js +7 -2
  356. package/dist/mds-table-header.js +8 -3
  357. package/dist/mds-table-header.server.js +10 -3
  358. package/dist/mds-table-row.js +8 -3
  359. package/dist/mds-table-row.server.js +7 -2
  360. package/dist/mds-table.js +11 -4
  361. package/dist/mds-table.server.js +7 -2
  362. package/dist/mds-text.js +8 -3
  363. package/dist/mds-text.server.js +7 -2
  364. package/dist/mds-toast-region.js +8 -3
  365. package/dist/mds-toast-region.server.js +7 -2
  366. package/dist/mds-toast.js +11 -4
  367. package/dist/mds-toast.server.js +7 -2
  368. package/dist/mds-tooltip.js +8 -3
  369. package/dist/mds-tooltip.server.js +7 -2
  370. package/dist/mds-tree-item.js +8 -3
  371. package/dist/mds-tree-item.server.js +7 -2
  372. package/dist/mds-tree.js +8 -3
  373. package/dist/mds-tree.server.js +7 -2
  374. package/dist/mds-url-view.js +11 -4
  375. package/dist/mds-url-view.server.js +7 -2
  376. package/dist/mds-usage.js +8 -3
  377. package/dist/mds-usage.server.js +7 -2
  378. package/dist/mds-video-wall.js +8 -3
  379. package/dist/mds-video-wall.server.js +7 -2
  380. package/dist/mds-zero.js +8 -3
  381. package/dist/mds-zero.server.js +7 -2
  382. package/dist/types/components.d.ts +117 -117
  383. package/dist/types/components.server.d.ts +118 -118
  384. package/dist/types/mds-accordion-item.d.ts +4 -8
  385. package/dist/types/mds-accordion-item.server.d.ts +4 -4
  386. package/dist/types/mds-accordion-timer-item.d.ts +4 -8
  387. package/dist/types/mds-accordion-timer-item.server.d.ts +4 -4
  388. package/dist/types/mds-accordion-timer.d.ts +4 -8
  389. package/dist/types/mds-accordion-timer.server.d.ts +4 -4
  390. package/dist/types/mds-accordion.d.ts +4 -8
  391. package/dist/types/mds-accordion.server.d.ts +4 -4
  392. package/dist/types/mds-author.d.ts +2 -6
  393. package/dist/types/mds-author.server.d.ts +3 -3
  394. package/dist/types/mds-avatar-stack-item.d.ts +2 -6
  395. package/dist/types/mds-avatar-stack-item.server.d.ts +3 -3
  396. package/dist/types/mds-avatar-stack.d.ts +2 -6
  397. package/dist/types/mds-avatar-stack.server.d.ts +3 -3
  398. package/dist/types/mds-avatar.d.ts +2 -6
  399. package/dist/types/mds-avatar.server.d.ts +3 -3
  400. package/dist/types/mds-badge.d.ts +2 -6
  401. package/dist/types/mds-badge.server.d.ts +3 -3
  402. package/dist/types/mds-banner.d.ts +4 -8
  403. package/dist/types/mds-banner.server.d.ts +4 -4
  404. package/dist/types/mds-benchmark-bar.d.ts +2 -6
  405. package/dist/types/mds-benchmark-bar.server.d.ts +3 -3
  406. package/dist/types/mds-bibliography.d.ts +2 -6
  407. package/dist/types/mds-bibliography.server.d.ts +3 -3
  408. package/dist/types/mds-book.d.ts +2 -6
  409. package/dist/types/mds-book.server.d.ts +3 -3
  410. package/dist/types/mds-breadcrumb-item.d.ts +4 -8
  411. package/dist/types/mds-breadcrumb-item.server.d.ts +4 -4
  412. package/dist/types/mds-breadcrumb.d.ts +4 -8
  413. package/dist/types/mds-breadcrumb.server.d.ts +4 -4
  414. package/dist/types/mds-button-dropdown.d.ts +4 -8
  415. package/dist/types/mds-button-dropdown.server.d.ts +4 -4
  416. package/dist/types/mds-button-group.d.ts +2 -6
  417. package/dist/types/mds-button-group.server.d.ts +3 -3
  418. package/dist/types/mds-button.d.ts +2 -6
  419. package/dist/types/mds-button.server.d.ts +3 -3
  420. package/dist/types/mds-calendar-cell.d.ts +2 -6
  421. package/dist/types/mds-calendar-cell.server.d.ts +3 -3
  422. package/dist/types/mds-calendar.d.ts +4 -8
  423. package/dist/types/mds-calendar.server.d.ts +4 -4
  424. package/dist/types/mds-card-content.d.ts +2 -6
  425. package/dist/types/mds-card-content.server.d.ts +3 -3
  426. package/dist/types/mds-card-footer.d.ts +2 -6
  427. package/dist/types/mds-card-footer.server.d.ts +3 -3
  428. package/dist/types/mds-card-header.d.ts +2 -6
  429. package/dist/types/mds-card-header.server.d.ts +3 -3
  430. package/dist/types/mds-card-media.d.ts +2 -6
  431. package/dist/types/mds-card-media.server.d.ts +3 -3
  432. package/dist/types/mds-card.d.ts +2 -6
  433. package/dist/types/mds-card.server.d.ts +3 -3
  434. package/dist/types/mds-chip.d.ts +4 -8
  435. package/dist/types/mds-chip.server.d.ts +4 -4
  436. package/dist/types/mds-details.d.ts +4 -8
  437. package/dist/types/mds-details.server.d.ts +4 -4
  438. package/dist/types/mds-dropdown.d.ts +4 -8
  439. package/dist/types/mds-dropdown.server.d.ts +4 -4
  440. package/dist/types/mds-emoji.d.ts +2 -6
  441. package/dist/types/mds-emoji.server.d.ts +3 -3
  442. package/dist/types/mds-entity.d.ts +2 -6
  443. package/dist/types/mds-entity.server.d.ts +3 -3
  444. package/dist/types/mds-file-preview.d.ts +4 -8
  445. package/dist/types/mds-file-preview.server.d.ts +4 -4
  446. package/dist/types/mds-file.d.ts +4 -8
  447. package/dist/types/mds-file.server.d.ts +4 -4
  448. package/dist/types/mds-filter-item.d.ts +4 -8
  449. package/dist/types/mds-filter-item.server.d.ts +4 -4
  450. package/dist/types/mds-filter.d.ts +4 -8
  451. package/dist/types/mds-filter.server.d.ts +4 -4
  452. package/dist/types/mds-header-bar.d.ts +4 -8
  453. package/dist/types/mds-header-bar.server.d.ts +4 -4
  454. package/dist/types/mds-header.d.ts +4 -8
  455. package/dist/types/mds-header.server.d.ts +4 -4
  456. package/dist/types/mds-help.d.ts +2 -6
  457. package/dist/types/mds-help.server.d.ts +3 -3
  458. package/dist/types/mds-horizontal-scroll.d.ts +2 -6
  459. package/dist/types/mds-horizontal-scroll.server.d.ts +3 -3
  460. package/dist/types/mds-hr.d.ts +2 -6
  461. package/dist/types/mds-hr.server.d.ts +3 -3
  462. package/dist/types/mds-icon.d.ts +2 -6
  463. package/dist/types/mds-icon.server.d.ts +3 -3
  464. package/dist/types/mds-img.d.ts +4 -8
  465. package/dist/types/mds-img.server.d.ts +4 -4
  466. package/dist/types/mds-input-date-range-preselection.d.ts +2 -6
  467. package/dist/types/mds-input-date-range-preselection.server.d.ts +3 -3
  468. package/dist/types/mds-input-date-range.d.ts +4 -8
  469. package/dist/types/mds-input-date-range.server.d.ts +4 -4
  470. package/dist/types/mds-input-date.d.ts +4 -8
  471. package/dist/types/mds-input-date.server.d.ts +4 -4
  472. package/dist/types/mds-input-field.d.ts +2 -6
  473. package/dist/types/mds-input-field.server.d.ts +3 -3
  474. package/dist/types/mds-input-otp.d.ts +2 -6
  475. package/dist/types/mds-input-otp.server.d.ts +3 -3
  476. package/dist/types/mds-input-range.d.ts +4 -8
  477. package/dist/types/mds-input-range.server.d.ts +4 -4
  478. package/dist/types/mds-input-select.d.ts +4 -8
  479. package/dist/types/mds-input-select.server.d.ts +4 -4
  480. package/dist/types/mds-input-switch.d.ts +4 -8
  481. package/dist/types/mds-input-switch.server.d.ts +4 -4
  482. package/dist/types/mds-input-tip-item.d.ts +2 -6
  483. package/dist/types/mds-input-tip-item.server.d.ts +3 -3
  484. package/dist/types/mds-input-tip.d.ts +2 -6
  485. package/dist/types/mds-input-tip.server.d.ts +3 -3
  486. package/dist/types/mds-input-upload.d.ts +4 -8
  487. package/dist/types/mds-input-upload.server.d.ts +4 -4
  488. package/dist/types/mds-input.d.ts +4 -8
  489. package/dist/types/mds-input.server.d.ts +4 -4
  490. package/dist/types/mds-keyboard-key.d.ts +2 -6
  491. package/dist/types/mds-keyboard-key.server.d.ts +3 -3
  492. package/dist/types/mds-keyboard.d.ts +2 -6
  493. package/dist/types/mds-keyboard.server.d.ts +3 -3
  494. package/dist/types/mds-kpi-item.d.ts +2 -6
  495. package/dist/types/mds-kpi-item.server.d.ts +3 -3
  496. package/dist/types/mds-kpi.d.ts +2 -6
  497. package/dist/types/mds-kpi.server.d.ts +3 -3
  498. package/dist/types/mds-label.d.ts +4 -8
  499. package/dist/types/mds-label.server.d.ts +4 -4
  500. package/dist/types/mds-link.d.ts +2 -6
  501. package/dist/types/mds-link.server.d.ts +3 -3
  502. package/dist/types/mds-list-item.d.ts +2 -6
  503. package/dist/types/mds-list-item.server.d.ts +3 -3
  504. package/dist/types/mds-list.d.ts +2 -6
  505. package/dist/types/mds-list.server.d.ts +3 -3
  506. package/dist/types/mds-mention.d.ts +4 -8
  507. package/dist/types/mds-mention.server.d.ts +4 -4
  508. package/dist/types/mds-modal.d.ts +4 -8
  509. package/dist/types/mds-modal.server.d.ts +4 -4
  510. package/dist/types/mds-note.d.ts +4 -8
  511. package/dist/types/mds-note.server.d.ts +4 -4
  512. package/dist/types/mds-notification.d.ts +2 -6
  513. package/dist/types/mds-notification.server.d.ts +3 -3
  514. package/dist/types/mds-paginator-item.d.ts +2 -6
  515. package/dist/types/mds-paginator-item.server.d.ts +3 -3
  516. package/dist/types/mds-paginator.d.ts +4 -8
  517. package/dist/types/mds-paginator.server.d.ts +4 -4
  518. package/dist/types/mds-policy-ai.d.ts +2 -6
  519. package/dist/types/mds-policy-ai.server.d.ts +3 -3
  520. package/dist/types/mds-pref-animation.d.ts +4 -8
  521. package/dist/types/mds-pref-animation.server.d.ts +4 -4
  522. package/dist/types/mds-pref-consumption.d.ts +4 -8
  523. package/dist/types/mds-pref-consumption.server.d.ts +4 -4
  524. package/dist/types/mds-pref-contrast.d.ts +4 -8
  525. package/dist/types/mds-pref-contrast.server.d.ts +4 -4
  526. package/dist/types/mds-pref-language-item.d.ts +4 -8
  527. package/dist/types/mds-pref-language-item.server.d.ts +4 -4
  528. package/dist/types/mds-pref-language.d.ts +4 -8
  529. package/dist/types/mds-pref-language.server.d.ts +4 -4
  530. package/dist/types/mds-pref-mode.d.ts +4 -8
  531. package/dist/types/mds-pref-mode.server.d.ts +4 -4
  532. package/dist/types/mds-pref-theme-item.d.ts +4 -8
  533. package/dist/types/mds-pref-theme-item.server.d.ts +4 -4
  534. package/dist/types/mds-pref-theme.d.ts +4 -8
  535. package/dist/types/mds-pref-theme.server.d.ts +4 -4
  536. package/dist/types/mds-pref.d.ts +2 -6
  537. package/dist/types/mds-pref.server.d.ts +3 -3
  538. package/dist/types/mds-price-table-features-cell.d.ts +2 -6
  539. package/dist/types/mds-price-table-features-cell.server.d.ts +3 -3
  540. package/dist/types/mds-price-table-features-row.d.ts +2 -6
  541. package/dist/types/mds-price-table-features-row.server.d.ts +3 -3
  542. package/dist/types/mds-price-table-features.d.ts +2 -6
  543. package/dist/types/mds-price-table-features.server.d.ts +3 -3
  544. package/dist/types/mds-price-table-header.d.ts +2 -6
  545. package/dist/types/mds-price-table-header.server.d.ts +3 -3
  546. package/dist/types/mds-price-table-list-item.d.ts +2 -6
  547. package/dist/types/mds-price-table-list-item.server.d.ts +3 -3
  548. package/dist/types/mds-price-table-list.d.ts +2 -6
  549. package/dist/types/mds-price-table-list.server.d.ts +3 -3
  550. package/dist/types/mds-price-table.d.ts +2 -6
  551. package/dist/types/mds-price-table.server.d.ts +3 -3
  552. package/dist/types/mds-progress.d.ts +2 -6
  553. package/dist/types/mds-progress.server.d.ts +3 -3
  554. package/dist/types/mds-push-notification-item.d.ts +4 -8
  555. package/dist/types/mds-push-notification-item.server.d.ts +4 -4
  556. package/dist/types/mds-push-notification.d.ts +4 -8
  557. package/dist/types/mds-push-notification.server.d.ts +4 -4
  558. package/dist/types/mds-quote.d.ts +2 -6
  559. package/dist/types/mds-quote.server.d.ts +3 -3
  560. package/dist/types/mds-radial-menu-item.d.ts +2 -6
  561. package/dist/types/mds-radial-menu-item.server.d.ts +3 -3
  562. package/dist/types/mds-radial-menu.d.ts +2 -6
  563. package/dist/types/mds-radial-menu.server.d.ts +3 -3
  564. package/dist/types/mds-radial-progress.d.ts +2 -6
  565. package/dist/types/mds-radial-progress.server.d.ts +3 -3
  566. package/dist/types/mds-separator.d.ts +2 -6
  567. package/dist/types/mds-separator.server.d.ts +3 -3
  568. package/dist/types/mds-spinner.d.ts +2 -6
  569. package/dist/types/mds-spinner.server.d.ts +3 -3
  570. package/dist/types/mds-status-bar.d.ts +2 -6
  571. package/dist/types/mds-status-bar.server.d.ts +3 -3
  572. package/dist/types/mds-stepper-bar-item.d.ts +4 -8
  573. package/dist/types/mds-stepper-bar-item.server.d.ts +4 -4
  574. package/dist/types/mds-stepper-bar.d.ts +4 -8
  575. package/dist/types/mds-stepper-bar.server.d.ts +4 -4
  576. package/dist/types/mds-tab-bar-item.d.ts +4 -8
  577. package/dist/types/mds-tab-bar-item.server.d.ts +4 -4
  578. package/dist/types/mds-tab-bar.d.ts +4 -8
  579. package/dist/types/mds-tab-bar.server.d.ts +4 -4
  580. package/dist/types/mds-tab-item.d.ts +4 -8
  581. package/dist/types/mds-tab-item.server.d.ts +4 -4
  582. package/dist/types/mds-tab.d.ts +4 -8
  583. package/dist/types/mds-tab.server.d.ts +4 -4
  584. package/dist/types/mds-table-body.d.ts +2 -6
  585. package/dist/types/mds-table-body.server.d.ts +3 -3
  586. package/dist/types/mds-table-cell.d.ts +2 -6
  587. package/dist/types/mds-table-cell.server.d.ts +3 -3
  588. package/dist/types/mds-table-footer.d.ts +2 -6
  589. package/dist/types/mds-table-footer.server.d.ts +3 -3
  590. package/dist/types/mds-table-header-cell.d.ts +4 -8
  591. package/dist/types/mds-table-header-cell.server.d.ts +4 -4
  592. package/dist/types/mds-table-header.d.ts +2 -6
  593. package/dist/types/mds-table-header.server.d.ts +3 -3
  594. package/dist/types/mds-table-row.d.ts +2 -6
  595. package/dist/types/mds-table-row.server.d.ts +3 -3
  596. package/dist/types/mds-table.d.ts +4 -8
  597. package/dist/types/mds-table.server.d.ts +4 -4
  598. package/dist/types/mds-text.d.ts +2 -6
  599. package/dist/types/mds-text.server.d.ts +3 -3
  600. package/dist/types/mds-toast-region.d.ts +2 -6
  601. package/dist/types/mds-toast-region.server.d.ts +3 -3
  602. package/dist/types/mds-toast.d.ts +4 -8
  603. package/dist/types/mds-toast.server.d.ts +4 -4
  604. package/dist/types/mds-tooltip.d.ts +2 -6
  605. package/dist/types/mds-tooltip.server.d.ts +3 -3
  606. package/dist/types/mds-tree-item.d.ts +4 -8
  607. package/dist/types/mds-tree-item.server.d.ts +4 -4
  608. package/dist/types/mds-tree.d.ts +2 -6
  609. package/dist/types/mds-tree.server.d.ts +3 -3
  610. package/dist/types/mds-url-view.d.ts +4 -8
  611. package/dist/types/mds-url-view.server.d.ts +4 -4
  612. package/dist/types/mds-usage.d.ts +2 -6
  613. package/dist/types/mds-usage.server.d.ts +3 -3
  614. package/dist/types/mds-video-wall.d.ts +2 -6
  615. package/dist/types/mds-video-wall.server.d.ts +3 -3
  616. package/dist/types/mds-zero.d.ts +2 -6
  617. package/dist/types/mds-zero.server.d.ts +3 -3
  618. package/package.json +3 -3
@@ -0,0 +1,221 @@
1
+ ---
2
+ # A Magma pattern: the format and the commands are in docs/PATTERNS.md.
3
+ id: loading
4
+ kind: pattern
5
+ title: Waiting for something
6
+ group: messages-and-states
7
+ layer: magma
8
+ status: decided
9
+ need: >-
10
+ The person waits for content or for the end of an action, and must know that it is coming and
11
+ whether they can do something else meanwhile.
12
+ principle: The wait shows where the person looked, keeps what is on screen, and always ends.
13
+ keywords: [loading, spinner, progress, please wait, busy, in progress, uploading, exporting, skeleton]
14
+ not-for:
15
+ - need: where the outcome of the action is told
16
+ use: message-placement
17
+ - need: a load that ended with nothing to show
18
+ use: empty-state
19
+ - need: a load that failed
20
+ use: error-recovery
21
+ assumptions:
22
+ - The application knows before starting whether an operation is long and whether it can tell how far it is.
23
+ high-stakes: false
24
+ components: [mds-spinner, mds-progress, mds-button, mds-input, mds-text, mds-toast]
25
+ related: [message-placement, empty-state, error-recovery, list-with-filters, record-detail, item-list]
26
+ validated-on: []
27
+
28
+ variables:
29
+ what: { values: [content, action], means: "content: data a part of the page shows; action: an operation the person started from a control" }
30
+ on-screen: { values: [nothing, previous], means: "for content: is there something to keep while it loads (a reload, a new search)" }
31
+ length: { values: [short, long], means: "long: an operation that can take more than 10 s, known before it starts (an export, an upload, many items, a report)" }
32
+ measurable: { values: ["no", "yes"], means: "can the application tell how far it is (bytes sent, items done)" }
33
+ needed: { values: ["yes", "no"], means: "does the person need the result before going on" }
34
+
35
+ cases:
36
+ - { id: first-load, what: content, on-screen: nothing, length: short, where: "a skeleton with the shape of the content, in its place; until Magma has one, a well as tall as the content to come (`surface-muted`, `rounded-md`) with a spinner in the middle; aria-busy on the part", use: ["mds-spinner"], magma-gap: "no skeleton" }
37
+ - { id: keep-while-reloading, what: content, on-screen: previous, length: short, where: "what was there stays; the region has aria-busy; the control that started it waits; a newer request cancels the older; in the new results, what was searched is marked (`mark`)", use: ["mds-input await"] }
38
+ - { id: long-load, what: content, length: long, measurable: "no", where: "the well and the spinner of the short case, with a sentence under the spinner that says what is happening", use: ["mds-spinner", "mds-text"] }
39
+ - { id: long-load-measured, what: content, length: long, measurable: "yes", where: "the well and the spinner of the short case, a sentence that says what is happening and how far, and a progress bar under it", use: ["mds-spinner", "mds-text", "mds-progress steps"] }
40
+ - { id: await-the-control, what: action, length: short, where: "the control that started it waits: its spinner, no second press, aria-busy, the focus stays on it", use: ["mds-button await"] }
41
+ - { id: progress-in-place, what: action, length: long, measurable: "yes", needed: "yes", where: "a progress bar next to the control, with a sentence that says what is happening", use: ["mds-progress steps", "mds-button await"] }
42
+ - { id: await-and-say, what: action, length: long, measurable: "no", needed: "yes", where: "the control waits, and a sentence next to it says what is happening", use: ["mds-button await", "mds-text"] }
43
+ - { id: run-in-background, what: action, length: long, needed: "no", where: "the control stops waiting at once and a toast says it started; the outcome comes later, as action-later", use: ["mds-toast variant=info"], see: message-placement }
44
+ gaps: []
45
+ not-applicable: []
46
+
47
+ always-true:
48
+ - id: no-flash-empty
49
+ rule: A reload never empties what is on screen.
50
+ checked-by: review
51
+ - id: control-waits
52
+ rule: The control that started an action shows the wait and cannot be pressed again.
53
+ checked-by: review
54
+ note: a double payment is what it prevents
55
+ - id: busy-region
56
+ rule: "The region being updated has aria-busy: mds-spinner has no role and leaves it to the context."
57
+ checked-by: review
58
+ - id: newest-wins
59
+ rule: An older answer never replaces a newer one.
60
+ checked-by: review
61
+ - id: always-ends
62
+ rule: A wait ends in content, an empty state or an error.
63
+ checked-by: review
64
+ - id: long-says-what
65
+ rule: A long wait says what is happening, not only an icon that turns.
66
+ checked-by: review
67
+ - id: cancel-only-if-it-stops
68
+ rule: Cancel is offered only when it stops the operation; it never only hides the wait.
69
+ checked-by: review
70
+
71
+ situations:
72
+ - { situation: A list opens for the first time, case: first-load }
73
+ - { situation: A search narrows a list already on screen, case: keep-while-reloading }
74
+ - { situation: "A report takes a minute to compute, with no measure of how far it is", case: long-load }
75
+ - { situation: A dashboard loads twelve widgets and counts them, case: long-load-measured }
76
+ - { situation: A form is saved, case: await-the-control }
77
+ - { situation: A file is uploaded and the form needs it, case: progress-in-place, note: with Cancel }
78
+ - { situation: A payment is sent and its answer is slow, case: await-and-say, note: without Cancel }
79
+ - { situation: An export of ten thousand rows is asked for, case: run-in-background }
80
+ ---
81
+
82
+ # Waiting for something
83
+
84
+ **The wait shows where the person looked, keeps what is on screen, and always ends.**
85
+
86
+ ## When to use it
87
+
88
+ Every wait the person sees: the first load of a part of the page, a reload of what is on
89
+ screen (a new search, a new page of results), an action started from a control (save, send,
90
+ delete), a long operation (an upload, an export, a report). Not the outcome of the wait: it is
91
+ told by `message-placement`, and it may be an empty state (`empty-state`) or an error
92
+ (`error-recovery`).
93
+
94
+ ## What decides it
95
+
96
+ Five questions: whether the person waits for content or for an action, whether something is
97
+ already on screen to keep, whether the wait is short or long, whether the application can tell
98
+ how far it is, and whether the person needs the result before going on.
99
+
100
+ ## Cases
101
+
102
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
103
+
104
+ | Variable | Values | Means |
105
+ | --- | --- | --- |
106
+ | `what` | `content`, `action` | content: data a part of the page shows; action: an operation the person started from a control |
107
+ | `on-screen` | `nothing`, `previous` | for content: is there something to keep while it loads (a reload, a new search) |
108
+ | `length` | `short`, `long` | long: an operation that can take more than 10 s, known before it starts (an export, an upload, many items, a report) |
109
+ | `measurable` | `no`, `yes` | can the application tell how far it is (bytes sent, items done) |
110
+ | `needed` | `yes`, `no` | does the person need the result before going on |
111
+
112
+ A case that leaves a variable out holds for any of its values.
113
+
114
+ | Case | When | Where | Use |
115
+ | --- | --- | --- | --- |
116
+ | `first-load` | what: content; on-screen: nothing; length: short | a skeleton with the shape of the content, in its place; until Magma has one, a well as tall as the content to come (`surface-muted`, `rounded-md`) with a spinner in the middle; aria-busy on the part; Magma gap: no skeleton | `mds-spinner` |
117
+ | `keep-while-reloading` | what: content; on-screen: previous; length: short | what was there stays; the region has aria-busy; the control that started it waits; a newer request cancels the older; in the new results, what was searched is marked (`mark`) | `mds-input await` |
118
+ | `long-load` | what: content; length: long; measurable: no | the well and the spinner of the short case, with a sentence under the spinner that says what is happening | `mds-spinner`, `mds-text` |
119
+ | `long-load-measured` | what: content; length: long; measurable: yes | the well and the spinner of the short case, a sentence that says what is happening and how far, and a progress bar under it | `mds-spinner`, `mds-text`, `mds-progress steps` |
120
+ | `await-the-control` | what: action; length: short | the control that started it waits: its spinner, no second press, aria-busy, the focus stays on it | `mds-button await` |
121
+ | `progress-in-place` | what: action; length: long; measurable: yes; needed: yes | a progress bar next to the control, with a sentence that says what is happening | `mds-progress steps`, `mds-button await` |
122
+ | `await-and-say` | what: action; length: long; measurable: no; needed: yes | the control waits, and a sentence next to it says what is happening | `mds-button await`, `mds-text` |
123
+ | `run-in-background` | what: action; length: long; needed: no | the control stops waiting at once and a toast says it started; the outcome comes later, as action-later; see `message-placement` | `mds-toast variant=info` |
124
+
125
+ No gaps: every combination has a case or is not applicable.
126
+
127
+ ## Parts
128
+
129
+ - The first load of a part: a skeleton with the shape of the content (rows of a list, the
130
+ blocks of a detail), so the layout does not jump when the data comes; until Magma has one, a
131
+ well that keeps the place of the content (`bg-surface-muted rounded-md`, as tall as what
132
+ comes), with `mds-spinner` in its middle: the spinner never floats alone on the page.
133
+ - A reload: the content stays, the region has `aria-busy="true"`, the control that started it
134
+ waits (`await` on `mds-input` shows the spinner in the search field). In the results of a
135
+ search, what was searched is marked (`mark`, painted with `bg-warning-surface`).
136
+ - An action: `await` on `mds-button`, which shows its spinner, refuses a second press, sets
137
+ `aria-busy` and keeps the focus.
138
+ - A long wait: a sentence that says what is happening ("Preparing the PDF..."), under the
139
+ spinner, in the well; `mds-progress` under the sentence when the application can tell how far
140
+ it is, with `steps` in the language of the page: the spinner stays, so the wait looks alive
141
+ between two steps of the bar.
142
+ - A long action the person does not need to wait for: a toast that says it started, then the
143
+ outcome as `action-later` of `message-placement`.
144
+
145
+ ## Behaviour over time
146
+
147
+ - A newer request cancels the one still running: an older, slower answer never replaces a
148
+ newer one (`list-with-filters`).
149
+ - The wait ends in content, in an empty state or in an error, never in an indicator that runs
150
+ for ever.
151
+ - A long wait the person needs has Cancel next to it when the operation can be stopped without
152
+ harm: it stops, and the message says what was done and what was not (`message-placement`,
153
+ partial outcome). An operation that cannot be called back, a payment already sent, offers
154
+ none.
155
+
156
+ ## Always true
157
+
158
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
159
+
160
+ These hold in every product: a product layer cannot change them.
161
+
162
+ | Id | Rule | Checked by |
163
+ | --- | --- | --- |
164
+ | `no-flash-empty` | A reload never empties what is on screen. | review |
165
+ | `control-waits` | The control that started an action shows the wait and cannot be pressed again. | review; a double payment is what it prevents |
166
+ | `busy-region` | The region being updated has aria-busy: mds-spinner has no role and leaves it to the context. | review |
167
+ | `newest-wins` | An older answer never replaces a newer one. | review |
168
+ | `always-ends` | A wait ends in content, an empty state or an error. | review |
169
+ | `long-says-what` | A long wait says what is happening, not only an icon that turns. | review |
170
+ | `cancel-only-if-it-stops` | Cancel is offered only when it stops the operation; it never only hides the wait. | review |
171
+
172
+ ## Situations
173
+
174
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
175
+
176
+ Situations every application has, each with its case: they give the examples, the texts and the keywords. The situations of a product's own domain go in its layer.
177
+
178
+ | Situation | Case |
179
+ | --- | --- |
180
+ | A list opens for the first time | `first-load` |
181
+ | A search narrows a list already on screen | `keep-while-reloading` |
182
+ | A report takes a minute to compute, with no measure of how far it is | `long-load` |
183
+ | A dashboard loads twelve widgets and counts them | `long-load-measured` |
184
+ | A form is saved | `await-the-control` |
185
+ | A file is uploaded and the form needs it | `progress-in-place`: with Cancel |
186
+ | A payment is sent and its answer is slow | `await-and-say`: without Cancel |
187
+ | An export of ten thousand rows is asked for | `run-in-background` |
188
+
189
+ ## Accessibility
190
+
191
+ - `aria-busy` on the region tells assistive technologies that it is being updated; the result
192
+ is read out by the status region of `message-placement`, or the summary of the results.
193
+ - The spinner is decorative; with reduced motion it slows down and never stops (`mds-spinner`).
194
+ - `mds-progress` reads out the step reached, not a raw number.
195
+
196
+ ## Content
197
+
198
+ - A long wait says what is happening, in the words of the person: "Preparing the PDF...", not
199
+ "Processing request".
200
+
201
+ ## Magma gaps
202
+
203
+ - No skeleton, neither a component nor a utility, and no component for the states of a load
204
+ (the well, the spinner, the sentence, the bar): an issue to open; until then, the well
205
+ written with classes.
206
+ - `mark` has no Magma style: the browser paints it in its own yellow, so the previews paint it
207
+ with `bg-warning-surface text-inherit`.
208
+ - `mds-progress`: the default `steps` are in Italian (`Inizio,Un quarto,...`) whatever the
209
+ language of the page.
210
+
211
+ ## Decisions
212
+
213
+ | Date | Decision | Why |
214
+ | --- | --- | --- |
215
+ | 2026-10-16 | Proposed: a skeleton for the first load of a region, `await` on the control that started an action, the results stay while the next ones load | Open decision of the docs site, `agents/patterns.md`. |
216
+ | 2026-10-28 | Draft with variables; the first load, when a wait is long, and Cancel left as gaps | The sources do not settle them. |
217
+ | 2026-10-28 | The first load shows a skeleton with the shape of the content; a spinner until Magma has one (`first-load`) | The layout does not jump when the data comes; the open decision of the docs site. |
218
+ | 2026-10-28 | A wait is long when the operation can take more than 10 s, known before it starts | The application picks the form of the wait before starting; 10 s is the limit of attention (Nielsen). |
219
+ | 2026-10-28 | Cancel next to a long wait the person needs, only when the operation can be stopped | A Cancel that only hides the wait lies about what happens. |
220
+ | 2026-11-03 | Until Magma has a skeleton, the first load is a well that keeps the place of the content, with the spinner in its middle; a long load keeps the well and the spinner, and adds the sentence and the bar (`first-load`, `long-load`, `long-load-measured`) | A spinner alone floats on the page and says nothing of what is coming, or where. Asked in review round 2 of the previews: https://github.com/magma-design-system/magma/issues/1233 |
221
+ | 2026-11-03 | In the results of a search, what was searched is marked (`keep-while-reloading`) | The person sees at once why each result is there. Asked in review round 2 of the previews: https://github.com/magma-design-system/magma/issues/1233 |
@@ -0,0 +1,304 @@
1
+ ---
2
+ # A Magma pattern: the format and the commands are in docs/PATTERNS.md.
3
+ id: message-placement
4
+ kind: pattern
5
+ title: Where a message goes
6
+ group: messages-and-states
7
+ layer: magma
8
+ status: decided
9
+ need: >-
10
+ The person did something or opened a view, and must know what happened without looking for
11
+ it.
12
+ principle: A message goes where the thing it talks about is.
13
+ keywords: [message, toast, banner, error message, saved, deleted, copied, failed, could not load, try again, connection lost, session ending]
14
+ not-for:
15
+ - need: deciding whether to ask before acting
16
+ use: confirm-action
17
+ - need: what an empty part of the page says
18
+ use: empty-state
19
+ - need: what stays on screen and how to try again after a failure
20
+ use: error-recovery
21
+ assumptions:
22
+ - The application has a shell, with one mds-toast-region in it.
23
+ - Desktop and mobile; on mobile with the keyboard open the bottom edge is still to verify.
24
+ high-stakes: false
25
+ components: [mds-input-field, mds-input, mds-banner, mds-toast, mds-toast-region, mds-modal]
26
+ related: [confirm-action, error-recovery, loading, empty-state, notification-center, app-shell]
27
+ validated-on: []
28
+
29
+ variables:
30
+ about: { values: [field, region, action, application], means: "what the message talks about" }
31
+ outcome: { values: [success, failure, partial, info], means: "what happened" }
32
+ place: { values: [on-screen, off-screen], means: "is the thing it talks about on screen when the message comes" }
33
+ timing: { values: [now, later], means: "later: the outcome comes after the person moved on" }
34
+ decision: { values: [none, needed, deadline], means: "does the person have to choose before going on" }
35
+ scope: { values: [page, part], means: "what an action changed: data shown across the page, or a part that works on its own" }
36
+
37
+ cases:
38
+ - { id: field-error, about: field, outcome: failure, place: on-screen, where: "under the field", use: ["mds-input-field message"] }
39
+ - { id: field-hint, about: field, outcome: info, place: on-screen, where: "under the field, its helper text; where an example of the value helps, the empty field shows one as its placeholder (\"Es: Mario Rossi\")", use: ["mds-input-field message", "mds-input placeholder"], magma-gap: "validation overwrites it" }
40
+ - { id: field-valid, about: field, outcome: success, place: on-screen, where: "no message, the field shows its valid state", use: ["mds-input-field"] }
41
+ - { id: region-failed, about: region, outcome: failure, where: "in that region, with Try again; what was there stays", use: ["mds-banner variant=error tone=strong"] }
42
+ - { id: region-info, about: region, outcome: info, where: "in that region", use: ["mds-banner variant=info"] }
43
+ - { id: action-failed-in-place, about: action, outcome: failure, place: on-screen, timing: now, where: "in its place, right above the row of actions of the dialog; what was written stays", use: ["mds-banner variant=error tone=strong"] }
44
+ - { id: action-done-elsewhere, about: action, outcome: success, place: off-screen, timing: now, where: "toast; the default light toast for a removal (`removal-toast-neutral`)", use: ["mds-toast variant=success"] }
45
+ - { id: action-done-in-page, about: action, outcome: success, place: on-screen, timing: now, scope: page, where: "toast; the default light toast for a removal (`removal-toast-neutral`)", use: ["mds-toast variant=success"] }
46
+ - { id: action-done-in-part, about: action, outcome: success, place: on-screen, timing: now, scope: part, where: "next to the part that was saved, inside it", use: ["mds-banner variant=success"], magma-gap: "no light confirmation that goes away" }
47
+ - { id: action-failed-elsewhere, about: action, outcome: failure, place: off-screen, timing: now, where: "a toast that stays, with Try again", use: ["mds-toast variant=error duration=0 dismissible"] }
48
+ - { id: action-partial-in-place, about: action, outcome: partial, place: on-screen, timing: now, where: "as a failure in its place: a banner that says how many worked and which did not", use: ["mds-banner variant=error tone=strong"], see: error-recovery }
49
+ - { id: action-partial-elsewhere, about: action, outcome: partial, place: off-screen, timing: now, where: "as a failure elsewhere: a toast that stays, with what to do about the ones that did not work", use: ["mds-toast variant=error duration=0 dismissible"], see: error-recovery }
50
+ - { id: action-taken, about: action, outcome: info, timing: now, where: "toast: taken in charge, and how the outcome will come", use: ["mds-toast variant=info"] }
51
+ - { id: action-later, about: action, timing: later, where: "a toast with its action, which therefore stays; then kept in the notification center", use: ["mds-toast duration=0 dismissible"], see: notification-center }
52
+ - { id: decision, decision: needed, where: "dialog", use: ["mds-modal"], see: confirm-action }
53
+ - { id: app-info, about: application, outcome: info, decision: none, where: "a toast that goes after its time: `warning` for a trouble that does not stop the work (the connection dropped), `info` for news", use: ["mds-toast variant=warning", "mds-toast variant=info"] }
54
+ - { id: app-failed, about: application, outcome: failure, where: "in place of the content of the page, with Try again; the shell stays", use: ["mds-banner variant=error tone=strong"], see: region-failed }
55
+ - { id: app-deadline, about: application, decision: deadline, where: "dialog, also over an open one; closing it means staying (`deadline-close` of actions)", use: ["mds-modal", "mds-banner slot=window variant=warning tone=box dismissible"] }
56
+ gaps: []
57
+ not-applicable:
58
+ - { about: field, place: off-screen, why: "a message about a field goes with its field" }
59
+ - { about: region, outcome: success, why: "a region that loads shows its content, the content is the message" }
60
+ - { about: [field, region, action], decision: deadline, why: "a deadline is about the whole application" }
61
+ - { about: [field, region, application], outcome: partial, why: "a partial outcome is about an action on several items" }
62
+ - { about: application, outcome: success, why: "an application does not succeed, its actions do" }
63
+
64
+ always-true:
65
+ - id: no-toast-over-dialog
66
+ rule: "Never a toast over an open dialog: what is about a dialog goes inside it."
67
+ checked-by: review
68
+ - id: one-toast-region
69
+ rule: One mds-toast-region per application.
70
+ checked-by: review
71
+ - id: toast-action-stays
72
+ rule: A toast with an action has duration="0" and dismissible.
73
+ checked-by: review
74
+ lint-planned: magma/toast-action-stays
75
+ - id: no-dismissible-banner-in-dialog
76
+ rule: "A banner inside an mds-modal is not dismissible: closing it closes the dialog, and what the person wrote is lost."
77
+ checked-by: review
78
+ lint-planned: magma/no-dismissible-banner-in-modal
79
+ - id: success-after-change
80
+ rule: "After every create, edit and delete the person is told it worked: a toast, or a confirmation next to the part when that part works on its own."
81
+ checked-by: review
82
+ - id: removal-toast-neutral
83
+ rule: "The toast of a removal (an item removed, archived, deleted after a confirmation), with or without Undo, is the default light toast: variant=\"success\" is for what an action creates or completes."
84
+ checked-by: review
85
+ - id: no-internal-text
86
+ rule: Never internal messages, HTTP status text or "coming soon".
87
+ checked-by: review
88
+
89
+ open-choices:
90
+ - { id: success-toast-duration, default: 5000 ms, may: "choose up to 8000 ms" }
91
+ - { id: message-wording, default: the texts under Content, may: "write its own, in its voice" }
92
+
93
+ situations:
94
+ - { situation: A form is sent with a required field empty, case: field-error }
95
+ - { situation: A field explains its format before it is filled, case: field-hint }
96
+ - { situation: The field is filled in correctly, case: field-valid }
97
+ - { situation: A list does not load, case: region-failed }
98
+ - { situation: A list shows data that are updated once a night, case: region-info }
99
+ - { situation: Saving a form in a dialog fails, case: action-failed-in-place }
100
+ - { situation: "Saving a form in a dialog works, and the dialog closes", case: action-done-elsewhere }
101
+ - { situation: An item is deleted from a list, case: action-done-elsewhere, note: "the default light toast (`removal-toast-neutral`)" }
102
+ - { situation: A link is copied, case: action-done-elsewhere }
103
+ - { situation: "Saving the details of a record, shown in its header and its tabs too, works", case: action-done-in-page }
104
+ - { situation: "Saving a card of settings that has its own Save, on a page that stays open, works", case: action-done-in-part }
105
+ - { situation: "Sending something from the menu of a row fails, after the menu closed", case: action-failed-elsewhere }
106
+ - { situation: An item is about to be deleted for good, case: decision }
107
+ - { situation: "The connection drops, then comes back", case: app-info }
108
+ - { situation: The server answers nothing at all, case: app-failed }
109
+ - { situation: "The session is about to end, with work not saved", case: app-deadline }
110
+ - { situation: "An export is ready minutes later, while the person works elsewhere", case: action-later }
111
+ - { situation: "A request is taken in charge; the answer comes by email", case: [action-taken, action-later], note: "the first at once, the second when the answer comes" }
112
+ - { situation: "An action on 20 items of a list on screen: 3 fail", case: action-partial-in-place }
113
+ - { situation: "An action on 20 items from a menu that closed: 3 fail", case: action-partial-elsewhere }
114
+ ---
115
+
116
+ # Where a message goes
117
+
118
+ **A message goes where the thing it talks about is.**
119
+
120
+ ## When to use it
121
+
122
+ Every message the application gives the person: the outcome of an action, a part of the page
123
+ that failed, the state of the whole application. Never internal messages, the raw text of an
124
+ HTTP status, or "coming soon".
125
+
126
+ ## What decides it
127
+
128
+ Six questions about the message: what it talks about (a field, a region of the page, an
129
+ action, the whole application), its outcome (success, failure, partial, information), whether
130
+ the thing it talks about is on screen when the message comes, whether the message comes now
131
+ or later, after the person moved on, whether the person has to choose before going on, and,
132
+ for an action, what it changed: data shown across the page, or a part that works on its own.
133
+
134
+ ## Cases
135
+
136
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
137
+
138
+ | Variable | Values | Means |
139
+ | --- | --- | --- |
140
+ | `about` | `field`, `region`, `action`, `application` | what the message talks about |
141
+ | `outcome` | `success`, `failure`, `partial`, `info` | what happened |
142
+ | `place` | `on-screen`, `off-screen` | is the thing it talks about on screen when the message comes |
143
+ | `timing` | `now`, `later` | later: the outcome comes after the person moved on |
144
+ | `decision` | `none`, `needed`, `deadline` | does the person have to choose before going on |
145
+ | `scope` | `page`, `part` | what an action changed: data shown across the page, or a part that works on its own |
146
+
147
+ A case that leaves a variable out holds for any of its values, except `decision`, which then means `none`.
148
+
149
+ | Case | When | Where | Use |
150
+ | --- | --- | --- | --- |
151
+ | `field-error` | about: field; outcome: failure; place: on-screen | under the field | `mds-input-field message` |
152
+ | `field-hint` | about: field; outcome: info; place: on-screen | under the field, its helper text; where an example of the value helps, the empty field shows one as its placeholder ("Es: Mario Rossi"); Magma gap: validation overwrites it | `mds-input-field message`, `mds-input placeholder` |
153
+ | `field-valid` | about: field; outcome: success; place: on-screen | no message, the field shows its valid state | `mds-input-field` |
154
+ | `region-failed` | about: region; outcome: failure | in that region, with Try again; what was there stays | `mds-banner variant=error tone=strong` |
155
+ | `region-info` | about: region; outcome: info | in that region | `mds-banner variant=info` |
156
+ | `action-failed-in-place` | about: action; outcome: failure; place: on-screen; timing: now | in its place, right above the row of actions of the dialog; what was written stays | `mds-banner variant=error tone=strong` |
157
+ | `action-done-elsewhere` | about: action; outcome: success; place: off-screen; timing: now | toast; the default light toast for a removal (`removal-toast-neutral`) | `mds-toast variant=success` |
158
+ | `action-done-in-page` | about: action; outcome: success; place: on-screen; timing: now; scope: page | toast; the default light toast for a removal (`removal-toast-neutral`) | `mds-toast variant=success` |
159
+ | `action-done-in-part` | about: action; outcome: success; place: on-screen; timing: now; scope: part | next to the part that was saved, inside it; Magma gap: no light confirmation that goes away | `mds-banner variant=success` |
160
+ | `action-failed-elsewhere` | about: action; outcome: failure; place: off-screen; timing: now | a toast that stays, with Try again | `mds-toast variant=error duration=0 dismissible` |
161
+ | `action-partial-in-place` | about: action; outcome: partial; place: on-screen; timing: now | as a failure in its place: a banner that says how many worked and which did not; see `error-recovery` | `mds-banner variant=error tone=strong` |
162
+ | `action-partial-elsewhere` | about: action; outcome: partial; place: off-screen; timing: now | as a failure elsewhere: a toast that stays, with what to do about the ones that did not work; see `error-recovery` | `mds-toast variant=error duration=0 dismissible` |
163
+ | `action-taken` | about: action; outcome: info; timing: now | toast: taken in charge, and how the outcome will come | `mds-toast variant=info` |
164
+ | `action-later` | about: action; timing: later | a toast with its action, which therefore stays; then kept in the notification center; see `notification-center` | `mds-toast duration=0 dismissible` |
165
+ | `decision` | decision: needed | dialog; see `confirm-action` | `mds-modal` |
166
+ | `app-info` | about: application; outcome: info; decision: none | a toast that goes after its time: `warning` for a trouble that does not stop the work (the connection dropped), `info` for news | `mds-toast variant=warning`, `mds-toast variant=info` |
167
+ | `app-failed` | about: application; outcome: failure | in place of the content of the page, with Try again; the shell stays; see `region-failed` | `mds-banner variant=error tone=strong` |
168
+ | `app-deadline` | about: application; decision: deadline | dialog, also over an open one; closing it means staying (`deadline-close` of actions) | `mds-modal`, `mds-banner slot=window variant=warning tone=box dismissible` |
169
+
170
+ Not applicable:
171
+
172
+ | When | Why |
173
+ | --- | --- |
174
+ | about: field; place: off-screen | a message about a field goes with its field |
175
+ | about: region; outcome: success | a region that loads shows its content, the content is the message |
176
+ | about: field or region or action; decision: deadline | a deadline is about the whole application |
177
+ | about: field or region or application; outcome: partial | a partial outcome is about an action on several items |
178
+ | about: application; outcome: success | an application does not succeed, its actions do |
179
+
180
+ No gaps: every combination has a case or is not applicable.
181
+
182
+ ## Parts
183
+
184
+ The toasts live in one `mds-toast-region` per application, at `bottom-center`, three at most.
185
+
186
+ ## Behaviour over time
187
+
188
+ - A toast never takes the focus: the region reads it out.
189
+ - Its timer stops while the pointer or the focus is on it.
190
+ - A toast with an action has no timer and can be sent away (`dismissible`).
191
+ - When a toast leaves with the focus inside it, the focus goes to the title of the page.
192
+ - When the element that opened a dialog is gone (the item just deleted), the focus goes to
193
+ the title of the page when the dialog closes: an `h1` with `tabindex="-1"`.
194
+
195
+ ## Always true
196
+
197
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
198
+
199
+ These hold in every product: a product layer cannot change them.
200
+
201
+ | Id | Rule | Checked by |
202
+ | --- | --- | --- |
203
+ | `no-toast-over-dialog` | Never a toast over an open dialog: what is about a dialog goes inside it. | review |
204
+ | `one-toast-region` | One mds-toast-region per application. | review |
205
+ | `toast-action-stays` | A toast with an action has duration="0" and dismissible. | review; lint `magma/toast-action-stays` to write |
206
+ | `no-dismissible-banner-in-dialog` | A banner inside an mds-modal is not dismissible: closing it closes the dialog, and what the person wrote is lost. | review; lint `magma/no-dismissible-banner-in-modal` to write |
207
+ | `success-after-change` | After every create, edit and delete the person is told it worked: a toast, or a confirmation next to the part when that part works on its own. | review |
208
+ | `removal-toast-neutral` | The toast of a removal (an item removed, archived, deleted after a confirmation), with or without Undo, is the default light toast: variant="success" is for what an action creates or completes. | review |
209
+ | `no-internal-text` | Never internal messages, HTTP status text or "coming soon". | review |
210
+
211
+ ## Open choices
212
+
213
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
214
+
215
+ The default decides these; a product layer may narrow them.
216
+
217
+ | Id | Default | A product may |
218
+ | --- | --- | --- |
219
+ | `success-toast-duration` | 5000 ms | choose up to 8000 ms |
220
+ | `message-wording` | the texts under Content | write its own, in its voice |
221
+
222
+ ## Situations
223
+
224
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
225
+
226
+ Situations every application has, each with its case: they give the examples, the texts and the keywords. The situations of a product's own domain go in its layer.
227
+
228
+ | Situation | Case |
229
+ | --- | --- |
230
+ | A form is sent with a required field empty | `field-error` |
231
+ | A field explains its format before it is filled | `field-hint` |
232
+ | The field is filled in correctly | `field-valid` |
233
+ | A list does not load | `region-failed` |
234
+ | A list shows data that are updated once a night | `region-info` |
235
+ | Saving a form in a dialog fails | `action-failed-in-place` |
236
+ | Saving a form in a dialog works, and the dialog closes | `action-done-elsewhere` |
237
+ | An item is deleted from a list | `action-done-elsewhere`: the default light toast (`removal-toast-neutral`) |
238
+ | A link is copied | `action-done-elsewhere` |
239
+ | Saving the details of a record, shown in its header and its tabs too, works | `action-done-in-page` |
240
+ | Saving a card of settings that has its own Save, on a page that stays open, works | `action-done-in-part` |
241
+ | Sending something from the menu of a row fails, after the menu closed | `action-failed-elsewhere` |
242
+ | An item is about to be deleted for good | `decision` |
243
+ | The connection drops, then comes back | `app-info` |
244
+ | The server answers nothing at all | `app-failed` |
245
+ | The session is about to end, with work not saved | `app-deadline` |
246
+ | An export is ready minutes later, while the person works elsewhere | `action-later` |
247
+ | A request is taken in charge; the answer comes by email | `action-taken`, `action-later`: the first at once, the second when the answer comes |
248
+ | An action on 20 items of a list on screen: 3 fail | `action-partial-in-place` |
249
+ | An action on 20 items from a menu that closed: 3 fail | `action-partial-elsewhere` |
250
+
251
+ ## Accessibility
252
+
253
+ - The region is a status region, in the page before any message: a toast is read out without
254
+ moving the focus. The button of a toast is reachable with the keyboard.
255
+ - An error banner is read out at once (`role="alert"`).
256
+ - An urgent message that is not a toast goes through a hidden `role="alert"` region.
257
+
258
+ ## Content
259
+
260
+ - An outcome names the object: "Mario Rossi deleted."
261
+ - An error says what did not happen and what to do: "Nothing was changed. Try again in a
262
+ moment."
263
+ - The placeholder of a field is an example of the value, "Es: Mario Rossi", never its label
264
+ or its hint: it goes at the first letter typed.
265
+
266
+ ## Magma gaps
267
+
268
+ - The hidden region for urgent messages is written by hand: an announcer next to
269
+ `mds-toast-region`? (to decide)
270
+ - `mds-toast` shows its text only when it has one at load, a gap left by #688 (to verify).
271
+ - The helper text of a field goes in the `message` of `mds-input-field`, which the validation
272
+ overwrites: the help is gone at the first check. A hint of its own, kept next to the errors?
273
+ (an issue to open)
274
+ - A light confirmation next to a part ("Saved" by its button), read out and then gone: Magma
275
+ has none, only `mds-banner`, which stays. (to decide whether it is needed)
276
+ - The notification center: `mds-push-notification` is a stack of messages with its own
277
+ "Clear notifications"; whether it can be a list to come back to is for the pattern
278
+ `notification-center` to verify.
279
+
280
+ ## Decisions
281
+
282
+ | Date | Decision | Why |
283
+ | --- | --- | --- |
284
+ | 2026-10-16 | The rule and the table of cases | A message read far from what it is about is missed or misread. |
285
+ | 2026-10-16 | To confirm: the session ending is a strict dialog, also over an open one; agreed first as a toast | A toast over an open dialog can be seen but not used. |
286
+ | 2026-10-27 | Id `message-placement`, group Messages and states (was Feedback) | "Feedback" read as the person telling the product something. |
287
+ | 2026-10-27 | `toast-action-stays` and `no-dismissible-banner-in-dialog` become lint rules | Both show in the markup; the second one loses data. |
288
+ | 2026-10-28 | The default is defined on variables of the situation, with situations every application has; no domain; real cases come later, as a validation | A domain scenario brought business rules into a default. |
289
+ | 2026-10-28 | To confirm: `field-valid` and `action-done-in-place`, two cases the variables showed and the table did not say | The table covered a field that fails and an action whose place is gone, not their other halves. |
290
+ | 2026-10-28 | A deadline is about the whole application; a partial outcome is about an action on several items; the cases of a field hold with the field on screen | Found by the check: 58 combinations that had no answer and no meaning. |
291
+ | 2026-10-28 | Information about a region goes in that region, as an info banner (`region-info`) | The rule: a message goes where the thing it talks about is. |
292
+ | 2026-10-28 | The whole application failing is a region that failed, the largest one: the shell stays (`app-failed`) | No new case for the same answer; the person keeps the menu and the way out. |
293
+ | 2026-10-28 | Information about a field is its helper text; an application does not succeed; information about an action joins the gap "later" | The last combinations the check found with no answer. |
294
+ | 2026-10-28 | Confirmed: a valid field shows its state and no message (`field-valid`); the session ending is a strict dialog, also over an open one (`app-deadline`); strict superseded on 2026-11-01 | Magma already does the first; a toast over an open dialog can be seen but not used. |
295
+ | 2026-10-28 | A success whose place stays on screen depends on what the action changed: data shown across the page, a toast (`action-done-in-page`); a part that works on its own, a confirmation next to it (`action-done-in-part`). `success-after-change` rewritten to match | A change that shows in many places is not "here"; an independent part is, and the confirmation belongs to it. |
296
+ | 2026-10-28 | To decide: the two gaps, later and partial | An outcome that comes later may belong to the candidate "Notification center"; a partial one to `error-recovery`. |
297
+ | 2026-10-28 | An outcome that comes later is a toast with its action, kept in the notification center (`action-later`); an action taken in charge says so at once (`action-taken`) | The person may have moved on or left: told when it comes, found again later. The notification center becomes a pattern of its own. |
298
+ | 2026-10-28 | A partial outcome goes where a failure goes (`action-partial-in-place`, `action-partial-elsewhere`); what to say and how to retry the ones that failed is `error-recovery` | The same places as a failure; the difference is in the text and in the retry. |
299
+ | 2026-11-01 | The toast of a removal, with or without Undo, is the default `light` toast; `success` is for what an action creates or completes (`removal-toast-neutral`) | A removal is a loss the person wanted, and green celebrates it; the colour follows the kind of action, not the presence of Undo. Chosen live with the domain Actions of the design language. https://github.com/magma-design-system/magma/issues/1189#issuecomment-6556983924 |
300
+ | 2026-11-01 | The session ending is a dialog that closes as Resta collegato: the default `interaction`, the `warning` window with its X; `strict` goes (`app-deadline`) | No gesture loses the work, and Esc closes it as every dialog; the focus and the meaning of closing are `deadline-close` of the domain Actions. Chosen live with the domain Actions of the design language. https://github.com/magma-design-system/magma/issues/1189#issuecomment-6558535505 |
301
+ | 2026-11-03 | An error that stops the person is `tone="strong"` in every place: a part that does not load as an action that fails (`region-failed`, `action-failed-in-place`, `action-partial-in-place`, `app-failed`) | One tone for every error; the weak tone of the drafts of 2026-10-29 read as a note. Chosen in review round 2 of the previews (https://github.com/magma-design-system/magma/issues/1233), over the weak tone. |
302
+ | 2026-11-03 | The error of a dialog stands right above its row of actions (`action-failed-in-place`) | Where the eye goes to try again; the place `actions` decided for the error of an action. Confirmed in review round 2 of the previews: https://github.com/magma-design-system/magma/issues/1233 |
303
+ | 2026-11-03 | The connection that drops is a `warning` toast that goes after its time (`app-info`) | A trouble that does not stop the work is a warning, not news; and what was written stays, so the toast need not stay. Chosen in review round 2 of the previews (https://github.com/magma-design-system/magma/issues/1233), over a toast that stays while the connection is off. |
304
+ | 2026-11-03 | Where an example of the value helps, the empty field shows one as its placeholder, "Es: ..." (`field-hint`) | The person sees the shape of the value before typing it; the hint under the field still says the rule. Asked in review round 2 of the previews: https://github.com/magma-design-system/magma/issues/1233 |
@@ -0,0 +1,18 @@
1
+ ---
2
+ # A Magma pattern: the format and the commands are in docs/PATTERNS.md.
3
+ id: notification-center
4
+ kind: pattern
5
+ title: Notification center
6
+ group: messages-and-states
7
+ layer: magma
8
+ status: candidate
9
+ need: >-
10
+ The person comes back to the outcomes that arrived while they were elsewhere, and to what they
11
+ still have to act on.
12
+ ---
13
+
14
+ # Notification center
15
+
16
+ A candidate: a need Magma knows and has not defined yet, cited by `message-placement` (`action-
17
+ later`). Until it is defined, the agent says that no default covers it, and proposes the pattern
18
+ (`get_guide reporting`).