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

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,24 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 1.0.0-beta.13
6
+
7
+ - Added `scrimOpacity` as an explicit `0–100` percentage for the official
8
+ Cover renderer, clamped at the public boundary and emitted through a scoped
9
+ CSS custom property.
10
+ - Preserved legacy Cover content by using native `dimRatio` as the opacity
11
+ fallback only when `scrimOpacity` is absent or invalid.
12
+
13
+ ## 1.0.0-beta.12
14
+
15
+ - Added the official `core/cover` renderer and editable default adapter with
16
+ image/video media, focal point, validated minimum height, nested content and
17
+ Styleflow root props.
18
+ - Added prefixed Styleflow coordinates for semantic scrims and kept native
19
+ `dimRatio` only as a temporary compatibility switch, never as raw CSS.
20
+ - Added a `default` root export so Node CommonJS resolution can locate the ESM
21
+ entry used by project scaffolding commands.
22
+
5
23
  ## 1.0.0-beta.11
6
24
 
7
25
  - 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.13 \
13
13
  @styleflow.app/astro@1.0.0-beta.6
14
14
  ```
15
15
 
@@ -131,6 +131,17 @@ 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 and `scrimOpacity` accepts an explicit percentage from `0` to `100`.
141
+ Values outside the interval are clamped. Native `dimRatio` remains a
142
+ compatibility input for both activation and opacity when the explicit
143
+ Styleflow-facing fields are absent.
144
+
134
145
  Static adapters produce no JavaScript by default. A project opts into client
135
146
  runtime only inside adapters classified as interactive; React views rendered
136
147
  without `client:*` remain server-only HTML.
@@ -235,7 +246,7 @@ The TypeScript template-hierarchy suite is self-contained. Its additional PHP
235
246
  parity test runs when the sibling `flowpress-wordpress-core` checkout is
236
247
  available locally and is skipped in a standalone package checkout.
237
248
 
238
- Publish `1.0.0-beta.11` on `next` only after the exact Styleflow prerelease is
249
+ Publish `1.0.0-beta.13` on `next` only after the exact Styleflow prerelease is
239
250
  available. Inspect `npm view`, `gitHead`, integrity and the downloaded tarball.
240
251
  Promote to `latest` only after the DMO canary and rollback gate.
241
252
 
@@ -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,155 @@
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
+ coverScrimOpacity,
19
+ coverTagName
20
+ } from "./cover.js";
21
+
22
+ interface Props {
23
+ block: FlowpressBlock;
24
+ contract?: StyleflowContract;
25
+ htmlProps?: FlowpressBlockHtmlProps;
26
+ styleflowProps?: DynamicStyleflowProps;
27
+ }
28
+
29
+ const { block, contract, htmlProps, styleflowProps } = Astro.props;
30
+ const attributes = block.attributes;
31
+ const rootStyleflowProps = styleflowProps ?? semanticProps(attributes, contract, {
32
+ layoutRole: "region",
33
+ density: "regular"
34
+ });
35
+ const normalizedHtmlProps = htmlProps ?? blockHtmlAttributes(attributes);
36
+ const rootHtmlProps = {
37
+ ...normalizedHtmlProps,
38
+ class: ["wp-block-cover", "flowpress-cover", normalizedHtmlProps.class]
39
+ .filter(Boolean)
40
+ .join(" ")
41
+ };
42
+ const backgroundType = coverBackgroundType(block);
43
+ const source = coverMediaSource(block);
44
+ const poster = coverPosterSource(block);
45
+ const alt = String(attributes.alt ?? block.resolvedData?.alt ?? "");
46
+ const width = Number(block.resolvedData?.width) || undefined;
47
+ const height = Number(block.resolvedData?.height) || undefined;
48
+ const objectPosition = coverObjectPosition(attributes.focalPoint);
49
+ const minimumHeight = coverMinimumHeight(
50
+ attributes.minHeight,
51
+ attributes.minHeightUnit
52
+ );
53
+ const [contentBlockPosition, contentInlinePosition] = coverContentPosition(
54
+ attributes.contentPosition
55
+ );
56
+ const scrimOpacity = coverScrimOpacity(attributes);
57
+ const rootStyle = [
58
+ `--flowpress-cover-object-position:${objectPosition}`,
59
+ minimumHeight ? `--flowpress-cover-min-height:${minimumHeight}` : "",
60
+ `--flowpress-cover-content-block:${contentBlockPosition}`,
61
+ `--flowpress-cover-content-inline:${contentInlinePosition}`,
62
+ `--flowpress-cover-scrim-opacity:${scrimOpacity / 100}`
63
+ ].filter(Boolean).join(";");
64
+ const scrimEnabled = backgroundType !== "color" && coverScrimEnabled(attributes);
65
+ const scrimStyleflowProps = resolvePrefixedFlowpressBlockStyleflowProps(
66
+ attributes,
67
+ "scrim",
68
+ contract,
69
+ {},
70
+ {
71
+ strict: process.env.NODE_ENV === "production" || process.env.STYLEFLOW_STRICT === "1",
72
+ onDiagnostic: (diagnostic) => console.warn(`[${diagnostic.code}] ${diagnostic.message}`)
73
+ }
74
+ );
75
+ const tagName = coverTagName(attributes.tagName);
76
+ ---
77
+
78
+ <S as={tagName} {...rootStyleflowProps} {...rootHtmlProps} style={rootStyle}>
79
+ {backgroundType === "image" && source ? (
80
+ <img
81
+ class="wp-block-cover__image-background flowpress-cover__media"
82
+ src={source}
83
+ width={width}
84
+ height={height}
85
+ alt={alt}
86
+ aria-hidden={alt ? undefined : "true"}
87
+ loading="lazy"
88
+ decoding="async"
89
+ />
90
+ ) : null}
91
+ {backgroundType === "video" && source ? (
92
+ <video
93
+ class="wp-block-cover__video-background flowpress-cover__media"
94
+ src={source}
95
+ poster={poster}
96
+ autoplay
97
+ muted
98
+ loop
99
+ playsinline
100
+ preload="metadata"
101
+ aria-hidden="true"
102
+ tabindex="-1"
103
+ />
104
+ ) : null}
105
+ {scrimEnabled ? (
106
+ <S.span
107
+ class="wp-block-cover__background flowpress-cover__scrim"
108
+ {...scrimStyleflowProps}
109
+ data-flowpress-cover-scrim
110
+ aria-hidden="true"
111
+ />
112
+ ) : null}
113
+ <S.div class="wp-block-cover__inner-container flowpress-cover__content">
114
+ <slot />
115
+ </S.div>
116
+ </S>
117
+
118
+ <style>
119
+ .flowpress-cover {
120
+ position: relative;
121
+ display: grid;
122
+ min-height: var(--flowpress-cover-min-height, 0);
123
+ overflow: hidden;
124
+ isolation: isolate;
125
+ }
126
+
127
+ .flowpress-cover__media,
128
+ .flowpress-cover__scrim {
129
+ position: absolute;
130
+ inset: 0;
131
+ width: 100%;
132
+ height: 100%;
133
+ }
134
+
135
+ .flowpress-cover__media {
136
+ z-index: 0;
137
+ object-fit: cover;
138
+ object-position: var(--flowpress-cover-object-position, 50% 50%);
139
+ }
140
+
141
+ .flowpress-cover__scrim {
142
+ z-index: 1;
143
+ background: var(--sf-background);
144
+ opacity: var(--flowpress-cover-scrim-opacity, 1);
145
+ pointer-events: none;
146
+ }
147
+
148
+ .flowpress-cover__content {
149
+ position: relative;
150
+ z-index: 2;
151
+ display: grid;
152
+ align-items: var(--flowpress-cover-content-block, center);
153
+ justify-items: var(--flowpress-cover-content-inline, center);
154
+ }
155
+ </style>
@@ -0,0 +1,12 @@
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
+ export declare function coverScrimOpacity(attributes: Record<string, unknown>): number;
12
+ //# 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;AAQD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAK7E"}
@@ -0,0 +1,105 @@
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
+ function clampedPercentage(value) {
94
+ const numeric = typeof value === "number" ? value : Number(value);
95
+ if (!Number.isFinite(numeric))
96
+ return undefined;
97
+ return Math.min(100, Math.max(0, numeric));
98
+ }
99
+ export function coverScrimOpacity(attributes) {
100
+ const explicitOpacity = clampedPercentage(attributes.scrimOpacity);
101
+ if (explicitOpacity !== undefined)
102
+ return explicitOpacity;
103
+ return clampedPercentage(attributes.dimRatio) ?? 100;
104
+ }
105
+ //# 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\nfunction clampedPercentage(value: unknown): number | undefined {\n const numeric = typeof value === \"number\" ? value : Number(value);\n if (!Number.isFinite(numeric)) return undefined;\n return Math.min(100, Math.max(0, numeric));\n}\n\nexport function coverScrimOpacity(attributes: Record<string, unknown>): number {\n const explicitOpacity = clampedPercentage(attributes.scrimOpacity);\n if (explicitOpacity !== undefined) return explicitOpacity;\n\n return clampedPercentage(attributes.dimRatio) ?? 100;\n}\n"]}
@@ -0,0 +1,118 @@
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
+ }
106
+
107
+ function clampedPercentage(value: unknown): number | undefined {
108
+ const numeric = typeof value === "number" ? value : Number(value);
109
+ if (!Number.isFinite(numeric)) return undefined;
110
+ return Math.min(100, Math.max(0, numeric));
111
+ }
112
+
113
+ export function coverScrimOpacity(attributes: Record<string, unknown>): number {
114
+ const explicitOpacity = clampedPercentage(attributes.scrimOpacity);
115
+ if (explicitOpacity !== undefined) return explicitOpacity;
116
+
117
+ return clampedPercentage(attributes.dimRatio) ?? 100;
118
+ }
@@ -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.13",
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": [