@styleflow.app/flowpress-astro-core 1.0.0-beta.11 → 1.0.0-beta.12

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 CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 1.0.0-beta.12
6
+
7
+ - Added the official `core/cover` renderer and editable default adapter with
8
+ image/video media, focal point, validated minimum height, nested content and
9
+ Styleflow root props.
10
+ - Added prefixed Styleflow coordinates for semantic scrims and kept native
11
+ `dimRatio` only as a temporary compatibility switch, never as raw CSS.
12
+ - Added a `default` root export so Node CommonJS resolution can locate the ESM
13
+ entry used by project scaffolding commands.
14
+
5
15
  ## 1.0.0-beta.11
6
16
 
7
17
  - Made the official default adapter usable by both Site Editor compositions
package/README.md CHANGED
@@ -9,7 +9,7 @@ The package must not import from an application or project plugin.
9
9
  ## Install
10
10
 
11
11
  ```bash
12
- pnpm add @styleflow.app/flowpress-astro-core@1.0.0-beta.11 \
12
+ pnpm add @styleflow.app/flowpress-astro-core@1.0.0-beta.12 \
13
13
  @styleflow.app/astro@1.0.0-beta.6
14
14
  ```
15
15
 
@@ -131,6 +131,15 @@ remain composition-only. File discovery never changes a
131
131
  source used by scaffolding when `--from-default` is selected. Unsupported
132
132
  blocks throw instead of pretending that a semantic implementation exists.
133
133
 
134
+ `core/cover` is part of catalog version 2. Its public `CoverBlock.astro`
135
+ renderer accepts the native image/video URL, focal point, content position and
136
+ minimum height, renders nested blocks through a slot and keeps media at
137
+ `object-fit: cover`. The root uses the normal Styleflow props; the overlay uses
138
+ the same validated contract through prefixed attributes such as `scrimTone`,
139
+ `scrimIntensity`, `scrimSurface` and `scrimTheme`. `scrimEnabled` controls its
140
+ presence. Native `dimRatio` is read only as a compatibility on/off signal and
141
+ is not converted to an inline opacity.
142
+
134
143
  Static adapters produce no JavaScript by default. A project opts into client
135
144
  runtime only inside adapters classified as interactive; React views rendered
136
145
  without `client:*` remain server-only HTML.
@@ -235,7 +244,7 @@ The TypeScript template-hierarchy suite is self-contained. Its additional PHP
235
244
  parity test runs when the sibling `flowpress-wordpress-core` checkout is
236
245
  available locally and is skipped in a standalone package checkout.
237
246
 
238
- Publish `1.0.0-beta.11` on `next` only after the exact Styleflow prerelease is
247
+ Publish `1.0.0-beta.12` on `next` only after the exact Styleflow prerelease is
239
248
  available. Inspect `npm view`, `gitHead`, integrity and the downloaded tarball.
240
249
  Promote to `latest` only after the DMO canary and rollback gate.
241
250
 
@@ -19,6 +19,7 @@ import type { DynamicStyleflowProps } from "../styleflow.js";
19
19
  import ColumnBlock from "./blocks/ColumnBlock.astro";
20
20
  import CarouselBlock from "./blocks/CarouselBlock.astro";
21
21
  import CarouselItemBlock from "./blocks/CarouselItemBlock.astro";
22
+ import CoverBlock from "./blocks/CoverBlock.astro";
22
23
  import FormBlock from "./blocks/FormBlock.astro";
23
24
  import GridBlock from "./blocks/GridBlock.astro";
24
25
  import HeroBlock from "./blocks/HeroBlock.astro";
@@ -254,6 +255,25 @@ function nestedRendererProps(nextParentBlockName: string) {
254
255
  return <NumberSpinnerBlock block={block} contract={contract} />;
255
256
  }
256
257
 
258
+ if (block.name === "core/cover") {
259
+ return (
260
+ <CoverBlock
261
+ block={block}
262
+ contract={contract}
263
+ htmlProps={htmlAttributes}
264
+ styleflowProps={semantic}
265
+ >
266
+ <Astro.self
267
+ blocks={children}
268
+ contract={contract}
269
+ blockRenderers={blockRenderers}
270
+ iconRenderer={IconRenderer}
271
+ {...nestedRendererProps(block.name)}
272
+ />
273
+ </CoverBlock>
274
+ );
275
+ }
276
+
257
277
  if ([
258
278
  "heading",
259
279
  "rich-text",
@@ -0,0 +1,151 @@
1
+ ---
2
+ import S from "@styleflow.app/astro/S.astro";
3
+ import type { DynamicStyleflowProps, StyleflowContract } from "../../styleflow.js";
4
+ import { resolvePrefixedFlowpressBlockStyleflowProps } from "../../styleflow.js";
5
+ import type {
6
+ FlowpressBlock,
7
+ FlowpressBlockHtmlProps
8
+ } from "../../types.js";
9
+ import { blockHtmlAttributes, semanticProps } from "./helpers.js";
10
+ import {
11
+ coverBackgroundType,
12
+ coverContentPosition,
13
+ coverMediaSource,
14
+ coverMinimumHeight,
15
+ coverObjectPosition,
16
+ coverPosterSource,
17
+ coverScrimEnabled,
18
+ coverTagName
19
+ } from "./cover.js";
20
+
21
+ interface Props {
22
+ block: FlowpressBlock;
23
+ contract?: StyleflowContract;
24
+ htmlProps?: FlowpressBlockHtmlProps;
25
+ styleflowProps?: DynamicStyleflowProps;
26
+ }
27
+
28
+ const { block, contract, htmlProps, styleflowProps } = Astro.props;
29
+ const attributes = block.attributes;
30
+ const rootStyleflowProps = styleflowProps ?? semanticProps(attributes, contract, {
31
+ layoutRole: "region",
32
+ density: "regular"
33
+ });
34
+ const normalizedHtmlProps = htmlProps ?? blockHtmlAttributes(attributes);
35
+ const rootHtmlProps = {
36
+ ...normalizedHtmlProps,
37
+ class: ["wp-block-cover", "flowpress-cover", normalizedHtmlProps.class]
38
+ .filter(Boolean)
39
+ .join(" ")
40
+ };
41
+ const backgroundType = coverBackgroundType(block);
42
+ const source = coverMediaSource(block);
43
+ const poster = coverPosterSource(block);
44
+ const alt = String(attributes.alt ?? block.resolvedData?.alt ?? "");
45
+ const width = Number(block.resolvedData?.width) || undefined;
46
+ const height = Number(block.resolvedData?.height) || undefined;
47
+ const objectPosition = coverObjectPosition(attributes.focalPoint);
48
+ const minimumHeight = coverMinimumHeight(
49
+ attributes.minHeight,
50
+ attributes.minHeightUnit
51
+ );
52
+ const [contentBlockPosition, contentInlinePosition] = coverContentPosition(
53
+ attributes.contentPosition
54
+ );
55
+ const rootStyle = [
56
+ `--flowpress-cover-object-position:${objectPosition}`,
57
+ minimumHeight ? `--flowpress-cover-min-height:${minimumHeight}` : "",
58
+ `--flowpress-cover-content-block:${contentBlockPosition}`,
59
+ `--flowpress-cover-content-inline:${contentInlinePosition}`
60
+ ].filter(Boolean).join(";");
61
+ const scrimEnabled = backgroundType !== "color" && coverScrimEnabled(attributes);
62
+ const scrimStyleflowProps = resolvePrefixedFlowpressBlockStyleflowProps(
63
+ attributes,
64
+ "scrim",
65
+ contract,
66
+ {},
67
+ {
68
+ strict: process.env.NODE_ENV === "production" || process.env.STYLEFLOW_STRICT === "1",
69
+ onDiagnostic: (diagnostic) => console.warn(`[${diagnostic.code}] ${diagnostic.message}`)
70
+ }
71
+ );
72
+ const tagName = coverTagName(attributes.tagName);
73
+ ---
74
+
75
+ <S as={tagName} {...rootStyleflowProps} {...rootHtmlProps} style={rootStyle}>
76
+ {backgroundType === "image" && source ? (
77
+ <img
78
+ class="wp-block-cover__image-background flowpress-cover__media"
79
+ src={source}
80
+ width={width}
81
+ height={height}
82
+ alt={alt}
83
+ aria-hidden={alt ? undefined : "true"}
84
+ loading="lazy"
85
+ decoding="async"
86
+ />
87
+ ) : null}
88
+ {backgroundType === "video" && source ? (
89
+ <video
90
+ class="wp-block-cover__video-background flowpress-cover__media"
91
+ src={source}
92
+ poster={poster}
93
+ autoplay
94
+ muted
95
+ loop
96
+ playsinline
97
+ preload="metadata"
98
+ aria-hidden="true"
99
+ tabindex="-1"
100
+ />
101
+ ) : null}
102
+ {scrimEnabled ? (
103
+ <S.span
104
+ class="wp-block-cover__background flowpress-cover__scrim"
105
+ {...scrimStyleflowProps}
106
+ data-flowpress-cover-scrim
107
+ aria-hidden="true"
108
+ />
109
+ ) : null}
110
+ <S.div class="wp-block-cover__inner-container flowpress-cover__content">
111
+ <slot />
112
+ </S.div>
113
+ </S>
114
+
115
+ <style>
116
+ .flowpress-cover {
117
+ position: relative;
118
+ display: grid;
119
+ min-height: var(--flowpress-cover-min-height, 0);
120
+ overflow: hidden;
121
+ isolation: isolate;
122
+ }
123
+
124
+ .flowpress-cover__media,
125
+ .flowpress-cover__scrim {
126
+ position: absolute;
127
+ inset: 0;
128
+ width: 100%;
129
+ height: 100%;
130
+ }
131
+
132
+ .flowpress-cover__media {
133
+ z-index: 0;
134
+ object-fit: cover;
135
+ object-position: var(--flowpress-cover-object-position, 50% 50%);
136
+ }
137
+
138
+ .flowpress-cover__scrim {
139
+ z-index: 1;
140
+ background: var(--sf-background);
141
+ pointer-events: none;
142
+ }
143
+
144
+ .flowpress-cover__content {
145
+ position: relative;
146
+ z-index: 2;
147
+ display: grid;
148
+ align-items: var(--flowpress-cover-content-block, center);
149
+ justify-items: var(--flowpress-cover-content-inline, center);
150
+ }
151
+ </style>
@@ -0,0 +1,11 @@
1
+ import type { FlowpressBlock } from "../../types.js";
2
+ export type CoverBackgroundType = "color" | "image" | "video";
3
+ export declare function coverTagName(value: unknown): string;
4
+ export declare function coverMediaSource(block: FlowpressBlock): string;
5
+ export declare function coverPosterSource(block: FlowpressBlock): string | undefined;
6
+ export declare function coverBackgroundType(block: FlowpressBlock): CoverBackgroundType;
7
+ export declare function coverObjectPosition(value: unknown): string;
8
+ export declare function coverMinimumHeight(value: unknown, unitValue: unknown): string | undefined;
9
+ export declare function coverContentPosition(value: unknown): [string, string];
10
+ export declare function coverScrimEnabled(attributes: Record<string, unknown>): boolean;
11
+ //# sourceMappingURL=cover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cover.d.ts","sourceRoot":"","sources":["../../../src/astro/blocks/cover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAwC9D,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAGnD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAE9D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CAI3E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,cAAc,GAAG,mBAAmB,CAK9E;AAUD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQ1D;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,OAAO,GACjB,MAAM,GAAG,SAAS,CAMpB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAGrE;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAM9E"}
@@ -0,0 +1,93 @@
1
+ const COVER_TAGS = new Set([
2
+ "article",
3
+ "aside",
4
+ "div",
5
+ "footer",
6
+ "header",
7
+ "main",
8
+ "section"
9
+ ]);
10
+ const HEIGHT_UNITS = new Set([
11
+ "px",
12
+ "%",
13
+ "em",
14
+ "rem",
15
+ "vh",
16
+ "svh",
17
+ "lvh",
18
+ "dvh",
19
+ "vw"
20
+ ]);
21
+ const CONTENT_POSITIONS = {
22
+ "top left": ["start", "start"],
23
+ "top center": ["start", "center"],
24
+ "top right": ["start", "end"],
25
+ "center left": ["center", "start"],
26
+ "center center": ["center", "center"],
27
+ "center right": ["center", "end"],
28
+ "bottom left": ["end", "start"],
29
+ "bottom center": ["end", "center"],
30
+ "bottom right": ["end", "end"]
31
+ };
32
+ function text(value) {
33
+ return typeof value === "string" ? value.trim() : "";
34
+ }
35
+ export function coverTagName(value) {
36
+ const candidate = text(value).toLowerCase();
37
+ return COVER_TAGS.has(candidate) ? candidate : "div";
38
+ }
39
+ export function coverMediaSource(block) {
40
+ return text(block.attributes.url) || text(block.resolvedData?.url);
41
+ }
42
+ export function coverPosterSource(block) {
43
+ return text(block.attributes.poster)
44
+ || text(block.resolvedData?.poster)
45
+ || undefined;
46
+ }
47
+ export function coverBackgroundType(block) {
48
+ const requested = text(block.attributes.backgroundType).toLowerCase();
49
+ if (requested === "video")
50
+ return "video";
51
+ if (requested === "color")
52
+ return "color";
53
+ return coverMediaSource(block) ? "image" : "color";
54
+ }
55
+ function percentage(value) {
56
+ const numeric = typeof value === "number" ? value : Number(value);
57
+ if (!Number.isFinite(numeric))
58
+ return undefined;
59
+ if (numeric >= 0 && numeric <= 1)
60
+ return numeric * 100;
61
+ if (numeric >= 0 && numeric <= 100)
62
+ return numeric;
63
+ return undefined;
64
+ }
65
+ export function coverObjectPosition(value) {
66
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
67
+ return "50% 50%";
68
+ }
69
+ const focalPoint = value;
70
+ const x = percentage(focalPoint.x);
71
+ const y = percentage(focalPoint.y);
72
+ return x === undefined || y === undefined ? "50% 50%" : `${x}% ${y}%`;
73
+ }
74
+ export function coverMinimumHeight(value, unitValue) {
75
+ const numeric = typeof value === "number" ? value : Number(value);
76
+ if (!Number.isFinite(numeric) || numeric < 0)
77
+ return undefined;
78
+ const requestedUnit = text(unitValue).toLowerCase();
79
+ const unit = HEIGHT_UNITS.has(requestedUnit) ? requestedUnit : "px";
80
+ return `${numeric}${unit}`;
81
+ }
82
+ export function coverContentPosition(value) {
83
+ return CONTENT_POSITIONS[text(value).toLowerCase()]
84
+ ?? ["center", "center"];
85
+ }
86
+ export function coverScrimEnabled(attributes) {
87
+ if (typeof attributes.scrimEnabled === "boolean") {
88
+ return attributes.scrimEnabled;
89
+ }
90
+ const nativeDimRatio = Number(attributes.dimRatio);
91
+ return Number.isFinite(nativeDimRatio) && nativeDimRatio > 0;
92
+ }
93
+ //# sourceMappingURL=cover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cover.js","sourceRoot":"","sources":["../../../src/astro/blocks/cover.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FlowpressBlock } from \"../../types.js\";\n\nexport type CoverBackgroundType = \"color\" | \"image\" | \"video\";\n\nconst COVER_TAGS = new Set([\n \"article\",\n \"aside\",\n \"div\",\n \"footer\",\n \"header\",\n \"main\",\n \"section\"\n]);\n\nconst HEIGHT_UNITS = new Set([\n \"px\",\n \"%\",\n \"em\",\n \"rem\",\n \"vh\",\n \"svh\",\n \"lvh\",\n \"dvh\",\n \"vw\"\n]);\n\nconst CONTENT_POSITIONS: Record<string, [string, string]> = {\n \"top left\": [\"start\", \"start\"],\n \"top center\": [\"start\", \"center\"],\n \"top right\": [\"start\", \"end\"],\n \"center left\": [\"center\", \"start\"],\n \"center center\": [\"center\", \"center\"],\n \"center right\": [\"center\", \"end\"],\n \"bottom left\": [\"end\", \"start\"],\n \"bottom center\": [\"end\", \"center\"],\n \"bottom right\": [\"end\", \"end\"]\n};\n\nfunction text(value: unknown): string {\n return typeof value === \"string\" ? value.trim() : \"\";\n}\n\nexport function coverTagName(value: unknown): string {\n const candidate = text(value).toLowerCase();\n return COVER_TAGS.has(candidate) ? candidate : \"div\";\n}\n\nexport function coverMediaSource(block: FlowpressBlock): string {\n return text(block.attributes.url) || text(block.resolvedData?.url);\n}\n\nexport function coverPosterSource(block: FlowpressBlock): string | undefined {\n return text(block.attributes.poster)\n || text(block.resolvedData?.poster)\n || undefined;\n}\n\nexport function coverBackgroundType(block: FlowpressBlock): CoverBackgroundType {\n const requested = text(block.attributes.backgroundType).toLowerCase();\n if (requested === \"video\") return \"video\";\n if (requested === \"color\") return \"color\";\n return coverMediaSource(block) ? \"image\" : \"color\";\n}\n\nfunction percentage(value: unknown): number | undefined {\n const numeric = typeof value === \"number\" ? value : Number(value);\n if (!Number.isFinite(numeric)) return undefined;\n if (numeric >= 0 && numeric <= 1) return numeric * 100;\n if (numeric >= 0 && numeric <= 100) return numeric;\n return undefined;\n}\n\nexport function coverObjectPosition(value: unknown): string {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return \"50% 50%\";\n }\n const focalPoint = value as Record<string, unknown>;\n const x = percentage(focalPoint.x);\n const y = percentage(focalPoint.y);\n return x === undefined || y === undefined ? \"50% 50%\" : `${x}% ${y}%`;\n}\n\nexport function coverMinimumHeight(\n value: unknown,\n unitValue: unknown\n): string | undefined {\n const numeric = typeof value === \"number\" ? value : Number(value);\n if (!Number.isFinite(numeric) || numeric < 0) return undefined;\n const requestedUnit = text(unitValue).toLowerCase();\n const unit = HEIGHT_UNITS.has(requestedUnit) ? requestedUnit : \"px\";\n return `${numeric}${unit}`;\n}\n\nexport function coverContentPosition(value: unknown): [string, string] {\n return CONTENT_POSITIONS[text(value).toLowerCase()]\n ?? [\"center\", \"center\"];\n}\n\nexport function coverScrimEnabled(attributes: Record<string, unknown>): boolean {\n if (typeof attributes.scrimEnabled === \"boolean\") {\n return attributes.scrimEnabled;\n }\n const nativeDimRatio = Number(attributes.dimRatio);\n return Number.isFinite(nativeDimRatio) && nativeDimRatio > 0;\n}\n"]}
@@ -0,0 +1,105 @@
1
+ import type { FlowpressBlock } from "../../types.js";
2
+
3
+ export type CoverBackgroundType = "color" | "image" | "video";
4
+
5
+ const COVER_TAGS = new Set([
6
+ "article",
7
+ "aside",
8
+ "div",
9
+ "footer",
10
+ "header",
11
+ "main",
12
+ "section"
13
+ ]);
14
+
15
+ const HEIGHT_UNITS = new Set([
16
+ "px",
17
+ "%",
18
+ "em",
19
+ "rem",
20
+ "vh",
21
+ "svh",
22
+ "lvh",
23
+ "dvh",
24
+ "vw"
25
+ ]);
26
+
27
+ const CONTENT_POSITIONS: Record<string, [string, string]> = {
28
+ "top left": ["start", "start"],
29
+ "top center": ["start", "center"],
30
+ "top right": ["start", "end"],
31
+ "center left": ["center", "start"],
32
+ "center center": ["center", "center"],
33
+ "center right": ["center", "end"],
34
+ "bottom left": ["end", "start"],
35
+ "bottom center": ["end", "center"],
36
+ "bottom right": ["end", "end"]
37
+ };
38
+
39
+ function text(value: unknown): string {
40
+ return typeof value === "string" ? value.trim() : "";
41
+ }
42
+
43
+ export function coverTagName(value: unknown): string {
44
+ const candidate = text(value).toLowerCase();
45
+ return COVER_TAGS.has(candidate) ? candidate : "div";
46
+ }
47
+
48
+ export function coverMediaSource(block: FlowpressBlock): string {
49
+ return text(block.attributes.url) || text(block.resolvedData?.url);
50
+ }
51
+
52
+ export function coverPosterSource(block: FlowpressBlock): string | undefined {
53
+ return text(block.attributes.poster)
54
+ || text(block.resolvedData?.poster)
55
+ || undefined;
56
+ }
57
+
58
+ export function coverBackgroundType(block: FlowpressBlock): CoverBackgroundType {
59
+ const requested = text(block.attributes.backgroundType).toLowerCase();
60
+ if (requested === "video") return "video";
61
+ if (requested === "color") return "color";
62
+ return coverMediaSource(block) ? "image" : "color";
63
+ }
64
+
65
+ function percentage(value: unknown): number | undefined {
66
+ const numeric = typeof value === "number" ? value : Number(value);
67
+ if (!Number.isFinite(numeric)) return undefined;
68
+ if (numeric >= 0 && numeric <= 1) return numeric * 100;
69
+ if (numeric >= 0 && numeric <= 100) return numeric;
70
+ return undefined;
71
+ }
72
+
73
+ export function coverObjectPosition(value: unknown): string {
74
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
75
+ return "50% 50%";
76
+ }
77
+ const focalPoint = value as Record<string, unknown>;
78
+ const x = percentage(focalPoint.x);
79
+ const y = percentage(focalPoint.y);
80
+ return x === undefined || y === undefined ? "50% 50%" : `${x}% ${y}%`;
81
+ }
82
+
83
+ export function coverMinimumHeight(
84
+ value: unknown,
85
+ unitValue: unknown
86
+ ): string | undefined {
87
+ const numeric = typeof value === "number" ? value : Number(value);
88
+ if (!Number.isFinite(numeric) || numeric < 0) return undefined;
89
+ const requestedUnit = text(unitValue).toLowerCase();
90
+ const unit = HEIGHT_UNITS.has(requestedUnit) ? requestedUnit : "px";
91
+ return `${numeric}${unit}`;
92
+ }
93
+
94
+ export function coverContentPosition(value: unknown): [string, string] {
95
+ return CONTENT_POSITIONS[text(value).toLowerCase()]
96
+ ?? ["center", "center"];
97
+ }
98
+
99
+ export function coverScrimEnabled(attributes: Record<string, unknown>): boolean {
100
+ if (typeof attributes.scrimEnabled === "boolean") {
101
+ return attributes.scrimEnabled;
102
+ }
103
+ const nativeDimRatio = Number(attributes.dimRatio);
104
+ return Number.isFinite(nativeDimRatio) && nativeDimRatio > 0;
105
+ }
@@ -1,4 +1,4 @@
1
- export declare const FLOWPRESS_DEFAULT_BLOCK_CATALOG_VERSION: "1";
1
+ export declare const FLOWPRESS_DEFAULT_BLOCK_CATALOG_VERSION: "2";
2
2
  export interface FlowpressDefaultBlockCatalogEntry {
3
3
  blockName: string;
4
4
  template: "DefaultBlockAdapter.astro";
@@ -1 +1 @@
1
- {"version":3,"file":"default-blocks.d.ts","sourceRoot":"","sources":["../src/default-blocks.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uCAAuC,EAAG,GAAY,CAAC;AAEpE,MAAM,WAAW,iCAAiC;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,2BAA2B,CAAC;CACvC;AAoCD,eAAO,MAAM,4BAA4B,EAAE,SAAS,iCAAiC,EACE,CAAC;AAIxF,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE1E;AAED,wBAAgB,wCAAwC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAalF"}
1
+ {"version":3,"file":"default-blocks.d.ts","sourceRoot":"","sources":["../src/default-blocks.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uCAAuC,EAAG,GAAY,CAAC;AAEpE,MAAM,WAAW,iCAAiC;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,2BAA2B,CAAC;CACvC;AAqCD,eAAO,MAAM,4BAA4B,EAAE,SAAS,iCAAiC,EACE,CAAC;AAIxF,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE1E;AAED,wBAAgB,wCAAwC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA+BlF"}
@@ -1,5 +1,6 @@
1
- export const FLOWPRESS_DEFAULT_BLOCK_CATALOG_VERSION = "1";
1
+ export const FLOWPRESS_DEFAULT_BLOCK_CATALOG_VERSION = "2";
2
2
  const blockNames = [
3
+ "core/cover",
3
4
  "core/group",
4
5
  "core/heading",
5
6
  "core/list",
@@ -41,6 +42,24 @@ export function createFlowpressDefaultBlockAdapterSource(blockName) {
41
42
  if (!hasFlowpressDefaultBlockAdapter(blockName)) {
42
43
  throw new Error(`FlowPress has no official default adapter for ${blockName}.`);
43
44
  }
45
+ if (blockName === "core/cover") {
46
+ return `---
47
+ import CoverBlock from "@styleflow.app/flowpress-astro-core/blocks/CoverBlock.astro";
48
+ import type { FlowpressBlockRendererProps } from "@styleflow.app/flowpress-astro-core";
49
+
50
+ const { block, contract, htmlProps, styleflowProps } = Astro.props as FlowpressBlockRendererProps;
51
+ ---
52
+
53
+ <CoverBlock
54
+ block={block}
55
+ contract={contract}
56
+ htmlProps={htmlProps}
57
+ styleflowProps={styleflowProps}
58
+ >
59
+ <slot />
60
+ </CoverBlock>
61
+ `;
62
+ }
44
63
  return `---
45
64
  import DefaultBlockAdapter from "@styleflow.app/flowpress-astro-core/DefaultBlockAdapter.astro";
46
65
  import type { FlowpressBlockRendererProps } from "@styleflow.app/flowpress-astro-core";
@@ -1 +1 @@
1
- {"version":3,"file":"default-blocks.js","sourceRoot":"","sources":["../src/default-blocks.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,uCAAuC,GAAG,GAAY,CAAC;AAOpE,MAAM,UAAU,GAAG;IACjB,YAAY;IACZ,cAAc;IACd,WAAW;IACX,gBAAgB;IAChB,gBAAgB;IAChB,YAAY;IACZ,mBAAmB;IACnB,WAAW;IACX,SAAS;IACT,aAAa;IACb,kBAAkB;IAClB,SAAS;IACT,SAAS;IACT,WAAW;IACX,iBAAiB;IACjB,SAAS;IACT,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,SAAS;IACT,SAAS;IACT,UAAU;IACV,QAAQ;IACR,mBAAmB;IACnB,UAAU;IACV,cAAc;IACd,YAAY;IACZ,aAAa;IACb,cAAc;IACd,UAAU;IACV,kBAAkB;CACV,CAAC;AAEX,MAAM,CAAC,MAAM,4BAA4B,GACvC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,2BAA2B,EAAE,CAAC,CAAC,CAAC;AAExF,MAAM,SAAS,GAAG,IAAI,GAAG,CAAS,UAAU,CAAC,CAAC;AAE9C,MAAM,UAAU,+BAA+B,CAAC,SAAiB;IAC/D,OAAO,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,wCAAwC,CAAC,SAAiB;IACxE,IAAI,CAAC,+BAA+B,CAAC,SAAS,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,iDAAiD,SAAS,GAAG,CAAC,CAAC;IACjF,CAAC;IACD,OAAO;;;;;;;;CAQR,CAAC;AACF,CAAC","sourcesContent":["export const FLOWPRESS_DEFAULT_BLOCK_CATALOG_VERSION = \"1\" as const;\n\nexport interface FlowpressDefaultBlockCatalogEntry {\n blockName: string;\n template: \"DefaultBlockAdapter.astro\";\n}\n\nconst blockNames = [\n \"core/group\",\n \"core/heading\",\n \"core/list\",\n \"core/list-item\",\n \"core/paragraph\",\n \"core/quote\",\n \"sf/accordion-item\",\n \"sf/button\",\n \"sf/card\",\n \"sf/carousel\",\n \"sf/carousel-item\",\n \"sf/chip\",\n \"sf/code\",\n \"sf/column\",\n \"sf/content-list\",\n \"sf/form\",\n \"sf/gallery\",\n \"sf/grid\",\n \"sf/heading\",\n \"sf/hero\",\n \"sf/icon\",\n \"sf/image\",\n \"sf/map\",\n \"sf/number-spinner\",\n \"sf/quote\",\n \"sf/rich-text\",\n \"sf/section\",\n \"sf/template\",\n \"sf/term-list\",\n \"sf/video\",\n \"sf/video-youtube\"\n] as const;\n\nexport const flowpressDefaultBlockCatalog: readonly FlowpressDefaultBlockCatalogEntry[] =\n blockNames.map((blockName) => ({ blockName, template: \"DefaultBlockAdapter.astro\" }));\n\nconst supported = new Set<string>(blockNames);\n\nexport function hasFlowpressDefaultBlockAdapter(blockName: string): boolean {\n return supported.has(blockName);\n}\n\nexport function createFlowpressDefaultBlockAdapterSource(blockName: string): string {\n if (!hasFlowpressDefaultBlockAdapter(blockName)) {\n throw new Error(`FlowPress has no official default adapter for ${blockName}.`);\n }\n return `---\nimport DefaultBlockAdapter from \"@styleflow.app/flowpress-astro-core/DefaultBlockAdapter.astro\";\nimport type { FlowpressBlockRendererProps } from \"@styleflow.app/flowpress-astro-core\";\n\nconst props = Astro.props as FlowpressBlockRendererProps;\n---\n\n<DefaultBlockAdapter {...props} />\n`;\n}\n"]}
1
+ {"version":3,"file":"default-blocks.js","sourceRoot":"","sources":["../src/default-blocks.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,uCAAuC,GAAG,GAAY,CAAC;AAOpE,MAAM,UAAU,GAAG;IACjB,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,WAAW;IACX,gBAAgB;IAChB,gBAAgB;IAChB,YAAY;IACZ,mBAAmB;IACnB,WAAW;IACX,SAAS;IACT,aAAa;IACb,kBAAkB;IAClB,SAAS;IACT,SAAS;IACT,WAAW;IACX,iBAAiB;IACjB,SAAS;IACT,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,SAAS;IACT,SAAS;IACT,UAAU;IACV,QAAQ;IACR,mBAAmB;IACnB,UAAU;IACV,cAAc;IACd,YAAY;IACZ,aAAa;IACb,cAAc;IACd,UAAU;IACV,kBAAkB;CACV,CAAC;AAEX,MAAM,CAAC,MAAM,4BAA4B,GACvC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,2BAA2B,EAAE,CAAC,CAAC,CAAC;AAExF,MAAM,SAAS,GAAG,IAAI,GAAG,CAAS,UAAU,CAAC,CAAC;AAE9C,MAAM,UAAU,+BAA+B,CAAC,SAAiB;IAC/D,OAAO,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,wCAAwC,CAAC,SAAiB;IACxE,IAAI,CAAC,+BAA+B,CAAC,SAAS,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,iDAAiD,SAAS,GAAG,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;QAC/B,OAAO;;;;;;;;;;;;;;;CAeV,CAAC;IACA,CAAC;IACD,OAAO;;;;;;;;CAQR,CAAC;AACF,CAAC","sourcesContent":["export const FLOWPRESS_DEFAULT_BLOCK_CATALOG_VERSION = \"2\" as const;\n\nexport interface FlowpressDefaultBlockCatalogEntry {\n blockName: string;\n template: \"DefaultBlockAdapter.astro\";\n}\n\nconst blockNames = [\n \"core/cover\",\n \"core/group\",\n \"core/heading\",\n \"core/list\",\n \"core/list-item\",\n \"core/paragraph\",\n \"core/quote\",\n \"sf/accordion-item\",\n \"sf/button\",\n \"sf/card\",\n \"sf/carousel\",\n \"sf/carousel-item\",\n \"sf/chip\",\n \"sf/code\",\n \"sf/column\",\n \"sf/content-list\",\n \"sf/form\",\n \"sf/gallery\",\n \"sf/grid\",\n \"sf/heading\",\n \"sf/hero\",\n \"sf/icon\",\n \"sf/image\",\n \"sf/map\",\n \"sf/number-spinner\",\n \"sf/quote\",\n \"sf/rich-text\",\n \"sf/section\",\n \"sf/template\",\n \"sf/term-list\",\n \"sf/video\",\n \"sf/video-youtube\"\n] as const;\n\nexport const flowpressDefaultBlockCatalog: readonly FlowpressDefaultBlockCatalogEntry[] =\n blockNames.map((blockName) => ({ blockName, template: \"DefaultBlockAdapter.astro\" }));\n\nconst supported = new Set<string>(blockNames);\n\nexport function hasFlowpressDefaultBlockAdapter(blockName: string): boolean {\n return supported.has(blockName);\n}\n\nexport function createFlowpressDefaultBlockAdapterSource(blockName: string): string {\n if (!hasFlowpressDefaultBlockAdapter(blockName)) {\n throw new Error(`FlowPress has no official default adapter for ${blockName}.`);\n }\n if (blockName === \"core/cover\") {\n return `---\nimport CoverBlock from \"@styleflow.app/flowpress-astro-core/blocks/CoverBlock.astro\";\nimport type { FlowpressBlockRendererProps } from \"@styleflow.app/flowpress-astro-core\";\n\nconst { block, contract, htmlProps, styleflowProps } = Astro.props as FlowpressBlockRendererProps;\n---\n\n<CoverBlock\n block={block}\n contract={contract}\n htmlProps={htmlProps}\n styleflowProps={styleflowProps}\n>\n <slot />\n</CoverBlock>\n`;\n }\n return `---\nimport DefaultBlockAdapter from \"@styleflow.app/flowpress-astro-core/DefaultBlockAdapter.astro\";\nimport type { FlowpressBlockRendererProps } from \"@styleflow.app/flowpress-astro-core\";\n\nconst props = Astro.props as FlowpressBlockRendererProps;\n---\n\n<DefaultBlockAdapter {...props} />\n`;\n}\n"]}
@@ -56,6 +56,13 @@ export interface ResolveDynamicStyleflowOptions {
56
56
  }
57
57
  /** Select and validate the semantic attributes authored on a Gutenberg block. */
58
58
  export declare function resolveFlowpressBlockStyleflowProps(attributes: Record<string, unknown>, contract?: StyleflowContract, defaults?: DynamicStyleflowProps, options?: ResolveDynamicStyleflowOptions): DynamicStyleflowProps;
59
+ /**
60
+ * Resolve a second, namespaced set of Styleflow coordinates stored on a block.
61
+ *
62
+ * A `scrimTone` attribute is therefore validated exactly like `tone`, without
63
+ * leaking the prefixed authoring attribute into the rendered DOM.
64
+ */
65
+ export declare function resolvePrefixedFlowpressBlockStyleflowProps(attributes: Record<string, unknown>, prefix: string, contract?: StyleflowContract, defaults?: DynamicStyleflowProps, options?: ResolveDynamicStyleflowOptions): DynamicStyleflowProps;
59
66
  /** Validate CMS-authored props against the grouped vNext project contract. */
60
67
  export declare function resolveDynamicStyleflowProps(input: DynamicStyleflowProps, defaults: DynamicStyleflowProps, contract: StyleflowContract, options?: ResolveDynamicStyleflowOptions): DynamicStyleflowProps;
61
68
  //# sourceMappingURL=styleflow.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"styleflow.d.ts","sourceRoot":"","sources":["../src/styleflow.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACnH,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;IACvG,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC7F,WAAW,EAAE;QAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACzD;AACD,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,IAAI,EAAE,qBAAqB,CAAC;QAC5B,WAAW,EAAE;YAAE,QAAQ,EAAE;gBAAE,UAAU,EAAE,MAAM,CAAC;gBAAC,OAAO,EAAE,MAAM,CAAC;gBAAC,UAAU,EAAE;oBAAE,EAAE,EAAE,MAAM,CAAC;oBAAC,CAAC,EAAE,MAAM,CAAC;oBAAC,CAAC,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,CAAA;SAAE,CAAC;KACtH,CAAC;CACH;AACD,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC5D,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,sBAAsB,GAAG,uBAAuB,CAAC;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AACD,MAAM,WAAW,8BAA8B;IAC7C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAC1D;AAuBD,iFAAiF;AACjF,wBAAgB,mCAAmC,CACjD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,QAAQ,CAAC,EAAE,iBAAiB,EAC5B,QAAQ,GAAE,qBAA0B,EACpC,OAAO,GAAE,8BAAmC,GAC3C,qBAAqB,CAevB;AAED,8EAA8E;AAC9E,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,qBAAqB,EAC5B,QAAQ,EAAE,qBAAqB,EAC/B,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,GAAE,8BAAmC,GAC3C,qBAAqB,CAiCvB"}
1
+ {"version":3,"file":"styleflow.d.ts","sourceRoot":"","sources":["../src/styleflow.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACnH,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;IACvG,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC7F,WAAW,EAAE;QAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACzD;AACD,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,IAAI,EAAE,qBAAqB,CAAC;QAC5B,WAAW,EAAE;YAAE,QAAQ,EAAE;gBAAE,UAAU,EAAE,MAAM,CAAC;gBAAC,OAAO,EAAE,MAAM,CAAC;gBAAC,UAAU,EAAE;oBAAE,EAAE,EAAE,MAAM,CAAC;oBAAC,CAAC,EAAE,MAAM,CAAC;oBAAC,CAAC,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,CAAA;SAAE,CAAC;KACtH,CAAC;CACH;AACD,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC5D,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,sBAAsB,GAAG,uBAAuB,CAAC;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AACD,MAAM,WAAW,8BAA8B;IAC7C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAC1D;AAuBD,iFAAiF;AACjF,wBAAgB,mCAAmC,CACjD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,QAAQ,CAAC,EAAE,iBAAiB,EAC5B,QAAQ,GAAE,qBAA0B,EACpC,OAAO,GAAE,8BAAmC,GAC3C,qBAAqB,CAevB;AAED;;;;;GAKG;AACH,wBAAgB,2CAA2C,CACzD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,iBAAiB,EAC5B,QAAQ,GAAE,qBAA0B,EACpC,OAAO,GAAE,8BAAmC,GAC3C,qBAAqB,CAWvB;AAED,8EAA8E;AAC9E,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,qBAAqB,EAC5B,QAAQ,EAAE,qBAAqB,EAC/B,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,GAAE,8BAAmC,GAC3C,qBAAqB,CAiCvB"}
package/dist/styleflow.js CHANGED
@@ -33,6 +33,19 @@ export function resolveFlowpressBlockStyleflowProps(attributes, contract, defaul
33
33
  }
34
34
  return resolved;
35
35
  }
36
+ /**
37
+ * Resolve a second, namespaced set of Styleflow coordinates stored on a block.
38
+ *
39
+ * A `scrimTone` attribute is therefore validated exactly like `tone`, without
40
+ * leaking the prefixed authoring attribute into the rendered DOM.
41
+ */
42
+ export function resolvePrefixedFlowpressBlockStyleflowProps(attributes, prefix, contract, defaults = {}, options = {}) {
43
+ const prefixed = Object.fromEntries(BLOCK_STYLEFLOW_PROPS.flatMap((key) => {
44
+ const name = `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;
45
+ return attributes[name] === undefined ? [] : [[key, attributes[name]]];
46
+ }));
47
+ return resolveFlowpressBlockStyleflowProps(prefixed, contract, defaults, options);
48
+ }
36
49
  /** Validate CMS-authored props against the grouped vNext project contract. */
37
50
  export function resolveDynamicStyleflowProps(input, defaults, contract, options = {}) {
38
51
  const resolved = { ...defaults };
@@ -1 +1 @@
1
- {"version":3,"file":"styleflow.js","sourceRoot":"","sources":["../src/styleflow.ts"],"names":[],"mappings":"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","sourcesContent":["export interface StyleflowContractAxes {\n color: { tones: string[]; intensitiesByTone: Record<string, string[]>; surfaces: string[]; foregrounds: string[] };\n layout: { roles: string[]; densities: string[]; breakpoints: Array<{ id: string; minWidth: number }> };\n typography: { types: string[]; variantsByType: Record<string, string[]>; weights: string[] };\n interaction: { priorities: string[]; states: string[] };\n}\nexport interface StyleflowContract {\n defaultTheme?: string;\n semantic: {\n themes: string[];\n axes: StyleflowContractAxes;\n agentPolicy: { defaults: { layoutRole: string; density: string; typography: { ty: string; v: string; w: string } } };\n };\n}\nexport type DynamicStyleflowProps = Record<string, unknown>;\nexport interface StyleflowDiagnostic {\n code: \"FP_STYLEFLOW_INVALID\" | \"FP_STYLEFLOW_FALLBACK\";\n prop: string;\n value: unknown;\n fallback?: unknown;\n blocking: boolean;\n message: string;\n}\nexport interface ResolveDynamicStyleflowOptions {\n strict?: boolean;\n onDiagnostic?: (diagnostic: StyleflowDiagnostic) => void;\n}\n\nconst INHERITED_PROPS = new Set([\"theme\", \"tone\", \"intensity\", \"foreground\"]);\nconst BLOCK_STYLEFLOW_PROPS = [\n \"theme\",\n \"tone\",\n \"intensity\",\n \"surface\",\n \"layoutRole\",\n \"density\",\n \"ty\",\n \"v\",\n \"w\",\n \"foreground\",\n \"interactivePriority\",\n \"noBackground\",\n \"noBorder\",\n \"noPadding\",\n \"noGap\",\n \"noRadius\",\n \"noForeground\"\n] as const;\n\n/** Select and validate the semantic attributes authored on a Gutenberg block. */\nexport function resolveFlowpressBlockStyleflowProps(\n attributes: Record<string, unknown>,\n contract?: StyleflowContract,\n defaults: DynamicStyleflowProps = {},\n options: ResolveDynamicStyleflowOptions = {}\n): DynamicStyleflowProps {\n const input = Object.fromEntries(\n BLOCK_STYLEFLOW_PROPS\n .filter((key) => attributes[key] !== undefined)\n .map((key) => [key, attributes[key]])\n );\n if (contract) {\n return resolveDynamicStyleflowProps(input, defaults, contract, options);\n }\n\n const resolved = { ...defaults, ...input };\n for (const key of INHERITED_PROPS) {\n if (input[key] === \"inherit\") delete resolved[key];\n }\n return resolved;\n}\n\n/** Validate CMS-authored props against the grouped vNext project contract. */\nexport function resolveDynamicStyleflowProps(\n input: DynamicStyleflowProps,\n defaults: DynamicStyleflowProps,\n contract: StyleflowContract,\n options: ResolveDynamicStyleflowOptions = {}\n): DynamicStyleflowProps {\n const resolved: DynamicStyleflowProps = { ...defaults };\n for (const [key, value] of Object.entries(input)) {\n if (value === undefined || value === null || value === \"\") continue;\n if (INHERITED_PROPS.has(key) && value === \"inherit\") { delete resolved[key]; continue; }\n if (key === \"interactionState\") {\n invalid(key, value, undefined, options); delete resolved[key]; continue;\n }\n const allowed = allowedValues(key, input, defaults, contract);\n if (!allowed) { resolved[key] = value; continue; }\n const candidate = typeof value === \"string\"\n ? value\n : typeof value === \"number\" && Number.isFinite(value)\n ? String(value)\n : undefined;\n if (candidate !== undefined && allowed.includes(candidate)) {\n resolved[key] = candidate;\n continue;\n }\n const fallback = explicitFallback(key, defaults, contract);\n invalid(key, value, fallback, options);\n if (fallback === undefined) delete resolved[key]; else resolved[key] = fallback;\n }\n // Validate dependent defaults too: a default is not permission to emit a\n // coordinate absent from the current project contract.\n for (const key of [\"theme\", \"tone\", \"intensity\", \"surface\", \"foreground\", \"layoutRole\", \"density\", \"ty\", \"v\", \"w\", \"interactivePriority\"]) {\n if (resolved[key] === undefined) continue;\n const allowed = allowedValues(key, resolved, defaults, contract);\n if (allowed && !allowed.includes(String(resolved[key]))) {\n invalid(key, resolved[key], undefined, options); delete resolved[key];\n }\n }\n return resolved;\n}\n\nfunction allowedValues(\n key: string, input: DynamicStyleflowProps, defaults: DynamicStyleflowProps,\n contract: StyleflowContract\n): string[] | undefined {\n const axes = contract.semantic.axes;\n if (key === \"theme\") return contract.semantic.themes;\n if (key === \"tone\") return axes.color.tones;\n if (key === \"intensity\") {\n const tone = String(input.tone ?? defaults.tone ?? \"\");\n return tone ? axes.color.intensitiesByTone[tone] ?? [] : [...new Set(Object.values(axes.color.intensitiesByTone).flat())];\n }\n if (key === \"surface\") return axes.color.surfaces;\n if (key === \"foreground\") return axes.color.foregrounds;\n if (key === \"layoutRole\") return axes.layout.roles;\n if (key === \"density\") return axes.layout.densities;\n if (key === \"ty\") return axes.typography.types;\n if (key === \"v\") {\n const authoredType = input.ty ?? defaults.ty;\n if (authoredType !== undefined && authoredType !== null && authoredType !== \"\") {\n return axes.typography.variantsByType[String(authoredType)] ?? [];\n }\n return [...new Set(Object.values(axes.typography.variantsByType).flat())];\n }\n if (key === \"w\") return axes.typography.weights;\n if (key === \"interactivePriority\") return axes.interaction.priorities;\n return undefined;\n}\n\nfunction explicitFallback(key: string, defaults: DynamicStyleflowProps, contract: StyleflowContract): unknown {\n if (defaults[key] !== undefined) return defaults[key];\n if (key === \"layoutRole\") return contract.semantic.agentPolicy.defaults.layoutRole;\n if (key === \"density\") return contract.semantic.agentPolicy.defaults.density;\n if (key === \"ty\" || key === \"v\" || key === \"w\") return contract.semantic.agentPolicy.defaults.typography[key];\n if (key === \"theme\") return contract.defaultTheme;\n return undefined;\n}\nfunction invalid(key: string, value: unknown, fallback: unknown, options: ResolveDynamicStyleflowOptions): void {\n const diagnostic: StyleflowDiagnostic = {\n code: fallback === undefined ? \"FP_STYLEFLOW_INVALID\" : \"FP_STYLEFLOW_FALLBACK\",\n prop: key, value, ...(fallback !== undefined ? { fallback } : {}),\n blocking: options.strict === true,\n message: fallback === undefined\n ? `Styleflow prop ${key}=${JSON.stringify(value)} is not in the grouped project contract.`\n : `Styleflow prop ${key}=${JSON.stringify(value)} fell back to ${JSON.stringify(fallback)}.`\n };\n (options.onDiagnostic ?? ((item) => console.warn(`[${item.code}] ${item.message}`)))(diagnostic);\n if (options.strict) throw new Error(`${diagnostic.code}: ${diagnostic.message}`);\n}\n"]}
1
+ {"version":3,"file":"styleflow.js","sourceRoot":"","sources":["../src/styleflow.ts"],"names":[],"mappings":"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","sourcesContent":["export interface StyleflowContractAxes {\n color: { tones: string[]; intensitiesByTone: Record<string, string[]>; surfaces: string[]; foregrounds: string[] };\n layout: { roles: string[]; densities: string[]; breakpoints: Array<{ id: string; minWidth: number }> };\n typography: { types: string[]; variantsByType: Record<string, string[]>; weights: string[] };\n interaction: { priorities: string[]; states: string[] };\n}\nexport interface StyleflowContract {\n defaultTheme?: string;\n semantic: {\n themes: string[];\n axes: StyleflowContractAxes;\n agentPolicy: { defaults: { layoutRole: string; density: string; typography: { ty: string; v: string; w: string } } };\n };\n}\nexport type DynamicStyleflowProps = Record<string, unknown>;\nexport interface StyleflowDiagnostic {\n code: \"FP_STYLEFLOW_INVALID\" | \"FP_STYLEFLOW_FALLBACK\";\n prop: string;\n value: unknown;\n fallback?: unknown;\n blocking: boolean;\n message: string;\n}\nexport interface ResolveDynamicStyleflowOptions {\n strict?: boolean;\n onDiagnostic?: (diagnostic: StyleflowDiagnostic) => void;\n}\n\nconst INHERITED_PROPS = new Set([\"theme\", \"tone\", \"intensity\", \"foreground\"]);\nconst BLOCK_STYLEFLOW_PROPS = [\n \"theme\",\n \"tone\",\n \"intensity\",\n \"surface\",\n \"layoutRole\",\n \"density\",\n \"ty\",\n \"v\",\n \"w\",\n \"foreground\",\n \"interactivePriority\",\n \"noBackground\",\n \"noBorder\",\n \"noPadding\",\n \"noGap\",\n \"noRadius\",\n \"noForeground\"\n] as const;\n\n/** Select and validate the semantic attributes authored on a Gutenberg block. */\nexport function resolveFlowpressBlockStyleflowProps(\n attributes: Record<string, unknown>,\n contract?: StyleflowContract,\n defaults: DynamicStyleflowProps = {},\n options: ResolveDynamicStyleflowOptions = {}\n): DynamicStyleflowProps {\n const input = Object.fromEntries(\n BLOCK_STYLEFLOW_PROPS\n .filter((key) => attributes[key] !== undefined)\n .map((key) => [key, attributes[key]])\n );\n if (contract) {\n return resolveDynamicStyleflowProps(input, defaults, contract, options);\n }\n\n const resolved = { ...defaults, ...input };\n for (const key of INHERITED_PROPS) {\n if (input[key] === \"inherit\") delete resolved[key];\n }\n return resolved;\n}\n\n/**\n * Resolve a second, namespaced set of Styleflow coordinates stored on a block.\n *\n * A `scrimTone` attribute is therefore validated exactly like `tone`, without\n * leaking the prefixed authoring attribute into the rendered DOM.\n */\nexport function resolvePrefixedFlowpressBlockStyleflowProps(\n attributes: Record<string, unknown>,\n prefix: string,\n contract?: StyleflowContract,\n defaults: DynamicStyleflowProps = {},\n options: ResolveDynamicStyleflowOptions = {}\n): DynamicStyleflowProps {\n const prefixed = Object.fromEntries(BLOCK_STYLEFLOW_PROPS.flatMap((key) => {\n const name = `${prefix}${key.charAt(0).toUpperCase()}${key.slice(1)}`;\n return attributes[name] === undefined ? [] : [[key, attributes[name]]];\n }));\n return resolveFlowpressBlockStyleflowProps(\n prefixed,\n contract,\n defaults,\n options\n );\n}\n\n/** Validate CMS-authored props against the grouped vNext project contract. */\nexport function resolveDynamicStyleflowProps(\n input: DynamicStyleflowProps,\n defaults: DynamicStyleflowProps,\n contract: StyleflowContract,\n options: ResolveDynamicStyleflowOptions = {}\n): DynamicStyleflowProps {\n const resolved: DynamicStyleflowProps = { ...defaults };\n for (const [key, value] of Object.entries(input)) {\n if (value === undefined || value === null || value === \"\") continue;\n if (INHERITED_PROPS.has(key) && value === \"inherit\") { delete resolved[key]; continue; }\n if (key === \"interactionState\") {\n invalid(key, value, undefined, options); delete resolved[key]; continue;\n }\n const allowed = allowedValues(key, input, defaults, contract);\n if (!allowed) { resolved[key] = value; continue; }\n const candidate = typeof value === \"string\"\n ? value\n : typeof value === \"number\" && Number.isFinite(value)\n ? String(value)\n : undefined;\n if (candidate !== undefined && allowed.includes(candidate)) {\n resolved[key] = candidate;\n continue;\n }\n const fallback = explicitFallback(key, defaults, contract);\n invalid(key, value, fallback, options);\n if (fallback === undefined) delete resolved[key]; else resolved[key] = fallback;\n }\n // Validate dependent defaults too: a default is not permission to emit a\n // coordinate absent from the current project contract.\n for (const key of [\"theme\", \"tone\", \"intensity\", \"surface\", \"foreground\", \"layoutRole\", \"density\", \"ty\", \"v\", \"w\", \"interactivePriority\"]) {\n if (resolved[key] === undefined) continue;\n const allowed = allowedValues(key, resolved, defaults, contract);\n if (allowed && !allowed.includes(String(resolved[key]))) {\n invalid(key, resolved[key], undefined, options); delete resolved[key];\n }\n }\n return resolved;\n}\n\nfunction allowedValues(\n key: string, input: DynamicStyleflowProps, defaults: DynamicStyleflowProps,\n contract: StyleflowContract\n): string[] | undefined {\n const axes = contract.semantic.axes;\n if (key === \"theme\") return contract.semantic.themes;\n if (key === \"tone\") return axes.color.tones;\n if (key === \"intensity\") {\n const tone = String(input.tone ?? defaults.tone ?? \"\");\n return tone ? axes.color.intensitiesByTone[tone] ?? [] : [...new Set(Object.values(axes.color.intensitiesByTone).flat())];\n }\n if (key === \"surface\") return axes.color.surfaces;\n if (key === \"foreground\") return axes.color.foregrounds;\n if (key === \"layoutRole\") return axes.layout.roles;\n if (key === \"density\") return axes.layout.densities;\n if (key === \"ty\") return axes.typography.types;\n if (key === \"v\") {\n const authoredType = input.ty ?? defaults.ty;\n if (authoredType !== undefined && authoredType !== null && authoredType !== \"\") {\n return axes.typography.variantsByType[String(authoredType)] ?? [];\n }\n return [...new Set(Object.values(axes.typography.variantsByType).flat())];\n }\n if (key === \"w\") return axes.typography.weights;\n if (key === \"interactivePriority\") return axes.interaction.priorities;\n return undefined;\n}\n\nfunction explicitFallback(key: string, defaults: DynamicStyleflowProps, contract: StyleflowContract): unknown {\n if (defaults[key] !== undefined) return defaults[key];\n if (key === \"layoutRole\") return contract.semantic.agentPolicy.defaults.layoutRole;\n if (key === \"density\") return contract.semantic.agentPolicy.defaults.density;\n if (key === \"ty\" || key === \"v\" || key === \"w\") return contract.semantic.agentPolicy.defaults.typography[key];\n if (key === \"theme\") return contract.defaultTheme;\n return undefined;\n}\nfunction invalid(key: string, value: unknown, fallback: unknown, options: ResolveDynamicStyleflowOptions): void {\n const diagnostic: StyleflowDiagnostic = {\n code: fallback === undefined ? \"FP_STYLEFLOW_INVALID\" : \"FP_STYLEFLOW_FALLBACK\",\n prop: key, value, ...(fallback !== undefined ? { fallback } : {}),\n blocking: options.strict === true,\n message: fallback === undefined\n ? `Styleflow prop ${key}=${JSON.stringify(value)} is not in the grouped project contract.`\n : `Styleflow prop ${key}=${JSON.stringify(value)} fell back to ${JSON.stringify(fallback)}.`\n };\n (options.onDiagnostic ?? ((item) => console.warn(`[${item.code}] ${item.message}`)))(diagnostic);\n if (options.strict) throw new Error(`${diagnostic.code}: ${diagnostic.message}`);\n}\n"]}
@@ -1 +1 @@
1
- {"root":["../src/astro.d.ts","../src/block-renderers.ts","../src/carousel.ts","../src/client.ts","../src/composition.ts","../src/default-blocks.ts","../src/env.ts","../src/index.ts","../src/links.ts","../src/media.ts","../src/number-spinner.ts","../src/style-classes.ts","../src/styleflow.ts","../src/template-hierarchy.ts","../src/templates.ts","../src/theme-runtime.ts","../src/types.ts","../src/astro/blocks/helpers.ts"],"version":"5.9.3"}
1
+ {"root":["../src/astro.d.ts","../src/block-renderers.ts","../src/carousel.ts","../src/client.ts","../src/composition.ts","../src/default-blocks.ts","../src/env.ts","../src/index.ts","../src/links.ts","../src/media.ts","../src/number-spinner.ts","../src/style-classes.ts","../src/styleflow.ts","../src/template-hierarchy.ts","../src/templates.ts","../src/theme-runtime.ts","../src/types.ts","../src/astro/blocks/cover.ts","../src/astro/blocks/helpers.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@styleflow.app/flowpress-astro-core",
3
- "version": "1.0.0-beta.11",
3
+ "version": "1.0.0-beta.12",
4
4
  "description": "Project-agnostic WordPress routing, templates, SEO and GraphQL runtime for FlowPress Astro apps.",
5
5
  "type": "module",
6
6
  "private": false,
@@ -21,7 +21,8 @@
21
21
  "exports": {
22
22
  ".": {
23
23
  "types": "./dist/index.d.ts",
24
- "import": "./dist/index.js"
24
+ "import": "./dist/index.js",
25
+ "default": "./dist/index.js"
25
26
  },
26
27
  "./templates": "./dist/templates.js",
27
28
  "./BaseLayout.astro": "./dist/astro/BaseLayout.astro",
@@ -31,6 +32,7 @@
31
32
  "./DefaultBlockAdapter.astro": "./dist/astro/DefaultBlockAdapter.astro",
32
33
  "./ThemeRuntime.astro": "./dist/astro/ThemeRuntime.astro",
33
34
  "./blocks/ThemeToggleBlock.astro": "./dist/astro/blocks/ThemeToggleBlock.astro",
35
+ "./blocks/CoverBlock.astro": "./dist/astro/blocks/CoverBlock.astro",
34
36
  "./blocks/SiteLogoBlock.astro": "./dist/astro/blocks/SiteLogoBlock.astro"
35
37
  },
36
38
  "files": [