@styleflow.app/flowpress-astro-core 1.0.0-beta.5 → 1.0.0-beta.7
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 +18 -1
- package/README.md +41 -3
- package/dist/astro/BaseLayout.astro +5 -1
- package/dist/astro/CompositionRenderer.astro +126 -0
- package/dist/astro/DefaultTemplate.astro +6 -1
- package/dist/astro/GutenbergRenderer.astro +62 -51
- package/dist/astro/ThemeRuntime.astro +24 -0
- package/dist/astro/blocks/CarouselBlock.astro +4 -6
- package/dist/astro/blocks/CarouselItemBlock.astro +2 -2
- package/dist/astro/blocks/ColumnBlock.astro +2 -3
- package/dist/astro/blocks/FormBlock.astro +5 -5
- package/dist/astro/blocks/GridBlock.astro +2 -2
- package/dist/astro/blocks/HeroBlock.astro +2 -3
- package/dist/astro/blocks/ImageBlock.astro +2 -3
- package/dist/astro/blocks/ListItemFallback.astro +4 -4
- package/dist/astro/blocks/NumberSpinnerBlock.astro +24 -18
- package/dist/astro/blocks/SemanticElement.astro +35 -0
- package/dist/astro/blocks/SiteLogoBlock.astro +53 -0
- package/dist/astro/blocks/TextBlock.astro +27 -23
- package/dist/astro/blocks/ThemeToggleBlock.astro +23 -0
- package/dist/astro/blocks/helpers.d.ts +7 -0
- package/dist/astro/blocks/helpers.d.ts.map +1 -1
- package/dist/astro/blocks/helpers.js +49 -36
- package/dist/astro/blocks/helpers.js.map +1 -1
- package/dist/astro/blocks/helpers.ts +61 -40
- package/dist/block-renderers.d.ts +18 -2
- package/dist/block-renderers.d.ts.map +1 -1
- package/dist/block-renderers.js.map +1 -1
- package/dist/client.d.ts +2 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +31 -0
- package/dist/client.js.map +1 -1
- package/dist/composition.d.ts +14 -0
- package/dist/composition.d.ts.map +1 -0
- package/dist/composition.js +86 -0
- package/dist/composition.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/styleflow.d.ts +2 -0
- package/dist/styleflow.d.ts.map +1 -1
- package/dist/styleflow.js +35 -1
- package/dist/styleflow.js.map +1 -1
- package/dist/theme-runtime.d.ts +16 -0
- package/dist/theme-runtime.d.ts.map +1 -0
- package/dist/theme-runtime.js +77 -0
- package/dist/theme-runtime.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +73 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +7 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 1.0.0-beta.7
|
|
6
|
+
|
|
7
|
+
- Fixed theme-aware logo selection by placing fallback visibility variables on
|
|
8
|
+
the document root, allowing the nearest global or nested Styleflow theme to
|
|
9
|
+
override them while preserving per-block logo overrides.
|
|
10
|
+
|
|
11
|
+
## 1.0.0-beta.6
|
|
12
|
+
|
|
13
|
+
- Added required `htmlProps`, `styleflowProps`, composition and deterministic
|
|
14
|
+
render context to every certified block adapter.
|
|
15
|
+
- Added single-emission composition stylesheets for validated WordPress block
|
|
16
|
+
CSS, plus theme-aware positive/negative Site Logo rendering.
|
|
17
|
+
- Added the no-hydration multi-theme runtime and `sf/theme-toggle` adapter.
|
|
18
|
+
- Made `<S.*>` the only public Astro authoring syntax in package sources.
|
|
19
|
+
- Added `FlowpressCompositionV1`, typed `resolvedData`,
|
|
20
|
+
`FlowpressClient.getComposition()` and recursive production fail-closed
|
|
21
|
+
rendering with exact compatibility commands in development.
|
|
22
|
+
|
|
5
23
|
## 1.0.0-beta.5
|
|
6
24
|
|
|
7
25
|
- Updated the exact `@styleflow.app/astro` dependency to `1.0.0-beta.4`,
|
|
@@ -44,7 +62,6 @@
|
|
|
44
62
|
- Updated the exact `@styleflow.app/astro` dependency to `1.0.0-beta.1`,
|
|
45
63
|
keeping consumer trees on one runtime while adopting deterministic CLI
|
|
46
64
|
reports. Runtime behavior is unchanged.
|
|
47
|
-
|
|
48
65
|
## 1.0.0-beta.0
|
|
49
66
|
|
|
50
67
|
- Adopted the grouped Styleflow vNext project contract and the exact Astro v1
|
package/README.md
CHANGED
|
@@ -9,8 +9,8 @@ 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.
|
|
13
|
-
@styleflow.app/astro@1.0.0-beta.
|
|
12
|
+
pnpm add @styleflow.app/flowpress-astro-core@1.0.0-beta.6 \
|
|
13
|
+
@styleflow.app/astro@1.0.0-beta.5
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
Prereleases are pinned exactly. The package expects Astro 7 or newer and the
|
|
@@ -79,6 +79,44 @@ grid and dead controls are hidden. If a legacy carousel contains any direct
|
|
|
79
79
|
child other than `sf/carousel-item`, no interactive instance is initialized:
|
|
80
80
|
the complete content renders statically, with a development diagnostic.
|
|
81
81
|
|
|
82
|
+
## Site Editor composition
|
|
83
|
+
|
|
84
|
+
`FlowpressClient.getComposition(uri, locale)` reads the public
|
|
85
|
+
`FlowpressCompositionV1` contract. `CompositionRenderer.astro` walks its block
|
|
86
|
+
tree through an explicit `FlowpressBlockAdapters` registry, passes authored
|
|
87
|
+
attributes and `resolvedData` separately, and never renders `innerHtml` as a
|
|
88
|
+
fallback. Blocking WordPress diagnostics always fail the render. Missing or
|
|
89
|
+
draft adapters, absent block-type descriptors and schema-fingerprint drift
|
|
90
|
+
are visible diagnostics in development and fail closed in production with
|
|
91
|
+
the exact scaffold, refresh or approval command. The fingerprint comparison
|
|
92
|
+
is repeated by Astro and does not rely only on the CMS gate.
|
|
93
|
+
Before invoking an adapter, the renderer resolves the universal Styleflow
|
|
94
|
+
attributes through the same framework-neutral validator used by the built-in
|
|
95
|
+
renderer and passes them as `styleflowProps`. Project adapters can therefore
|
|
96
|
+
apply the authored semantic context to their real root without accepting raw
|
|
97
|
+
WordPress visual values.
|
|
98
|
+
|
|
99
|
+
Every adapter also receives required normalized `htmlProps` (`anchor` → `id`
|
|
100
|
+
and the additional classes), the full composition and a deterministic render
|
|
101
|
+
context. WordPress-processed block custom CSS is emitted once at the root.
|
|
102
|
+
`ThemeRuntime.astro` applies the persisted contract theme before paint and
|
|
103
|
+
progressively enhances `sf/theme-toggle` without hydrating React. The shared
|
|
104
|
+
Site Logo adapter renders positive and negative variants while inherited CSS
|
|
105
|
+
variables make the nearest nested theme authoritative.
|
|
106
|
+
|
|
107
|
+
```astro
|
|
108
|
+
---
|
|
109
|
+
import CompositionRenderer from "@styleflow.app/flowpress-astro-core/CompositionRenderer.astro";
|
|
110
|
+
import { blockAdapters } from "./generated/block-adapter-registry";
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
<CompositionRenderer composition={composition} adapters={blockAdapters} />
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Static adapters produce no JavaScript by default. A project opts into client
|
|
117
|
+
runtime only inside adapters classified as interactive; React views rendered
|
|
118
|
+
without `client:*` remain server-only HTML.
|
|
119
|
+
|
|
82
120
|
Heading, rich-text, quote and matching core blocks accept Gutenberg alignment
|
|
83
121
|
from either `style.typography.textAlign` or the FlowPress `textAlign` field.
|
|
84
122
|
Only `left`, `center`, `right`, `justify`, `start` and `end` reach CSS.
|
|
@@ -167,7 +205,7 @@ The TypeScript template-hierarchy suite is self-contained. Its additional PHP
|
|
|
167
205
|
parity test runs when the sibling `flowpress-wordpress-core` checkout is
|
|
168
206
|
available locally and is skipped in a standalone package checkout.
|
|
169
207
|
|
|
170
|
-
Publish
|
|
208
|
+
Publish `1.0.0-beta.6` on `next` only after Components and WordPress Core are
|
|
171
209
|
available. Inspect `npm view`, `gitHead`, integrity and the downloaded tarball.
|
|
172
210
|
Promote to `latest` only after the DMO canary and rollback gate.
|
|
173
211
|
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { SfSeo } from "../types.js";
|
|
3
3
|
import S from "@styleflow.app/astro/S.astro";
|
|
4
|
+
import ThemeRuntime from "./ThemeRuntime.astro";
|
|
4
5
|
|
|
5
6
|
interface Props {
|
|
6
7
|
lang?: string;
|
|
7
8
|
seo?: SfSeo | null;
|
|
8
9
|
siteName?: string;
|
|
9
10
|
theme?: string;
|
|
11
|
+
themes?: string[];
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
const {
|
|
13
15
|
lang = "it",
|
|
14
16
|
seo = null,
|
|
15
17
|
siteName = import.meta.env.PROJECT_NAME ?? "FlowPress",
|
|
16
|
-
theme
|
|
18
|
+
theme,
|
|
19
|
+
themes = theme ? [theme] : []
|
|
17
20
|
} = Astro.props;
|
|
18
21
|
const title = seo?.title || siteName;
|
|
19
22
|
const description = seo?.description || "";
|
|
@@ -26,6 +29,7 @@ const jsonLd = seo?.jsonLd ? JSON.stringify(seo.jsonLd) : null;
|
|
|
26
29
|
<head>
|
|
27
30
|
<meta charset="UTF-8" />
|
|
28
31
|
<meta name="viewport" content="width=device-width" />
|
|
32
|
+
{theme && themes.length ? <ThemeRuntime themes={themes} defaultTheme={theme} /> : null}
|
|
29
33
|
<title>{title}</title>
|
|
30
34
|
{description && <meta name="description" content={description} />}
|
|
31
35
|
{robots && <meta name="robots" content={robots} />}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { FlowpressBlockAdapters } from "../block-renderers.js";
|
|
3
|
+
import {
|
|
4
|
+
flowpressAdapterCompatibilityIssue,
|
|
5
|
+
flowpressBlockHtmlProps,
|
|
6
|
+
flowpressCompositionLogoStyles,
|
|
7
|
+
flowpressBlockTypeDescriptors
|
|
8
|
+
} from "../composition.js";
|
|
9
|
+
import {
|
|
10
|
+
resolveFlowpressBlockStyleflowProps,
|
|
11
|
+
type StyleflowContract
|
|
12
|
+
} from "../styleflow.js";
|
|
13
|
+
import type { FlowpressBlock, FlowpressCompositionV1 } from "../types.js";
|
|
14
|
+
|
|
15
|
+
interface Props {
|
|
16
|
+
composition: FlowpressCompositionV1;
|
|
17
|
+
adapters: FlowpressBlockAdapters;
|
|
18
|
+
blocks?: FlowpressBlock[];
|
|
19
|
+
contract?: StyleflowContract;
|
|
20
|
+
parentBlockName?: string;
|
|
21
|
+
production?: boolean;
|
|
22
|
+
depth?: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const {
|
|
26
|
+
composition,
|
|
27
|
+
adapters,
|
|
28
|
+
blocks = composition.blocks,
|
|
29
|
+
contract,
|
|
30
|
+
parentBlockName,
|
|
31
|
+
production = import.meta.env.PROD,
|
|
32
|
+
depth = 0
|
|
33
|
+
} = Astro.props;
|
|
34
|
+
|
|
35
|
+
const blocking = composition.diagnostics.filter((diagnostic) => diagnostic.blocking);
|
|
36
|
+
if (blocking.length > 0 && production) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`FlowPress composition ${composition.sourceDigest} is not renderable:\n`
|
|
39
|
+
+ blocking.map(({ code, message }) => `- ${code}: ${message}`).join("\n")
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
const descriptors = flowpressBlockTypeDescriptors(composition);
|
|
43
|
+
const logoStyles = parentBlockName === undefined
|
|
44
|
+
? flowpressCompositionLogoStyles(composition)
|
|
45
|
+
: "";
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
{parentBlockName === undefined && composition.stylesheets.map((stylesheet) => (
|
|
49
|
+
<style data-flowpress-composition-style={stylesheet.id} set:html={stylesheet.css} />
|
|
50
|
+
))}
|
|
51
|
+
{logoStyles ? <style data-flowpress-logo-styles set:html={logoStyles} /> : null}
|
|
52
|
+
|
|
53
|
+
{blocking.length > 0 && !production && parentBlockName === undefined ? (
|
|
54
|
+
<aside data-flowpress-composition-diagnostics role="status">
|
|
55
|
+
<strong>FlowPress composition diagnostics</strong>
|
|
56
|
+
<ul>
|
|
57
|
+
{blocking.map(({ code, message, command }) => (
|
|
58
|
+
<li data-diagnostic-code={code}>
|
|
59
|
+
{message}
|
|
60
|
+
{command ? <code>{command}</code> : null}
|
|
61
|
+
</li>
|
|
62
|
+
))}
|
|
63
|
+
</ul>
|
|
64
|
+
</aside>
|
|
65
|
+
) : null}
|
|
66
|
+
|
|
67
|
+
{blocks.map((block) => {
|
|
68
|
+
const adapter = adapters[block.name];
|
|
69
|
+
const issue = flowpressAdapterCompatibilityIssue(block.name, descriptors, adapters);
|
|
70
|
+
if (issue && production) throw new Error(issue.message);
|
|
71
|
+
if (!adapter) {
|
|
72
|
+
return (
|
|
73
|
+
<aside data-flowpress-compatibility={issue?.code ?? "missing-adapter"} data-block-name={block.name} role="status">
|
|
74
|
+
<strong>Missing block adapter: {block.name}</strong>
|
|
75
|
+
<code>{issue?.command}</code>
|
|
76
|
+
</aside>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
const Adapter = adapter.renderer;
|
|
80
|
+
const children = block.innerBlocks ?? [];
|
|
81
|
+
const styleflowProps = resolveFlowpressBlockStyleflowProps(
|
|
82
|
+
block.attributes,
|
|
83
|
+
contract,
|
|
84
|
+
{},
|
|
85
|
+
{
|
|
86
|
+
strict: production,
|
|
87
|
+
onDiagnostic: (diagnostic) => console.warn(
|
|
88
|
+
`[${diagnostic.code}] ${diagnostic.message}`
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
const htmlProps = flowpressBlockHtmlProps(block.attributes);
|
|
93
|
+
return (
|
|
94
|
+
<>
|
|
95
|
+
{issue && (
|
|
96
|
+
<aside data-flowpress-compatibility={issue.code} data-block-name={block.name} role="status">
|
|
97
|
+
<strong>{issue.message}</strong>
|
|
98
|
+
<code>{issue.command}</code>
|
|
99
|
+
</aside>
|
|
100
|
+
)}
|
|
101
|
+
<Adapter
|
|
102
|
+
block={block}
|
|
103
|
+
parentBlockName={parentBlockName}
|
|
104
|
+
contract={contract}
|
|
105
|
+
composition={composition}
|
|
106
|
+
styleflowProps={styleflowProps}
|
|
107
|
+
htmlProps={htmlProps}
|
|
108
|
+
context={{
|
|
109
|
+
...(parentBlockName ? { parentBlockName } : {}),
|
|
110
|
+
depth,
|
|
111
|
+
production
|
|
112
|
+
}}
|
|
113
|
+
>
|
|
114
|
+
<Astro.self
|
|
115
|
+
composition={composition}
|
|
116
|
+
adapters={adapters}
|
|
117
|
+
blocks={children}
|
|
118
|
+
contract={contract}
|
|
119
|
+
parentBlockName={block.name}
|
|
120
|
+
production={production}
|
|
121
|
+
depth={depth + 1}
|
|
122
|
+
/>
|
|
123
|
+
</Adapter>
|
|
124
|
+
</>
|
|
125
|
+
);
|
|
126
|
+
})}
|
|
@@ -11,7 +11,12 @@ const hasGutembergBlocks = Array.isArray(content?.contentBlocks) && content.cont
|
|
|
11
11
|
//TODO SET GLOBAL LOCAL ON ENV
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
<BaseLayout
|
|
14
|
+
<BaseLayout
|
|
15
|
+
lang={route.locale || "it"}
|
|
16
|
+
seo={route.seo}
|
|
17
|
+
theme={styleflowContract?.defaultTheme}
|
|
18
|
+
themes={styleflowContract?.semantic.themes}
|
|
19
|
+
>
|
|
15
20
|
|
|
16
21
|
{hasGutembergBlocks ? (
|
|
17
22
|
<GutenbergRenderer
|
|
@@ -5,7 +5,8 @@ import type {
|
|
|
5
5
|
FlowpressIconRenderer
|
|
6
6
|
} from "../block-renderers.js";
|
|
7
7
|
import type { StyleflowContract } from "../styleflow.js";
|
|
8
|
-
import type { FlowpressBlock } from "../types.js";
|
|
8
|
+
import type { FlowpressBlock, FlowpressBlockHtmlProps } from "../types.js";
|
|
9
|
+
import type { DynamicStyleflowProps } from "../styleflow.js";
|
|
9
10
|
import ColumnBlock from "./blocks/ColumnBlock.astro";
|
|
10
11
|
import CarouselBlock from "./blocks/CarouselBlock.astro";
|
|
11
12
|
import CarouselItemBlock from "./blocks/CarouselItemBlock.astro";
|
|
@@ -29,9 +30,18 @@ interface Props {
|
|
|
29
30
|
contract?: StyleflowContract;
|
|
30
31
|
blockRenderers?: FlowpressBlockRenderers;
|
|
31
32
|
iconRenderer?: FlowpressIconRenderer;
|
|
33
|
+
rootHtmlProps?: FlowpressBlockHtmlProps;
|
|
34
|
+
rootStyleflowProps?: DynamicStyleflowProps;
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
const {
|
|
37
|
+
const {
|
|
38
|
+
blocks,
|
|
39
|
+
contract,
|
|
40
|
+
blockRenderers = {},
|
|
41
|
+
iconRenderer: IconRenderer,
|
|
42
|
+
rootHtmlProps,
|
|
43
|
+
rootStyleflowProps
|
|
44
|
+
} = Astro.props;
|
|
35
45
|
|
|
36
46
|
function youtubeEmbedUrl(value: unknown): string | null {
|
|
37
47
|
try {
|
|
@@ -51,11 +61,15 @@ function youtubeEmbedUrl(value: unknown): string | null {
|
|
|
51
61
|
}
|
|
52
62
|
---
|
|
53
63
|
|
|
54
|
-
{blocks.map((block) => {
|
|
64
|
+
{blocks.map((block, index) => {
|
|
55
65
|
const name = block.name.replace(/^sf\//, "");
|
|
56
66
|
const children = block.innerBlocks ?? [];
|
|
57
|
-
const
|
|
58
|
-
|
|
67
|
+
const semantic = index === 0 && blocks.length === 1 && rootStyleflowProps
|
|
68
|
+
? rootStyleflowProps
|
|
69
|
+
: semanticProps(block.attributes, contract);
|
|
70
|
+
const htmlAttributes = index === 0 && blocks.length === 1 && rootHtmlProps
|
|
71
|
+
? rootHtmlProps
|
|
72
|
+
: blockHtmlAttributes(block.attributes);
|
|
59
73
|
const CustomBlockRenderer = blockRenderers[block.name];
|
|
60
74
|
|
|
61
75
|
if (CustomBlockRenderer) {
|
|
@@ -193,8 +207,7 @@ function youtubeEmbedUrl(value: unknown): string | null {
|
|
|
193
207
|
</>
|
|
194
208
|
);
|
|
195
209
|
return href ? (
|
|
196
|
-
<S
|
|
197
|
-
as="a"
|
|
210
|
+
<S.a
|
|
198
211
|
href={href}
|
|
199
212
|
target={opensInNewTab ? "_blank" : undefined}
|
|
200
213
|
rel={opensInNewTab ? "noopener noreferrer" : undefined}
|
|
@@ -202,17 +215,16 @@ function youtubeEmbedUrl(value: unknown): string | null {
|
|
|
202
215
|
{...htmlAttributes}
|
|
203
216
|
>
|
|
204
217
|
{buttonContent}
|
|
205
|
-
</S>
|
|
218
|
+
</S.a>
|
|
206
219
|
) : (
|
|
207
|
-
<S
|
|
208
|
-
as="span"
|
|
220
|
+
<S.span
|
|
209
221
|
aria-disabled="true"
|
|
210
222
|
data-flowpress-link-unresolved
|
|
211
223
|
{...buttonSemantic}
|
|
212
224
|
{...htmlAttributes}
|
|
213
225
|
>
|
|
214
226
|
{buttonContent}
|
|
215
|
-
</S>
|
|
227
|
+
</S.span>
|
|
216
228
|
);
|
|
217
229
|
}
|
|
218
230
|
|
|
@@ -259,7 +271,7 @@ function youtubeEmbedUrl(value: unknown): string | null {
|
|
|
259
271
|
? block.attributes.images as Array<Record<string, unknown>>
|
|
260
272
|
: [];
|
|
261
273
|
return (
|
|
262
|
-
<S
|
|
274
|
+
<S.div {...semantic} {...htmlAttributes}>
|
|
263
275
|
{images.map((image) => image.url ? (
|
|
264
276
|
<img
|
|
265
277
|
src={String(image.url)}
|
|
@@ -268,7 +280,7 @@ function youtubeEmbedUrl(value: unknown): string | null {
|
|
|
268
280
|
decoding="async"
|
|
269
281
|
/>
|
|
270
282
|
) : null)}
|
|
271
|
-
</S>
|
|
283
|
+
</S.div>
|
|
272
284
|
);
|
|
273
285
|
}
|
|
274
286
|
|
|
@@ -276,7 +288,7 @@ function youtubeEmbedUrl(value: unknown): string | null {
|
|
|
276
288
|
const video = objectValue(block, "video");
|
|
277
289
|
const poster = objectValue(block, "poster");
|
|
278
290
|
return video.url ? (
|
|
279
|
-
<S
|
|
291
|
+
<S.div {...semantic} {...htmlAttributes}>
|
|
280
292
|
<video
|
|
281
293
|
src={String(video.url)}
|
|
282
294
|
poster={poster.url ? String(poster.url) : undefined}
|
|
@@ -285,14 +297,14 @@ function youtubeEmbedUrl(value: unknown): string | null {
|
|
|
285
297
|
muted={Boolean(block.attributes.autoplay)}
|
|
286
298
|
playsinline
|
|
287
299
|
/>
|
|
288
|
-
</S>
|
|
300
|
+
</S.div>
|
|
289
301
|
) : null;
|
|
290
302
|
}
|
|
291
303
|
|
|
292
304
|
if (name === "video-youtube") {
|
|
293
305
|
const embed = youtubeEmbedUrl(block.attributes.url);
|
|
294
306
|
return embed ? (
|
|
295
|
-
<S
|
|
307
|
+
<S.div {...semantic} {...htmlAttributes}>
|
|
296
308
|
<iframe
|
|
297
309
|
src={embed}
|
|
298
310
|
title={String(block.attributes.title ?? "YouTube video")}
|
|
@@ -300,15 +312,15 @@ function youtubeEmbedUrl(value: unknown): string | null {
|
|
|
300
312
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
301
313
|
allowfullscreen
|
|
302
314
|
/>
|
|
303
|
-
</S>
|
|
315
|
+
</S.div>
|
|
304
316
|
) : null;
|
|
305
317
|
}
|
|
306
318
|
|
|
307
319
|
if (name === "chip") {
|
|
308
320
|
return (
|
|
309
|
-
<S
|
|
321
|
+
<S.span {...semantic} {...htmlAttributes}>
|
|
310
322
|
{textValue(block, "label")}
|
|
311
|
-
</S>
|
|
323
|
+
</S.span>
|
|
312
324
|
);
|
|
313
325
|
}
|
|
314
326
|
|
|
@@ -316,14 +328,14 @@ function youtubeEmbedUrl(value: unknown): string | null {
|
|
|
316
328
|
const media = objectValue(block, "image");
|
|
317
329
|
const href = linkValue(block);
|
|
318
330
|
return (
|
|
319
|
-
<S
|
|
331
|
+
<S.article {...semantic} {...htmlAttributes}>
|
|
320
332
|
{media.url && (
|
|
321
333
|
<img src={String(media.url)} alt={String(media.alt ?? "")} loading="lazy" />
|
|
322
334
|
)}
|
|
323
|
-
{block.attributes.title && <S
|
|
324
|
-
{block.attributes.text && <S
|
|
325
|
-
{href && <S
|
|
326
|
-
</S>
|
|
335
|
+
{block.attributes.title && <S.h3>{String(block.attributes.title)}</S.h3>}
|
|
336
|
+
{block.attributes.text && <S.p>{String(block.attributes.text)}</S.p>}
|
|
337
|
+
{href && <S.a href={href}>Scopri</S.a>}
|
|
338
|
+
</S.article>
|
|
327
339
|
);
|
|
328
340
|
}
|
|
329
341
|
|
|
@@ -335,9 +347,9 @@ function youtubeEmbedUrl(value: unknown): string | null {
|
|
|
335
347
|
? block.attributes.resolvedBlocks as FlowpressBlock[][]
|
|
336
348
|
: [];
|
|
337
349
|
return (
|
|
338
|
-
<S
|
|
350
|
+
<S.ul {...semantic} {...htmlAttributes}>
|
|
339
351
|
{items.map((item, index) => (
|
|
340
|
-
<S
|
|
352
|
+
<S.li>
|
|
341
353
|
{resolvedBlocks[index]?.length ? (
|
|
342
354
|
<Astro.self
|
|
343
355
|
blocks={resolvedBlocks[index]}
|
|
@@ -348,9 +360,9 @@ function youtubeEmbedUrl(value: unknown): string | null {
|
|
|
348
360
|
) : (
|
|
349
361
|
<ListItemFallback item={item} />
|
|
350
362
|
)}
|
|
351
|
-
</S>
|
|
363
|
+
</S.li>
|
|
352
364
|
))}
|
|
353
|
-
</S>
|
|
365
|
+
</S.ul>
|
|
354
366
|
);
|
|
355
367
|
}
|
|
356
368
|
|
|
@@ -380,7 +392,7 @@ function youtubeEmbedUrl(value: unknown): string | null {
|
|
|
380
392
|
|
|
381
393
|
if (name === "accordion-item") {
|
|
382
394
|
return (
|
|
383
|
-
<S
|
|
395
|
+
<S.div {...semantic} {...htmlAttributes}>
|
|
384
396
|
<details>
|
|
385
397
|
<summary>{String(block.attributes.title ?? "")}</summary>
|
|
386
398
|
<Astro.self
|
|
@@ -390,7 +402,7 @@ function youtubeEmbedUrl(value: unknown): string | null {
|
|
|
390
402
|
iconRenderer={IconRenderer}
|
|
391
403
|
/>
|
|
392
404
|
</details>
|
|
393
|
-
</S>
|
|
405
|
+
</S.div>
|
|
394
406
|
);
|
|
395
407
|
}
|
|
396
408
|
|
|
@@ -411,42 +423,41 @@ function youtubeEmbedUrl(value: unknown): string | null {
|
|
|
411
423
|
+ `?key=${encodeURIComponent(googleMapsApiKey)}`
|
|
412
424
|
+ `&q=${encodeURIComponent(query)}`;
|
|
413
425
|
return (
|
|
414
|
-
<S
|
|
426
|
+
<S.div {...semantic} {...htmlAttributes}>
|
|
415
427
|
<iframe
|
|
416
428
|
src={source}
|
|
417
429
|
title={address || "Map"}
|
|
418
430
|
loading="lazy"
|
|
419
431
|
referrerpolicy="no-referrer-when-downgrade"
|
|
420
432
|
/>
|
|
421
|
-
</S>
|
|
433
|
+
</S.div>
|
|
422
434
|
);
|
|
423
435
|
}
|
|
424
436
|
return query ? (
|
|
425
|
-
<S
|
|
426
|
-
<S
|
|
427
|
-
as="a"
|
|
437
|
+
<S.div {...semantic} {...htmlAttributes}>
|
|
438
|
+
<S.a
|
|
428
439
|
href={`https://www.openstreetmap.org/search?query=${encodeURIComponent(query)}`}
|
|
429
440
|
rel="noreferrer"
|
|
430
441
|
>
|
|
431
442
|
{address || query}
|
|
432
|
-
</S>
|
|
433
|
-
</S>
|
|
443
|
+
</S.a>
|
|
444
|
+
</S.div>
|
|
434
445
|
) : null;
|
|
435
446
|
}
|
|
436
447
|
|
|
437
|
-
const
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
</S>
|
|
448
|
+
const fallbackContent = block.innerHtml && children.length === 0
|
|
449
|
+
? <S.div set:html={block.innerHtml} />
|
|
450
|
+
: (
|
|
451
|
+
<Astro.self
|
|
452
|
+
blocks={children}
|
|
453
|
+
contract={contract}
|
|
454
|
+
blockRenderers={blockRenderers}
|
|
455
|
+
iconRenderer={IconRenderer}
|
|
456
|
+
/>
|
|
457
|
+
);
|
|
458
|
+
return name === "section" ? (
|
|
459
|
+
<S.section {...semantic} {...htmlAttributes}>{fallbackContent}</S.section>
|
|
460
|
+
) : (
|
|
461
|
+
<S.div {...semantic} {...htmlAttributes}>{fallbackContent}</S.div>
|
|
451
462
|
);
|
|
452
463
|
})}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { styleflowThemeBootstrapScript } from "../theme-runtime.js";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
themes: string[];
|
|
6
|
+
defaultTheme: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const { themes, defaultTheme } = Astro.props;
|
|
10
|
+
const bootstrap = styleflowThemeBootstrapScript(themes, defaultTheme);
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
<script is:inline set:html={bootstrap}></script>
|
|
14
|
+
<script>
|
|
15
|
+
import { initializeStyleflowThemeRuntime } from "../theme-runtime.js";
|
|
16
|
+
|
|
17
|
+
const initialize = () => initializeStyleflowThemeRuntime();
|
|
18
|
+
if (document.readyState === "loading") {
|
|
19
|
+
document.addEventListener("DOMContentLoaded", initialize, { once: true });
|
|
20
|
+
} else {
|
|
21
|
+
initialize();
|
|
22
|
+
}
|
|
23
|
+
document.addEventListener("astro:page-load", initialize);
|
|
24
|
+
</script>
|
|
@@ -44,8 +44,7 @@ if (!validChildren && import.meta.env.DEV) {
|
|
|
44
44
|
|
|
45
45
|
{validChildren ? (
|
|
46
46
|
<flowpress-carousel>
|
|
47
|
-
<S
|
|
48
|
-
as="section"
|
|
47
|
+
<S.section
|
|
49
48
|
{...semantic}
|
|
50
49
|
{...htmlAttributes}
|
|
51
50
|
aria-label={settings.ariaLabel}
|
|
@@ -79,11 +78,10 @@ if (!validChildren && import.meta.env.DEV) {
|
|
|
79
78
|
<span class="splide__toggle__pause">Pausa</span>
|
|
80
79
|
</button>
|
|
81
80
|
) : null}
|
|
82
|
-
</S>
|
|
81
|
+
</S.section>
|
|
83
82
|
</flowpress-carousel>
|
|
84
83
|
) : (
|
|
85
|
-
<S
|
|
86
|
-
as="section"
|
|
84
|
+
<S.section
|
|
87
85
|
{...semantic}
|
|
88
86
|
{...htmlAttributes}
|
|
89
87
|
aria-label={settings.ariaLabel}
|
|
@@ -92,7 +90,7 @@ if (!validChildren && import.meta.env.DEV) {
|
|
|
92
90
|
style={style}
|
|
93
91
|
>
|
|
94
92
|
<slot />
|
|
95
|
-
</S>
|
|
93
|
+
</S.section>
|
|
96
94
|
)}
|
|
97
95
|
|
|
98
96
|
<script>
|
|
@@ -33,8 +33,7 @@ const style = [
|
|
|
33
33
|
].join(";");
|
|
34
34
|
---
|
|
35
35
|
|
|
36
|
-
<S
|
|
37
|
-
as="div"
|
|
36
|
+
<S.div
|
|
38
37
|
{...semantic}
|
|
39
38
|
{...htmlAttributes}
|
|
40
39
|
data-partial={partial}
|
|
@@ -42,7 +41,7 @@ const style = [
|
|
|
42
41
|
style={style}
|
|
43
42
|
>
|
|
44
43
|
<slot />
|
|
45
|
-
</S>
|
|
44
|
+
</S.div>
|
|
46
45
|
|
|
47
46
|
<style>
|
|
48
47
|
.flowpress-column {
|
|
@@ -39,11 +39,11 @@ const optionLabel = (field: FormField, index: number): string =>
|
|
|
39
39
|
---
|
|
40
40
|
|
|
41
41
|
{schema?.available ? (
|
|
42
|
-
<S
|
|
42
|
+
<S.div {...semantic} {...htmlAttributes}>
|
|
43
43
|
<flowpress-cf7-form>
|
|
44
44
|
<form action={schema.submitUrl} method="post" enctype="multipart/form-data" novalidate>
|
|
45
45
|
{block.attributes.title || schema.title ? (
|
|
46
|
-
<S
|
|
46
|
+
<S.h2>{String(block.attributes.title || schema.title)}</S.h2>
|
|
47
47
|
) : null}
|
|
48
48
|
{schema.fields.map((field) => {
|
|
49
49
|
if (field.type === "submit") {
|
|
@@ -130,11 +130,11 @@ const optionLabel = (field: FormField, index: number): string =>
|
|
|
130
130
|
<p data-form-status role="status" aria-live="polite"></p>
|
|
131
131
|
</form>
|
|
132
132
|
</flowpress-cf7-form>
|
|
133
|
-
</S>
|
|
133
|
+
</S.div>
|
|
134
134
|
) : (
|
|
135
|
-
<S
|
|
135
|
+
<S.p {...semantic} {...htmlAttributes} role="status">
|
|
136
136
|
Il modulo non è temporaneamente disponibile.
|
|
137
|
-
</S>
|
|
137
|
+
</S.p>
|
|
138
138
|
)}
|
|
139
139
|
|
|
140
140
|
<script>
|
|
@@ -38,9 +38,9 @@ const style = [
|
|
|
38
38
|
].join(";");
|
|
39
39
|
---
|
|
40
40
|
|
|
41
|
-
<S
|
|
41
|
+
<S.div {...semantic} {...htmlAttributes} data-align={align} style={style}>
|
|
42
42
|
<slot />
|
|
43
|
-
</S>
|
|
43
|
+
</S.div>
|
|
44
44
|
|
|
45
45
|
<style>
|
|
46
46
|
.flowpress-grid {
|