@getvitops/emdash 2.0.0-alpha.0 → 2.0.0-alpha.1

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 (36) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/index.d.mts +1 -0
  3. package/dist/index.d.mts.map +1 -1
  4. package/dist/index.mjs +152 -3
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +5 -5
  7. package/src/astro/Nothing.astro +3 -0
  8. package/src/astro/WidgetArea.astro +91 -0
  9. package/src/astro/blocks/Accordion.astro +2 -1
  10. package/src/astro/blocks/ActionLink.astro +2 -1
  11. package/src/astro/blocks/Badges.astro +67 -0
  12. package/src/astro/blocks/Banner.astro +3 -2
  13. package/src/astro/blocks/Callout.astro +2 -7
  14. package/src/astro/blocks/Cards.astro +2 -1
  15. package/src/astro/blocks/Carousel.astro +2 -0
  16. package/src/astro/blocks/CopyButton.astro +3 -2
  17. package/src/astro/blocks/Details.astro +2 -1
  18. package/src/astro/blocks/Embed.astro +2 -1
  19. package/src/astro/blocks/Entries.astro +2 -1
  20. package/src/astro/blocks/Form.astro +2 -1
  21. package/src/astro/blocks/Gallery.astro +2 -0
  22. package/src/astro/blocks/Hero.astro +2 -1
  23. package/src/astro/blocks/ImageCompare.astro +2 -1
  24. package/src/astro/blocks/Logos.astro +2 -2
  25. package/src/astro/blocks/Marquee.astro +2 -1
  26. package/src/astro/blocks/Nav.astro +2 -2
  27. package/src/astro/blocks/Pricing.astro +2 -2
  28. package/src/astro/blocks/Reviews.astro +2 -2
  29. package/src/astro/blocks/Section.astro +8 -10
  30. package/src/astro/blocks/Stats.astro +2 -2
  31. package/src/astro/blocks/Steps.astro +2 -2
  32. package/src/astro/blocks/WidgetArea.astro +21 -0
  33. package/src/astro/blocks/attrs.test.ts +56 -0
  34. package/src/astro/blocks/attrs.ts +104 -0
  35. package/src/astro/blocks/render.container.test.ts +40 -0
  36. package/src/astro/index.ts +7 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @getvitops/emdash
2
2
 
3
+ ## 2.0.0-alpha.1
4
+
5
+ ### Minor Changes
6
+
7
+ - 24c568b: Escape hatches on every block, a section theme, widget areas, a badges block, Tailwind scanning of package renderers, and a sturdier `vitops audit`.
8
+
9
+ **@getvitops/emdash**
10
+
11
+ - Every `vitops.*` block and `vitops_section` gains three fields: `anchor` (rendered as the `id`, so `#contact` works), `className` (`class_name` on the section type: block-type slugs are lowercase) and `style`. `style` takes CSS custom properties only (`--p-card: 2rem`); any other declaration, and any value containing `url(`, `@`, `{`, `}` or a backslash, is dropped. With the `tailwind` format a class typed in the CMS only works if the site already uses it. They are applied to the block's own outermost element (the grid `<ul>` for `vitops.cards`), never an extra wrapper, so a block's markup is the same whether or not an editor fills them in.
12
+ - `vitops_section` gains a `theme` select: a role, or `<role>:solid`, with readable text chosen by the generator's contrast rules. It overrides `tone`/`color`/`solid`, which stay for existing content. Other site roles still go through `tone`.
13
+ - New `vitops.badges` block (a row of `.badge` or `.tag` labels, each with an optional tone, icon and link) and `vitops.widgetArea` block, plus `<VitopsWidgetArea name level />` from `@getvitops/emdash/astro`. A widget area is content defined once under Widgets and shown wherever it is placed. An area cannot hold another area, and an area containing a `core:*` component widget is rendered by EmDash's own renderer.
14
+ - Existing sites: re-run the block-type seed only on a new database; on an existing one add the `theme`, `anchor`, `className` and `style` fields to the `vitops_section` block type in the admin.
15
+
16
+ **@getvitops/create**: the emdash template seeds `announcement` and `pre-footer` widget areas, renders them in `Layout.astro`, and documents when to use a Section, a block or a widget area. Sites scaffolded earlier add the two `<VitopsWidgetArea>` lines and the `widgetAreas` seed entries by hand.
17
+
18
+ **@getvitops/generator / astro / vite** (`tailwind` format only): the Astro integration now adds `@source` lines for `@getvitops/astro` and `@getvitops/emdash`, because Tailwind v4 does not scan `node_modules`; utilities used only by their renderers (`font-display`, `font-caption`, `font-footnote`) were never emitted and the page silently rendered at body size. New `sources` option on `generate()` and the Vite plugin. A site's `src/package-classes.txt` workaround can be deleted. css and bricks: no change.
19
+
20
+ **@getvitops/cli**: `vitops emdash check-prerender` now also warns when a page uses a type-role class (`font-display`, …) the built CSS has no rule for; `--strict` makes it fail. `vitops audit` checks for its optional packages and a Chromium binary before starting the preview server (so a failed run no longer leaves port 4398 busy), stops the server on Ctrl+C and termination, and takes its page list from the built sitemap, then the menus; the guessed defaults (`/privacy`, `/contact`, …) are used only when neither exists.
21
+
22
+ **@getvitops/utils**: the audit helpers behind the above (`preflight`, `fetchSitemapPaths`, `sitemapLocs`, `pathsFromSitemapLocs`).
23
+
24
+ **@getvitops/core** (all formats): new `.block-anchor` rule gives an anchored block `scroll-margin-top: var(--header-offset, 5rem)`; set `--header-offset` to a sticky header's height. New `widget-area.css` partial. No other consumer-facing change.
25
+
26
+ The other fixed-group packages: no consumer-facing change beyond the above.
27
+
28
+ **Also fixed in the emdash template** (`site.json`): it defined only the `display`, `heading` and `body` type roles while the blocks use `title`, `eyebrow`, `lead`, `caption` and `footnote`, so those rendered at body size with no rule behind them. The roles are added with the reference design system's specs. A site scaffolded earlier adds the same five entries under `designSystem.themes.default.typography.roles`; `vitops emdash check-prerender` now names any that are missing.
29
+
30
+ ### Patch Changes
31
+
32
+ - Updated dependencies [24c568b]
33
+ - @getvitops/generator@8.3.0-alpha.1
34
+ - @getvitops/utils@8.3.0-alpha.1
35
+
3
36
  ## 2.0.0-alpha.0
4
37
 
5
38
  ### Minor Changes
package/dist/index.d.mts CHANGED
@@ -7,6 +7,7 @@ type BlockKitFieldDef = Extract<NonNullable<PortableTextBlockConfig['fields']>[n
7
7
  type PortableTextBlockDef = Omit<PortableTextBlockConfig, 'fields'> & {
8
8
  fields?: BlockKitFieldDef[];
9
9
  };
10
+ /** Every block gets the escape hatches last, so the editor reads content first. */
10
11
  export declare const BLOCKS: PortableTextBlockDef[];
11
12
  /** Which Vitops blocks a site's editor offers, and any it adds of its own. */
12
13
  interface BlockSelection {
@@ -1 +1 @@
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"}
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;;;qBA8/BE,QAAQ;;UAMJ;;EAEf;;EAEA;;;;;;;EAOA,QAAQ;;;;;;;;wBASM,aAAa,YAAW,iBAAsB;UCvgC7C;;;;;;;;EAQf;;EAEA;;;;;;;wBC9Bc,gBAAgB,kBAAiB;;qBCZpC;;qBA+DA,oBAAoB;;;;;;wBAejB,oBAAoB;;wBCnDpB,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;iBClBhE;;;;;;;;;;;EAWf;;EAEA;;;;;;;;;EASA,qBAAqB;;;;;;EAMrB,SAAS;;;;;;;EAOT;;;;;;wBAOc,aAAa,UAAS,sBAA2B;;wBAmBjD,aAAa,UAAS,uCAAwB,gCAAA"}
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { definePlugin, getMenus, pluginResponse } from "emdash";
1
+ import { definePlugin, getMenus, getWidgetAreas, pluginResponse } from "emdash";
2
2
  import { iconMap } from "@getvitops/utils";
3
3
  import { designSystemPath, formatConfig, getAt, isConfig, mergePatch, resolveInput, setAt } from "@getvitops/generator/config";
4
4
  import { buildReverseIndex, patchToOverrideCss, validateColorContract } from "@getvitops/generator/tokens";
@@ -167,6 +167,31 @@ function toneFields() {
167
167
  label: "Palette colour instead of a tone (e.g. amber or amber-300)"
168
168
  }];
169
169
  }
170
+ /** Route that lists the site's widget areas for `vitops.widgetArea`'s `area` select. */
171
+ const WIDGET_AREAS_ROUTE = "widget-areas/list";
172
+ /**
173
+ * The escape hatches every block carries, appended last by `BLOCKS` (see `astro/blocks/attrs.ts`
174
+ * for how each is validated and why `style` takes custom properties only).
175
+ */
176
+ function commonFields() {
177
+ return [
178
+ {
179
+ type: "text_input",
180
+ action_id: "anchor",
181
+ label: "Anchor id (so a link can point here with #id)"
182
+ },
183
+ {
184
+ type: "text_input",
185
+ action_id: "className",
186
+ label: "Extra CSS classes (with the tailwind format, only classes the site already uses)"
187
+ },
188
+ {
189
+ type: "text_input",
190
+ action_id: "style",
191
+ label: "CSS custom properties, e.g. --p-card: 2rem; --tone-bg: #fee"
192
+ }
193
+ ];
194
+ }
170
195
  /** Heading level for a block's own heading; `h1` is reserved for the page title. */
171
196
  const levelField = (initial) => ({
172
197
  type: "select",
@@ -184,7 +209,7 @@ const levelField = (initial) => ({
184
209
  value: n
185
210
  }))
186
211
  });
187
- const BLOCKS = [
212
+ const BASE_BLOCKS = [
188
213
  {
189
214
  /**
190
215
  * A link or button, optionally with an icon at either end.
@@ -1530,8 +1555,95 @@ const BLOCKS = [
1530
1555
  },
1531
1556
  ...toneFields()
1532
1557
  ]
1558
+ },
1559
+ {
1560
+ /** A row of static labels (`badge`) or editable/dismissable ones (`tag`). */
1561
+ type: "vitops.badges",
1562
+ label: "Badges",
1563
+ icon: "tag",
1564
+ placeholder: "A row of short labels",
1565
+ fields: [
1566
+ {
1567
+ type: "repeater",
1568
+ action_id: "items",
1569
+ label: "Labels",
1570
+ fields: [
1571
+ {
1572
+ type: "text_input",
1573
+ action_id: "label",
1574
+ label: "Label"
1575
+ },
1576
+ {
1577
+ type: "select",
1578
+ action_id: "tone",
1579
+ label: "Tone (blank uses the block tone)",
1580
+ initial_value: "",
1581
+ options: STATIC_TONE_OPTIONS,
1582
+ optionsRoute: TONES_ROUTE
1583
+ },
1584
+ {
1585
+ type: "text_input",
1586
+ action_id: "color",
1587
+ label: "Palette colour instead (e.g. amber)"
1588
+ },
1589
+ {
1590
+ type: "combobox",
1591
+ action_id: "icon",
1592
+ label: "Icon before the label",
1593
+ placeholder: "None",
1594
+ options: SEMANTIC_ICON_OPTIONS
1595
+ },
1596
+ {
1597
+ type: "text_input",
1598
+ action_id: "href",
1599
+ label: "Link URL (optional)"
1600
+ }
1601
+ ]
1602
+ },
1603
+ {
1604
+ type: "select",
1605
+ action_id: "variant",
1606
+ label: "Style",
1607
+ initial_value: "badge",
1608
+ options: [{
1609
+ label: "Badge (static label)",
1610
+ value: "badge"
1611
+ }, {
1612
+ label: "Tag",
1613
+ value: "tag"
1614
+ }]
1615
+ },
1616
+ ...toneFields()
1617
+ ]
1618
+ },
1619
+ {
1620
+ /**
1621
+ * A widget area: content defined once under Widgets in the admin and shown wherever this
1622
+ * block is placed. Edits reach every page it sits on (after the next build, on a
1623
+ * prerendered site) — unlike a Section, which is copied.
1624
+ */
1625
+ type: "vitops.widgetArea",
1626
+ label: "Widget area",
1627
+ icon: "layout",
1628
+ placeholder: "Shared content managed under Widgets",
1629
+ fields: [{
1630
+ type: "select",
1631
+ action_id: "area",
1632
+ label: "Widget area",
1633
+ initial_value: "",
1634
+ options: [{
1635
+ label: "Choose…",
1636
+ value: ""
1637
+ }],
1638
+ optionsRoute: WIDGET_AREAS_ROUTE
1639
+ }, levelField("3")]
1533
1640
  }
1534
1641
  ];
1642
+ /** Every block gets the escape hatches last, so the editor reads content first. */
1643
+ const BLOCKS = BASE_BLOCKS.map((b) => ({
1644
+ ...b,
1645
+ fields: [...b.fields ?? [], ...commonFields()]
1646
+ }));
1535
1647
  /**
1536
1648
  * Resolve {@link BlockSelection} against {@link BLOCKS}.
1537
1649
  *
@@ -1778,6 +1890,26 @@ const select = (slug, label, options, defaultValue) => ({
1778
1890
  defaultValue,
1779
1891
  validation: { options }
1780
1892
  });
1893
+ /**
1894
+ * The `theme` select's values: `none`, a role, or `<role>:solid`. Block-type selects are
1895
+ * static, so this lists the roles every site defines; any other site role still works through
1896
+ * the `tone` field. `<role>:solid` is the filled backdrop with the contrast-computed text.
1897
+ */
1898
+ const THEME_ROLES = [
1899
+ "neutral",
1900
+ "surface",
1901
+ "brand-primary",
1902
+ "brand-secondary",
1903
+ "info",
1904
+ "success",
1905
+ "warning",
1906
+ "danger"
1907
+ ];
1908
+ const THEMES = [
1909
+ "none",
1910
+ ...THEME_ROLES,
1911
+ ...THEME_ROLES.map((r) => `${r}:solid`)
1912
+ ];
1781
1913
  const SECTION_FIELDS = [
1782
1914
  {
1783
1915
  slug: "kicker",
@@ -1832,6 +1964,22 @@ const SECTION_FIELDS = [
1832
1964
  label: "Fill with the solid colour",
1833
1965
  type: "boolean",
1834
1966
  defaultValue: false
1967
+ },
1968
+ select("theme", "Theme (backdrop and readable text in one pick; overrides the tone fields)", THEMES, "none"),
1969
+ {
1970
+ slug: "anchor",
1971
+ label: "Anchor id (so a link can point here with #id)",
1972
+ type: "string"
1973
+ },
1974
+ {
1975
+ slug: "class_name",
1976
+ label: "Extra CSS classes",
1977
+ type: "string"
1978
+ },
1979
+ {
1980
+ slug: "style",
1981
+ label: "CSS custom properties, e.g. --p-card: 2rem",
1982
+ type: "string"
1835
1983
  }
1836
1984
  ];
1837
1985
  /** `vitops.section`: kicker, heading, lead-in, tone/backdrop, optional heading-left layout, and a body of blocks. */
@@ -1986,7 +2134,7 @@ async function vitopsHosting(options = {}) {
1986
2134
  }
1987
2135
 
1988
2136
  // package.json
1989
- var version = "2.0.0-alpha.0";
2137
+ var version = "2.0.0-alpha.1";
1990
2138
 
1991
2139
  // src/index.ts
1992
2140
  /**
@@ -2089,6 +2237,7 @@ function createPlugin(options = {}) {
2089
2237
  routes: {
2090
2238
  [TONES_ROUTE]: createTonesRoute(() => roles),
2091
2239
  [MENUS_ROUTE]: createMenusRoute(() => getMenus()),
2240
+ [WIDGET_AREAS_ROUTE]: createMenusRoute(() => getWidgetAreas()),
2092
2241
  ...editor ? { "design-system": createDesignSystemRoute(editor) } : {}
2093
2242
  }
2094
2243
  });