@thewhatmatters/wmds 0.4.2 → 0.4.4
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.
- package/CHANGELOG.md +48 -0
- package/CONSUMING.md +2 -2
- package/bin/wmds-check.mjs +108 -10
- package/dist/components/organisms/ChatDock/ChatDock.d.ts +21 -15
- package/dist/components/organisms/ChatDock/ChatDock.d.ts.map +1 -1
- package/dist/components/organisms/ChatDock/ChatDock.js +418 -423
- package/dist/components/organisms/ChatDock/ChatDockGate.d.ts +21 -10
- package/dist/components/organisms/ChatDock/ChatDockGate.d.ts.map +1 -1
- package/dist/components/organisms/ChatDock/ChatDockGate.js +124 -118
- package/dist/components/organisms/ChatDock/chatDockGateContext.d.ts +12 -0
- package/dist/components/organisms/ChatDock/chatDockGateContext.d.ts.map +1 -0
- package/dist/components/organisms/ChatDock/chatDockGateContext.js +9 -0
- package/dist/components/organisms/ChatDock/chatDockGateStyles.d.ts +21 -9
- package/dist/components/organisms/ChatDock/chatDockGateStyles.d.ts.map +1 -1
- package/dist/components/organisms/ChatDock/chatDockGateStyles.js +2 -3
- package/dist/components/organisms/ChatDock/chatDockStyles.d.ts +6 -6
- package/dist/components/organisms/ChatDock/chatDockStyles.d.ts.map +1 -1
- package/dist/components/organisms/ChatDock/chatDockStyles.js +2 -2
- package/dist/components/organisms/ChatDock/chatDockViewport.d.ts +6 -0
- package/dist/components/organisms/ChatDock/chatDockViewport.d.ts.map +1 -1
- package/dist/components/organisms/ChatDock/chatDockViewport.js +14 -1
- package/dist/components/organisms/Toast/Toast.d.ts.map +1 -1
- package/dist/components/organisms/Toast/Toast.js +11 -5
- package/dist/lib/dialogOverlay.d.ts.map +1 -1
- package/dist/lib/dialogOverlay.js +18 -15
- package/dist/styles.css +1 -1
- package/docs/component-contracts.md +4 -2
- package/docs/components.md +5 -5
- package/docs/exports.json +1 -1
- package/docs/patterns/components-accordion--flush.tsx +1 -1
- package/docs/patterns/components-avatar--dropdown-row.tsx +1 -1
- package/docs/patterns/components-badge--outline-tags.tsx +1 -1
- package/docs/patterns/components-badge--with-avatar.tsx +1 -1
- package/docs/patterns/components-breadcrumb--editorial.tsx +1 -1
- package/docs/patterns/components-breadcrumb--long-path.tsx +1 -1
- package/docs/patterns/components-breadcrumb--path.tsx +1 -1
- package/docs/patterns/components-breadcrumb--router-links.tsx +1 -1
- package/docs/patterns/components-button-button--copy-button.tsx +1 -1
- package/docs/patterns/components-button-button--destructive-action.tsx +1 -1
- package/docs/patterns/components-button-button--external-link.tsx +1 -1
- package/docs/patterns/components-button-button--ghost-action.tsx +1 -1
- package/docs/patterns/components-button-button--inverse-action.tsx +1 -1
- package/docs/patterns/components-button-button--link-render.tsx +1 -1
- package/docs/patterns/components-button-button--multi-state-badge.tsx +1 -1
- package/docs/patterns/components-button-button--outline-mono.tsx +1 -1
- package/docs/patterns/components-button-button--primary-action.tsx +1 -1
- package/docs/patterns/components-button-button--row-hug.tsx +1 -1
- package/docs/patterns/components-button-button--row-layout.tsx +1 -1
- package/docs/patterns/components-button-button--secondary-action.tsx +1 -1
- package/docs/patterns/components-button-button--suggestion-pills.tsx +1 -1
- package/docs/patterns/components-button-button--with-count.tsx +1 -1
- package/docs/patterns/components-button-button--with-icon.tsx +1 -1
- package/docs/patterns/components-button-floatingactionbutton--vertical-actions.tsx +1 -1
- package/docs/patterns/components-calembed--pattern-skip-in-footer.tsx +1 -1
- package/docs/patterns/components-card-card--body-slot-occupancy-history.tsx +1 -1
- package/docs/patterns/components-card-card--headerless-media.tsx +1 -1
- package/docs/patterns/components-card-card--outlined-layout.tsx +1 -1
- package/docs/patterns/components-card-card--pinned-height.tsx +1 -1
- package/docs/patterns/components-card-selectablecard--selectable-cards-pattern.tsx +1 -1
- package/docs/patterns/components-chart--audience-activity-heatmap.tsx +1 -1
- package/docs/patterns/components-chart--cartesian-no-data-gaps.tsx +1 -1
- package/docs/patterns/components-chart--occupancy-history-in-card.tsx +1 -1
- package/docs/patterns/components-chart--occupancy-in-card.tsx +1 -1
- package/docs/patterns/components-chart--post-reach-distribution.tsx +1 -1
- package/docs/patterns/components-chart--ranked-audience-breakdown.tsx +1 -1
- package/docs/patterns/components-chart--unit-grid-composition.tsx +1 -1
- package/docs/patterns/components-chatdock--pattern-chat-dock.tsx +3 -2
- package/docs/patterns/components-chatdock--pattern-start-project-gate.tsx +54 -11
- package/docs/patterns/components-chatqa--pattern-qa-with-reply.tsx +1 -1
- package/docs/patterns/components-checkbox-checkbox--default.tsx +1 -1
- package/docs/patterns/components-checkbox-checkbox--with-count.tsx +1 -1
- package/docs/patterns/components-checkbox-checkbox--with-description.tsx +1 -1
- package/docs/patterns/components-checkbox-checkboxgroup--default.tsx +1 -1
- package/docs/patterns/components-checkbox-checkboxgroup--option-counts.tsx +1 -1
- package/docs/patterns/components-descriptionlist--details.tsx +1 -1
- package/docs/patterns/components-descriptionlist--post-metadata.tsx +1 -1
- package/docs/patterns/components-dialog--alert-dialog-destructive.tsx +1 -1
- package/docs/patterns/components-dialog--default-dialog.tsx +1 -1
- package/docs/patterns/components-dialog--form-dialog.tsx +1 -1
- package/docs/patterns/components-displaycontrols--page-utilities.tsx +1 -1
- package/docs/patterns/components-field--horizontal-input.tsx +1 -1
- package/docs/patterns/components-field--horizontal-text-area.tsx +1 -1
- package/docs/patterns/components-field--multi-control.tsx +1 -1
- package/docs/patterns/components-footerreveal--marketing-hero-pattern.tsx +1 -1
- package/docs/patterns/components-footerreveal--marketing-hero-ruled-pattern.tsx +1 -1
- package/docs/patterns/components-footerreveal--marketing-hero-with-gallery-intro.tsx +1 -1
- package/docs/patterns/components-footerreveal--marketing-page-pattern.tsx +1 -1
- package/docs/patterns/components-footerreveal--ruled-grid-footer-pattern.tsx +1 -1
- package/docs/patterns/components-footerreveal--sequenced-marketing-hero.tsx +1 -1
- package/docs/patterns/components-herointro--two-line-intro.tsx +1 -1
- package/docs/patterns/components-herotilestack--marketing-hero-pattern.tsx +1 -1
- package/docs/patterns/components-herotilestack--marketing-hero-text-sequence.tsx +1 -1
- package/docs/patterns/components-herotilestack--marketing-hero-with-gallery-intro.tsx +1 -1
- package/docs/patterns/components-indexlist--post-index.tsx +1 -1
- package/docs/patterns/components-intakeconfirmation--booked-pattern.tsx +1 -1
- package/docs/patterns/components-intakeconfirmation--emailed-pattern.tsx +1 -1
- package/docs/patterns/components-intakeform--about-you-pattern.tsx +1 -1
- package/docs/patterns/components-intakemodal--intake-modal-pattern.tsx +1 -1
- package/docs/patterns/components-kbd--command-row.tsx +1 -1
- package/docs/patterns/components-kbd--numbered-choices.tsx +1 -1
- package/docs/patterns/components-kbd--shortcut.tsx +1 -1
- package/docs/patterns/components-moremenu--action-menu.tsx +1 -1
- package/docs/patterns/components-moremenu--in-card-header.tsx +1 -1
- package/docs/patterns/components-navlist--side-nav-settings.tsx +1 -1
- package/docs/patterns/components-pageheader--app-header-pattern.tsx +1 -1
- package/docs/patterns/components-pageheader--page-section-header.tsx +1 -1
- package/docs/patterns/components-pageheader--toolbar-header.tsx +1 -1
- package/docs/patterns/components-panel--end-detail-rail.tsx +1 -1
- package/docs/patterns/components-pillgroup--pill-group-pattern.tsx +1 -1
- package/docs/patterns/components-promptbar--pattern-prompt-bar.tsx +1 -1
- package/docs/patterns/components-prose--article-body.tsx +1 -1
- package/docs/patterns/components-radio-radiogroup--default.tsx +1 -1
- package/docs/patterns/components-scrollhorizontal--project-gallery-pattern.tsx +1 -1
- package/docs/patterns/components-scrollhorizontal--with-intro.tsx +1 -1
- package/docs/patterns/components-sectioncaption--column-caption.tsx +1 -1
- package/docs/patterns/components-sectioncaption--with-action.tsx +1 -1
- package/docs/patterns/components-sheet--bottom-sheet.tsx +1 -1
- package/docs/patterns/components-sheet--end-sheet.tsx +1 -1
- package/docs/patterns/components-sitenav--brand-and-cta.tsx +1 -1
- package/docs/patterns/components-sitenav--centered-links.tsx +1 -1
- package/docs/patterns/components-sitenav--compact.tsx +1 -1
- package/docs/patterns/components-sitenav--marketing-header.tsx +1 -1
- package/docs/patterns/components-sitenav--mega-menu.tsx +1 -1
- package/docs/patterns/components-stat--insights-row.tsx +1 -1
- package/docs/patterns/components-stepprogress--step-progress-pattern.tsx +1 -1
- package/docs/patterns/components-switch--default.tsx +1 -1
- package/docs/patterns/components-switch--settings-row.tsx +1 -1
- package/docs/patterns/components-tab--settings-pages.tsx +1 -1
- package/docs/patterns/components-taskrows--action-details.tsx +1 -1
- package/docs/patterns/components-taskrows--capsules.tsx +1 -1
- package/docs/patterns/components-taskrows--card-with-status-rows.tsx +1 -1
- package/docs/patterns/components-taskrows--controlled-expand.tsx +1 -1
- package/docs/patterns/components-taskrows--custom-slots.tsx +1 -1
- package/docs/patterns/components-taskrows--status-list.tsx +1 -1
- package/docs/patterns/components-taskrows--tag-chips.tsx +1 -1
- package/docs/patterns/components-textlink--external-destination.tsx +1 -1
- package/docs/patterns/components-textlink--inline-prose.tsx +1 -1
- package/docs/patterns/components-textlink--quiet-title.tsx +1 -1
- package/docs/patterns/components-textlink--supporting-copy.tsx +1 -1
- package/docs/patterns/components-textsequence--default.tsx +1 -1
- package/docs/patterns/components-textsequence--reduced-motion.tsx +1 -1
- package/docs/patterns/components-textsequence--shapes.tsx +1 -1
- package/docs/patterns/components-toast--stacked-notifications.tsx +1 -1
- package/docs/patterns/components-tooltip--controlled.tsx +1 -1
- package/docs/patterns/components-tooltip--disabled-control.tsx +1 -1
- package/docs/patterns/components-tooltip--icon-action.tsx +1 -1
- package/docs/patterns/components-tooltip--keyboard-shortcut.tsx +1 -1
- package/docs/patterns/components-tooltip--placement.tsx +1 -1
- package/docs/patterns/foundations-scroll-fade--horizontal-rail.tsx +1 -1
- package/docs/patterns/foundations-scroll-fade--overflowing-list.tsx +1 -1
- package/docs/patterns/guides-chart-explorations--comparison-gallery.tsx +1 -1
- package/docs/patterns/guides-filter-panel--filtered-index.tsx +41 -17
- package/docs/patterns/guides-overlay-flows--notification-preferences.tsx +1 -1
- package/docs/patterns/guides-post-page--post-page.tsx +34 -4
- package/docs/patterns/guides-profile-typography--editorial-profile.tsx +1 -1
- package/docs/patterns/index.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,54 @@ Every release of `@thewhatmatters/wmds` is listed here, newest first.
|
|
|
7
7
|
- **Pasted patterns:** when a release changes a **Pattern — …** story's Show code, it is named under Consumer actions so apps re-copy it.
|
|
8
8
|
- **How to add an entry** (contributors): add your change to the top entry. If that version is already on npm (`npm view @thewhatmatters/wmds versions`), start a new entry above it and bump `version` in `package.json` to match. `npm run check:changelog` enforces the format.
|
|
9
9
|
|
|
10
|
+
## 0.4.4
|
|
11
|
+
|
|
12
|
+
**ChatDock: the Start a project form sits in the conversation.** Having seen 0.4.3 live, the form goes back inside the chat window instead of replacing it — as a component in the conversation, without the 0.4.2 problems (no card inside a card, one header and one close, no gap above the form, no cap that clips the step). See the second 2026-10-05 amendment to **ADR-0039**.
|
|
13
|
+
|
|
14
|
+
- **ChatDock `gate`** — the form is the last item in the conversation, under the latest message, where a reply would go. The window keeps its header and its close. The composer stays in place but is off, with the placeholder "Finish or cancel the form to keep chatting" (new label `gatePlaceholder`); suggestion rows, follow-ups, and the rows under replies (Copy, thumbs, score) step aside until the form goes. The disclaimer stays.
|
|
15
|
+
- **The window stays non-modal.** No scrim; the page behind stays usable, and focus is not held in the window.
|
|
16
|
+
- **The step is never clipped.** The form never scrolls on its own. From `md` the window grows to fit the conversation and the form — up to the viewport less 7rem — and eases back after; at 1280×900, step 1 shows all seven services with the reply above it. Past that the conversation scrolls, and each step is brought into view: the whole form when it fits, else its top.
|
|
17
|
+
- **`gateSubtitle`** (new) — the window's subtitle while a gate is up, for example "Start a project". Without it the subtitle is hidden while the gate is up.
|
|
18
|
+
- **ChatDock.Gate** — flat on the window surface under a hairline, and as wide as the conversation's turns. Its header is the step's title (now an `h3`), subtitle, previous, "2 of 4", and next; it has **no close of its own** — the window's close and Escape fold the window and keep the form, and Cancel leaves it. `pending` and `error` are unchanged. `labels.close` is unused and deprecated.
|
|
19
|
+
- **Unchanged from 0.4.3:** closing the window keeps the form and its answers, and reopening brings it back at the same step; `onSubmit` returns a promise, with "Sending…", the error, and Try again; the Toaster and reduced-motion hydration fixes, the post page and filtered index options, and the `wmds-check` changes.
|
|
20
|
+
- **Components/ChatDock → Pattern — chat dock** passes `gateSubtitle="Start a project"`. **Pattern — start a project gate**: only its `close` description changed. New stories: **Start a project — after a long conversation** at 1280 and 390; the step stories now show the reply above the form.
|
|
21
|
+
- **Fix:** the conversation stays at its end while the window changes size, so the confirmation a finished form leaves is in view.
|
|
22
|
+
|
|
23
|
+
### Consumer actions
|
|
24
|
+
|
|
25
|
+
1. **WhatMatters site: re-copy Components/ChatDock → Pattern — chat dock** (`node_modules/@thewhatmatters/wmds/docs/patterns/components-chatdock--pattern-chat-dock.tsx`) over your ask component, and re-apply only your content, data, and handlers. It adds `gateSubtitle="Start a project"` to **ChatDock**. If you'd rather not re-copy, add that one prop by hand.
|
|
26
|
+
2. **WhatMatters site: re-copy Components/ChatDock → Pattern — start a project gate** (`node_modules/@thewhatmatters/wmds/docs/patterns/components-chatdock--pattern-start-project-gate.tsx`) over `components/start-project-gate.tsx` and re-apply only your services, budgets, step copy, and calendar. Only a comment changed, so `npx wmds-check` reports nothing either way; re-copy to keep the header at 0.4.4.
|
|
27
|
+
3. **The form in the conversation: nothing else to do.** It comes with the upgrade, and your `onSubmit`, `renderCalendar`, and the 0.4.3 wiring stay as they are. Check your tests:
|
|
28
|
+
- The page is no longer blocked while the form is up: a test that closed the window before clicking the page no longer needs to.
|
|
29
|
+
- The form has no close: a test that pressed the gate's close should press the window's (**Close chat**) or Escape — both still keep the form — or **Cancel** to leave it.
|
|
30
|
+
- The composer is disabled while the form is up, not hidden: a test that expected no textbox should expect a disabled one.
|
|
31
|
+
- The step's title is an `h3`.
|
|
32
|
+
4. Other apps: step 3 only, if they render a ChatDock `gate`. `gateSubtitle` is optional.
|
|
33
|
+
|
|
34
|
+
## 0.4.3
|
|
35
|
+
|
|
36
|
+
**ChatDock: the gate takes over the window.** Start a project no longer sits as a card inside the chat. While a `gate` is up the window is the form: one header, the step, and the footer on the window's bottom edge, and the window is modal. Also: two hydration fixes, a promise-based send for the gate pattern, options for the post page and filtered index patterns, and fewer false positives in `wmds-check`. See the amendments to **ADR-0039**, **ADR-0040**, and **ADR-0041**.
|
|
37
|
+
|
|
38
|
+
- **ChatDock `gate`** — fills the window. The window's header, the conversation, the composer, the suggestion rows, the follow-ups, and the disclaimer fade out and wait behind it; finishing or cancelling brings them back as they were. The cap that kept the latest reply in view is gone: the step body takes the window's height and scrolls, and the footer sits on the window's bottom edge (above the home indicator on phones). While the gate is up the fixed window is modal: a scrim covers the page and **SiteNav**, the page is inert and does not scroll, and Tab stays inside (`aria-modal="true"`). Inline previews are not modal.
|
|
39
|
+
- **One close.** The gate's header close (named "Close chat", from ChatDock's `labels.close`), Escape, and a click on the scrim fold the window and keep the gate with its progress; reopening the chat brings it back. The gate's Cancel leaves it. Before, Escape and the gate's close left the gate and the window had a second close.
|
|
40
|
+
- **ChatDock.Gate** — a flush shell in the window instead of a raised card; the step sits on the window surface, not an inset well. New `pending` (shows `labels.pending`, "Sending…", in a status line, disables the step controls, sets `aria-busy`) and `error` (a line over the footer, announced). The header's next control is off on the last step, so `onNext` there is the footer's primary action — "Send" or "Try again" through `continueLabel`. New label `pending`.
|
|
41
|
+
- **Components/ChatDock → Pattern — start a project gate** — `onSubmit` returns a promise. Booking or skipping shows "Sending…"; the confetti, the answers, and the confirmation wait for it to resolve. If it rejects, every answer stays, the gate says the send failed, and Try again sends it again. `close` is the gate's Cancel. New stories: **Start a project — send failed** at 1280 and 390.
|
|
42
|
+
- **Fix: Toaster hydration.** **Toaster** rendered its list in the browser and nothing on the server, so a layout that held it failed hydration on every page. It now renders nothing on the server and in the hydration render, and mounts its list right after.
|
|
43
|
+
- **Fix: ChatDock hydration under reduced motion.** The closed window's inline style differed between the server and a browser that prefers reduced motion. ChatDock now reads reduced motion as off on the server and in the hydration render, and switches right after, while the window is hidden.
|
|
44
|
+
- **Guides/Post page → Pattern — post page** — `metadataSide` (`"start"`, default, or `"end"`) and `metadataColumns` (`4`, default, or `3`; the article takes the rest) place the metadata panel from `lg`. Below `lg` it stacks above the article either way. New story **Metadata on the right**.
|
|
45
|
+
- **Guides/Filter panel → Pattern — filtered index** — a post's `facets` take one option or a list per group (`{ topic: ["guides", "brand"] }`); within a group the options on are alternatives, and each option counts every post that has it. New `defaultSelection` (the filters on when the page opens) and `selection` + `onSelectionChange` (the app holds them). New exported types `FilterSelection` and `FilteredIndexProps`. New story **Starting selection**.
|
|
46
|
+
- **`wmds-check`** — `pattern-drift` compares a pasted pattern's markup and classes with the shipped file (its elements in order, its `className` and `style` values, and its `*Classes` constants), so edits to content, data, handlers, and exported names no longer warn; the warning names the first difference. `raw-color` no longer reads a character reference such as `'` as a hex color.
|
|
47
|
+
|
|
48
|
+
### Consumer actions
|
|
49
|
+
|
|
50
|
+
1. **WhatMatters site: re-copy Components/ChatDock → Pattern — start a project gate** (`node_modules/@thewhatmatters/wmds/docs/patterns/components-chatdock--pattern-start-project-gate.tsx`) over `components/start-project-gate.tsx`, and re-apply only your services, budgets, step copy, and calendar. Then make `onSubmit` return the send's promise and reject when it fails — for example `onSubmit={async (intake) => { const response = await fetch("/api/intake", { method: "POST", body: JSON.stringify(intake) }); if (!response.ok) throw new Error("Intake failed"); }}`. TypeScript flags a handler that returns nothing. Remove the toast you show on a failed send; the gate shows the error and Try again.
|
|
51
|
+
2. **The gate taking over the window: nothing to re-copy.** It comes with the upgrade, and **Pattern — chat dock** is unchanged. While the gate is up the page behind is inert: a site test that clicks the page with the gate open must close the window first (the gate's close, Escape, or the scrim). A test that pressed Escape or the gate's close to leave the gate now finds the window folded with the gate kept; press **Cancel** to leave it.
|
|
52
|
+
3. **Mount `<Toaster />` directly in the layout** and remove the after-hydration workaround.
|
|
53
|
+
4. **WhatMatters site, post page: re-copy Guides/Post page → Pattern — post page** (`node_modules/@thewhatmatters/wmds/docs/patterns/guides-post-page--post-page.tsx`), re-apply only your content, data, and handlers, and pass `metadataSide="end"` and `metadataColumns={3}` where you render `PostPage` instead of editing the panel's classes.
|
|
54
|
+
5. **WhatMatters site, blog index: re-copy Guides/Filter panel → Pattern — filtered index** (`node_modules/@thewhatmatters/wmds/docs/patterns/guides-filter-panel--filtered-index.tsx`) and re-apply only your content and data. Map each post's topics to a list (`facets: { topic: post.topics }`). For the category tags that link to `/blog?topic=<id>`, read the parameter in the page and pass `defaultSelection={{ topic: [topic] }}` when it is set — or pass `selection` and `onSelectionChange` to keep the filters in the URL.
|
|
55
|
+
6. **`npx wmds-check --max-warnings 0`** now passes with content-only edits to pasted patterns. A remaining `pattern-drift` names the first markup or class that differs: re-copy that pattern, or use the pattern's props (steps 4 and 5) instead of editing its classes.
|
|
56
|
+
7. Other apps: steps 2 and 3 only, if they render a ChatDock `gate` or a **Toaster**. **ChatDock.Gate** `pending` and `error`, and the patterns' new props, are optional.
|
|
57
|
+
|
|
10
58
|
## 0.4.2
|
|
11
59
|
|
|
12
60
|
**Breadcrumb** — the path to the current page, after the shadcn/ui breadcrumb: links from the root, a separator between them, the current page last, and a long path folded into a "…" menu of links. See **ADR-0042**.
|
package/CONSUMING.md
CHANGED
|
@@ -152,7 +152,7 @@ npx wmds-check app components --max-warnings 0
|
|
|
152
152
|
| `raw-color` | error | hex, `rgb()`, `hsl()`, `oklch()` values in `className` or `style` |
|
|
153
153
|
| `raw-type` | warning | `text-sm`-style sizes or `text-[…]` — use `type-*` utilities |
|
|
154
154
|
| `raw-motion` | warning | `duration-[…]`, `ease-[…]`, `delay-[…]`, numeric Motion durations |
|
|
155
|
-
| `pattern-drift` | warning | a pasted pattern
|
|
155
|
+
| `pattern-drift` | warning | a pasted pattern's markup or classes differ from `docs/patterns/<id>.tsx` in the installed version — its elements in order, its `className` and `style` values, and its `*Classes` constants. Content, data, handlers, and exported names may change without a warning |
|
|
156
156
|
| `pattern-stale` | warning | a pasted pattern's header names an older version |
|
|
157
157
|
| `pattern-removed` | error | a pasted pattern's id no longer ships |
|
|
158
158
|
|
|
@@ -265,7 +265,7 @@ import {
|
|
|
265
265
|
| `Input` | `label`, `description`, `status`, `message`, `loading`, `endBadge`, `icon`, `size` | Components/Input — pill shell; Required via `endBadge={<Badge>…</Badge>}` |
|
|
266
266
|
| `Search` | `size`, `placeholder`, `onSubmit` | Components/Search — inline input + button row |
|
|
267
267
|
| `PromptBar` | `value`, `onValueChange`, `onSend`, `placeholder` (default Ask anything…), `start`, `end` | Components/PromptBar — **Pattern — prompt bar**. Wide pill, inline field (one line empty, up to 3 lines, then scroll), inset **IconButton** send. Muted until there is text, then `--color-brand` (`#011272`). Enter sends. `start` takes the brand mark; `end` takes extra inset controls. Voice and attachments are not part of this version. |
|
|
268
|
-
| `ChatDock` | `title`, `subtitle`, `mark`, `greeting`, `messages` (replies may carry `copyText`, `meta`, `feedback`), `thinking`, `suggestions`, `followUps`, `followUpsPlacement`, `onSend`, `onSuggestionSelect`, `onMessageFeedback`, `gate` (**ChatDock.Gate**), `disclaimer` | Components/ChatDock — **Pattern — chat dock**. The site assistant: a pinned **PromptBar** with suggested-question pills on hover that opens into a non-modal chat window (full screen on phones). The app owns the conversation and the request, and passes `followUps` for the latest reply when it has them (shown under the reply by default). Finished replies get Copy, thumbs, and a score row from `copyText`, `onMessageFeedback` with `feedback`, and `meta`. Start a project runs as a `gate` in the composer
|
|
268
|
+
| `ChatDock` | `title`, `subtitle`, `mark`, `greeting`, `messages` (replies may carry `copyText`, `meta`, `feedback`), `thinking`, `suggestions`, `followUps`, `followUpsPlacement`, `onSend`, `onSuggestionSelect`, `onMessageFeedback`, `gate` (**ChatDock.Gate**), `gateSubtitle`, `disclaimer` | Components/ChatDock — **Pattern — chat dock**. The site assistant: a pinned **PromptBar** with suggested-question pills on hover that opens into a non-modal chat window (full screen on phones). The app owns the conversation and the request, and passes `followUps` for the latest reply when it has them (shown under the reply by default). Finished replies get Copy, thumbs, and a score row from `copyText`, `onMessageFeedback` with `feedback`, and `meta`. Start a project runs as a `gate` in the conversation, under the latest message, with the composer off until it finishes — **Pattern — start a project gate**. Replaces the separate ask page. |
|
|
269
269
|
| `Card` | `variant`, `shape`, `padding` | Components/Card/Card — `Card.Header` (`start` | `end`), **`Card.Body` slot** (no default fill), `Card.Footer` |
|
|
270
270
|
| `Accordion` | `variant`, `flush` (plain), `Accordion.Item` `leading` / `label` / `trailing` / `open` | Components/Accordion — FAQ, settings sections; **Pattern — flush** for filter groups. Closed panels leave the tab order |
|
|
271
271
|
| `Breadcrumb` | `items` (`{ label, href }`, current page last), `maxItems`, `separator` (`chevron` \| `slash`), `variant` (`sans` \| `mono`), `renderLink`, `labels` | Components/Breadcrumb — **Pattern — path**, **long path**, **router links**, **editorial** |
|
package/bin/wmds-check.mjs
CHANGED
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
* raw-color error hex / rgb / hsl colors in className or style
|
|
14
14
|
* raw-type warn text-xs…text-9xl or text-[…] sizes — use type-* utilities
|
|
15
15
|
* raw-motion warn duration-[…] / ease-[…] / delay-[…] utilities, or numeric Motion durations
|
|
16
|
-
* pattern-drift warn a pasted pattern
|
|
16
|
+
* pattern-drift warn a pasted pattern's markup or classes differ from docs/patterns/<id>.tsx in the
|
|
17
|
+
* installed package (its elements, className / style values, *Classes constants);
|
|
18
|
+
* content, data, handlers, and exports may change
|
|
17
19
|
* pattern-stale warn a pasted pattern's header names an older package version
|
|
18
20
|
* pattern-removed error a pasted pattern's id no longer ships
|
|
19
21
|
*
|
|
@@ -77,12 +79,100 @@ const rawControls = [
|
|
|
77
79
|
["textarea", "TextArea / PromptBar"],
|
|
78
80
|
];
|
|
79
81
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
// Hex colors, not character references such as ' or '.
|
|
83
|
+
const colorValue = /(?<![&\w])#[0-9a-fA-F]{3,8}\b|rgba?\(|hsla?\(|oklch\(/;
|
|
84
|
+
const colorMatch = /(?<![&\w])#[0-9a-fA-F]{3,8}|rgba?\(.*?\)|hsla?\(.*?\)|oklch\(.*?\)/;
|
|
85
|
+
|
|
86
|
+
/** The index past the end of the string literal that opens at `start` (quote or backtick). */
|
|
87
|
+
const skipString = (code, start) => {
|
|
88
|
+
const quote = code[start];
|
|
89
|
+
for (let index = start + 1; index < code.length; index++) {
|
|
90
|
+
const char = code[index];
|
|
91
|
+
if (char === "\\") {
|
|
92
|
+
index++;
|
|
93
|
+
} else if (quote === "`" && char === "$" && code[index + 1] === "{") {
|
|
94
|
+
index = skipBalanced(code, index + 1) - 1;
|
|
95
|
+
} else if (char === quote) {
|
|
96
|
+
return index + 1;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return code.length;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/** The index past the bracket that closes the one at `start`, skipping strings. */
|
|
103
|
+
const skipBalanced = (code, start) => {
|
|
104
|
+
let depth = 0;
|
|
105
|
+
for (let index = start; index < code.length; index++) {
|
|
106
|
+
const char = code[index];
|
|
107
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
108
|
+
index = skipString(code, index) - 1;
|
|
109
|
+
} else if ("{([".includes(char)) {
|
|
110
|
+
depth++;
|
|
111
|
+
} else if ("})]".includes(char)) {
|
|
112
|
+
depth--;
|
|
113
|
+
if (depth === 0) return index + 1;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return code.length;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/** One attribute value from `start`: a quoted string or a {…} expression. */
|
|
120
|
+
const readValue = (code, start) => {
|
|
121
|
+
const char = code[start];
|
|
122
|
+
if (char === '"' || char === "'") return code.slice(start, skipString(code, start));
|
|
123
|
+
if (char === "{") return code.slice(start, skipBalanced(code, start));
|
|
124
|
+
return "";
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/** A declaration's value from `start` to the semicolon that ends it. */
|
|
128
|
+
const readDeclaration = (code, start) => {
|
|
129
|
+
let depth = 0;
|
|
130
|
+
for (let index = start; index < code.length; index++) {
|
|
131
|
+
const char = code[index];
|
|
132
|
+
if (char === '"' || char === "'" || char === "`") index = skipString(code, index) - 1;
|
|
133
|
+
else if ("{([".includes(char)) depth++;
|
|
134
|
+
else if ("})]".includes(char)) depth--;
|
|
135
|
+
else if (char === ";" && depth === 0) return code.slice(start, index);
|
|
136
|
+
}
|
|
137
|
+
return code.slice(start);
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const squash = (text) => text.replace(/\s+/g, " ").trim();
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* What a pasted pattern must keep: its JSX elements in order, every className and style value, and
|
|
144
|
+
* every *Classes constant. Text, data, handler bodies, and names an app exports are content — they
|
|
145
|
+
* can change without drift.
|
|
146
|
+
*/
|
|
147
|
+
const patternStructure = (source) => {
|
|
148
|
+
const code = source.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:"'`\\])\/\/.*$/gm, "$1");
|
|
149
|
+
const parts = [];
|
|
150
|
+
const tokens = /(?<![\w.$)\]])<([A-Za-z][\w.]*)|\b(className|style)=|\bconst\s+(\w*Classes)\b[^=]*=\s*/g;
|
|
151
|
+
for (const match of code.matchAll(tokens)) {
|
|
152
|
+
const end = match.index + match[0].length;
|
|
153
|
+
if (match[1]) parts.push(`<${match[1]}>`);
|
|
154
|
+
else if (match[2]) parts.push(`${match[2]}=${squash(readValue(code, end))}`);
|
|
155
|
+
else parts.push(`${match[3]} = ${squash(readDeclaration(code, end))}`);
|
|
156
|
+
}
|
|
157
|
+
return parts;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
/** The first place two structures part, for the finding's message — clipped around where they differ. */
|
|
161
|
+
const firstDifference = (shipped, pasted) => {
|
|
162
|
+
const length = Math.max(shipped.length, pasted.length);
|
|
163
|
+
for (let index = 0; index < length; index++) {
|
|
164
|
+
const want = shipped[index];
|
|
165
|
+
const have = pasted[index];
|
|
166
|
+
if (want === have) continue;
|
|
167
|
+
let common = 0;
|
|
168
|
+
while (want != null && have != null && common < want.length && want[common] === have[common]) common++;
|
|
169
|
+
const from = Math.max(0, common - 24);
|
|
170
|
+
const clip = (text) =>
|
|
171
|
+
text == null ? "nothing" : `${from > 0 ? "…" : ""}${text.slice(from, from + 64)}${text.length > from + 64 ? "…" : ""}`;
|
|
172
|
+
return `${clip(have)} where the pattern has ${clip(want)}`;
|
|
173
|
+
}
|
|
174
|
+
return "";
|
|
175
|
+
};
|
|
86
176
|
|
|
87
177
|
for (const file of files) {
|
|
88
178
|
const source = readFileSync(file, "utf8");
|
|
@@ -120,7 +210,7 @@ for (const file of files) {
|
|
|
120
210
|
}
|
|
121
211
|
|
|
122
212
|
if (/(className|class|style)=/.test(line) || /(color|background|border|fill|stroke)\s*:/.test(line)) {
|
|
123
|
-
if (
|
|
213
|
+
if (colorValue.test(line) && !/var\(--/.test(line.match(colorMatch)?.[0] ?? "") && !ignored(lines, index, "raw-color")) {
|
|
124
214
|
report(file, n, "raw-color", "error", "raw color value — use a semantic color utility or token");
|
|
125
215
|
}
|
|
126
216
|
}
|
|
@@ -150,8 +240,16 @@ for (const file of files) {
|
|
|
150
240
|
if (header[1] !== packageVersion) {
|
|
151
241
|
report(file, 1, "pattern-stale", "warn", `pasted from ${header[1]}, installed ${packageVersion} — re-copy if CHANGELOG names it`);
|
|
152
242
|
}
|
|
153
|
-
|
|
154
|
-
|
|
243
|
+
const shippedStructure = patternStructure(readFileSync(shipped, "utf8"));
|
|
244
|
+
const pastedStructure = patternStructure(source);
|
|
245
|
+
if (shippedStructure.join("\n") !== pastedStructure.join("\n")) {
|
|
246
|
+
report(
|
|
247
|
+
file,
|
|
248
|
+
1,
|
|
249
|
+
"pattern-drift",
|
|
250
|
+
"warn",
|
|
251
|
+
`markup or classes differ from docs/patterns/${id}.tsx (${firstDifference(shippedStructure, pastedStructure)}) — allowed edits are content, data, handlers, exports`,
|
|
252
|
+
);
|
|
155
253
|
}
|
|
156
254
|
}
|
|
157
255
|
}
|
|
@@ -64,6 +64,8 @@ export interface ChatDockLabels {
|
|
|
64
64
|
helpful: string;
|
|
65
65
|
/** Thumbs down under a reply. Default: "Mark this reply not helpful". */
|
|
66
66
|
notHelpful: string;
|
|
67
|
+
/** The field's placeholder while a `gate` is up and the composer is off. Default: "Finish or cancel the form to keep chatting". */
|
|
68
|
+
gatePlaceholder: string;
|
|
67
69
|
}
|
|
68
70
|
export declare const chatDockDefaultLabels: ChatDockLabels;
|
|
69
71
|
export declare const chatDockFollowUpsPlacements: readonly ["inline", "composer"];
|
|
@@ -110,14 +112,20 @@ export interface ChatDockProps {
|
|
|
110
112
|
*/
|
|
111
113
|
onMessageFeedback?: (message: ChatDockMessage, value: ChatDockFeedback) => void;
|
|
112
114
|
/**
|
|
113
|
-
* A form in the
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
* window and moves focus into it; clearing it brings the composer back with
|
|
117
|
-
*
|
|
118
|
-
* the gate
|
|
115
|
+
* A form in the conversation — usually **ChatDock.Gate** with the steps of Start a project. While
|
|
116
|
+
* it is set it sits under the latest message, where a reply would, and the window keeps its
|
|
117
|
+
* header: the composer stays in place but is off, and the suggestion rows and follow-ups step aside.
|
|
118
|
+
* Setting it opens the window and moves focus into it; clearing it brings the composer back with
|
|
119
|
+
* focus. The window grows to fit the form, up to the viewport, and the conversation scrolls past
|
|
120
|
+
* that. Closing the window keeps the gate, with its progress, for when it reopens. The window stays
|
|
121
|
+
* non-modal.
|
|
119
122
|
*/
|
|
120
123
|
gate?: ReactNode;
|
|
124
|
+
/**
|
|
125
|
+
* The window's subtitle while `gate` is set — the form's name, for example "Start a project".
|
|
126
|
+
* Without it the subtitle is hidden while the gate is up.
|
|
127
|
+
*/
|
|
128
|
+
gateSubtitle?: string;
|
|
121
129
|
/** Controlled open state. */
|
|
122
130
|
open?: boolean;
|
|
123
131
|
defaultOpen?: boolean;
|
|
@@ -169,15 +177,13 @@ export declare function chatDockReplyRow({ message, isLatest, thinking, takesVot
|
|
|
169
177
|
*/
|
|
170
178
|
export declare function chatDockOpenHeight(placement: ChatDockPlacement, viewportHeight: number, remPx: number): number;
|
|
171
179
|
/**
|
|
172
|
-
* The
|
|
173
|
-
*
|
|
174
|
-
* below 12rem, so a gate stays usable when a phone keyboard leaves little room.
|
|
180
|
+
* The window's height while a gate is up, in px: tall enough for the conversation and the form
|
|
181
|
+
* (`needed`), never below its usual height (`normal`), and never past `max` (the viewport less 7rem).
|
|
175
182
|
*/
|
|
176
|
-
export declare function
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
remPx: number;
|
|
183
|
+
export declare function chatDockGateWindowHeight({ normal, needed, max }: {
|
|
184
|
+
normal: number;
|
|
185
|
+
needed: number;
|
|
186
|
+
max: number;
|
|
181
187
|
}): number;
|
|
182
188
|
/**
|
|
183
189
|
* How the window moves. `grow` (from `md`, and inline): it sits on the composer's bottom edge and
|
|
@@ -190,7 +196,7 @@ export type ChatDockWindowMotion = "grow" | "rise";
|
|
|
190
196
|
* around the same composer — header, conversation, suggestion rows, and an optional disclaimer.
|
|
191
197
|
* Escape or Close folds it back into the bar. The page behind stays usable.
|
|
192
198
|
*/
|
|
193
|
-
declare function ChatDockRoot({ title, subtitle, mark, greeting, messages, thinking, suggestions, onSend, onSuggestionSelect, followUps, followUpsPlacement, onMessageFeedback, gate, open: openProp, defaultOpen, onOpenChange, placeholder, disclaimer, labels: labelsProp, placement, className, }: ChatDockProps): import("react").JSX.Element;
|
|
199
|
+
declare function ChatDockRoot({ title, subtitle, mark, greeting, messages, thinking, suggestions, onSend, onSuggestionSelect, followUps, followUpsPlacement, onMessageFeedback, gate, gateSubtitle, open: openProp, defaultOpen, onOpenChange, placeholder, disclaimer, labels: labelsProp, placement, className, }: ChatDockProps): import("react").JSX.Element;
|
|
194
200
|
/**
|
|
195
201
|
* Pinned prompt that opens into a chat window. At rest it is a **PromptBar** with the brand
|
|
196
202
|
* mark; hovering shows suggestion pills above it. Focusing or typing opens a non-modal window
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChatDock.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/ChatDock/ChatDock.tsx"],"names":[],"mappings":"AAAA,OAAO,EAUL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ChatDock.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/ChatDock/ChatDock.tsx"],"names":[],"mappings":"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"}
|