@thewhatmatters/wmds 0.4.34 → 0.4.35
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 +24 -0
- package/dist/components/molecules/CalEmbed/CalEmbed.d.ts +6 -6
- package/dist/components/molecules/CalEmbed/CalEmbed.d.ts.map +1 -1
- package/dist/components/molecules/CalEmbed/CalEmbed.js +20 -15
- package/dist/components/molecules/IntakeForm/IntakeHoneypot.d.ts +17 -0
- package/dist/components/molecules/IntakeForm/IntakeHoneypot.d.ts.map +1 -0
- package/dist/components/molecules/IntakeForm/IntakeHoneypot.js +29 -0
- package/dist/components/organisms/IntakeConfirmation/IntakeConfirmation.d.ts +14 -2
- package/dist/components/organisms/IntakeConfirmation/IntakeConfirmation.d.ts.map +1 -1
- package/dist/components/organisms/IntakeConfirmation/IntakeConfirmation.js +38 -33
- package/dist/components/organisms/IntakeConfirmation/intakeConfirmationStyles.d.ts +5 -1
- package/dist/components/organisms/IntakeConfirmation/intakeConfirmationStyles.d.ts.map +1 -1
- package/dist/components/organisms/IntakeConfirmation/intakeConfirmationStyles.js +3 -3
- package/dist/components/organisms/IntakeModal/IntakeModal.d.ts +11 -2
- package/dist/components/organisms/IntakeModal/IntakeModal.d.ts.map +1 -1
- package/dist/components/organisms/IntakeModal/IntakeModal.js +91 -59
- package/dist/components/organisms/IntakeModal/intakeModalStyles.d.ts +3 -3
- package/dist/components/organisms/IntakeModal/intakeModalStyles.d.ts.map +1 -1
- package/dist/components/organisms/IntakeModal/intakeModalStyles.js +1 -1
- package/dist/components/organisms/IntakeModal/useIntakeUrlState.d.ts +12 -0
- package/dist/components/organisms/IntakeModal/useIntakeUrlState.d.ts.map +1 -0
- package/dist/components/organisms/IntakeModal/useIntakeUrlState.js +16 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +82 -80
- package/dist/styles.css +1 -1
- package/docs/components.md +1 -1
- package/docs/exports.json +2 -2
- package/docs/patterns/components-accordion--flush.tsx +1 -1
- package/docs/patterns/components-appshell--portal-dashboard-pattern.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--status-pill.tsx +1 -1
- package/docs/patterns/components-badge--with-avatar.tsx +1 -1
- package/docs/patterns/components-band--page-in-bands.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-above.tsx +16 -0
- 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-card--terminal-frame.tsx +1 -1
- package/docs/patterns/components-card-selectablecard--selectable-cards-pattern.tsx +1 -1
- package/docs/patterns/components-carousel--image-carousel.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--revenue-by-line.tsx +1 -1
- package/docs/patterns/components-chart--segmented-ring-pattern.tsx +1 -1
- package/docs/patterns/components-chart--unit-grid-composition.tsx +1 -1
- package/docs/patterns/components-chatdock--pattern-chat-dock.tsx +1 -1
- package/docs/patterns/components-chatdock--pattern-start-project-gate.tsx +1 -1
- 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-copyfield--clipboard-blocked.tsx +1 -1
- package/docs/patterns/components-copyfield--copied.tsx +1 -1
- package/docs/patterns/components-copyfield--copy-key.tsx +1 -1
- package/docs/patterns/components-copyfield--on-navy.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--alert-dialog-typed-confirmation.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-displaycontrols--theme-switch.tsx +1 -1
- package/docs/patterns/components-errorsummary--contact-form.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-filterpanel--panel.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-herointro--with-actions.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 +8 -2
- package/docs/patterns/components-intakeform--about-you-pattern.tsx +1 -1
- package/docs/patterns/components-intakeform--short-form-pattern.tsx +1 -1
- package/docs/patterns/components-intakemodal--intake-modal-pattern.tsx +2 -2
- 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-linktile--resource-tile.tsx +1 -1
- package/docs/patterns/components-linktile--router-link.tsx +1 -1
- package/docs/patterns/components-logview--detail-pane.tsx +1 -1
- package/docs/patterns/components-logview--log-viewer.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--app-sidebar.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-sheet--side-sheet-header-actions.tsx +1 -1
- package/docs/patterns/components-sheet--side-sheet-url-deep-link.tsx +1 -1
- package/docs/patterns/components-sheet--side-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--hero-stat.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-table--approvals-with-sheet.tsx +1 -1
- package/docs/patterns/components-table--approvals.tsx +1 -1
- package/docs/patterns/components-table--basic.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--needs-you-table.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-textarea--save-status.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-tilegrid--masonry.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-grid.tsx +1 -1
- package/docs/patterns/guides-filter-panel--filtered-index.tsx +1 -1
- package/docs/patterns/guides-overlay-flows--notification-preferences.tsx +1 -1
- package/docs/patterns/guides-post-page--post-page.tsx +1 -1
- package/docs/patterns/guides-profile-typography--editorial-profile.tsx +1 -1
- package/docs/patterns/guides-resource-detail--detail.tsx +1 -1
- package/docs/patterns/index.json +5 -5
- package/package.json +1 -1
- package/docs/patterns/components-calembed--pattern-skip-in-footer.tsx +0 -25
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,30 @@ 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.35
|
|
11
|
+
|
|
12
|
+
**Contact and booking forms: two steps, booking after the request, a way out above the calendar, and nothing lost on close.**
|
|
13
|
+
|
|
14
|
+
- **IntakeModal** (Contact and booking forms T7, T9):
|
|
15
|
+
- Two steps by default (`steps` was 4): details, then the optional booking. The confirmation isn't counted.
|
|
16
|
+
- New `hasAnswers`: with typed answers, Close and Escape ask "Discard your answers?" (Keep editing, focused / Discard).
|
|
17
|
+
- New **useIntakeUrlState**: keeps `?sketch` in the URL while the modal is open. The link can be shared, a refresh reopens it, and Back closes it.
|
|
18
|
+
- **CalEmbed** (T8): the "Skip, just email me" link sits **above** the calendar, so on a phone it's visible without scrolling past the month. With no embed (not set up, or it failed), the email route shows inside the empty state straight away.
|
|
19
|
+
- **CalEmbed stories:** "Pattern — skip in footer" is replaced by **Pattern — skip above the calendar** (`CalEmbed.Skip` in `Card.Header`). The pasted pattern id changes, so `wmds-check` reports `pattern-removed` for copies of the old one: move the skip above the calendar.
|
|
20
|
+
- **IntakeConfirmation** (T2, T3): one "what happens next and when" sentence: `email` and `replyWithin` (default "within one business day") give "We'll email you at {email} within one business day with a few times that fit."; the booked variant names `bookingTime` in it. `summary` shows as "You told us: “…”". Then `contact`, then Done. New export `intakeConfirmationReplyWithin`.
|
|
21
|
+
- **IntakeModal**: no Back on step 1; the WM mark and wordmark take the ink in dark mode (navy on near-black failed 3:1).
|
|
22
|
+
- **IntakeHoneypot** and `isIntakeHoneypotFilled` (new, T4): a spam trap people never see or reach (`aria-hidden`, `tabindex="-1"`, no autofill). Drop requests where it's filled, on the server, with rate limits. No CAPTCHA.
|
|
23
|
+
- Stories **Components/IntakeModal → Pattern — sketch request** (details → optional booking → confirmation; "Send my request"; reply time under the form; contact details on the confirmation) and **Pattern — send failed** (answers kept, Try again, email route; T5, T6). Interaction tests cover the URL, the discard question, both steps, Back keeping answers, the skip above the calendar, the failure and the honeypot.
|
|
24
|
+
|
|
25
|
+
### Consumer actions
|
|
26
|
+
|
|
27
|
+
- Pass `steps={2}` or drop `steps`, and move the booking after the details are sent.
|
|
28
|
+
- Pass `hasAnswers` while the visitor has typed something, and keep answers in your state.
|
|
29
|
+
- Open the modal with `useIntakeUrlState`, and give the form its own page too (see wmds-patterns Contact — Sketch Page).
|
|
30
|
+
- Add **IntakeHoneypot** and check it on the server.
|
|
31
|
+
- On the confirmation, pass `summary` and `contact`. Pass `email` so the sentence names it, and change `replyWithin` if one business day isn't true for you.
|
|
32
|
+
- If you placed `CalEmbed.Skip` after the calendar (for example in `Card.Footer`), move it to `Card.Header`, above the calendar.
|
|
33
|
+
|
|
10
34
|
## 0.4.34
|
|
11
35
|
|
|
12
36
|
**Required and optional fields: mark the exception, read the badge with the field, never on autofill. Field width and form layout: widths that hint at the answer, a State select, side labels only on wide screens, and counters that don't cut text. Dropdowns, radios and checkboxes: a native Select for forms, bigger boxes with visible borders, and errors on Continue.**
|
|
@@ -4,7 +4,7 @@ export type CalEmbedLayoutClassName = string;
|
|
|
4
4
|
export declare const calEmbedSkipHref = "#email";
|
|
5
5
|
export declare const calEmbedSkipLabel = "Skip, just email me";
|
|
6
6
|
export declare const calEmbedEmptyTitle = "Booking isn\u2019t available right now";
|
|
7
|
-
export declare const calEmbedEmptyDescription = "
|
|
7
|
+
export declare const calEmbedEmptyDescription = "We\u2019ll follow up by email with a few times instead.";
|
|
8
8
|
export interface CalEmbedSkipProps {
|
|
9
9
|
/** Skip destination. Default `#email`. */
|
|
10
10
|
skipHref?: string;
|
|
@@ -26,10 +26,10 @@ export interface CalEmbedProps {
|
|
|
26
26
|
/** Empty-state supporting line. Default points visitors at the skip. */
|
|
27
27
|
emptyDescription?: ReactNode;
|
|
28
28
|
/**
|
|
29
|
-
* Skip slot. Omit to render the default **TextLink**
|
|
30
|
-
* Pass `false` or **CalEmbed.Skip** when you place the skip yourself
|
|
31
|
-
* (
|
|
32
|
-
* when this slot is used.
|
|
29
|
+
* Skip slot. Omit to render the default **TextLink** above the frame (or inside the empty state).
|
|
30
|
+
* Pass `false` or **CalEmbed.Skip** when you place the skip yourself. Keep it visible without
|
|
31
|
+
* scrolling past the calendar at 390 (T8): above the frame or in a pinned footer, not after a month
|
|
32
|
+
* grid. CalEmbed does not render an in-body skip when this slot is used.
|
|
33
33
|
*/
|
|
34
34
|
skip?: ReactNode | false;
|
|
35
35
|
/** Skip destination when the in-body skip is shown. Default `#email`. */
|
|
@@ -41,7 +41,7 @@ export interface CalEmbedProps {
|
|
|
41
41
|
className?: CalEmbedLayoutClassName;
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
|
-
* Same **TextLink** CalEmbed uses
|
|
44
|
+
* Same **TextLink** CalEmbed uses above the frame. Place it in **Card.Header** (above the calendar, T8)
|
|
45
45
|
* and pass `skip={false}` (or `skip={<CalEmbed.Skip />}`) so the in-body link is omitted.
|
|
46
46
|
*/
|
|
47
47
|
export declare function CalEmbedSkip({ skipHref, skipLabel, onSkip, className, }: CalEmbedSkipProps): import("react").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CalEmbed.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/CalEmbed/CalEmbed.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,OAAO,CAAC;AAUnD,qCAAqC;AACrC,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE7C,eAAO,MAAM,gBAAgB,WAAW,CAAC;AACzC,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AACvD,eAAO,MAAM,kBAAkB,2CAAsC,CAAC;AACtE,eAAO,MAAM,wBAAwB,
|
|
1
|
+
{"version":3,"file":"CalEmbed.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/CalEmbed/CalEmbed.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,OAAO,CAAC;AAUnD,qCAAqC;AACrC,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE7C,eAAO,MAAM,gBAAgB,WAAW,CAAC;AACzC,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AACvD,eAAO,MAAM,kBAAkB,2CAAsC,CAAC;AACtE,eAAO,MAAM,wBAAwB,4DAAuD,CAAC;AAE7F,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,uBAAuB,CAAC;CACrC;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iGAAiG;IACjG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,uBAAuB,CAAC;CACrC;AAcD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAA2B,EAC3B,SAA6B,EAC7B,MAAM,EACN,SAAS,GACV,EAAE,iBAAiB,+BAWnB;AAED;;;;GAIG;AACH,iBAAS,YAAY,CAAC,EACpB,QAAQ,EACR,UAA+B,EAC/B,gBAA2C,EAC3C,IAAI,EACJ,QAA2B,EAC3B,SAA6B,EAC7B,MAAM,EACN,SAAS,GACV,EAAE,aAAa,+BAsBf;AAED,eAAO,MAAM,QAAQ;;CAEnB,CAAC"}
|
|
@@ -5,7 +5,7 @@ import { TextLink as n } from "../../atoms/TextLink/TextLink.js";
|
|
|
5
5
|
import { calEmbedClasses as r, calEmbedEmptyClasses as i, calEmbedFrameClasses as a } from "./calEmbedStyles.js";
|
|
6
6
|
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
7
7
|
//#region src/components/molecules/CalEmbed/CalEmbed.tsx
|
|
8
|
-
var c = "#email", l = "Skip, just email me", u = "Booking isn’t available right now", d = "
|
|
8
|
+
var c = "#email", l = "Skip, just email me", u = "Booking isn’t available right now", d = "We’ll follow up by email with a few times instead.";
|
|
9
9
|
function f(e) {
|
|
10
10
|
return e != null && e !== !1 && e !== "";
|
|
11
11
|
}
|
|
@@ -22,27 +22,32 @@ function m({ skipHref: e = c, skipLabel: t = l, onSkip: r, className: i }) {
|
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
function h({ children: n, emptyTitle: p = u, emptyDescription: h = d, skip: g, skipHref: _ = c, skipLabel: v = l, onSkip: y, className: b }) {
|
|
25
|
+
let x = f(n), S = g === void 0 ? /* @__PURE__ */ o(m, {
|
|
26
|
+
skipHref: _,
|
|
27
|
+
skipLabel: v,
|
|
28
|
+
onSkip: y
|
|
29
|
+
}) : null;
|
|
25
30
|
return /* @__PURE__ */ s("div", {
|
|
26
31
|
className: e(r, b),
|
|
27
32
|
"data-cal-embed": "",
|
|
28
|
-
children: [/* @__PURE__ */ o("div", {
|
|
33
|
+
children: [x ? S : null, /* @__PURE__ */ o("div", {
|
|
29
34
|
className: a,
|
|
30
|
-
children:
|
|
35
|
+
children: x ? n : /* @__PURE__ */ s("div", {
|
|
31
36
|
className: i,
|
|
32
37
|
"data-cal-embed-empty": "",
|
|
33
|
-
children: [
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
children: [
|
|
39
|
+
/* @__PURE__ */ o("p", {
|
|
40
|
+
className: t("subheading"),
|
|
41
|
+
children: p
|
|
42
|
+
}),
|
|
43
|
+
/* @__PURE__ */ o("p", {
|
|
44
|
+
className: e(t("caption"), "text-muted"),
|
|
45
|
+
children: h
|
|
46
|
+
}),
|
|
47
|
+
S
|
|
48
|
+
]
|
|
40
49
|
})
|
|
41
|
-
})
|
|
42
|
-
skipHref: _,
|
|
43
|
-
skipLabel: v,
|
|
44
|
-
onSkip: y
|
|
45
|
-
}) : null]
|
|
50
|
+
})]
|
|
46
51
|
});
|
|
47
52
|
}
|
|
48
53
|
var g = Object.assign(h, { Skip: m });
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Props for **IntakeHoneypot**. */
|
|
2
|
+
export interface IntakeHoneypotProps {
|
|
3
|
+
/** Field name the server checks. Default `fax`: plausible to a bot, never a real question here. */
|
|
4
|
+
name?: string;
|
|
5
|
+
value: string;
|
|
6
|
+
onChange: (value: string) => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Contact and booking forms T4: spam checks without a puzzle. A field people never see or reach, hidden
|
|
10
|
+
* from screen readers too (`aria-hidden`, `tabindex="-1"`, no autofill), that bots fill in. Drop any
|
|
11
|
+
* request where it has a value, on the server, alongside rate limits and a time-to-submit check. Never
|
|
12
|
+
* a CAPTCHA.
|
|
13
|
+
*/
|
|
14
|
+
export declare function IntakeHoneypot({ name, value, onChange }: IntakeHoneypotProps): import("react").JSX.Element;
|
|
15
|
+
/** True when the honeypot was filled: treat the request as spam (check this on the server too). */
|
|
16
|
+
export declare function isIntakeHoneypotFilled(value: string | null | undefined): boolean;
|
|
17
|
+
//# sourceMappingURL=IntakeHoneypot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IntakeHoneypot.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/IntakeForm/IntakeHoneypot.tsx"],"names":[],"mappings":"AAEA,oCAAoC;AACpC,MAAM,WAAW,mBAAmB;IAClC,mGAAmG;IACnG,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAAE,IAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,mBAAmB,+BAgBpF;AAED,mGAAmG;AACnG,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEhF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useId as e } from "react";
|
|
3
|
+
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/molecules/IntakeForm/IntakeHoneypot.tsx
|
|
5
|
+
function r({ name: r = "fax", value: i, onChange: a }) {
|
|
6
|
+
let o = e();
|
|
7
|
+
return /* @__PURE__ */ n("div", {
|
|
8
|
+
"aria-hidden": "true",
|
|
9
|
+
className: "absolute -left-[9999px] size-px overflow-hidden",
|
|
10
|
+
"data-intake-honeypot": "",
|
|
11
|
+
children: [/* @__PURE__ */ t("label", {
|
|
12
|
+
htmlFor: o,
|
|
13
|
+
children: "Leave this empty"
|
|
14
|
+
}), /* @__PURE__ */ t("input", {
|
|
15
|
+
id: o,
|
|
16
|
+
name: r,
|
|
17
|
+
type: "text",
|
|
18
|
+
tabIndex: -1,
|
|
19
|
+
autoComplete: "off",
|
|
20
|
+
value: i,
|
|
21
|
+
onChange: (e) => a(e.target.value)
|
|
22
|
+
})]
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function i(e) {
|
|
26
|
+
return (e ?? "").trim().length > 0;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { r as IntakeHoneypot, i as isIntakeHoneypotFilled };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
1
2
|
import { type IntakeConfirmationVariant } from "./intakeConfirmationStyles";
|
|
2
|
-
export { intakeConfirmationCopy, intakeConfirmationVariants, intakeConfettiColors, type IntakeConfirmationVariant, } from "./intakeConfirmationStyles";
|
|
3
|
+
export { intakeConfirmationCopy, intakeConfirmationReplyWithin, intakeConfirmationVariants, intakeConfettiColors, type IntakeConfirmationVariant, } from "./intakeConfirmationStyles";
|
|
3
4
|
/** Layout-only — width or margin. */
|
|
4
5
|
export type IntakeConfirmationLayoutClassName = string;
|
|
5
6
|
export interface IntakeConfirmationProps {
|
|
@@ -21,6 +22,17 @@ export interface IntakeConfirmationProps {
|
|
|
21
22
|
icsHref?: string;
|
|
22
23
|
/** Label for the `.ics` action. Default `Download .ics`. */
|
|
23
24
|
icsLabel?: string;
|
|
25
|
+
/** Where we'll reply (`emailed`): "We'll email you at {email} …". */
|
|
26
|
+
email?: string;
|
|
27
|
+
/**
|
|
28
|
+
* When we'll reply (Contact and booking forms T3), part of the one "what happens next" sentence. Default
|
|
29
|
+
* "within one business day". Never promise what you don't keep.
|
|
30
|
+
*/
|
|
31
|
+
replyWithin?: string;
|
|
32
|
+
/** What we got: a short recap of their request, shown as "You told us: “…”" (e.g. "A new site before spring"). */
|
|
33
|
+
summary?: ReactNode;
|
|
34
|
+
/** How to reach us meanwhile: phone, email, hours (T1, T3). */
|
|
35
|
+
contact?: ReactNode;
|
|
24
36
|
className?: IntakeConfirmationLayoutClassName;
|
|
25
37
|
}
|
|
26
38
|
/**
|
|
@@ -29,5 +41,5 @@ export interface IntakeConfirmationProps {
|
|
|
29
41
|
* Optional booking actions reuse **TextLink** and **Button** — no new confirmation style.
|
|
30
42
|
* Mount **ConfettiProvider** above this component.
|
|
31
43
|
*/
|
|
32
|
-
export declare function IntakeConfirmation({ variant, onDone, bookingTime, videoHref, videoLabel, googleCalendarHref, googleCalendarLabel, icsHref, icsLabel, className, }: IntakeConfirmationProps): import("react").JSX.Element;
|
|
44
|
+
export declare function IntakeConfirmation({ variant, onDone, bookingTime, videoHref, videoLabel, googleCalendarHref, googleCalendarLabel, icsHref, icsLabel, email, replyWithin, summary, contact, className, }: IntakeConfirmationProps): import("react").JSX.Element;
|
|
33
45
|
//# sourceMappingURL=IntakeConfirmation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntakeConfirmation.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/IntakeConfirmation/IntakeConfirmation.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"IntakeConfirmation.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/IntakeConfirmation/IntakeConfirmation.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAOvC,OAAO,EASL,KAAK,yBAAyB,EAC/B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAC7B,0BAA0B,EAC1B,oBAAoB,EACpB,KAAK,yBAAyB,GAC/B,MAAM,4BAA4B,CAAC;AAEpC,qCAAqC;AACrC,MAAM,MAAM,iCAAiC,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,uBAAuB;IACtC,wEAAwE;IACxE,OAAO,EAAE,yBAAyB,CAAC;IACnC,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kHAAkH;IAClH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,iCAAiC,CAAC;CAC/C;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,MAAM,EACN,WAAW,EACX,SAAS,EACT,UAA8B,EAC9B,kBAAkB,EAClB,mBAA8C,EAC9C,OAAO,EACP,QAA0B,EAC1B,KAAK,EACL,WAA2C,EAC3C,OAAO,EACP,OAAO,EACP,SAAS,GACV,EAAE,uBAAuB,+BAmEzB"}
|
|
@@ -5,11 +5,11 @@ import { Badge as t } from "../../atoms/Badge/Badge.js";
|
|
|
5
5
|
import { Button as n } from "../../atoms/Button/Button.js";
|
|
6
6
|
import { TextLink as r } from "../../atoms/TextLink/TextLink.js";
|
|
7
7
|
import { useConfettiOnMount as i } from "../Confetti/Confetti.js";
|
|
8
|
-
import { intakeConfettiColors as a, intakeConfirmationActionsClasses as o, intakeConfirmationBodyClasses as s, intakeConfirmationClasses as c, intakeConfirmationCopy as l, intakeConfirmationMetaClasses as u,
|
|
9
|
-
import { jsx as
|
|
8
|
+
import { intakeConfettiColors as a, intakeConfirmationActionsClasses as o, intakeConfirmationBodyClasses as s, intakeConfirmationClasses as c, intakeConfirmationCopy as l, intakeConfirmationMetaClasses as u, intakeConfirmationReplyWithin as d, intakeConfirmationTitleClasses as f, intakeConfirmationVariants as p } from "./intakeConfirmationStyles.js";
|
|
9
|
+
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
10
10
|
//#region src/components/organisms/IntakeConfirmation/IntakeConfirmation.tsx
|
|
11
|
-
function
|
|
12
|
-
let
|
|
11
|
+
function g({ variant: p, onDone: g, bookingTime: _, videoHref: v, videoLabel: y = "Join video call", googleCalendarHref: b, googleCalendarLabel: x = "Add to Google Calendar", icsHref: S, icsLabel: C = "Download .ics", email: w, replyWithin: T = d, summary: E, contact: D, className: O }) {
|
|
12
|
+
let k = l[p], A = p === "emailed" ? `We'll email you${w ? ` at ${w}` : ""} ${T} with a few times that fit.` : _ == null ? k.body : `We'll see you on ${_}, and we'll email a short note before so you know what to bring.`, j = v != null || b != null || S != null;
|
|
13
13
|
return i({
|
|
14
14
|
particleCount: 90,
|
|
15
15
|
spread: 180,
|
|
@@ -19,59 +19,64 @@ function h({ variant: f, onDone: h, bookingTime: g, videoHref: _, videoLabel: v
|
|
|
19
19
|
x: typeof window > "u" ? 0 : window.innerWidth / 2,
|
|
20
20
|
y: 0
|
|
21
21
|
}
|
|
22
|
-
}), /* @__PURE__ */
|
|
23
|
-
className: e(c,
|
|
24
|
-
"data-intake-confirmation":
|
|
22
|
+
}), /* @__PURE__ */ h("div", {
|
|
23
|
+
className: e(c, O),
|
|
24
|
+
"data-intake-confirmation": p,
|
|
25
25
|
children: [
|
|
26
|
-
/* @__PURE__ */
|
|
27
|
-
variant:
|
|
26
|
+
/* @__PURE__ */ m(t, {
|
|
27
|
+
variant: p === "booked" ? "neutral" : "info",
|
|
28
28
|
emphasis: "muted",
|
|
29
|
-
children:
|
|
29
|
+
children: k.badge
|
|
30
30
|
}),
|
|
31
|
-
/* @__PURE__ */
|
|
32
|
-
className:
|
|
33
|
-
children:
|
|
31
|
+
/* @__PURE__ */ m("h2", {
|
|
32
|
+
className: f,
|
|
33
|
+
children: k.title
|
|
34
34
|
}),
|
|
35
|
-
/* @__PURE__ */
|
|
35
|
+
/* @__PURE__ */ m("p", {
|
|
36
36
|
className: s,
|
|
37
|
-
children:
|
|
37
|
+
children: A
|
|
38
38
|
}),
|
|
39
|
-
|
|
39
|
+
E == null ? null : /* @__PURE__ */ h("p", {
|
|
40
|
+
className: u,
|
|
41
|
+
"data-intake-summary": "",
|
|
42
|
+
children: ["You told us: ", /* @__PURE__ */ m("q", { children: E })]
|
|
43
|
+
}),
|
|
44
|
+
j ? /* @__PURE__ */ h("div", {
|
|
40
45
|
className: o,
|
|
41
46
|
children: [
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
children: g
|
|
45
|
-
}),
|
|
46
|
-
_ == null ? null : /* @__PURE__ */ p(r, {
|
|
47
|
-
href: _,
|
|
47
|
+
v == null ? null : /* @__PURE__ */ m(r, {
|
|
48
|
+
href: v,
|
|
48
49
|
external: !0,
|
|
49
|
-
children:
|
|
50
|
+
children: y
|
|
50
51
|
}),
|
|
51
|
-
|
|
52
|
-
href:
|
|
52
|
+
b == null ? null : /* @__PURE__ */ m(r, {
|
|
53
|
+
href: b,
|
|
53
54
|
external: !0,
|
|
54
|
-
children:
|
|
55
|
+
children: x
|
|
55
56
|
}),
|
|
56
|
-
|
|
57
|
+
S == null ? null : /* @__PURE__ */ m(n, {
|
|
57
58
|
role: "secondary",
|
|
58
59
|
size: "md",
|
|
59
|
-
render: /* @__PURE__ */
|
|
60
|
-
href:
|
|
60
|
+
render: /* @__PURE__ */ m("a", {
|
|
61
|
+
href: S,
|
|
61
62
|
download: !0
|
|
62
63
|
}),
|
|
63
|
-
children:
|
|
64
|
+
children: C
|
|
64
65
|
})
|
|
65
66
|
]
|
|
66
67
|
}) : null,
|
|
67
|
-
|
|
68
|
+
D == null ? null : /* @__PURE__ */ m("div", {
|
|
69
|
+
className: u,
|
|
70
|
+
children: D
|
|
71
|
+
}),
|
|
72
|
+
g == null ? null : /* @__PURE__ */ m(n, {
|
|
68
73
|
role: "primary",
|
|
69
74
|
type: "button",
|
|
70
|
-
onClick:
|
|
75
|
+
onClick: g,
|
|
71
76
|
children: "Done"
|
|
72
77
|
})
|
|
73
78
|
]
|
|
74
79
|
});
|
|
75
80
|
}
|
|
76
81
|
//#endregion
|
|
77
|
-
export {
|
|
82
|
+
export { g as IntakeConfirmation, a as intakeConfettiColors, l as intakeConfirmationCopy, d as intakeConfirmationReplyWithin, p as intakeConfirmationVariants };
|
|
@@ -5,11 +5,15 @@
|
|
|
5
5
|
export declare const intakeConfettiColors: readonly ["var(--color-brand)", "var(--color-brand-soft)", "var(--color-primary)", "var(--color-info-muted)", "var(--color-accent)", "var(--color-chart-categorical-1)", "var(--color-chart-categorical-4)"];
|
|
6
6
|
export declare const intakeConfirmationVariants: readonly ["booked", "emailed"];
|
|
7
7
|
export type IntakeConfirmationVariant = (typeof intakeConfirmationVariants)[number];
|
|
8
|
+
/** T2, T3: when the reply comes. Keep it true for your team. */
|
|
9
|
+
/** When we reply, inside the confirmation's one "what happens next" sentence (T3). */
|
|
10
|
+
export declare const intakeConfirmationReplyWithin = "within one business day";
|
|
8
11
|
export declare const intakeConfirmationCopy: Record<IntakeConfirmationVariant, {
|
|
9
12
|
badge: string;
|
|
10
13
|
title: string;
|
|
11
14
|
body: string;
|
|
12
15
|
}>;
|
|
16
|
+
/** Left on phones, where the next-step sentence with an email runs 3 lines; centred from md (Headings H8). */
|
|
13
17
|
export declare const intakeConfirmationClasses: string;
|
|
14
18
|
/** Existing display-2 — the confirmation headline, larger than the step titles. */
|
|
15
19
|
export declare const intakeConfirmationTitleClasses = "type-display-2 text-balance text-fg";
|
|
@@ -19,5 +23,5 @@ export declare const intakeConfirmationBodyClasses = "type-large max-w-2xl text-
|
|
|
19
23
|
/** Booked time under the body — supporting muted type. */
|
|
20
24
|
export declare const intakeConfirmationMetaClasses = "type-body text-balance text-muted";
|
|
21
25
|
/** Optional booking actions — **TextLink** / **Button** stack, same center column. */
|
|
22
|
-
export declare const intakeConfirmationActionsClasses = "flex w-full max-w-md flex-col items-
|
|
26
|
+
export declare const intakeConfirmationActionsClasses = "flex w-full max-w-md flex-col items-start gap-3 md:items-center";
|
|
23
27
|
//# sourceMappingURL=intakeConfirmationStyles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intakeConfirmationStyles.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/IntakeConfirmation/intakeConfirmationStyles.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,8MAQvB,CAAC;AAEX,eAAO,MAAM,0BAA0B,gCAAiC,CAAC;AAEzE,MAAM,MAAM,yBAAyB,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpF,eAAO,MAAM,sBAAsB,EAAE,MAAM,CACzC,yBAAyB,EACzB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAY/C,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAErC,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,8BAA8B,wCAAwC,CAAC;AAEpF,yEAAyE;AACzE,6EAA6E;AAC7E,eAAO,MAAM,6BAA6B,8CAA8C,CAAC;AAEzF,0DAA0D;AAC1D,eAAO,MAAM,6BAA6B,sCAAsC,CAAC;AAEjF,sFAAsF;AACtF,eAAO,MAAM,gCAAgC,
|
|
1
|
+
{"version":3,"file":"intakeConfirmationStyles.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/IntakeConfirmation/intakeConfirmationStyles.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,oBAAoB,8MAQvB,CAAC;AAEX,eAAO,MAAM,0BAA0B,gCAAiC,CAAC;AAEzE,MAAM,MAAM,yBAAyB,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpF,gEAAgE;AAChE,sFAAsF;AACtF,eAAO,MAAM,6BAA6B,4BAA4B,CAAC;AAEvE,eAAO,MAAM,sBAAsB,EAAE,MAAM,CACzC,yBAAyB,EACzB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAY/C,CAAC;AAEF,8GAA8G;AAC9G,eAAO,MAAM,yBAAyB,QAErC,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,8BAA8B,wCAAwC,CAAC;AAEpF,yEAAyE;AACzE,6EAA6E;AAC7E,eAAO,MAAM,6BAA6B,8CAA8C,CAAC;AAEzF,0DAA0D;AAC1D,eAAO,MAAM,6BAA6B,sCAAsC,CAAC;AAEjF,sFAAsF;AACtF,eAAO,MAAM,gCAAgC,oEACsB,CAAC"}
|
|
@@ -9,7 +9,7 @@ var t = [
|
|
|
9
9
|
"var(--color-accent)",
|
|
10
10
|
"var(--color-chart-categorical-1)",
|
|
11
11
|
"var(--color-chart-categorical-4)"
|
|
12
|
-
], n = ["booked", "emailed"], r = {
|
|
12
|
+
], n = ["booked", "emailed"], r = "within one business day", i = {
|
|
13
13
|
booked: {
|
|
14
14
|
badge: "Booked",
|
|
15
15
|
title: "You're booked",
|
|
@@ -20,6 +20,6 @@ var t = [
|
|
|
20
20
|
title: "We'll be in touch",
|
|
21
21
|
body: "No calendar needed. We'll reply by email with a few times that fit."
|
|
22
22
|
}
|
|
23
|
-
},
|
|
23
|
+
}, a = e("flex w-full max-w-3xl flex-col items-start gap-8 text-left md:items-center md:text-center"), o = "type-display-2 text-balance text-fg", s = "type-large max-w-2xl text-balance text-fg", c = "type-body text-balance text-muted", l = "flex w-full max-w-md flex-col items-start gap-3 md:items-center";
|
|
24
24
|
//#endregion
|
|
25
|
-
export { t as intakeConfettiColors,
|
|
25
|
+
export { t as intakeConfettiColors, l as intakeConfirmationActionsClasses, s as intakeConfirmationBodyClasses, a as intakeConfirmationClasses, i as intakeConfirmationCopy, c as intakeConfirmationMetaClasses, r as intakeConfirmationReplyWithin, o as intakeConfirmationTitleClasses, n as intakeConfirmationVariants };
|
|
@@ -6,7 +6,10 @@ export interface IntakeModalProps {
|
|
|
6
6
|
onOpenChange: (open: boolean) => void;
|
|
7
7
|
/** Current step, 1-based. Shown when `showProgress` is set. */
|
|
8
8
|
step?: number;
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* Segment count. Default 2: details, then the optional booking; the confirmation isn't counted
|
|
11
|
+
* (Contact and booking forms T7: at most 3 steps, and only when a later step depends on earlier ones).
|
|
12
|
+
*/
|
|
10
13
|
steps?: number;
|
|
11
14
|
/** Accessible name. Default `Start a project`. */
|
|
12
15
|
title?: string;
|
|
@@ -29,6 +32,12 @@ export interface IntakeModalProps {
|
|
|
29
32
|
* (the Close button still closes). Default `true`.
|
|
30
33
|
*/
|
|
31
34
|
dismissOnEscape?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* The visitor has typed answers. Close and Escape then ask "Discard your answers?" before closing
|
|
37
|
+
* (Contact and booking forms T9). Keep the answers in the caller's state, so an accidental close
|
|
38
|
+
* that's undone, or reopening, finds them still there.
|
|
39
|
+
*/
|
|
40
|
+
hasAnswers?: boolean;
|
|
32
41
|
children?: ReactNode;
|
|
33
42
|
className?: IntakeModalLayoutClassName;
|
|
34
43
|
}
|
|
@@ -37,5 +46,5 @@ export interface IntakeModalProps {
|
|
|
37
46
|
* Wordmark, close, step progress, and a pinned footer.
|
|
38
47
|
* Focus trap, Escape, scroll lock, and `aria-modal`.
|
|
39
48
|
*/
|
|
40
|
-
export declare function IntakeModal({ open, onOpenChange, step, steps, title, showProgress, hideFooter, hideContinue, onBack, onContinue, backDisabled, continueDisabled, continueLabel, dismissOnEscape, children, className, }: IntakeModalProps): import("react").ReactPortal | null;
|
|
49
|
+
export declare function IntakeModal({ open, onOpenChange, step, steps, title, showProgress, hideFooter, hideContinue, onBack, onContinue, backDisabled, continueDisabled, continueLabel, dismissOnEscape, hasAnswers, children, className, }: IntakeModalProps): import("react").ReactPortal | null;
|
|
41
50
|
//# sourceMappingURL=IntakeModal.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntakeModal.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/IntakeModal/IntakeModal.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"IntakeModal.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/IntakeModal/IntakeModal.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAwBxF,wDAAwD;AACxD,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uEAAuE;IACvE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qFAAqF;IACrF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,0BAA0B,CAAC;CACxC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,YAAY,EACZ,IAAQ,EACR,KAAS,EACT,KAAyB,EACzB,YAAmB,EACnB,UAAkB,EAClB,YAAoB,EACpB,MAAM,EACN,UAAU,EACV,YAAoB,EACpB,gBAAwB,EACxB,aAA0B,EAC1B,eAAsB,EACtB,UAAkB,EAClB,QAAQ,EACR,SAAS,GACV,EAAE,gBAAgB,sCAqIlB"}
|
|
@@ -1,96 +1,128 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
"use client";
|
|
3
3
|
import { cn as e } from "../../../lib/cn.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
4
|
+
import { typographyClass as t } from "../../../lib/typography.js";
|
|
5
|
+
import { motionTransitionProp as n } from "../../../lib/motion.js";
|
|
6
|
+
import { Button as r } from "../../atoms/Button/Button.js";
|
|
7
|
+
import { IconButton as i } from "../../atoms/IconButton/IconButton.js";
|
|
8
|
+
import { StepProgress as a } from "../../molecules/StepProgress/StepProgress.js";
|
|
9
|
+
import { useOverlayLifecycle as o } from "../../../lib/dialogOverlay.js";
|
|
10
|
+
import { intakeModalBodyClasses as s, intakeModalBrandClasses as c, intakeModalCenteredContentClasses as l, intakeModalContentClasses as u, intakeModalFooterClasses as d, intakeModalHeaderClasses as f, intakeModalMarkClasses as p, intakeModalProgressClasses as m, intakeModalRootClasses as h, intakeModalWordmarkClasses as g } from "./intakeModalStyles.js";
|
|
11
|
+
import { useCallback as _, useEffect as v, useId as y, useRef as b, useState as x } from "react";
|
|
12
|
+
import { X as S } from "lucide-react";
|
|
13
|
+
import { jsx as C, jsxs as w } from "react/jsx-runtime";
|
|
14
|
+
import { AnimatePresence as T, motion as E } from "motion/react";
|
|
15
|
+
import { createPortal as D } from "react-dom";
|
|
15
16
|
//#region src/components/organisms/IntakeModal/IntakeModal.tsx
|
|
16
|
-
function
|
|
17
|
-
let
|
|
18
|
-
|
|
19
|
-
}, [
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
17
|
+
function O({ open: O, onOpenChange: k, step: A = 1, steps: j = 2, title: M = "Start a project", showProgress: N = !0, hideFooter: P = !1, hideContinue: F = !1, onBack: I, onContinue: L, backDisabled: R = !1, continueDisabled: z = !1, continueLabel: B = "Continue", dismissOnEscape: V = !0, hasAnswers: H = !1, children: U, className: W }) {
|
|
18
|
+
let G = y(), K = b(null), q = y(), J = b(null), [Y, X] = x(!1), Z = _(() => {
|
|
19
|
+
X(!1), k(!1);
|
|
20
|
+
}, [k]), Q = _(() => {
|
|
21
|
+
H ? X(!0) : Z();
|
|
22
|
+
}, [H, Z]);
|
|
23
|
+
return v(() => {
|
|
24
|
+
Y && J.current?.focus();
|
|
25
|
+
}, [Y]), v(() => {
|
|
26
|
+
O || X(!1);
|
|
27
|
+
}, [O]), o(K, {
|
|
28
|
+
open: O,
|
|
29
|
+
onClose: Q,
|
|
30
|
+
closeOnEscape: V,
|
|
24
31
|
initialFocus: "[aria-label=\"Close\"]"
|
|
25
|
-
}), typeof document > "u" ? null :
|
|
26
|
-
ref:
|
|
27
|
-
className: e(
|
|
32
|
+
}), typeof document > "u" ? null : D(/* @__PURE__ */ C(T, { children: O ? /* @__PURE__ */ w(E.div, {
|
|
33
|
+
ref: K,
|
|
34
|
+
className: e(h, W),
|
|
28
35
|
role: "dialog",
|
|
29
36
|
"aria-modal": "true",
|
|
30
|
-
"aria-labelledby":
|
|
37
|
+
"aria-labelledby": G,
|
|
31
38
|
"data-intake-modal": "",
|
|
32
39
|
initial: { opacity: 0 },
|
|
33
40
|
animate: { opacity: 1 },
|
|
34
41
|
exit: { opacity: 0 },
|
|
35
|
-
transition:
|
|
42
|
+
transition: n("medium"),
|
|
36
43
|
children: [
|
|
37
|
-
/* @__PURE__ */
|
|
38
|
-
id:
|
|
44
|
+
/* @__PURE__ */ C("h1", {
|
|
45
|
+
id: G,
|
|
39
46
|
className: "sr-only",
|
|
40
|
-
children:
|
|
47
|
+
children: M
|
|
41
48
|
}),
|
|
42
|
-
/* @__PURE__ */
|
|
43
|
-
className:
|
|
44
|
-
children: [/* @__PURE__ */
|
|
45
|
-
className:
|
|
46
|
-
children: [/* @__PURE__ */
|
|
47
|
-
className:
|
|
49
|
+
/* @__PURE__ */ w("header", {
|
|
50
|
+
className: f,
|
|
51
|
+
children: [/* @__PURE__ */ w("div", {
|
|
52
|
+
className: c,
|
|
53
|
+
children: [/* @__PURE__ */ C("span", {
|
|
54
|
+
className: p,
|
|
48
55
|
"aria-hidden": !0,
|
|
49
56
|
children: "WM"
|
|
50
|
-
}), /* @__PURE__ */
|
|
51
|
-
className:
|
|
57
|
+
}), /* @__PURE__ */ C("span", {
|
|
58
|
+
className: g,
|
|
52
59
|
children: "WhatMatters"
|
|
53
60
|
})]
|
|
54
|
-
}), /* @__PURE__ */
|
|
55
|
-
icon: /* @__PURE__ */
|
|
61
|
+
}), /* @__PURE__ */ C(i, {
|
|
62
|
+
icon: /* @__PURE__ */ C(S, { strokeWidth: 2 }),
|
|
56
63
|
"aria-label": "Close",
|
|
57
64
|
role: "ghost",
|
|
58
65
|
size: "md",
|
|
59
|
-
onClick:
|
|
66
|
+
onClick: Q
|
|
60
67
|
})]
|
|
61
68
|
}),
|
|
62
|
-
|
|
63
|
-
className:
|
|
64
|
-
children: /* @__PURE__ */
|
|
65
|
-
step:
|
|
66
|
-
steps:
|
|
69
|
+
N ? /* @__PURE__ */ C("div", {
|
|
70
|
+
className: m,
|
|
71
|
+
children: /* @__PURE__ */ C(a, {
|
|
72
|
+
step: A,
|
|
73
|
+
steps: j
|
|
67
74
|
})
|
|
68
75
|
}) : null,
|
|
69
|
-
/* @__PURE__ */
|
|
70
|
-
className:
|
|
71
|
-
children: /* @__PURE__ */
|
|
72
|
-
className:
|
|
73
|
-
children:
|
|
76
|
+
/* @__PURE__ */ C("div", {
|
|
77
|
+
className: s,
|
|
78
|
+
children: /* @__PURE__ */ C("div", {
|
|
79
|
+
className: P ? l : u,
|
|
80
|
+
children: U
|
|
74
81
|
})
|
|
75
82
|
}),
|
|
76
|
-
|
|
77
|
-
className:
|
|
78
|
-
|
|
83
|
+
Y ? /* @__PURE__ */ w("footer", {
|
|
84
|
+
className: e(d, "flex-wrap"),
|
|
85
|
+
role: "alertdialog",
|
|
86
|
+
"aria-labelledby": q,
|
|
87
|
+
"data-intake-discard": "",
|
|
88
|
+
children: [
|
|
89
|
+
/* @__PURE__ */ C("p", {
|
|
90
|
+
id: q,
|
|
91
|
+
className: e(t("ui-label"), "basis-full text-fg md:basis-auto"),
|
|
92
|
+
children: "Discard your answers?"
|
|
93
|
+
}),
|
|
94
|
+
/* @__PURE__ */ C(r, {
|
|
95
|
+
ref: J,
|
|
96
|
+
role: "primary",
|
|
97
|
+
type: "button",
|
|
98
|
+
onClick: () => X(!1),
|
|
99
|
+
children: "Keep editing"
|
|
100
|
+
}),
|
|
101
|
+
/* @__PURE__ */ C(r, {
|
|
102
|
+
role: "ghost",
|
|
103
|
+
type: "button",
|
|
104
|
+
onClick: Z,
|
|
105
|
+
children: "Discard"
|
|
106
|
+
})
|
|
107
|
+
]
|
|
108
|
+
}) : P ? null : /* @__PURE__ */ w("footer", {
|
|
109
|
+
className: d,
|
|
110
|
+
children: [F ? null : /* @__PURE__ */ C(r, {
|
|
79
111
|
role: "primary",
|
|
80
112
|
type: "button",
|
|
81
|
-
disabled:
|
|
82
|
-
onClick:
|
|
83
|
-
children:
|
|
84
|
-
}), /* @__PURE__ */
|
|
113
|
+
disabled: z,
|
|
114
|
+
onClick: L,
|
|
115
|
+
children: B
|
|
116
|
+
}), A > 1 ? /* @__PURE__ */ C(r, {
|
|
85
117
|
role: "ghost",
|
|
86
118
|
type: "button",
|
|
87
|
-
disabled:
|
|
88
|
-
onClick:
|
|
119
|
+
disabled: R,
|
|
120
|
+
onClick: I,
|
|
89
121
|
children: "Back"
|
|
90
|
-
})]
|
|
122
|
+
}) : null]
|
|
91
123
|
})
|
|
92
124
|
]
|
|
93
125
|
}) : null }), document.body);
|
|
94
126
|
}
|
|
95
127
|
//#endregion
|
|
96
|
-
export {
|
|
128
|
+
export { O as IntakeModal };
|