@styleflow.app/flowpress-astro-core 1.0.0-beta.12 → 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 +8 -0
- package/README.md +6 -4
- package/dist/astro/blocks/CoverBlock.astro +5 -1
- package/dist/astro/blocks/cover.d.ts +1 -0
- package/dist/astro/blocks/cover.d.ts.map +1 -1
- package/dist/astro/blocks/cover.js +12 -0
- package/dist/astro/blocks/cover.js.map +1 -1
- package/dist/astro/blocks/cover.ts +13 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
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
|
+
|
|
5
13
|
## 1.0.0-beta.12
|
|
6
14
|
|
|
7
15
|
- Added the official `core/cover` renderer and editable default adapter with
|
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.
|
|
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
|
|
|
@@ -137,8 +137,10 @@ minimum height, renders nested blocks through a slot and keeps media at
|
|
|
137
137
|
`object-fit: cover`. The root uses the normal Styleflow props; the overlay uses
|
|
138
138
|
the same validated contract through prefixed attributes such as `scrimTone`,
|
|
139
139
|
`scrimIntensity`, `scrimSurface` and `scrimTheme`. `scrimEnabled` controls its
|
|
140
|
-
presence
|
|
141
|
-
|
|
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.
|
|
142
144
|
|
|
143
145
|
Static adapters produce no JavaScript by default. A project opts into client
|
|
144
146
|
runtime only inside adapters classified as interactive; React views rendered
|
|
@@ -244,7 +246,7 @@ The TypeScript template-hierarchy suite is self-contained. Its additional PHP
|
|
|
244
246
|
parity test runs when the sibling `flowpress-wordpress-core` checkout is
|
|
245
247
|
available locally and is skipped in a standalone package checkout.
|
|
246
248
|
|
|
247
|
-
Publish `1.0.0-beta.
|
|
249
|
+
Publish `1.0.0-beta.13` on `next` only after the exact Styleflow prerelease is
|
|
248
250
|
available. Inspect `npm view`, `gitHead`, integrity and the downloaded tarball.
|
|
249
251
|
Promote to `latest` only after the DMO canary and rollback gate.
|
|
250
252
|
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
coverObjectPosition,
|
|
16
16
|
coverPosterSource,
|
|
17
17
|
coverScrimEnabled,
|
|
18
|
+
coverScrimOpacity,
|
|
18
19
|
coverTagName
|
|
19
20
|
} from "./cover.js";
|
|
20
21
|
|
|
@@ -52,11 +53,13 @@ const minimumHeight = coverMinimumHeight(
|
|
|
52
53
|
const [contentBlockPosition, contentInlinePosition] = coverContentPosition(
|
|
53
54
|
attributes.contentPosition
|
|
54
55
|
);
|
|
56
|
+
const scrimOpacity = coverScrimOpacity(attributes);
|
|
55
57
|
const rootStyle = [
|
|
56
58
|
`--flowpress-cover-object-position:${objectPosition}`,
|
|
57
59
|
minimumHeight ? `--flowpress-cover-min-height:${minimumHeight}` : "",
|
|
58
60
|
`--flowpress-cover-content-block:${contentBlockPosition}`,
|
|
59
|
-
`--flowpress-cover-content-inline:${contentInlinePosition}
|
|
61
|
+
`--flowpress-cover-content-inline:${contentInlinePosition}`,
|
|
62
|
+
`--flowpress-cover-scrim-opacity:${scrimOpacity / 100}`
|
|
60
63
|
].filter(Boolean).join(";");
|
|
61
64
|
const scrimEnabled = backgroundType !== "color" && coverScrimEnabled(attributes);
|
|
62
65
|
const scrimStyleflowProps = resolvePrefixedFlowpressBlockStyleflowProps(
|
|
@@ -138,6 +141,7 @@ const tagName = coverTagName(attributes.tagName);
|
|
|
138
141
|
.flowpress-cover__scrim {
|
|
139
142
|
z-index: 1;
|
|
140
143
|
background: var(--sf-background);
|
|
144
|
+
opacity: var(--flowpress-cover-scrim-opacity, 1);
|
|
141
145
|
pointer-events: none;
|
|
142
146
|
}
|
|
143
147
|
|
|
@@ -8,4 +8,5 @@ export declare function coverObjectPosition(value: unknown): string;
|
|
|
8
8
|
export declare function coverMinimumHeight(value: unknown, unitValue: unknown): string | undefined;
|
|
9
9
|
export declare function coverContentPosition(value: unknown): [string, string];
|
|
10
10
|
export declare function coverScrimEnabled(attributes: Record<string, unknown>): boolean;
|
|
11
|
+
export declare function coverScrimOpacity(attributes: Record<string, unknown>): number;
|
|
11
12
|
//# sourceMappingURL=cover.d.ts.map
|
|
@@ -1 +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"}
|
|
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"}
|
|
@@ -90,4 +90,16 @@ export function coverScrimEnabled(attributes) {
|
|
|
90
90
|
const nativeDimRatio = Number(attributes.dimRatio);
|
|
91
91
|
return Number.isFinite(nativeDimRatio) && nativeDimRatio > 0;
|
|
92
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
|
+
}
|
|
93
105
|
//# sourceMappingURL=cover.js.map
|
|
@@ -1 +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"]}
|
|
1
|
+
{"version":3,"file":"cover.js","sourceRoot":"","sources":["../../../src/astro/blocks/cover.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,SAAS;IACT,OAAO;IACP,KAAK;IACL,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,SAAS;CACV,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,IAAI;IACJ,GAAG;IACH,IAAI;IACJ,KAAK;IACL,IAAI;IACJ,KAAK;IACL,KAAK;IACL,KAAK;IACL,IAAI;CACL,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAqC;IAC1D,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;IAC9B,YAAY,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;IACjC,WAAW,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC;IAC7B,aAAa,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;IAClC,eAAe,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;IACrC,cAAc,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC;IACjC,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC;IAC/B,eAAe,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC;IAClC,cAAc,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;CAC/B,CAAC;AAEF,SAAS,IAAI,CAAC,KAAc;IAC1B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5C,OAAO,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAqB;IACpD,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAqB;IACrD,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;WAC/B,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,MAAM,CAAC;WAChC,SAAS,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAqB;IACvD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC;IACtE,IAAI,SAAS,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IAC1C,IAAI,SAAS,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IAC1C,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AACrD,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,MAAM,OAAO,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IAChD,IAAI,OAAO,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC;QAAE,OAAO,OAAO,GAAG,GAAG,CAAC;IACvD,IAAI,OAAO,IAAI,CAAC,IAAI,OAAO,IAAI,GAAG;QAAE,OAAO,OAAO,CAAC;IACnD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,UAAU,GAAG,KAAgC,CAAC;IACpD,MAAM,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACnC,OAAO,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,KAAc,EACd,SAAkB;IAElB,MAAM,OAAO,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC/D,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;IACpD,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,OAAO,GAAG,OAAO,GAAG,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,OAAO,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;WAC9C,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,UAAmC;IACnE,IAAI,OAAO,UAAU,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACjD,OAAO,UAAU,CAAC,YAAY,CAAC;IACjC,CAAC;IACD,MAAM,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACnD,OAAO,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,cAAc,GAAG,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,MAAM,OAAO,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IAChD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,UAAmC;IACnE,MAAM,eAAe,GAAG,iBAAiB,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IACnE,IAAI,eAAe,KAAK,SAAS;QAAE,OAAO,eAAe,CAAC;IAE1D,OAAO,iBAAiB,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC;AACvD,CAAC","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"]}
|
|
@@ -103,3 +103,16 @@ export function coverScrimEnabled(attributes: Record<string, unknown>): boolean
|
|
|
103
103
|
const nativeDimRatio = Number(attributes.dimRatio);
|
|
104
104
|
return Number.isFinite(nativeDimRatio) && nativeDimRatio > 0;
|
|
105
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
|
+
}
|
package/package.json
CHANGED