@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,237 @@
1
+ ---
2
+ # A Magma pattern: the format and the commands are in docs/PATTERNS.md.
3
+ id: error-recovery
4
+ kind: pattern
5
+ title: When something fails
6
+ group: messages-and-states
7
+ layer: magma
8
+ status: decided
9
+ need: >-
10
+ Something did not work, and the person must understand what did not happen and go on without
11
+ losing their work.
12
+ principle: >-
13
+ A failure keeps what the person did, says what did not happen, and gives a way on: Try again
14
+ when it may work, another way when it cannot.
15
+ keywords: [error, failed, could not load, could not save, try again, retry, connection lost, not saved, session expired, conflict]
16
+ not-for:
17
+ - need: where the error message goes
18
+ use: message-placement
19
+ - need: a field with a wrong value
20
+ use: form-and-validation
21
+ - need: a list with no results
22
+ use: empty-state
23
+ - need: merging the changes of two people on the same record
24
+ use: concurrent-editing
25
+ assumptions:
26
+ - The application can tell a failure that trying again may fix from one it cannot.
27
+ high-stakes: false
28
+ components: [mds-banner, mds-toast, mds-button, mds-zero, mds-input-field]
29
+ related: [message-placement, loading, empty-state, confirm-action, form-and-validation, concurrent-editing]
30
+ validated-on: []
31
+
32
+ variables:
33
+ what: { values: [content, action], means: "content: data a part of the page loads; action: an operation the person started" }
34
+ cause: { values: [transient, lasting, conflict, session], means: "transient: the network or the server failed, trying again may work; lasting: trying again fails the same way (no permission, the item is gone, the data is refused); conflict: someone else changed the same thing meanwhile; session: the session ended" }
35
+ known: { values: ["yes", "no"], means: "does the application know what happened (no: the connection dropped after sending)" }
36
+ items: { values: [one, many], means: "how many items the action acts on" }
37
+
38
+ cases:
39
+ - { id: retry-content, what: content, cause: transient, known: "yes", where: "what was there stays; an error banner in that part with Try again; when it works, the banner goes", use: ["mds-banner variant=error tone=strong", "mds-button slot=action await"] }
40
+ - { id: content-another-way, what: content, cause: lasting, known: "yes", where: "no Try again: says why and gives another way (the not-found of empty-state for a thing that is gone; who can give access)", use: ["mds-banner variant=error tone=strong", "mds-zero"] }
41
+ - { id: retry-action, what: action, cause: transient, known: "yes", items: one, where: "says nothing was changed; what was written stays; in the place message-placement gives: a banner in place, right above the row, whose action on screen is the new try, so the banner has no Try again of its own; or a toast that stays, with Try again", use: ["mds-banner variant=error tone=strong", "mds-toast variant=error duration=0 dismissible"] }
42
+ - { id: action-another-way, what: action, cause: lasting, known: "yes", items: one, where: "no Try again: says why and gives another way (the errors on the fields for refused data; who can do it; back to the list for a thing that is gone)", use: ["mds-banner variant=error", "mds-input-field message"] }
43
+ - { id: check-or-repeat, what: action, cause: transient, known: "no", where: "Try again at once when repeating does no harm (saving the same values); otherwise the application first asks the server what happened, then tells it: done as a success, not done as retry-action, the action on screen being the new try", use: ["mds-banner variant=error tone=strong", "mds-toast variant=error duration=0 dismissible"] }
44
+ - { id: changed-meanwhile, what: action, cause: conflict, known: "yes", where: "never overwrite in silence: says who changed it and when, that nothing was saved, and the changes of the person stay on screen", use: ["mds-banner variant=error tone=strong"], see: concurrent-editing }
45
+ - { id: sign-in-again, cause: session, known: "yes", where: "says the session ended and nothing was saved; Sign in, alone in the banner, opens the sign-in in a new tab, and the action that failed is hidden until the session is back, so it cannot fail again; back on the page the banner goes and the action comes back: the work never leaves the page", use: ["mds-banner variant=error tone=strong", "mds-button slot=action href target=blank"] }
46
+ - { id: partial, what: action, cause: [transient, lasting], known: "yes", items: many, where: "says how many worked and which did not, and why; Try again acts only on those that failed for a transient cause", use: ["mds-banner variant=error tone=strong", "mds-toast variant=error duration=0 dismissible"] }
47
+ gaps: []
48
+ not-applicable:
49
+ - { what: content, cause: conflict, why: "loading changes nothing: there is nothing to conflict with" }
50
+ - { what: content, known: "no", why: "loading changes nothing: the outcome is always known" }
51
+ - { cause: [lasting, conflict, session], known: "no", why: "the server answered: the outcome is known" }
52
+
53
+ always-true:
54
+ - id: keep-the-work
55
+ rule: A failure never loses what the person wrote or chose.
56
+ checked-by: review
57
+ - id: says-what-did-not-happen
58
+ rule: The error says what did not happen and what to do.
59
+ checked-by: review
60
+ - id: retry-only-if-it-may-work
61
+ rule: Try again only when trying again may work; otherwise another way.
62
+ checked-by: review
63
+ - id: no-raw-error
64
+ rule: Never the raw text of an HTTP status or an exception.
65
+ checked-by: review
66
+ - id: no-repeat-by-itself
67
+ rule: An action is never repeated by itself, unless repeating it does no harm.
68
+ checked-by: review
69
+ - id: no-silent-overwrite
70
+ rule: A save never overwrites a change made by someone else without saying so.
71
+ checked-by: review
72
+ - id: no-dismissible-banner-in-dialog
73
+ from: message-placement
74
+
75
+ open-choices:
76
+ - { id: support-contact, default: "none: the text says to try again later", may: "say who to contact when the problem stays (\"If the problem stays, write to the help desk\")" }
77
+
78
+ situations:
79
+ - { situation: A list does not load, case: retry-content }
80
+ - { situation: "A record opens, and the person may not see it", case: content-another-way }
81
+ - { situation: Saving a form fails on the server, case: retry-action }
82
+ - { situation: A form is refused by the server because a code is already in use, case: action-another-way }
83
+ - { situation: "12 items are archived, 3 fail", case: partial }
84
+ - { situation: A save fails because the session ended, case: sign-in-again }
85
+ - { situation: The connection drops while a message is being sent, case: check-or-repeat, note: the application checks first }
86
+ - { situation: The connection drops while a form is saved, case: check-or-repeat, note: Try again at once }
87
+ - { situation: "A record is saved, and someone else had changed it meanwhile", case: changed-meanwhile }
88
+ ---
89
+
90
+ # When something fails
91
+
92
+ **A failure keeps what the person did, says what did not happen, and gives a way on: Try again when it may work, another way when it cannot.**
93
+
94
+ ## When to use it
95
+
96
+ A load or an action that failed: the network, the server, a permission, a thing that is gone,
97
+ a change made by someone else, a session that ended. Where the message goes is
98
+ `message-placement`; this pattern is what follows. Not a field with a wrong value
99
+ (`form-and-validation`), not a list with no results (`empty-state`): no results is not an error.
100
+
101
+ ## What decides it
102
+
103
+ Four questions: whether a load or an action failed, why (trying again may work, it will fail
104
+ the same way, someone else changed the same thing, the session ended), whether the application
105
+ knows what happened, and whether the action was on one item or many.
106
+
107
+ ## Cases
108
+
109
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
110
+
111
+ | Variable | Values | Means |
112
+ | --- | --- | --- |
113
+ | `what` | `content`, `action` | content: data a part of the page loads; action: an operation the person started |
114
+ | `cause` | `transient`, `lasting`, `conflict`, `session` | transient: the network or the server failed, trying again may work; lasting: trying again fails the same way (no permission, the item is gone, the data is refused); conflict: someone else changed the same thing meanwhile; session: the session ended |
115
+ | `known` | `yes`, `no` | does the application know what happened (no: the connection dropped after sending) |
116
+ | `items` | `one`, `many` | how many items the action acts on |
117
+
118
+ A case that leaves a variable out holds for any of its values.
119
+
120
+ | Case | When | Where | Use |
121
+ | --- | --- | --- | --- |
122
+ | `retry-content` | what: content; cause: transient; known: yes | what was there stays; an error banner in that part with Try again; when it works, the banner goes | `mds-banner variant=error tone=strong`, `mds-button slot=action await` |
123
+ | `content-another-way` | what: content; cause: lasting; known: yes | no Try again: says why and gives another way (the not-found of empty-state for a thing that is gone; who can give access) | `mds-banner variant=error tone=strong`, `mds-zero` |
124
+ | `retry-action` | what: action; cause: transient; known: yes; items: one | says nothing was changed; what was written stays; in the place message-placement gives: a banner in place, right above the row, whose action on screen is the new try, so the banner has no Try again of its own; or a toast that stays, with Try again | `mds-banner variant=error tone=strong`, `mds-toast variant=error duration=0 dismissible` |
125
+ | `action-another-way` | what: action; cause: lasting; known: yes; items: one | no Try again: says why and gives another way (the errors on the fields for refused data; who can do it; back to the list for a thing that is gone) | `mds-banner variant=error`, `mds-input-field message` |
126
+ | `check-or-repeat` | what: action; cause: transient; known: no | Try again at once when repeating does no harm (saving the same values); otherwise the application first asks the server what happened, then tells it: done as a success, not done as retry-action, the action on screen being the new try | `mds-banner variant=error tone=strong`, `mds-toast variant=error duration=0 dismissible` |
127
+ | `changed-meanwhile` | what: action; cause: conflict; known: yes | never overwrite in silence: says who changed it and when, that nothing was saved, and the changes of the person stay on screen; see `concurrent-editing` | `mds-banner variant=error tone=strong` |
128
+ | `sign-in-again` | cause: session; known: yes | says the session ended and nothing was saved; Sign in, alone in the banner, opens the sign-in in a new tab, and the action that failed is hidden until the session is back, so it cannot fail again; back on the page the banner goes and the action comes back: the work never leaves the page | `mds-banner variant=error tone=strong`, `mds-button slot=action href target=blank` |
129
+ | `partial` | what: action; cause: transient or lasting; known: yes; items: many | says how many worked and which did not, and why; Try again acts only on those that failed for a transient cause | `mds-banner variant=error tone=strong`, `mds-toast variant=error duration=0 dismissible` |
130
+
131
+ Not applicable:
132
+
133
+ | When | Why |
134
+ | --- | --- |
135
+ | what: content; cause: conflict | loading changes nothing: there is nothing to conflict with |
136
+ | what: content; known: no | loading changes nothing: the outcome is always known |
137
+ | cause: lasting or conflict or session; known: no | the server answered: the outcome is known |
138
+
139
+ No gaps: every combination has a case or is not applicable.
140
+
141
+ ## Parts
142
+
143
+ - An error banner, `mds-banner` with `variant="error" tone="strong"`, in the place
144
+ `message-placement` gives: a title that says what did not happen, a sentence with what to do,
145
+ and Try again (`mds-button` in its `action` slot) when trying again may work. Where the action
146
+ that failed is on screen (a form, a dialog), the banner stands right above its row and has no
147
+ Try again: the action itself is the new try.
148
+ - When the place is gone, a toast that stays, with Try again (`message-placement`,
149
+ `action-failed-elsewhere`).
150
+ - For a thing that is gone, the not-found panel of `empty-state`.
151
+ - For an ended session, Sign in alone in the banner: the sign-in opens in a new tab, so the
152
+ page and what was written stay where they are; the action that failed is hidden until the
153
+ session is back, then the banner goes and the action comes back.
154
+
155
+ ## Behaviour over time
156
+
157
+ - What was on screen stays, and what was written stays.
158
+ - Try again waits (`await`), and when it works the banner goes.
159
+ - From the third failure in a row on the same thing, the text says to try again later; Try
160
+ again stays.
161
+ - An action whose outcome is unknown is repeated at once only when repeating does no harm;
162
+ otherwise the application asks the server first. A payment follows the rule of high-stakes
163
+ flows: no default decides for the person.
164
+
165
+ ## Always true
166
+
167
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
168
+
169
+ These hold in every product: a product layer cannot change them.
170
+
171
+ | Id | Rule | Checked by |
172
+ | --- | --- | --- |
173
+ | `keep-the-work` | A failure never loses what the person wrote or chose. | review |
174
+ | `says-what-did-not-happen` | The error says what did not happen and what to do. | review |
175
+ | `retry-only-if-it-may-work` | Try again only when trying again may work; otherwise another way. | review |
176
+ | `no-raw-error` | Never the raw text of an HTTP status or an exception. | review |
177
+ | `no-repeat-by-itself` | An action is never repeated by itself, unless repeating it does no harm. | review |
178
+ | `no-silent-overwrite` | A save never overwrites a change made by someone else without saying so. | review |
179
+ | `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. (from `message-placement`) | review; lint `magma/no-dismissible-banner-in-modal` to write |
180
+
181
+ ## Open choices
182
+
183
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
184
+
185
+ The default decides these; a product layer may narrow them.
186
+
187
+ | Id | Default | A product may |
188
+ | --- | --- | --- |
189
+ | `support-contact` | none: the text says to try again later | say who to contact when the problem stays ("If the problem stays, write to the help desk") |
190
+
191
+ ## Situations
192
+
193
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
194
+
195
+ 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.
196
+
197
+ | Situation | Case |
198
+ | --- | --- |
199
+ | A list does not load | `retry-content` |
200
+ | A record opens, and the person may not see it | `content-another-way` |
201
+ | Saving a form fails on the server | `retry-action` |
202
+ | A form is refused by the server because a code is already in use | `action-another-way` |
203
+ | 12 items are archived, 3 fail | `partial` |
204
+ | A save fails because the session ended | `sign-in-again` |
205
+ | The connection drops while a message is being sent | `check-or-repeat`: the application checks first |
206
+ | The connection drops while a form is saved | `check-or-repeat`: Try again at once |
207
+ | A record is saved, and someone else had changed it meanwhile | `changed-meanwhile` |
208
+
209
+ ## Accessibility
210
+
211
+ - An error banner is read out at once (`role="alert"`, `mds-banner` error).
212
+ - The focus stays on the control that was waiting; Try again takes it only when the person
213
+ moves to it.
214
+
215
+ ## Content
216
+
217
+ - What did not happen, then what to do: "The users could not be loaded. Check the connection,
218
+ then try again." "Nothing was changed."
219
+ - For many items, how many and which: "9 archived, 3 not: they are open in another window."
220
+
221
+ ## Magma gaps
222
+
223
+ None blocking: retrying is logic of the application.
224
+
225
+ ## Decisions
226
+
227
+ | Date | Decision | Why |
228
+ | --- | --- | --- |
229
+ | 2026-10-16 | Where the error goes is `message-placement`; this pattern is what follows | One answers where, the other what stays, how to retry, when to stop. |
230
+ | 2026-10-28 | Draft with variables; the ended session, the unknown outcome, the conflict and several failures in a row left as gaps | The sources do not settle them. |
231
+ | 2026-10-28 | An ended session signs in again in a new tab, then Try again (`sign-in-again`) | The work never leaves the page; it works with an external single sign-on too. |
232
+ | 2026-10-28 | An unknown outcome is repeated at once only when repeating does no harm; otherwise the server is asked first (`check-or-repeat`) | A blind Try again can send or create twice. |
233
+ | 2026-10-28 | A change made by someone else meanwhile: here only the rule (`no-silent-overwrite`, `changed-meanwhile`); merging is the candidate `concurrent-editing` | Locks, versions and merging are a pattern of their own. |
234
+ | 2026-10-28 | From the third failure in a row, the text says to try again later; who to contact is a product's choice (`support-contact`) | Insisting with the same text does not help; the help desk differs by product. |
235
+ | 2026-11-03 | An error that stops the person is `tone="strong"` (`retry-content`, `content-another-way`, `retry-action`, `check-or-repeat`, `changed-meanwhile`, `sign-in-again`, `partial`) | One tone for every error, as `message-placement`. Chosen in review round 2 of the previews (https://github.com/magma-design-system/magma/issues/1233), over the weak tone. |
236
+ | 2026-11-03 | Where the action that failed is on screen, its banner has no Try again: the action is the new try (`retry-action`, `check-or-repeat`) | Two buttons that do the same thing; the rule `failed` of the domain Actions. Applied in review round 2 of the previews: https://github.com/magma-design-system/magma/issues/1233 |
237
+ | 2026-11-03 | An ended session shows Sign in alone, in the banner, and hides the action that failed until the session is back (`sign-in-again`) | The action would fail again until the person signs in: it is not offered. Asked in review round 2 of the previews: https://github.com/magma-design-system/magma/issues/1233 |
@@ -0,0 +1,16 @@
1
+ ---
2
+ # A Magma pattern: the format and the commands are in docs/PATTERNS.md.
3
+ id: form-and-validation
4
+ kind: pattern
5
+ title: Form and validation
6
+ group: input
7
+ layer: magma
8
+ status: candidate
9
+ need: >-
10
+ The person fills in a form, sees what is wrong and where, and sends it.
11
+ ---
12
+
13
+ # Form and validation
14
+
15
+ A candidate: a need Magma knows and has not defined yet, cited by `error-recovery`. Until it is
16
+ defined, the agent says that no default covers it, and proposes the pattern (`get_guide reporting`).
@@ -0,0 +1,214 @@
1
+ ---
2
+ # A Magma building block: the format and the commands are in docs/PATTERNS.md, "A building block".
3
+ id: item-list
4
+ kind: block
5
+ title: Item list
6
+ group: data
7
+ layer: magma
8
+ status: decided
9
+ need: >-
10
+ The person sees a set of items, narrows it to the ones they need, knows how many there are,
11
+ and reaches the rest.
12
+ principle: "The search on top, then how many, then the items, then the pages: the same order in every list."
13
+ keywords: [list, list of items, results, search form, filter bar, filters, results summary, how many, table of items, list of cards, pages, pagination, sub-list, select rows, batch actions, new items]
14
+ not-for:
15
+ - need: the head of the page that holds the list, its title and its actions (New, Export)
16
+ use: page-header
17
+ - need: choosing items from a list for something else (members to add to a group, documents to attach)
18
+ use: choose-items
19
+ assumptions:
20
+ - The back end can search, count, sort and page the set (list-with-filters).
21
+ high-stakes: false
22
+ components: [mds-input, mds-input-field, mds-input-select, mds-filter, mds-filter-item, mds-notification, mds-text, mds-button, mds-table, mds-table-header-cell, mds-file, mds-paginator]
23
+ used-by: [list-with-filters, empty-state, loading]
24
+ related: [list-with-filters, empty-state, loading, error-recovery, page-header, choose-items]
25
+ validated-on: []
26
+
27
+ variables:
28
+ size: { values: [few, many], means: "few: the items fit in one page and are read at a glance (the documents of a request, the members of a small group); many: more than a page, to search and to page through" }
29
+ goal: { values: [open, act], means: "open: the person opens one item at a time; act: the person acts on several items at once (assign, archive)" }
30
+ changes: { values: ["no", by-others], means: "by-others: other people or systems add or change items while the list is on screen (a queue of incoming requests)" }
31
+
32
+ regions:
33
+ - { id: search, when: { size: many }, what: "the search form: a field that searches the number and the name, then a select for each property with a few values, as short fields under it, two to a row, in a group of fields at the width of a form", use: ["mds-input type=search", "mds-input-field", "mds-input-select"] }
34
+ - { id: filters, when: { size: many }, what: "the statuses as one filter, each with how many items it would show, in the search form under its fields, when the items have a status", use: ["mds-filter", "mds-filter-item"] }
35
+ - { id: summary, when: { size: many }, what: "one line: which items are on screen out of how many (\"11-20 di 46 pratiche\"), read out after every change, with Rimuovi i filtri when there are any", use: ["mds-text typography=detail tag=p", "mds-button variant=dark tone=text size=sm"] }
36
+ - { id: new-items, when: { changes: by-others }, what: "at the end of the line of the summary: how many items are new, the count in an info dot that pulses when it grows and the words in the info colour, and Mostra; the line keeps its place while nothing is new; Mostra hides once pressed and the focus goes to the heading of the list (list-with-filters, show-new-items)", use: ["mds-notification variant=info pulse", "mds-text typography=detail", "mds-button variant=info tone=outline size=sm"] }
37
+ - { id: selection, when: { goal: act }, what: "a checkbox on each row and the bar of the batch actions, with how many are selected (list-with-filters, act-on-many)", use: ["mds-table selectable", "mds-button slot=batch-action"] }
38
+ - { id: results, required: true, what: "the items: one row each, its number or its name the link to its page; the columns that can order the list order it from their headers; files as mds-file, one per file, in a grid; cards in a grid when the items are seen rather than read (results-as-cards)", use: ["mds-table sorting=external", "mds-table-header-cell sortable sort-key", "mds-file"] }
39
+ - { id: pages, when: { size: many }, what: "the pages, under the items, only when there is more than one", use: ["mds-paginator"] }
40
+
41
+ always-true:
42
+ - id: same-order
43
+ rule: "The search form, the summary, the items, the pages: in this order in every list; a region with nothing to show is left out, with its space."
44
+ checked-by: review
45
+ - id: order-in-the-headers
46
+ rule: "The order of the list is set from the headers of the columns that can sort it, never by a field of the search form."
47
+ checked-by: review
48
+ - id: frame-wide-results
49
+ rule: "The fields of the search form stand at the width of a form, the filter of the statuses as wide as its statuses; the items take the whole frame of the page or of their section."
50
+ checked-by: review
51
+ - id: summary-says-how-many
52
+ from: list-with-filters
53
+ - id: link-names-the-item
54
+ from: list-with-filters
55
+ - id: nothing-moves-by-itself
56
+ from: list-with-filters
57
+ - id: form
58
+ from: widths
59
+ - id: between-groups
60
+ from: rhythm
61
+ - id: between-fields
62
+ from: rhythm
63
+ - id: title-content
64
+ from: rhythm
65
+
66
+ open-choices:
67
+ - { id: results-as-cards, default: "a table, one row per item", may: "show the items as cards in a grid (mds-card) when they are seen rather than read: pictures, documents, people" }
68
+
69
+ situations:
70
+ - { id: requests-of-an-office, situation: "The requests of an office, opened one at a time", size: many, goal: open, changes: "no" }
71
+ - { id: requests-to-assign, situation: "Requests to assign to an operator, several at once", size: many, goal: act, changes: "no" }
72
+ - { id: queue-of-a-desk, situation: "The queue of a front desk, where requests arrive while it is open", size: many, goal: open, changes: by-others }
73
+ - { id: documents-of-a-request, situation: "The documents of a request, a section of its page", size: few, goal: open, changes: "no" }
74
+ ---
75
+
76
+ # Item list
77
+
78
+ **The search on top, then how many, then the items, then the pages: the same order in every list.**
79
+
80
+ ## When to use it
81
+
82
+ Wherever a page shows a set of items: the list of the requests of an office, the queue of a
83
+ desk, the documents of a request in a section of its page. It came out of the round of the
84
+ building blocks (2026-11-03): the search form, the summary and the results come back in the same
85
+ arrangement in `list-with-filters`, in `empty-state` (`clear-filters`: the panel takes the place
86
+ of the results, the search and the summary stay) and in `loading` (`keep-while-reloading`: the
87
+ results stay while the search reloads them). One block, not a bar of filters and a summary
88
+ apart: the regions always come together, in one order, and their spaces relate. The behaviour
89
+ over time (the query in the address, the first page after a change, the newest answer wins) is
90
+ `list-with-filters`; the block is where each part stands. Not the head of the page that holds
91
+ the list (`page-header`).
92
+
93
+ ## What decides it
94
+
95
+ Three questions: whether the items fit in one page (then there is nothing to search nor to
96
+ page), whether the person acts on several at once (then they select them), and whether others
97
+ change the set while it is on screen (then the new items wait behind a line).
98
+
99
+ ## Regions
100
+
101
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
102
+
103
+ | Variable | Values | Means |
104
+ | --- | --- | --- |
105
+ | `size` | `few`, `many` | few: the items fit in one page and are read at a glance (the documents of a request, the members of a small group); many: more than a page, to search and to page through |
106
+ | `goal` | `open`, `act` | open: the person opens one item at a time; act: the person acts on several items at once (assign, archive) |
107
+ | `changes` | `no`, `by-others` | by-others: other people or systems add or change items while the list is on screen (a queue of incoming requests) |
108
+
109
+ A region shows where its When holds, in this order: a required one always, the others when there is something to put in them.
110
+
111
+ | Region | When | Required | What | Use |
112
+ | --- | --- | --- | --- | --- |
113
+ | `search` | size: many | | the search form: a field that searches the number and the name, then a select for each property with a few values, as short fields under it, two to a row, in a group of fields at the width of a form | `mds-input type=search`, `mds-input-field`, `mds-input-select` |
114
+ | `filters` | size: many | | the statuses as one filter, each with how many items it would show, in the search form under its fields, when the items have a status | `mds-filter`, `mds-filter-item` |
115
+ | `summary` | size: many | | one line: which items are on screen out of how many ("11-20 di 46 pratiche"), read out after every change, with Rimuovi i filtri when there are any | `mds-text typography=detail tag=p`, `mds-button variant=dark tone=text size=sm` |
116
+ | `new-items` | changes: by-others | | at the end of the line of the summary: how many items are new, the count in an info dot that pulses when it grows and the words in the info colour, and Mostra; the line keeps its place while nothing is new; Mostra hides once pressed and the focus goes to the heading of the list (list-with-filters, show-new-items) | `mds-notification variant=info pulse`, `mds-text typography=detail`, `mds-button variant=info tone=outline size=sm` |
117
+ | `selection` | goal: act | | a checkbox on each row and the bar of the batch actions, with how many are selected (list-with-filters, act-on-many) | `mds-table selectable`, `mds-button slot=batch-action` |
118
+ | `results` | any | yes | the items: one row each, its number or its name the link to its page; the columns that can order the list order it from their headers; files as mds-file, one per file, in a grid; cards in a grid when the items are seen rather than read (results-as-cards) | `mds-table sorting=external`, `mds-table-header-cell sortable sort-key`, `mds-file` |
119
+ | `pages` | size: many | | the pages, under the items, only when there is more than one | `mds-paginator` |
120
+
121
+ ## Layout
122
+
123
+ - The block is one column of two groups, `gap-between-groups` (1000) between them
124
+ (`rhythm/between-groups`): the search form, then the items.
125
+ - The search form is a `form role="search"`, its fields in a `field-group` at `max-w-form`
126
+ (`widths/form`): the search field, then the selects as `short` fields under it, two to a
127
+ row; the filter of the statuses under them, aligned to the start, as wide as its statuses;
128
+ `gap-between-fields` (600) between the fields and the filter.
129
+ - The items group: the summary line, then the items, `gap-title-content` (300) between them, as
130
+ a title and the content it names (`rhythm/title-content`); the pages under the items,
131
+ `gap-between-fields` (600), aligned to the start.
132
+ - The summary line is a row: the summary, Rimuovi i filtri beside it (`gap-inline`), and at its
133
+ end the line of the new items; on a narrow screen the line of the new items sits under the
134
+ summary from the start, so neither its arrival nor its count moves the items.
135
+ - The items take the whole width of the frame or of their section (`w-full`); a table wider
136
+ than a phone scrolls inside its own border, never the page, with its cells on one line
137
+ (`[&_mds-table-cell]:text-nowrap`, as the usage of `mds-table` says).
138
+ - With few items there is no search, no summary and no pages: the items stand right under the
139
+ title of their section.
140
+ - Files are `mds-file`, one per file, in a grid at `gap-between-containers` (400): one column,
141
+ two from `@2xl` of their section, as `record-detail` lays out its documents.
142
+ - When nothing matches, the panel of `empty-state` (`clear-filters`) takes the place of the
143
+ items, and the search and the summary stay; on the first load, the well of `loading` takes it.
144
+
145
+ ## Always true
146
+
147
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
148
+
149
+ These hold in every product: a product layer cannot change them.
150
+
151
+ | Id | Rule | Checked by |
152
+ | --- | --- | --- |
153
+ | `same-order` | The search form, the summary, the items, the pages: in this order in every list; a region with nothing to show is left out, with its space. | review |
154
+ | `order-in-the-headers` | The order of the list is set from the headers of the columns that can sort it, never by a field of the search form. | review |
155
+ | `frame-wide-results` | The fields of the search form stand at the width of a form, the filter of the statuses as wide as its statuses; the items take the whole frame of the page or of their section. | review |
156
+ | `summary-says-how-many` | The summary says which items are on screen out of how many, and is read out after every change. (from `list-with-filters`) | review |
157
+ | `link-names-the-item` | Each item is opened by a link that names it, never by an Open repeated on every row. (from `list-with-filters`) | review |
158
+ | `nothing-moves-by-itself` | Items added or changed by others never move what is on screen; they wait until the person asks for them. (from `list-with-filters`) | review |
159
+ | `form` | `max-w-form` on the form, the width of the text around it (`56ch`, 532 px at 16 px); its fields take the whole column, and its row of actions stands at the end of the column (`actions/place`) (from `widths`) | |
160
+ | `between-groups` | `gap-between-groups` (1000) between two groups of fields of one form (the fieldsets of personal data and of residence) (from `rhythm`) | |
161
+ | `between-fields` | `gap-between-fields` (600) between two fields of a form, or two rows of data (from `rhythm`) | |
162
+ | `title-content` | `gap-title-content` (300) between a title and the content it names (from `rhythm`) | |
163
+
164
+ ## Open choices
165
+
166
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
167
+
168
+ The default decides these; a product layer may narrow them.
169
+
170
+ | Id | Default | A product may |
171
+ | --- | --- | --- |
172
+ | `results-as-cards` | a table, one row per item | show the items as cards in a grid (mds-card) when they are seen rather than read: pictures, documents, people |
173
+
174
+ ## Situations
175
+
176
+ <!-- Generated from the frontmatter: edit it there, then run nx run stencil:generate.pattern -- --sync. -->
177
+
178
+ Situations every application has, each with the regions it shows: they give the examples, the texts and the keywords. The situations of a product's own domain go in its layer.
179
+
180
+ | Id | Situation | Regions |
181
+ | --- | --- | --- |
182
+ | `requests-of-an-office` | The requests of an office, opened one at a time | `search`, `filters`, `summary`, `results`, `pages` |
183
+ | `requests-to-assign` | Requests to assign to an operator, several at once | `search`, `filters`, `summary`, `selection`, `results`, `pages` |
184
+ | `queue-of-a-desk` | The queue of a front desk, where requests arrive while it is open | `search`, `filters`, `summary`, `new-items`, `results`, `pages` |
185
+ | `documents-of-a-request` | The documents of a request, a section of its page | `results` |
186
+
187
+ ## Accessibility
188
+
189
+ - The search form has `role="search"`; each field has its label (`mds-input-field`).
190
+ - The summary has `role="status"`: it is read out after every change, without moving the focus.
191
+ - Each item is opened by a link that names it, never by an Open repeated on every row.
192
+ - The selection of a row is a checkbox named after its item (`mds-table selectable`).
193
+
194
+ ## Content
195
+
196
+ - The summary says which items out of how many, with the noun of the set: "11-20 di 46
197
+ pratiche". When nothing matches it says so ("Nessuna pratica corrisponde") and the panel of
198
+ `empty-state` takes the place of the items, with Rimuovi i filtri only in the panel
199
+ (`clear-filters`).
200
+ - Rimuovi i filtri, the words of `mds-filter`.
201
+ - The new items: "2 nuove pratiche", the 2 in the dot, then Mostra.
202
+
203
+ ## Magma gaps
204
+
205
+ - None for the default: every region is a component of Magma or a class of its Tailwind layer.
206
+
207
+ ## Decisions
208
+
209
+ | Date | Decision | Why |
210
+ | --- | --- | --- |
211
+ | 2026-11-03 | The list of items is a block: the search, the summary, the items and the pages come back in `list-with-filters`, `empty-state` and `loading` | The round of the building blocks, from the previews of the three patterns; the docs site names the filter bar and the results summary among the candidates (`plan/DIRECTION.md`, Building blocks section). |
212
+ | 2026-11-03 | One block, not a bar of filters and a summary apart | The maintainer's choice: the regions always come together, in one order, with related spaces, so one answer of `get_pattern` gives the whole list; the regions with a When cover the list of a section, with no search. |
213
+ | 2026-11-03 | The line of the new items carries the dot that pulses when the count grows, from `mds-notification` once #1216 lands; until then, none | The maintainer's note in the review of round 3 ("l'elemento dovrebbe avere una icona pulsante"); asked whether to draw it by hand meanwhile, he chose #1216 first: a product never writes the animation itself (`list-with-filters`, Magma gaps). |
214
+ | 2026-11-04 | The dot of the new items is `mds-notification variant="info" pulse`, the count its `value` | #1216 landed (PR #1239), as the decision of 2026-11-03 waited for: the pulse follows `value`, so the dot carries the count (`list-with-filters`). |