@thewhatmatters/wmds 0.4.31 → 0.4.33

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 (220) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/bin/wmds-check.mjs +38 -0
  3. package/dist/colors.css +2 -1
  4. package/dist/components/atoms/Checkbox/Checkbox.d.ts.map +1 -1
  5. package/dist/components/atoms/Checkbox/Checkbox.js +73 -72
  6. package/dist/components/atoms/Input/Input.d.ts.map +1 -1
  7. package/dist/components/atoms/Input/Input.js +44 -49
  8. package/dist/components/atoms/Input/inputShellStyles.js +2 -2
  9. package/dist/components/atoms/Radio/Radio.d.ts.map +1 -1
  10. package/dist/components/atoms/Radio/Radio.js +61 -60
  11. package/dist/components/atoms/Switch/Switch.d.ts.map +1 -1
  12. package/dist/components/atoms/Switch/Switch.js +31 -30
  13. package/dist/components/atoms/TextArea/TextArea.d.ts.map +1 -1
  14. package/dist/components/atoms/TextArea/TextArea.js +56 -55
  15. package/dist/components/atoms/TextArea/textareaShellStyles.js +2 -2
  16. package/dist/components/atoms/inputShared/InputStatusBanner.d.ts +5 -0
  17. package/dist/components/atoms/inputShared/InputStatusBanner.d.ts.map +1 -1
  18. package/dist/components/atoms/inputShared/InputStatusBanner.js +15 -4
  19. package/dist/components/molecules/Card/Card.d.ts +10 -1
  20. package/dist/components/molecules/Card/Card.d.ts.map +1 -1
  21. package/dist/components/molecules/Card/Card.js +56 -43
  22. package/dist/components/molecules/CheckboxGroup/CheckboxGroup.d.ts.map +1 -1
  23. package/dist/components/molecules/CheckboxGroup/CheckboxGroup.js +53 -53
  24. package/dist/components/molecules/CopyField/copyFieldStyles.d.ts.map +1 -1
  25. package/dist/components/molecules/CopyField/copyFieldStyles.js +1 -1
  26. package/dist/components/molecules/ErrorSummary/ErrorSummary.d.ts +32 -0
  27. package/dist/components/molecules/ErrorSummary/ErrorSummary.d.ts.map +1 -0
  28. package/dist/components/molecules/ErrorSummary/ErrorSummary.js +37 -0
  29. package/dist/components/molecules/ErrorSummary/errorSummaryStyles.d.ts +12 -0
  30. package/dist/components/molecules/ErrorSummary/errorSummaryStyles.d.ts.map +1 -0
  31. package/dist/components/molecules/ErrorSummary/errorSummaryStyles.js +5 -0
  32. package/dist/components/molecules/IntakeForm/IntakeForm.d.ts.map +1 -1
  33. package/dist/components/molecules/IntakeForm/IntakeForm.js +4 -6
  34. package/dist/components/molecules/PromptBar/promptBarStyles.d.ts +3 -2
  35. package/dist/components/molecules/PromptBar/promptBarStyles.d.ts.map +1 -1
  36. package/dist/components/molecules/PromptBar/promptBarStyles.js +2 -2
  37. package/dist/components/molecules/RadioGroup/RadioGroup.d.ts.map +1 -1
  38. package/dist/components/molecules/RadioGroup/RadioGroup.js +53 -53
  39. package/dist/components/molecules/Search/Search.d.ts +5 -0
  40. package/dist/components/molecules/Search/Search.d.ts.map +1 -1
  41. package/dist/components/molecules/Search/Search.js +14 -13
  42. package/dist/components/molecules/Search/searchStyles.d.ts +2 -1
  43. package/dist/components/molecules/Search/searchStyles.d.ts.map +1 -1
  44. package/dist/components/molecules/Search/searchStyles.js +4 -4
  45. package/dist/components/organisms/Carousel/Carousel.d.ts +21 -1
  46. package/dist/components/organisms/Carousel/Carousel.d.ts.map +1 -1
  47. package/dist/components/organisms/Carousel/Carousel.js +319 -190
  48. package/dist/components/organisms/Carousel/carouselStyles.d.ts +9 -0
  49. package/dist/components/organisms/Carousel/carouselStyles.d.ts.map +1 -1
  50. package/dist/components/organisms/Carousel/carouselStyles.js +12 -3
  51. package/dist/index.d.ts +2 -1
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +99 -97
  54. package/dist/lib/compositionAudit.d.ts.map +1 -1
  55. package/dist/stateColors.css +2 -1
  56. package/dist/styles.css +1 -1
  57. package/docs/components.md +2 -1
  58. package/docs/exports.json +14 -1
  59. package/docs/patterns/components-accordion--flush.tsx +1 -1
  60. package/docs/patterns/components-appshell--portal-dashboard-pattern.tsx +1 -1
  61. package/docs/patterns/components-avatar--dropdown-row.tsx +1 -1
  62. package/docs/patterns/components-badge--outline-tags.tsx +1 -1
  63. package/docs/patterns/components-badge--status-pill.tsx +1 -1
  64. package/docs/patterns/components-badge--with-avatar.tsx +1 -1
  65. package/docs/patterns/components-band--page-in-bands.tsx +1 -1
  66. package/docs/patterns/components-breadcrumb--editorial.tsx +1 -1
  67. package/docs/patterns/components-breadcrumb--long-path.tsx +1 -1
  68. package/docs/patterns/components-breadcrumb--path.tsx +1 -1
  69. package/docs/patterns/components-breadcrumb--router-links.tsx +1 -1
  70. package/docs/patterns/components-button-button--copy-button.tsx +1 -1
  71. package/docs/patterns/components-button-button--destructive-action.tsx +1 -1
  72. package/docs/patterns/components-button-button--external-link.tsx +1 -1
  73. package/docs/patterns/components-button-button--ghost-action.tsx +1 -1
  74. package/docs/patterns/components-button-button--inverse-action.tsx +1 -1
  75. package/docs/patterns/components-button-button--link-render.tsx +1 -1
  76. package/docs/patterns/components-button-button--multi-state-badge.tsx +1 -1
  77. package/docs/patterns/components-button-button--outline-mono.tsx +1 -1
  78. package/docs/patterns/components-button-button--primary-action.tsx +1 -1
  79. package/docs/patterns/components-button-button--row-hug.tsx +1 -1
  80. package/docs/patterns/components-button-button--row-layout.tsx +1 -1
  81. package/docs/patterns/components-button-button--secondary-action.tsx +1 -1
  82. package/docs/patterns/components-button-button--suggestion-pills.tsx +1 -1
  83. package/docs/patterns/components-button-button--with-count.tsx +1 -1
  84. package/docs/patterns/components-button-button--with-icon.tsx +1 -1
  85. package/docs/patterns/components-button-floatingactionbutton--vertical-actions.tsx +1 -1
  86. package/docs/patterns/components-calembed--pattern-skip-in-footer.tsx +1 -1
  87. package/docs/patterns/components-card-card--body-slot-occupancy-history.tsx +1 -1
  88. package/docs/patterns/components-card-card--headerless-media.tsx +1 -1
  89. package/docs/patterns/components-card-card--outlined-layout.tsx +1 -1
  90. package/docs/patterns/components-card-card--pinned-height.tsx +1 -1
  91. package/docs/patterns/components-card-card--terminal-frame.tsx +1 -1
  92. package/docs/patterns/components-card-selectablecard--selectable-cards-pattern.tsx +1 -1
  93. package/docs/patterns/components-carousel--image-carousel.tsx +1 -1
  94. package/docs/patterns/components-chart--audience-activity-heatmap.tsx +1 -1
  95. package/docs/patterns/components-chart--cartesian-no-data-gaps.tsx +1 -1
  96. package/docs/patterns/components-chart--occupancy-history-in-card.tsx +1 -1
  97. package/docs/patterns/components-chart--occupancy-in-card.tsx +1 -1
  98. package/docs/patterns/components-chart--post-reach-distribution.tsx +1 -1
  99. package/docs/patterns/components-chart--ranked-audience-breakdown.tsx +1 -1
  100. package/docs/patterns/components-chart--revenue-by-line.tsx +1 -1
  101. package/docs/patterns/components-chart--segmented-ring-pattern.tsx +1 -1
  102. package/docs/patterns/components-chart--unit-grid-composition.tsx +1 -1
  103. package/docs/patterns/components-chatdock--pattern-chat-dock.tsx +1 -1
  104. package/docs/patterns/components-chatdock--pattern-start-project-gate.tsx +1 -1
  105. package/docs/patterns/components-chatqa--pattern-qa-with-reply.tsx +1 -1
  106. package/docs/patterns/components-checkbox-checkbox--default.tsx +1 -1
  107. package/docs/patterns/components-checkbox-checkbox--with-count.tsx +1 -1
  108. package/docs/patterns/components-checkbox-checkbox--with-description.tsx +1 -1
  109. package/docs/patterns/components-checkbox-checkboxgroup--default.tsx +1 -1
  110. package/docs/patterns/components-checkbox-checkboxgroup--option-counts.tsx +1 -1
  111. package/docs/patterns/components-copyfield--clipboard-blocked.tsx +1 -1
  112. package/docs/patterns/components-copyfield--copied.tsx +1 -1
  113. package/docs/patterns/components-copyfield--copy-key.tsx +1 -1
  114. package/docs/patterns/components-copyfield--on-navy.tsx +1 -1
  115. package/docs/patterns/components-descriptionlist--details.tsx +1 -1
  116. package/docs/patterns/components-descriptionlist--post-metadata.tsx +1 -1
  117. package/docs/patterns/components-dialog--alert-dialog-destructive.tsx +1 -1
  118. package/docs/patterns/components-dialog--alert-dialog-typed-confirmation.tsx +1 -1
  119. package/docs/patterns/components-dialog--default-dialog.tsx +1 -1
  120. package/docs/patterns/components-dialog--form-dialog.tsx +3 -3
  121. package/docs/patterns/components-displaycontrols--page-utilities.tsx +1 -1
  122. package/docs/patterns/components-displaycontrols--theme-switch.tsx +1 -1
  123. package/docs/patterns/components-errorsummary--contact-form.tsx +35 -0
  124. package/docs/patterns/components-field--horizontal-input.tsx +2 -2
  125. package/docs/patterns/components-field--horizontal-text-area.tsx +2 -2
  126. package/docs/patterns/components-field--multi-control.tsx +2 -2
  127. package/docs/patterns/components-filterpanel--panel.tsx +1 -1
  128. package/docs/patterns/components-footerreveal--marketing-hero-pattern.tsx +1 -1
  129. package/docs/patterns/components-footerreveal--marketing-hero-ruled-pattern.tsx +1 -1
  130. package/docs/patterns/components-footerreveal--marketing-hero-with-gallery-intro.tsx +1 -1
  131. package/docs/patterns/components-footerreveal--marketing-page-pattern.tsx +1 -1
  132. package/docs/patterns/components-footerreveal--ruled-grid-footer-pattern.tsx +1 -1
  133. package/docs/patterns/components-footerreveal--sequenced-marketing-hero.tsx +1 -1
  134. package/docs/patterns/components-herointro--two-line-intro.tsx +1 -1
  135. package/docs/patterns/components-herointro--with-actions.tsx +1 -1
  136. package/docs/patterns/components-herotilestack--marketing-hero-pattern.tsx +1 -1
  137. package/docs/patterns/components-herotilestack--marketing-hero-text-sequence.tsx +1 -1
  138. package/docs/patterns/components-herotilestack--marketing-hero-with-gallery-intro.tsx +1 -1
  139. package/docs/patterns/components-indexlist--post-index.tsx +1 -1
  140. package/docs/patterns/components-intakeconfirmation--booked-pattern.tsx +1 -1
  141. package/docs/patterns/components-intakeconfirmation--emailed-pattern.tsx +1 -1
  142. package/docs/patterns/components-intakeform--about-you-pattern.tsx +1 -1
  143. package/docs/patterns/components-intakeform--short-form-pattern.tsx +1 -1
  144. package/docs/patterns/components-intakemodal--intake-modal-pattern.tsx +1 -1
  145. package/docs/patterns/components-kbd--command-row.tsx +1 -1
  146. package/docs/patterns/components-kbd--numbered-choices.tsx +1 -1
  147. package/docs/patterns/components-kbd--shortcut.tsx +1 -1
  148. package/docs/patterns/components-linktile--resource-tile.tsx +1 -1
  149. package/docs/patterns/components-linktile--router-link.tsx +1 -1
  150. package/docs/patterns/components-logview--detail-pane.tsx +1 -1
  151. package/docs/patterns/components-logview--log-viewer.tsx +1 -1
  152. package/docs/patterns/components-moremenu--action-menu.tsx +1 -1
  153. package/docs/patterns/components-moremenu--in-card-header.tsx +1 -1
  154. package/docs/patterns/components-navlist--app-sidebar.tsx +1 -1
  155. package/docs/patterns/components-navlist--side-nav-settings.tsx +1 -1
  156. package/docs/patterns/components-pageheader--app-header-pattern.tsx +1 -1
  157. package/docs/patterns/components-pageheader--page-section-header.tsx +1 -1
  158. package/docs/patterns/components-pageheader--toolbar-header.tsx +1 -1
  159. package/docs/patterns/components-panel--end-detail-rail.tsx +1 -1
  160. package/docs/patterns/components-pillgroup--pill-group-pattern.tsx +1 -1
  161. package/docs/patterns/components-promptbar--pattern-prompt-bar.tsx +1 -1
  162. package/docs/patterns/components-prose--article-body.tsx +1 -1
  163. package/docs/patterns/components-radio-radiogroup--default.tsx +1 -1
  164. package/docs/patterns/components-scrollhorizontal--project-gallery-pattern.tsx +1 -1
  165. package/docs/patterns/components-scrollhorizontal--with-intro.tsx +1 -1
  166. package/docs/patterns/components-sectioncaption--column-caption.tsx +1 -1
  167. package/docs/patterns/components-sectioncaption--with-action.tsx +1 -1
  168. package/docs/patterns/components-sheet--bottom-sheet.tsx +3 -3
  169. package/docs/patterns/components-sheet--end-sheet.tsx +1 -1
  170. package/docs/patterns/components-sheet--side-sheet-header-actions.tsx +1 -1
  171. package/docs/patterns/components-sheet--side-sheet-url-deep-link.tsx +1 -1
  172. package/docs/patterns/components-sheet--side-sheet.tsx +1 -1
  173. package/docs/patterns/components-sitenav--brand-and-cta.tsx +1 -1
  174. package/docs/patterns/components-sitenav--centered-links.tsx +1 -1
  175. package/docs/patterns/components-sitenav--compact.tsx +1 -1
  176. package/docs/patterns/components-sitenav--marketing-header.tsx +1 -1
  177. package/docs/patterns/components-sitenav--mega-menu.tsx +1 -1
  178. package/docs/patterns/components-stat--hero-stat.tsx +1 -1
  179. package/docs/patterns/components-stat--insights-row.tsx +1 -1
  180. package/docs/patterns/components-stepprogress--step-progress-pattern.tsx +1 -1
  181. package/docs/patterns/components-switch--default.tsx +1 -1
  182. package/docs/patterns/components-switch--settings-row.tsx +1 -1
  183. package/docs/patterns/components-tab--settings-pages.tsx +1 -1
  184. package/docs/patterns/components-table--approvals-with-sheet.tsx +1 -1
  185. package/docs/patterns/components-table--approvals.tsx +1 -1
  186. package/docs/patterns/components-table--basic.tsx +1 -1
  187. package/docs/patterns/components-taskrows--action-details.tsx +1 -1
  188. package/docs/patterns/components-taskrows--capsules.tsx +1 -1
  189. package/docs/patterns/components-taskrows--card-with-status-rows.tsx +1 -1
  190. package/docs/patterns/components-taskrows--controlled-expand.tsx +1 -1
  191. package/docs/patterns/components-taskrows--custom-slots.tsx +1 -1
  192. package/docs/patterns/components-taskrows--needs-you-table.tsx +1 -1
  193. package/docs/patterns/components-taskrows--status-list.tsx +1 -1
  194. package/docs/patterns/components-taskrows--tag-chips.tsx +1 -1
  195. package/docs/patterns/components-textarea--save-status.tsx +1 -1
  196. package/docs/patterns/components-textlink--external-destination.tsx +1 -1
  197. package/docs/patterns/components-textlink--inline-prose.tsx +1 -1
  198. package/docs/patterns/components-textlink--quiet-title.tsx +1 -1
  199. package/docs/patterns/components-textlink--supporting-copy.tsx +1 -1
  200. package/docs/patterns/components-textsequence--default.tsx +1 -1
  201. package/docs/patterns/components-textsequence--reduced-motion.tsx +1 -1
  202. package/docs/patterns/components-textsequence--shapes.tsx +1 -1
  203. package/docs/patterns/components-tilegrid--masonry.tsx +1 -1
  204. package/docs/patterns/components-toast--stacked-notifications.tsx +1 -1
  205. package/docs/patterns/components-tooltip--controlled.tsx +1 -1
  206. package/docs/patterns/components-tooltip--disabled-control.tsx +1 -1
  207. package/docs/patterns/components-tooltip--icon-action.tsx +1 -1
  208. package/docs/patterns/components-tooltip--keyboard-shortcut.tsx +1 -1
  209. package/docs/patterns/components-tooltip--placement.tsx +1 -1
  210. package/docs/patterns/foundations-scroll-fade--horizontal-rail.tsx +1 -1
  211. package/docs/patterns/foundations-scroll-fade--overflowing-list.tsx +1 -1
  212. package/docs/patterns/guides-chart-explorations--comparison-gallery.tsx +1 -1
  213. package/docs/patterns/guides-filter-panel--filtered-grid.tsx +1 -1
  214. package/docs/patterns/guides-filter-panel--filtered-index.tsx +1 -1
  215. package/docs/patterns/guides-overlay-flows--notification-preferences.tsx +3 -3
  216. package/docs/patterns/guides-post-page--post-page.tsx +1 -1
  217. package/docs/patterns/guides-profile-typography--editorial-profile.tsx +1 -1
  218. package/docs/patterns/guides-resource-detail--detail.tsx +1 -1
  219. package/docs/patterns/index.json +9 -1
  220. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  # @thewhatmatters/wmds — component contracts
2
2
 
3
- Version 0.4.31. Generated from the WMDS repository's AGENTS.md (Storybook-first) by `scripts/generate-package-docs.mjs` — do not edit here.
3
+ Version 0.4.33. Generated from the WMDS repository's AGENTS.md (Storybook-first) by `scripts/generate-package-docs.mjs` — do not edit here.
4
4
 
5
5
  Storybook paths such as **Components/Button/Button → Pattern — …** name a story; its Show code is in `patterns/` (see `patterns/index.json`). Longer contracts for FooterReveal, HeroTileStack, TextSequence, ScrollHorizontal, RiveHand, and PromptBar are in `component-contracts.md`. ADR numbers refer to decision records in the WMDS repository.
6
6
 
@@ -53,6 +53,7 @@ Storybook paths such as **Components/Button/Button → Pattern — …** name a
53
53
  - **PromptBar:** wide prompt pill — inline **TextArea** (one line when empty, grows through 3 lines, then scrolls) and an inset **IconButton** `sm` send control. Enter sends; Shift+Enter inserts a newline; send stays disabled until the draft has text. Optional `start` (brand mark — **Avatar** `size="md"`) and `end` (extra inset **IconButton** `sm`) slots. No new Button role. Copy **Components/PromptBar → Pattern — prompt bar**. The site assistant on the marketing pages is **ChatDock**, not a hand-pinned PromptBar. Do not restyle **SiteNav**. Full contract: **docs/component-contracts.md → PromptBar**.
54
54
  - **ChatDock:** the site assistant — a **PromptBar** pinned to the bottom of the page grid (`--grid-max: 40rem`, under **SiteNav**) with the brand `mark`; hovering shows `suggestions` that carry a `prompt` as **Button** `secondary` pills above it; focusing, clicking, or typing opens a non-modal chat window around the same composer (shared overlay header with `title` / `subtitle` / close, `greeting`, `messages` (visitor turns on `bg-brand-tint`, replies as plain text), `thinking` row, suggestion rows — **Button** `layout="row"` — until the first message (a row that sends hands focus to the composer as the rows leave), `disclaimer` under the composer). One **PromptBar** serves both states: the window grows up out of the bar and Escape or close folds it back; either reverses the other midway. Below `md` it fills the screen, rising from the bottom edge. Reduced motion crossfades. `followUps` (same items as `suggestions`; `icon` not shown — inline rows lead with **CornerDownRight**, composer pills are text only) show under the latest reply only — hidden while `thinking`, gone the moment the visitor sends; `followUpsPlacement` is `inline` (default, rows in the thread, 44px on phones) or `composer` (pills above the composer). Under each finished reply, a row: **Copy** (`copyText`), thumbs (`onMessageFeedback`, on replies that carry `feedback` — `null` until the visitor votes; **IconButton** `pressed`), and a muted score (`meta: { label, description? }`, e.g. "Match 99%") — each part on its own; shown on hover or focus where the pointer can hover, always on touch; it keeps its place so the thread never moves, and stays empty while the latest reply is still arriving. Never put actions inside `content`. `gate` puts a multi-step form in the conversation — **ChatDock.Gate**, under the latest message where a reply would go, set in as a well (hairline border at the card body radius, `bg-body`, `shadow-inset-well` — embedded, not raised): step title, subtitle, previous · "2 of 4" · next (no close of its own), the step, `pending` ("Sending…") / `error` lines, and a footer (start slot, Cancel, Next). Setting it opens the window and takes focus; the window keeps its header (`gateSubtitle` replaces the subtitle) and its close; the composer stays in place but is off (`labels.gatePlaceholder`); suggestion rows, follow-ups, and reply rows step aside. The window grows to fit the step, up to the viewport less 7rem; past that the conversation scrolls, and each step is brought into view. The window stays non-modal. Its close and Escape fold it and keep the gate with its progress; Cancel leaves the gate and the composer comes back with focus. Phones keep the window inside the area a keyboard leaves visible. Start a project runs as a gate, not a dialog — paste **Pattern — start a project gate** (its `onSubmit` returns a promise; a rejection keeps the answers and offers Try again) and return it from **Pattern — chat dock**'s `renderStartProject`. Never put a form inside `content`. The app owns `messages`, `followUps`, votes, the gate's open state, and `onSend`; suggestions without a `prompt` (for example **Start a project**) only call `onSuggestionSelect`. No full-page chat, no header send/expand arrow, no voice. `placement="inline"` is for previews only. Copy **Components/ChatDock → Pattern — chat dock** (it holds the follow-up state, the votes, and Start a project). See **ADR-0039**. Full contract: **docs/component-contracts.md → ChatDock**.
55
55
  - **TextArea:** element-radius multiline — same optional `label`, `description`, `status`, `message`, and `loading` as **Input**; default `resize="vertical"`. See **ADR-0006**.
56
+ - **ErrorSummary:** after a failed submit, at the top of the form: "There's a problem" (`title`), `errors` `{ field, message }[]` (one link per error, same words as the field's message; `field` is the input `id`), takes focus when its errors change (`focusOnShow`), each link focuses its field; `as` `h2` / `h3`. Fields keep their inline messages. Paste **Components/ErrorSummary → Pattern — form with an error summary**.
56
57
  - **Field:** label/layout wrapper — `orientation="vertical" | "horizontal"`; never required. Validation stays on **Input** / **TextArea**. See **ADR-0006**.
57
58
  - **CopyField:** read-only monospace value inside **PromptBar**'s pill, with **Button** `role="secondary"` `size="sm"` seated at the trailing end the way PromptBar seats send (Lucide **Copy**; the confirmation check is the status glyph). **Input** is `inline` `mono` `readOnly` (`type-code`); a long value truncates and does not run under the button. A click copies `value`. The label becomes "Copied" for `buttonStatusHoldMs` (2s), announced from the button's `aria-live="polite"` region, then returns. Enter and Space activate the button; focusing the value selects it, so Cmd/Ctrl+C copies from the field. If the Clipboard API is missing or blocked, the value is selected, `execCommand('copy')` is tried, and a polite hint reads "Press Cmd/Ctrl+C to copy." The value is never logged. The label and the blocked-clipboard hint inherit color (`type-label` / `type-supporting`, not `text-fg` or `text-muted`); the pill stays `bg-surface` so the key stays dark on white. On navy, wrap the section in `bg-brand text-on-brand` and use **Button** `role="inverse"` plus `role="inverse-outline"`. Do not set `data-theme="dark"` on that section — the dark surface is about 1:1 on `#011272`. `state` (`"copied"` | `"fallback"`) pins a specimen — omit it in the app. `className` is layout only. No new color. Paste **Components/CopyField → Pattern — copy key**, or **Pattern — on a navy field** for the unlock page. See **ADR-0045**, **ADR-0046**.
58
59
  - **LogView:** a scrolling log — `lines`, `label`, line numbers, a tabular line count, **Copy** (**Button**), and **Follow** (`aria-pressed`, keeps the scroller on the last line). `loading` is a **Skeleton**. An empty log reads "No log lines". `className` is layout only. Paste **Components/LogView → Pattern — log viewer**. The dark run detail is **Pattern — detail pane**: prev/next **IconButton**, **Badge** tags, **Stat** `detail`, and **LogView**, wrapped in `data-theme="dark"`.
package/docs/exports.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "@thewhatmatters/wmds",
3
- "version": "0.4.31",
3
+ "version": "0.4.33",
4
4
  "import": "import { Button } from \"@thewhatmatters/wmds\";",
5
5
  "styles": [
6
6
  "@thewhatmatters/wmds/styles.css",
@@ -350,6 +350,19 @@
350
350
  },
351
351
  "patterns": []
352
352
  },
353
+ {
354
+ "name": "ErrorSummary",
355
+ "tier": "molecule",
356
+ "category": "Form controls",
357
+ "summary": "\"There's a problem\" at the top of a form after a failed submit: one link per error that focuses its field.",
358
+ "storybook": {
359
+ "title": "Components/ErrorSummary",
360
+ "docs": "?path=/docs/components-errorsummary--docs"
361
+ },
362
+ "patterns": [
363
+ "components-errorsummary--contact-form"
364
+ ]
365
+ },
353
366
  {
354
367
  "name": "Field",
355
368
  "tier": "molecule",
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — flush
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — flush
2
2
  // Storybook: Components/Accordion → Pattern — flush (?path=/story/components-accordion--flush)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — portal dashboard
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — portal dashboard
2
2
  // Storybook: Components/AppShell → Pattern — portal dashboard (?path=/story/components-appshell--portal-dashboard-pattern)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — dropdown row
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — dropdown row
2
2
  // Storybook: Components/Avatar → Pattern — dropdown row (?path=/story/components-avatar--dropdown-row)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — outline tags
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — outline tags
2
2
  // Storybook: Components/Badge → Pattern — outline tags (?path=/story/components-badge--outline-tags)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — status pill
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — status pill
2
2
  // Storybook: Components/Badge → Pattern — status pill (?path=/story/components-badge--status-pill)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — with avatar
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — with avatar
2
2
  // Storybook: Components/Badge → Pattern — with avatar (?path=/story/components-badge--with-avatar)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — page in bands
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — page in bands
2
2
  // Storybook: Components/Band → Pattern — page in bands (?path=/story/components-band--page-in-bands)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — editorial
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — editorial
2
2
  // Storybook: Components/Breadcrumb → Pattern — editorial (?path=/story/components-breadcrumb--editorial)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — long path
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — long path
2
2
  // Storybook: Components/Breadcrumb → Pattern — long path (?path=/story/components-breadcrumb--long-path)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — path
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — path
2
2
  // Storybook: Components/Breadcrumb → Pattern — path (?path=/story/components-breadcrumb--path)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — router links
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — router links
2
2
  // Storybook: Components/Breadcrumb → Pattern — router links (?path=/story/components-breadcrumb--router-links)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — copy button
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — copy button
2
2
  // Storybook: Components/Button/Button → Pattern — copy button (?path=/story/components-button-button--copy-button)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — destructive action
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — destructive action
2
2
  // Storybook: Components/Button/Button → Pattern — destructive action (?path=/story/components-button-button--destructive-action)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — external link
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — external link
2
2
  // Storybook: Components/Button/Button → Pattern — external link (?path=/story/components-button-button--external-link)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — ghost action
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — ghost action
2
2
  // Storybook: Components/Button/Button → Pattern — ghost action (?path=/story/components-button-button--ghost-action)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — inverse action
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — inverse action
2
2
  // Storybook: Components/Button/Button → Pattern — inverse action (?path=/story/components-button-button--inverse-action)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — link
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — link
2
2
  // Storybook: Components/Button/Button → Pattern — link (?path=/story/components-button-button--link-render)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — submit / async
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — submit / async
2
2
  // Storybook: Components/Button/Button → Pattern — submit / async (?path=/story/components-button-button--multi-state-badge)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — outline mono
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — outline mono
2
2
  // Storybook: Components/Button/Button → Pattern — outline mono (?path=/story/components-button-button--outline-mono)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — primary action
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — primary action
2
2
  // Storybook: Components/Button/Button → Pattern — primary action (?path=/story/components-button-button--primary-action)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — row (hug)
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — row (hug)
2
2
  // Storybook: Components/Button/Button → Pattern — row (hug) (?path=/story/components-button-button--row-hug)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — row
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — row
2
2
  // Storybook: Components/Button/Button → Pattern — row (?path=/story/components-button-button--row-layout)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — secondary action
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — secondary action
2
2
  // Storybook: Components/Button/Button → Pattern — secondary action (?path=/story/components-button-button--secondary-action)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — suggestion pills
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — suggestion pills
2
2
  // Storybook: Components/Button/Button → Pattern — suggestion pills (?path=/story/components-button-button--suggestion-pills)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — with count
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — with count
2
2
  // Storybook: Components/Button/Button → Pattern — with count (?path=/story/components-button-button--with-count)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — with icon
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — with icon
2
2
  // Storybook: Components/Button/Button → Pattern — with icon (?path=/story/components-button-button--with-icon)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — vertical actions
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — vertical actions
2
2
  // Storybook: Components/Button/FloatingActionButton → Pattern — vertical actions (?path=/story/components-button-floatingactionbutton--vertical-actions)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — skip in footer
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — skip in footer
2
2
  // Storybook: Components/CalEmbed → Pattern — skip in footer (?path=/story/components-calembed--pattern-skip-in-footer)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Example — body slot (occupancy history)
1
+ // @thewhatmatters/wmds@0.4.33 · Example — body slot (occupancy history)
2
2
  // Storybook: Components/Card/Card → Example — body slot (occupancy history) (?path=/story/components-card-card--body-slot-occupancy-history)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — headerless media
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — headerless media
2
2
  // Storybook: Components/Card/Card → Pattern — headerless media (?path=/story/components-card-card--headerless-media)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — outlined layout
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — outlined layout
2
2
  // Storybook: Components/Card/Card → Pattern — outlined layout (?path=/story/components-card-card--outlined-layout)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — pinned height
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — pinned height
2
2
  // Storybook: Components/Card/Card → Pattern — pinned height (?path=/story/components-card-card--pinned-height)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — terminal frame
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — terminal frame
2
2
  // Storybook: Components/Card/Card → Pattern — terminal frame (?path=/story/components-card-card--terminal-frame)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — selectable cards
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — selectable cards
2
2
  // Storybook: Components/Card/SelectableCard → Pattern — selectable cards (?path=/story/components-card-selectablecard--selectable-cards-pattern)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — image carousel
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — image carousel
2
2
  // Storybook: Components/Carousel → Pattern — image carousel (?path=/story/components-carousel--image-carousel)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — matrix heatmap
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — matrix heatmap
2
2
  // Storybook: Components/Chart → Pattern — matrix heatmap (?path=/story/components-chart--audience-activity-heatmap)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — Cartesian no-data gaps
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — Cartesian no-data gaps
2
2
  // Storybook: Components/Chart → Pattern — Cartesian no-data gaps (?path=/story/components-chart--cartesian-no-data-gaps)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — occupancy history in Card
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — occupancy history in Card
2
2
  // Storybook: Components/Chart → Pattern — occupancy history in Card (?path=/story/components-chart--occupancy-history-in-card)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — occupancy KPI in Card
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — occupancy KPI in Card
2
2
  // Storybook: Components/Chart → Pattern — occupancy KPI in Card (?path=/story/components-chart--occupancy-in-card)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — distribution strip
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — distribution strip
2
2
  // Storybook: Components/Chart → Pattern — distribution strip (?path=/story/components-chart--post-reach-distribution)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — ranked audience breakdown
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — ranked audience breakdown
2
2
  // Storybook: Components/Chart → Pattern — ranked audience breakdown (?path=/story/components-chart--ranked-audience-breakdown)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — revenue by line
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — revenue by line
2
2
  // Storybook: Components/Chart → Pattern — revenue by line (?path=/story/components-chart--revenue-by-line)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — segmented ring
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — segmented ring
2
2
  // Storybook: Components/Chart → Pattern — segmented ring (?path=/story/components-chart--segmented-ring-pattern)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — 100-unit composition
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — 100-unit composition
2
2
  // Storybook: Components/Chart → Pattern — 100-unit composition (?path=/story/components-chart--unit-grid-composition)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — chat dock
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — chat dock
2
2
  // Storybook: Components/ChatDock → Pattern — chat dock (?path=/story/components-chatdock--pattern-chat-dock)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — start a project gate
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — start a project gate
2
2
  // Storybook: Components/ChatDock → Pattern — start a project gate (?path=/story/components-chatdock--pattern-start-project-gate)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — Q&A with reply
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — Q&A with reply
2
2
  // Storybook: Components/ChatQa → Pattern — Q&A with reply (?path=/story/components-chatqa--pattern-qa-with-reply)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — default
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — default
2
2
  // Storybook: Components/Checkbox/Checkbox → Pattern — default (?path=/story/components-checkbox-checkbox--default)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — with count
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — with count
2
2
  // Storybook: Components/Checkbox/Checkbox → Pattern — with count (?path=/story/components-checkbox-checkbox--with-count)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — with description
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — with description
2
2
  // Storybook: Components/Checkbox/Checkbox → Pattern — with description (?path=/story/components-checkbox-checkbox--with-description)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — default
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — default
2
2
  // Storybook: Components/Checkbox/CheckboxGroup → Pattern — default (?path=/story/components-checkbox-checkboxgroup--default)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — option counts
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — option counts
2
2
  // Storybook: Components/Checkbox/CheckboxGroup → Pattern — option counts (?path=/story/components-checkbox-checkboxgroup--option-counts)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — clipboard blocked
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — clipboard blocked
2
2
  // Storybook: Components/CopyField → Pattern — clipboard blocked (?path=/story/components-copyfield--clipboard-blocked)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — copied
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — copied
2
2
  // Storybook: Components/CopyField → Pattern — copied (?path=/story/components-copyfield--copied)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — copy key
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — copy key
2
2
  // Storybook: Components/CopyField → Pattern — copy key (?path=/story/components-copyfield--copy-key)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — on a navy field
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — on a navy field
2
2
  // Storybook: Components/CopyField → Pattern — on a navy field (?path=/story/components-copyfield--on-navy)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — details
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — details
2
2
  // Storybook: Components/DescriptionList → Pattern — details (?path=/story/components-descriptionlist--details)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — post metadata
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — post metadata
2
2
  // Storybook: Components/DescriptionList → Pattern — post metadata (?path=/story/components-descriptionlist--post-metadata)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — alert dialog (destructive)
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — alert dialog (destructive)
2
2
  // Storybook: Components/Dialog → Pattern — alert dialog (destructive) (?path=/story/components-dialog--alert-dialog-destructive)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — alert dialog (typed confirmation delete)
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — alert dialog (typed confirmation delete)
2
2
  // Storybook: Components/Dialog → Pattern — alert dialog (typed confirmation delete) (?path=/story/components-dialog--alert-dialog-typed-confirmation)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — dialog
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — dialog
2
2
  // Storybook: Components/Dialog → Pattern — dialog (?path=/story/components-dialog--default-dialog)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — form dialog
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — form dialog
2
2
  // Storybook: Components/Dialog → Pattern — form dialog (?path=/story/components-dialog--form-dialog)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -31,8 +31,8 @@ export function InviteDialog() {
31
31
  }
32
32
  >
33
33
  <div className="flex flex-col gap-4 pb-2">
34
- <Input label="Email address" placeholder="name@company.com" />
35
- <Input label="Role" placeholder="Editor" />
34
+ <Input label="Email address" />
35
+ <Input label="Role" />
36
36
  </div>
37
37
  </Dialog.Content>
38
38
  </Dialog>
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — page display controls
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — page display controls
2
2
  // Storybook: Components/DisplayControls → Pattern — page display controls (?path=/story/components-displaycontrols--page-utilities)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -1,4 +1,4 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — theme switch
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — theme switch
2
2
  // Storybook: Components/DisplayControls → Pattern — theme switch (?path=/story/components-displaycontrols--theme-switch)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
@@ -0,0 +1,35 @@
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — form with an error summary
2
+ // Storybook: Components/ErrorSummary → Pattern — form with an error summary (?path=/story/components-errorsummary--contact-form)
3
+ // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
+
5
+ "use client";
6
+
7
+ import { useState, type FormEvent } from "react";
8
+ import { Button, ErrorSummary, Input, type ErrorSummaryItem } from "@thewhatmatters/wmds";
9
+
10
+ export function ContactFormExample() {
11
+ const [errors, setErrors] = useState<ErrorSummaryItem[]>([]);
12
+ const messageFor = (field: string) => errors.find((error) => error.field === field)?.message as string | undefined;
13
+
14
+ function submit(event: FormEvent<HTMLFormElement>) {
15
+ event.preventDefault();
16
+ const data = new FormData(event.currentTarget);
17
+ const next: ErrorSummaryItem[] = [];
18
+ if (String(data.get("name") ?? "").trim() === "") next.push({ field: "contact-name", message: "Enter your name" });
19
+ const email = String(data.get("email") ?? "").trim();
20
+ if (email === "") next.push({ field: "contact-email", message: "Enter your email address" });
21
+ else if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) next.push({ field: "contact-email", message: "Enter an email address like name@example.com" });
22
+ setErrors(next);
23
+ }
24
+
25
+ return (
26
+ <form noValidate onSubmit={submit} className="flex max-w-md flex-col gap-6">
27
+ <ErrorSummary errors={errors} />
28
+ <Input id="contact-name" name="name" label="Name" status={messageFor("contact-name") ? "error" : undefined} message={messageFor("contact-name")} />
29
+ <Input id="contact-email" name="email" type="email" label="Email" status={messageFor("contact-email") ? "error" : undefined} message={messageFor("contact-email")} />
30
+ <div>
31
+ <Button type="submit">Send message</Button>
32
+ </div>
33
+ </form>
34
+ );
35
+ }
@@ -1,9 +1,9 @@
1
- // @thewhatmatters/wmds@0.4.31 · Pattern — horizontal input
1
+ // @thewhatmatters/wmds@0.4.33 · Pattern — horizontal input
2
2
  // Storybook: Components/Field → Pattern — horizontal input (?path=/story/components-field--horizontal-input)
3
3
  // Show code — copy verbatim and keep this header; upgrades find pasted patterns by it.
4
4
 
5
5
  import { Field, Input } from "@thewhatmatters/wmds";
6
6
 
7
7
  <Field label="ZIP code" description="5-digit US ZIP." orientation="horizontal">
8
- <Input placeholder="97201" aria-label="ZIP code" />
8
+ <Input aria-label="ZIP code" />
9
9
  </Field>