@getvitops/emdash 1.0.0 → 2.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/dist/index.d.mts +33 -1
  3. package/dist/index.d.mts.map +1 -1
  4. package/dist/index.mjs +1308 -184
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +10 -7
  7. package/src/admin/DesignSystemEditorPage.tsx +15 -42
  8. package/src/astro/blocks/Callout.astro +73 -0
  9. package/src/astro/blocks/Cards.astro +53 -9
  10. package/src/astro/blocks/Embed.astro +67 -0
  11. package/src/astro/blocks/Entries.astro +30 -0
  12. package/src/astro/blocks/Form.astro +194 -0
  13. package/src/astro/blocks/Hero.astro +77 -23
  14. package/src/astro/blocks/Logos.astro +48 -0
  15. package/src/astro/blocks/Nav.astro +85 -0
  16. package/src/astro/blocks/NavTree.astro +48 -0
  17. package/src/astro/blocks/Pricing.astro +66 -0
  18. package/src/astro/blocks/Reviews.astro +122 -0
  19. package/src/astro/blocks/RichText.astro +14 -0
  20. package/src/astro/blocks/Section.astro +84 -0
  21. package/src/astro/blocks/Stats.astro +59 -0
  22. package/src/astro/blocks/Steps.astro +48 -0
  23. package/src/astro/blocks/embed.test.ts +43 -0
  24. package/src/astro/blocks/embed.ts +84 -0
  25. package/src/astro/blocks/form.sample.ts +33 -0
  26. package/src/astro/blocks/form.test.ts +55 -0
  27. package/src/astro/blocks/form.ts +158 -0
  28. package/src/astro/blocks/head.stub.ts +2 -0
  29. package/src/astro/blocks/nav.test.ts +51 -0
  30. package/src/astro/blocks/nav.ts +65 -0
  31. package/src/astro/blocks/render.container.test.ts +570 -0
  32. package/src/astro/blocks/tone.test.ts +53 -0
  33. package/src/astro/blocks/tone.ts +122 -0
  34. package/src/astro/blocks/value.test.ts +36 -1
  35. package/src/astro/blocks/value.ts +78 -1
  36. package/src/astro/index.ts +30 -0
  37. package/src/admin/core-editor.d.ts +0 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,74 @@
1
1
  # @getvitops/emdash
2
2
 
3
+ ## 2.0.0-alpha.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 161c7f3: A contact form that works end to end: `vitops setup turnstile`, `<wc-turnstile>`, the `vitops.form` EmDash block, and the route the emdash template ships to receive it.
8
+
9
+ **CSS, all formats** (no existing class changes): `forms.css` gains `.form-notice--target:not(:target)` (a message revealed only when the URL fragment names it, which is how a prerendered page shows a no-JS form's result) and `:where(wc-turnstile) { display: block }`.
10
+
11
+ **`@getvitops/core`:** new `<wc-turnstile sitekey="…">` in `elements.js`. It loads Cloudflare Turnstile on the first interaction with its form (no request to `challenges.cloudflare.com` for a visitor who only reads the page), holds an early submit until the token arrives, and leaves its slotted no-JS explanation in place until JS takes over. Turnstile is category `necessary`, so it is not behind the consent banner.
12
+
13
+ **`@getvitops/utils` / `@getvitops/cli`:** new `@getvitops/utils/turnstile` and `vitops setup turnstile [--dry] [--check] [--no-write] [--no-secret]`. It plans from the site's hostnames, creates a managed widget unless one already covers them (an existing widget is adopted, never edited, rotated or deleted), writes the public key to `site.security.turnstile.siteKey`, and pipes the one-time secret to `wrangler secret put VITOPS_TURNSTILE_SECRET` without writing it to any file. Needs `CLOUDFLARE_API_TOKEN` with **Account > Turnstile > Edit** and `CLOUDFLARE_ACCOUNT_ID`.
14
+
15
+ **`@getvitops/astro`:** `virtual:getvitops/head` gains `turnstileSiteKey` (read from `site.security.turnstile.siteKey`) so blocks can render the widget. No other change.
16
+
17
+ **`@getvitops/generator`:** `TIERS` gains a `turnstile` entry (wc-turnstile, claimed by `vitops.form`); `wc-multi-field`'s `emdashExempt` reason is reworded now the form block exists.
18
+
19
+ **`@getvitops/emdash`:** new `vitops.form` block: a field repeater (text, email, phone, long text, choose one, tick box), required flags, help text, success/error messages, optional Turnstile. It renders a semantic `<form method="post">` that works with no JavaScript, with a honeypot named per `createConversionRoute`'s defaults. A field named `phone` submits as `tel`, because the route reserves `phone` and `event`.
20
+
21
+ **`@getvitops/create`:** the emdash template ships `src/pages/api/track.ts` (`prerender = false`, `createConversionRoute()`), a seeded contact form, and `challenges.cloudflare.com` in both templates' Report-Only CSP (`script-src`, `frame-src`). The route refuses a post with nowhere to deliver and fails closed when a site key exists without `VITOPS_TURNSTILE_SECRET`. SETUP.html gains the Turnstile step. Existing sites: copy the route and the CSP change, then run `vitops setup turnstile`.
22
+
23
+ - 1e36b83: Seven new blocks, a section block type, and a shared `tone`.
24
+
25
+ **New Portable Text blocks:** `vitops.logos` (a still grid; `marquee` only scrolls), `vitops.steps`, `vitops.stats` (each figure is a `<Counter>`; a `tiles` style adds group, change and good/bad state), `vitops.callout` (a call-to-action band, not the dismissible `banner`), `vitops.entries` (wraps `<wc-entries>`), `vitops.pricing` (aligned plan cards) and `vitops.embed` (a video or map that loads only after consent: the iframe ships with no `src`, the address rides on `data-consent-src`, and a `title` is required).
26
+
27
+ **New block TYPE `vitops_section`** (kicker, heading with a level, lead-in, tone, an optional heading-left `split` layout, and a Portable Text body that accepts every `vitops.*` block). It is a schema-level block type, not a Portable Text block, because Block Kit fields cannot hold rich text. Add `...vitopsBlockTypes()` to `seed.json`'s `blockTypes`, allow `vitops_section` on the collection's `blocks` field, and map it with `blockTypeComponents` from `@getvitops/emdash/astro` (`defineBlockComponents`).
28
+
29
+ **Extended, non-breaking:** `vitops.hero` gains accent marks (`*words*` in the heading), a heading `level`, `tone`/`color` and an optional row of cards. `vitops.cards` gains a `panel` style (tone, checklist, button), a heading `level`, `tone`/`color`, and `[text](/url)` inline links in the body. **Cards fix:** the card title is now a real heading element (default `h3`, `font-heading`) instead of `<p class="font-heading">`; saved content is unchanged, but the markup and the page outline change. Set `level` to taste.
30
+
31
+ **Shared `tone` + `color`** on every block that colours anything: a role from `site.json`, falling back through its semantic relatives to `neutral`, or a palette hue/step. Renderers emit `--tone-*` custom properties (never a class built from a value, which Tailwind cannot see). New option `vitopsEmdash({ tones })` (or the roles are read from `designSystemEditor.config`) fills each block's `tone` select with the site's own roles through a `tones/list` plugin route; with neither, the select offers the semantic names. `vitops.banner.tone` and `vitops.actionLink.role` keep their existing values.
32
+
33
+ **Render tests:** `pnpm --filter @getvitops/emdash run test:render` renders the block adapters through Astro's container API in a separate vitest config.
34
+
35
+ - 175d16e: **Added: `vitops.reviews` and `vitops.nav` EmDash blocks.** Non-breaking.
36
+
37
+ - **`vitops.reviews`** renders Google reviews from the committed `.vitops/reviews.json` cache (`vitops reviews`) as a grid, carousel or marquee of `<ReviewCard>`. Fields: location key, layout, columns, limit, lowest rating, order, featured ids, reviewer photos (off by default), tone/colour. Which reviews show is `selectReviews()`, the one shared decision. Review JSON-LD is not offered (Google treats self-marked-up reviews as ineligible for rich results). A new review reaches the page after `vitops reviews` is re-run, committed and the site rebuilt, not when an editor saves; with no cache file the block renders nothing (a note in `astro dev`).
38
+ - **`vitops.nav`** renders a named EmDash menu inside page content (site map, section links, footer-style columns), never the header. Fields: menu (picked from the site's menus via a new `menus/list` plugin route, with `footer-sitemap`/`footer-legal`/`primary` as the static fallback), accessible name, visible heading and level, layout `list | inline | columns | sitenav`, depth 1-3, tone/colour. It is a `<nav>` with a name that is never `Primary`, `Site map` or `Legal` (the layout's landmarks), `aria-current="page"`, no runtime JS; a missing or empty menu renders nothing.
39
+ - `@getvitops/astro`: **`virtual:getvitops/reviews`**, served by `vitops()`, is `.vitops/reviews.json` as a build-time import (an empty cache when absent or unreadable), because a Worker cannot read the file. `<ReviewCard>` now renders the review's source link (`.review__source`, `rel="nofollow noopener noreferrer"`), which the pattern already styled. **Fix:** `src/json-ld.ts` was missing from the published `files`, so any consumer importing `<ReviewCard>` (which composes `schemas/Review.astro`) failed to build with an unresolved import. `@getvitops/emdash` now needs this version of `@getvitops/astro` for the `vitops.reviews` block.
40
+ - `@getvitops/utils`: new Worker-safe subpath **`@getvitops/utils/reviews/select`** (`selectReviews` and the review types, no `node:fs`). `selectReviews` now takes only the display fields (`featured`, `minRating`, `limit`, `sort`), so a caller with no configured `locationId` can use it; existing calls are unchanged.
41
+ - `@getvitops/core`: new `.navlist` pattern in `patterns/sitenav.css` (`.navlist`, `__item`, `__link`, `__label`, `__sub`, `--inline`, `--columns`). **All formats** (css, bricks, tailwind). No existing class changes.
42
+ - `@getvitops/generator`: `TIERS.review` lists `vitops.reviews` and `TIERS.sitenav` lists `vitops.nav` (and `.navlist`), so `vitops docs components` and the docsite show them.
43
+
44
+ - 06d6112: Fix the EmDash `/design-system` admin page erroring on a tailwind site. It fetches `/vitops/design-manifest.json`, which the `tailwind` format never emitted and the integration only mirrored under `editor: true` (which also loads `editor.js` on every public page).
45
+
46
+ - **generator** (`tailwind` format only): `design-manifest.json` is now emitted alongside `tailwind.css`. No change to the CSS.
47
+ - **astro**: new `vitops({ editorManifest: true })` writes everything an outside host needs into `public/vitops/` (`design-manifest.json`, `editor.js`, a standalone `editor.css`, and `design-system-editor.html`) without loading the editor on public pages. `editor: true` still loads it from `<Head />`.
48
+ - **vite**: `editorManifestDir` also writes `vitops/editor.css`, from a throwaway `css`-format pass on tailwind sites.
49
+ - **emdash**: the `/design-system` admin page was unstyled and overflowed the admin, because the editor borrows the framework CSS and the admin never loads it. It now embeds `/vitops/design-system-editor.html` in an iframe, so the design system can't leak into the admin's styles. **Requires `editorManifest: true`** in `vitops({ … })`.
50
+ - **create**: the EmDash template sets `editorManifest: true`. Existing sites: add it to `vitops({ … })` in `astro.config.mjs`.
51
+
52
+ No consumer-facing change in the other toolchain packages.
53
+
54
+ ### Patch Changes
55
+
56
+ - Updated dependencies [efd4e72]
57
+ - Updated dependencies [93d2067]
58
+ - Updated dependencies [161c7f3]
59
+ - Updated dependencies [175d16e]
60
+ - Updated dependencies [83d6f3c]
61
+ - Updated dependencies [892b204]
62
+ - Updated dependencies [06d6112]
63
+ - Updated dependencies [6297337]
64
+ - Updated dependencies [224a731]
65
+ - Updated dependencies [55061e2]
66
+ - Updated dependencies [b47df4d]
67
+ - @getvitops/astro@8.3.0-alpha.0
68
+ - @getvitops/core@8.3.0-alpha.0
69
+ - @getvitops/generator@8.3.0-alpha.0
70
+ - @getvitops/utils@8.3.0-alpha.0
71
+
3
72
  ## 1.0.0
4
73
 
5
74
  ### Major Changes
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { PluginDescriptor, PortableTextBlockConfig } from "emdash";
1
+ import { ApplySeedBlockTypeInput, PluginDescriptor, PortableTextBlockConfig } from "emdash";
2
2
  import { AstroIntegration } from "astro";
3
3
  /** The subset of EmDash Block Kit field elements these blocks use. */
4
4
  type BlockKitFieldDef = Extract<NonNullable<PortableTextBlockConfig['fields']>[number], {
@@ -47,6 +47,31 @@ interface DesignSystemEditorOptions {
47
47
  * it cannot describe a field the editor doesn't offer.
48
48
  */
49
49
  export declare function renderBlocksDoc(blocks?: readonly PortableTextBlockDef[]): string;
50
+ /** Block-type slugs may not contain a dot, so `vitops.section` is stored as `vitops_section`. */
51
+ export declare const SECTION_SLUG = "vitops_section";
52
+ /** `vitops.section`: kicker, heading, lead-in, tone/backdrop, optional heading-left layout, and a body of blocks. */
53
+ export declare const SECTION_BLOCK_TYPE: ApplySeedBlockTypeInput;
54
+ /**
55
+ * Every block type this plugin ships, in the shape `seed.json`'s `blockTypes` takes. Spread
56
+ * it into the seed (and allow the slugs on the collection's `blocks` field), e.g.
57
+ * `blockTypes: [...vitopsBlockTypes()]`.
58
+ */
59
+ export declare function vitopsBlockTypes(): ApplySeedBlockTypeInput[];
60
+ /** The role chain for a tone: itself, its relatives, then `neutral`. Pure and exported for tests. */
61
+ export declare function toneChain(tone: unknown): string[];
62
+ interface ResolvedTone {
63
+ /** Always `tone`; a block adds `tone--solid` itself when it fills rather than tints. */
64
+ className: string;
65
+ /** Inline `style` value of `--tone-*` properties (no trailing semicolon). Empty when unset. */
66
+ style: string;
67
+ }
68
+ /**
69
+ * Resolve a block's `tone` / `color` fields.
70
+ *
71
+ * Returns an empty style when neither is set, so an unconfigured block carries no tone at
72
+ * all (rather than a neutral one) and stays transparent.
73
+ */
74
+ export declare function resolveTone(tone?: unknown, color?: unknown): ResolvedTone;
50
75
  type HostingTarget = 'cloudflare' | 'node';
51
76
  interface VitopsHostingOptions {
52
77
  /** Hosting target. Overridden by the `HOSTING` env var. Default 'cloudflare'. */
@@ -115,6 +140,13 @@ export interface VitopsEmdashOptions {
115
140
  * site's own — whose renderers the site supplies, see {@link BlockSelection}.
116
141
  */
117
142
  blocks?: BlockSelection;
143
+ /**
144
+ * The site's colour role names (`Object.keys(site.designSystem.colors.roles)`), offered in
145
+ * every block's `tone` select next to the semantic names. When omitted and
146
+ * `designSystemEditor.config` is set, they are read from that config. With neither, the
147
+ * select offers only the semantic names — an editor can still type a palette colour.
148
+ */
149
+ tones?: string[];
118
150
  }
119
151
  /**
120
152
  * Descriptor factory — import in `astro.config.mjs` and pass to the emdash()
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/blocks.ts","../src/design-system-route.ts","../src/blocks-doc.ts","../src/hosting.ts","../src/index.ts"],"mappings":";;;KAsBY,mBAAmB,QAC7B,YAAY;EAEV;;KAWQ,uBAAuB,KAAK;EACtC,SAAS;;qBAGE,QAAQ;;UAsVJ;;EAEf;;EAEA;;;;;;;EAOA,QAAQ;;;;;;;;wBASM,aAAa,YAAW,iBAAsB;UC3V7C;;;;;;;;EAQf;;EAEA;;;;;;;wBC/Bc,gBAAgB,kBAAiB;KCFrC;UAIK;;EAEf,SAAS;EACT;;IAEE;;IAEA;;IAEA;;;;;;;IAOA;;EAEF;;IAEE;;IAEA;;IAEA;;IAEA;;;UAIa;EACf,QAAQ;EACR,SAAS;;EAET;;EAEA;;wBAoBoB,cAAc,UAAS,uBAA4B,QAAQ;iBC7BhE;;;;;;;;;;;EAWf;;EAEA;;;;;;;;;EASA,qBAAqB;;;;;;EAMrB,SAAS;;;;;;wBAOK,aAAa,UAAS,sBAA2B;;wBAmBjD,aAAa,UAAS,uCAAwB,gCAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/blocks.ts","../src/design-system-route.ts","../src/blocks-doc.ts","../src/block-types.ts","../src/astro/blocks/tone.ts","../src/hosting.ts","../src/index.ts"],"mappings":";;;KAuBY,mBAAmB,QAC7B,YAAY;EAEV;;KAWQ,uBAAuB,KAAK;EACtC,SAAS;;qBAmDE,QAAQ;;UA62BJ;;EAEf;;EAEA;;;;;;;EAOA,QAAQ;;;;;;;;wBASM,aAAa,YAAW,iBAAsB;UCn6B7C;;;;;;;;EAQf;;EAEA;;;;;;;wBC9Bc,gBAAgB,kBAAiB;;qBCZpC;;qBAqCA,oBAAoB;;;;;;wBAejB,oBAAoB;;wBCzBpB,UAAU;UAcT;;EAEf;;EAEA;;;;;;;;wBASc,YAAY,gBAAgB,kBAAkB;KC7ClD;UAIK;;EAEf,SAAS;EACT;;IAEE;;IAEA;;IAEA;;;;;;;IAOA;;EAEF;;IAEE;;IAEA;;IAEA;;IAEA;;;UAIa;EACf,QAAQ;EACR,SAAS;;EAET;;EAEA;;wBAoBoB,cAAc,UAAS,uBAA4B,QAAQ;iBCzBhE;;;;;;;;;;;EAWf;;EAEA;;;;;;;;;EASA,qBAAqB;;;;;;EAMrB,SAAS;;;;;;;EAOT;;;;;;wBAOc,aAAa,UAAS,sBAA2B;;wBAmBjD,aAAa,UAAS,uCAAwB,gCAAA"}