@standhigher/puck-page-builder 0.1.0 → 0.7.2
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/dist/chunk-KYXIXIWK.js +25 -0
- package/dist/{chunk-G2LNCKYO.js → chunk-OBN4DMOR.js} +25 -12
- package/dist/{chunk-RGB53WE6.js → chunk-PUTYZI7B.js} +37 -4
- package/dist/chunk-YK2AUHF6.js +38 -0
- package/dist/extensions.d.ts +25 -2
- package/dist/extensions.js +7 -3
- package/dist/index.d.ts +3 -2
- package/dist/index.js +25 -9
- package/dist/renderer.d.ts +1 -0
- package/dist/renderer.js +2 -1
- package/dist/runtime.d.ts +5 -0
- package/dist/runtime.js +36 -0
- package/dist/schema.d.ts +17 -8
- package/dist/schema.js +2 -1
- package/dist/theme.d.ts +14 -0
- package/dist/theme.js +12 -0
- package/package.json +10 -2
- package/dist/chunk-72MFV6J7.js +0 -15
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mergeThemeTokens,
|
|
3
|
+
toThemeStyle
|
|
4
|
+
} from "./chunk-YK2AUHF6.js";
|
|
5
|
+
|
|
6
|
+
// src/renderer/web/WebRenderer.tsx
|
|
7
|
+
import { jsx } from "react/jsx-runtime";
|
|
8
|
+
function WebRenderer({ document, className, registry }) {
|
|
9
|
+
const template = document.templateId ? registry?.getTemplate(document.templateId) : void 0;
|
|
10
|
+
const pageTheme = mergeThemeTokens(template?.theme, document.theme);
|
|
11
|
+
return /* @__PURE__ */ jsx("main", { className: className ?? "pb-web-renderer", "data-page-id": document.pageId, lang: document.settings.locale, style: toThemeStyle(pageTheme), children: document.blocks.map((block) => {
|
|
12
|
+
const definition = registry?.getBlock(block.type);
|
|
13
|
+
const variant = definition?.variants?.find((item) => item.id === block.variant);
|
|
14
|
+
const style = toThemeStyle(mergeThemeTokens(template?.theme, document.theme, variant?.theme, block.style));
|
|
15
|
+
if (block.type === "core.text") return /* @__PURE__ */ jsx("section", { "data-block-id": block.id, "data-block-variant": block.variant, style, className: "pb-web-renderer__text", children: /* @__PURE__ */ jsx("p", { children: typeof block.props.content === "string" ? block.props.content : "" }) }, block.id);
|
|
16
|
+
if (block.type === "core.image") return /* @__PURE__ */ jsx("figure", { "data-block-id": block.id, "data-block-variant": block.variant, style, className: "pb-web-renderer__image", children: /* @__PURE__ */ jsx("img", { src: typeof block.props.src === "string" ? block.props.src : "", alt: typeof block.props.alt === "string" ? block.props.alt : "" }) }, block.id);
|
|
17
|
+
const BlockRenderer = definition?.render.web;
|
|
18
|
+
if (BlockRenderer) return /* @__PURE__ */ jsx("section", { "data-block-id": block.id, "data-block-variant": block.variant, style, children: /* @__PURE__ */ jsx(BlockRenderer, { ...block.props }) }, block.id);
|
|
19
|
+
return null;
|
|
20
|
+
}) });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export {
|
|
24
|
+
WebRenderer
|
|
25
|
+
};
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizeThemeTokens
|
|
3
|
+
} from "./chunk-YK2AUHF6.js";
|
|
4
|
+
|
|
1
5
|
// src/core/schema/page-document.ts
|
|
2
|
-
var pageDocumentKeys = /* @__PURE__ */ new Set(["schemaVersion", "pageId", "target", "templateId", "root", "blocks", "settings"]);
|
|
3
|
-
var blockKeys = /* @__PURE__ */ new Set(["id", "type", "version", "props", "slots", "binding"]);
|
|
6
|
+
var pageDocumentKeys = /* @__PURE__ */ new Set(["schemaVersion", "pageId", "target", "templateId", "templateVersion", "theme", "root", "blocks", "settings"]);
|
|
7
|
+
var blockKeys = /* @__PURE__ */ new Set(["id", "type", "version", "props", "variant", "style", "slots", "binding"]);
|
|
4
8
|
function isRecord(value) {
|
|
5
9
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6
10
|
}
|
|
@@ -9,6 +13,10 @@ function isJsonValue(value) {
|
|
|
9
13
|
if (Array.isArray(value)) return value.every(isJsonValue);
|
|
10
14
|
return isRecord(value) && Object.values(value).every(isJsonValue);
|
|
11
15
|
}
|
|
16
|
+
function themeTokensOrEmpty(value) {
|
|
17
|
+
const result = normalizeThemeTokens(value);
|
|
18
|
+
return result.success ? result.data : {};
|
|
19
|
+
}
|
|
12
20
|
function normalizeBlock(value, path, issues) {
|
|
13
21
|
if (!isRecord(value)) {
|
|
14
22
|
issues.push({ path, message: "\u5FC5\u987B\u662F\u5BF9\u8C61" });
|
|
@@ -19,6 +27,8 @@ function normalizeBlock(value, path, issues) {
|
|
|
19
27
|
if (typeof value.type !== "string" || !value.type) issues.push({ path: `${path}.type`, message: "\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32" });
|
|
20
28
|
if (typeof value.version !== "number" || !Number.isInteger(value.version) || value.version < 1) issues.push({ path: `${path}.version`, message: "\u5FC5\u987B\u662F\u5927\u4E8E 0 \u7684\u6574\u6570" });
|
|
21
29
|
if (!isRecord(value.props) || !Object.values(value.props).every(isJsonValue)) issues.push({ path: `${path}.props`, message: "\u5FC5\u987B\u662F JSON \u5BF9\u8C61" });
|
|
30
|
+
if (typeof value.variant !== "string" || !value.variant) issues.push({ path: `${path}.variant`, message: "\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32" });
|
|
31
|
+
if (!normalizeThemeTokens(value.style).success) issues.push({ path: `${path}.style`, message: "\u5FC5\u987B\u662F\u53D7\u63A7 Theme Token \u5BF9\u8C61" });
|
|
22
32
|
if (value.binding !== void 0 && (!isRecord(value.binding) || typeof value.binding.source !== "string" || value.binding.params !== void 0 && (!isRecord(value.binding.params) || !Object.values(value.binding.params).every(isJsonValue)))) issues.push({ path: `${path}.binding`, message: "\u5FC5\u987B\u5305\u542B source\uFF0C\u4E14 params \u5FC5\u987B\u662F JSON \u5BF9\u8C61" });
|
|
23
33
|
if (issues.some((issue) => issue.path.startsWith(path))) return null;
|
|
24
34
|
const slots = normalizeSlots(value.slots, `${path}.slots`, issues);
|
|
@@ -28,6 +38,8 @@ function normalizeBlock(value, path, issues) {
|
|
|
28
38
|
type: value.type,
|
|
29
39
|
version: value.version,
|
|
30
40
|
props: value.props,
|
|
41
|
+
variant: value.variant,
|
|
42
|
+
style: themeTokensOrEmpty(value.style),
|
|
31
43
|
...slots ? { slots } : {},
|
|
32
44
|
...value.binding ? { binding: value.binding } : {}
|
|
33
45
|
};
|
|
@@ -53,9 +65,10 @@ function createPageDocument(input) {
|
|
|
53
65
|
schemaVersion: 1,
|
|
54
66
|
pageId: input.pageId,
|
|
55
67
|
target: input.target ?? "web",
|
|
56
|
-
...input.templateId ? { templateId: input.templateId } : {},
|
|
68
|
+
...input.templateId ? { templateId: input.templateId, templateVersion: input.templateVersion ?? 1 } : {},
|
|
69
|
+
theme: themeTokensOrEmpty(input.theme),
|
|
57
70
|
root: input.root ?? {},
|
|
58
|
-
blocks: input.blocks ?? [],
|
|
71
|
+
blocks: (input.blocks ?? []).map((block) => ({ ...block, variant: block.variant ?? "default", style: themeTokensOrEmpty(block.style) })),
|
|
59
72
|
settings: { locale: input.settings?.locale ?? "en", ...input.settings?.seoTitle ? { seoTitle: input.settings.seoTitle } : {} }
|
|
60
73
|
};
|
|
61
74
|
}
|
|
@@ -67,6 +80,10 @@ function validatePageDocument(value) {
|
|
|
67
80
|
if (typeof value.pageId !== "string" || !value.pageId) issues.push({ path: "$.pageId", message: "\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32" });
|
|
68
81
|
if (value.target !== "web" && value.target !== "email") issues.push({ path: "$.target", message: "\u5FC5\u987B\u662F web \u6216 email" });
|
|
69
82
|
if (value.templateId !== void 0 && typeof value.templateId !== "string") issues.push({ path: "$.templateId", message: "\u5FC5\u987B\u662F\u5B57\u7B26\u4E32" });
|
|
83
|
+
if (value.templateVersion !== void 0 && (typeof value.templateVersion !== "number" || !Number.isInteger(value.templateVersion) || value.templateVersion < 1)) issues.push({ path: "$.templateVersion", message: "\u5FC5\u987B\u662F\u5927\u4E8E 0 \u7684\u6574\u6570" });
|
|
84
|
+
if (typeof value.templateId === "string" && value.templateVersion === void 0) issues.push({ path: "$.templateVersion", message: "\u4F7F\u7528\u6A21\u677F\u65F6\u5FC5\u987B\u4FDD\u5B58\u6A21\u677F\u7248\u672C" });
|
|
85
|
+
if (value.templateId === void 0 && value.templateVersion !== void 0) issues.push({ path: "$.templateVersion", message: "\u672A\u4F7F\u7528\u6A21\u677F\u65F6\u4E0D\u5F97\u4FDD\u5B58\u6A21\u677F\u7248\u672C" });
|
|
86
|
+
if (!normalizeThemeTokens(value.theme).success) issues.push({ path: "$.theme", message: "\u5FC5\u987B\u662F\u53D7\u63A7 Theme Token \u5BF9\u8C61" });
|
|
70
87
|
if (!isRecord(value.root) || !Object.values(value.root).every(isJsonValue)) issues.push({ path: "$.root", message: "\u5FC5\u987B\u662F JSON \u5BF9\u8C61" });
|
|
71
88
|
if (!isRecord(value.settings) || typeof value.settings.locale !== "string") issues.push({ path: "$.settings.locale", message: "\u5FC5\u987B\u662F\u5B57\u7B26\u4E32" });
|
|
72
89
|
if (!Array.isArray(value.blocks)) issues.push({ path: "$.blocks", message: "\u5FC5\u987B\u662F\u6570\u7EC4" });
|
|
@@ -83,6 +100,8 @@ function validatePageDocument(value) {
|
|
|
83
100
|
pageId: value.pageId,
|
|
84
101
|
target: value.target,
|
|
85
102
|
...typeof value.templateId === "string" ? { templateId: value.templateId } : {},
|
|
103
|
+
...typeof value.templateVersion === "number" ? { templateVersion: value.templateVersion } : {},
|
|
104
|
+
theme: themeTokensOrEmpty(value.theme),
|
|
86
105
|
root: value.root,
|
|
87
106
|
blocks,
|
|
88
107
|
settings: value.settings
|
|
@@ -90,14 +109,8 @@ function validatePageDocument(value) {
|
|
|
90
109
|
};
|
|
91
110
|
}
|
|
92
111
|
function migratePageDocument(value) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return validation2.success ? { ...validation2, migrated: false } : validation2;
|
|
96
|
-
}
|
|
97
|
-
const migrated = value.schemaVersion === void 0;
|
|
98
|
-
const candidate = migrated ? { ...value, schemaVersion: 1 } : value;
|
|
99
|
-
const validation = validatePageDocument(candidate);
|
|
100
|
-
return validation.success ? { ...validation, migrated } : validation;
|
|
112
|
+
const validation = validatePageDocument(value);
|
|
113
|
+
return validation.success ? { ...validation, migrated: false } : validation;
|
|
101
114
|
}
|
|
102
115
|
|
|
103
116
|
export {
|
|
@@ -56,8 +56,31 @@ function resolveOrder(extensions, disabled) {
|
|
|
56
56
|
for (const extension of [...active].sort(compareByOrder)) visit(extension);
|
|
57
57
|
return sorted;
|
|
58
58
|
}
|
|
59
|
+
var TemplateRegistry = class _TemplateRegistry {
|
|
60
|
+
constructor(templateMap) {
|
|
61
|
+
this.templateMap = templateMap;
|
|
62
|
+
}
|
|
63
|
+
templateMap;
|
|
64
|
+
get templates() {
|
|
65
|
+
return Object.freeze([...this.templateMap.values()]);
|
|
66
|
+
}
|
|
67
|
+
get(id) {
|
|
68
|
+
return this.templateMap.get(id);
|
|
69
|
+
}
|
|
70
|
+
static create(templates, blocks) {
|
|
71
|
+
const blockTypes = new Set(blocks.map((block) => block.type));
|
|
72
|
+
for (const template of templates) {
|
|
73
|
+
if (template.source !== "built-in" && template.source !== "marketplace" && template.source !== "custom") throw new ExtensionRegistryError("invalid-identifier", `Template ${template.id} \u5FC5\u987B\u58F0\u660E built-in\u3001marketplace \u6216 custom \u6765\u6E90`);
|
|
74
|
+
if (template.target !== "web" && template.target !== "email") throw new ExtensionRegistryError("invalid-target", `Template ${template.id} \u5FC5\u987B\u58F0\u660E web \u6216 email target`);
|
|
75
|
+
for (const type of template.requiredBlocks ?? []) {
|
|
76
|
+
if (!blockTypes.has(type)) throw new ExtensionRegistryError("missing-template-dependency", `Template ${template.id} \u7F3A\u5C11\u5DF2\u6CE8\u518C\u533A\u5757\uFF1A${type}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return Object.freeze(new _TemplateRegistry(new Map(templates.map((template) => [template.id, template]))));
|
|
80
|
+
}
|
|
81
|
+
};
|
|
59
82
|
var ExtensionRegistry = class _ExtensionRegistry {
|
|
60
|
-
constructor(extensions, blockMap, fieldMap, actionMap, rendererMap, dataSourceMap, templateMap, slotMap, hooks) {
|
|
83
|
+
constructor(extensions, blockMap, fieldMap, actionMap, rendererMap, dataSourceMap, templateMap, templateRegistry, slotMap, hooks) {
|
|
61
84
|
this.extensions = extensions;
|
|
62
85
|
this.blockMap = blockMap;
|
|
63
86
|
this.fieldMap = fieldMap;
|
|
@@ -65,6 +88,7 @@ var ExtensionRegistry = class _ExtensionRegistry {
|
|
|
65
88
|
this.rendererMap = rendererMap;
|
|
66
89
|
this.dataSourceMap = dataSourceMap;
|
|
67
90
|
this.templateMap = templateMap;
|
|
91
|
+
this.templateRegistry = templateRegistry;
|
|
68
92
|
this.slotMap = slotMap;
|
|
69
93
|
this.hooks = hooks;
|
|
70
94
|
}
|
|
@@ -75,6 +99,7 @@ var ExtensionRegistry = class _ExtensionRegistry {
|
|
|
75
99
|
rendererMap;
|
|
76
100
|
dataSourceMap;
|
|
77
101
|
templateMap;
|
|
102
|
+
templateRegistry;
|
|
78
103
|
slotMap;
|
|
79
104
|
hooks;
|
|
80
105
|
get blocks() {
|
|
@@ -93,7 +118,7 @@ var ExtensionRegistry = class _ExtensionRegistry {
|
|
|
93
118
|
return Object.freeze([...this.dataSourceMap.values()]);
|
|
94
119
|
}
|
|
95
120
|
get templates() {
|
|
96
|
-
return
|
|
121
|
+
return this.templateRegistry.templates;
|
|
97
122
|
}
|
|
98
123
|
getBlock(type) {
|
|
99
124
|
return this.blockMap.get(type);
|
|
@@ -111,7 +136,7 @@ var ExtensionRegistry = class _ExtensionRegistry {
|
|
|
111
136
|
return this.dataSourceMap.get(key);
|
|
112
137
|
}
|
|
113
138
|
getTemplate(id) {
|
|
114
|
-
return this.
|
|
139
|
+
return this.templateRegistry.get(id);
|
|
115
140
|
}
|
|
116
141
|
getSlot(slot) {
|
|
117
142
|
return this.slotMap.get(slot) ?? [];
|
|
@@ -154,6 +179,7 @@ var ExtensionRegistry = class _ExtensionRegistry {
|
|
|
154
179
|
slots.set(slot.slot, current);
|
|
155
180
|
}
|
|
156
181
|
}
|
|
182
|
+
const templateRegistry = TemplateRegistry.create(templateItems.map((template) => templates.get(template.id)), blockItems);
|
|
157
183
|
const sortedSlots = /* @__PURE__ */ new Map();
|
|
158
184
|
for (const [slot, contributions] of slots) sortedSlots.set(slot, Object.freeze([...contributions].sort(compareByOrder)));
|
|
159
185
|
return Object.freeze(new _ExtensionRegistry(
|
|
@@ -164,6 +190,7 @@ var ExtensionRegistry = class _ExtensionRegistry {
|
|
|
164
190
|
renderers,
|
|
165
191
|
dataSources,
|
|
166
192
|
templates,
|
|
193
|
+
templateRegistry,
|
|
167
194
|
sortedSlots,
|
|
168
195
|
Object.freeze(resolved.flatMap((extension) => extension.hooks ? [extension.hooks] : []))
|
|
169
196
|
));
|
|
@@ -172,9 +199,15 @@ var ExtensionRegistry = class _ExtensionRegistry {
|
|
|
172
199
|
function createExtensionRegistry(extensions, options) {
|
|
173
200
|
return ExtensionRegistry.create(extensions, options);
|
|
174
201
|
}
|
|
202
|
+
function createTemplateRegistry(templates, blocks = []) {
|
|
203
|
+
const registered = templates.map((template) => Object.freeze({ ...template, extension: "standalone" }));
|
|
204
|
+
return TemplateRegistry.create(registered, blocks);
|
|
205
|
+
}
|
|
175
206
|
|
|
176
207
|
export {
|
|
177
208
|
ExtensionRegistryError,
|
|
209
|
+
TemplateRegistry,
|
|
178
210
|
ExtensionRegistry,
|
|
179
|
-
createExtensionRegistry
|
|
211
|
+
createExtensionRegistry,
|
|
212
|
+
createTemplateRegistry
|
|
180
213
|
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// src/core/theme/index.ts
|
|
2
|
+
var systemThemeTokens = Object.freeze({
|
|
3
|
+
"color.background": "#ffffff",
|
|
4
|
+
"color.surface": "#ffffff",
|
|
5
|
+
"color.text": "#202223",
|
|
6
|
+
"color.muted": "#6d7175",
|
|
7
|
+
"color.primary": "#005bd3",
|
|
8
|
+
"color.border": "#d2d5d8",
|
|
9
|
+
"font.family": "system-ui, sans-serif",
|
|
10
|
+
"font.size": "16px",
|
|
11
|
+
radius: "8px",
|
|
12
|
+
spacing: "16px"
|
|
13
|
+
});
|
|
14
|
+
var themeTokenNames = new Set(Object.keys(systemThemeTokens));
|
|
15
|
+
var unsafeCssValue = /[{};]|url\s*\(|expression\s*\(|@import/i;
|
|
16
|
+
function normalizeThemeTokens(value) {
|
|
17
|
+
if (value === void 0) return { success: true, data: {} };
|
|
18
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return { success: false };
|
|
19
|
+
const tokens = {};
|
|
20
|
+
for (const [name, tokenValue] of Object.entries(value)) {
|
|
21
|
+
if (!themeTokenNames.has(name) || typeof tokenValue !== "string" || !tokenValue || unsafeCssValue.test(tokenValue)) return { success: false };
|
|
22
|
+
tokens[name] = tokenValue;
|
|
23
|
+
}
|
|
24
|
+
return { success: true, data: tokens };
|
|
25
|
+
}
|
|
26
|
+
function mergeThemeTokens(...layers) {
|
|
27
|
+
return Object.freeze(Object.assign({}, systemThemeTokens, ...layers));
|
|
28
|
+
}
|
|
29
|
+
function toThemeStyle(tokens) {
|
|
30
|
+
return Object.fromEntries(Object.entries(tokens).map(([name, value]) => [`--pb-${name.replaceAll(".", "-")}`, value]));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export {
|
|
34
|
+
systemThemeTokens,
|
|
35
|
+
normalizeThemeTokens,
|
|
36
|
+
mergeThemeTokens,
|
|
37
|
+
toThemeStyle
|
|
38
|
+
};
|
package/dist/extensions.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ComponentType, ReactNode } from 'react';
|
|
2
2
|
import { RenderTarget, PageDocument } from './schema.js';
|
|
3
|
+
import { ThemeTokens } from './theme.js';
|
|
3
4
|
|
|
4
5
|
type ExtensionTarget = RenderTarget | "all";
|
|
5
6
|
type EditorActionPosition = "left" | "center" | "right";
|
|
@@ -26,9 +27,16 @@ interface BlockDefinition<P = Record<string, unknown>> {
|
|
|
26
27
|
defaultProps: P;
|
|
27
28
|
fields: Record<string, FieldConfig>;
|
|
28
29
|
render: Partial<Record<RenderTarget, ComponentType<P>>>;
|
|
30
|
+
defaultVariant?: string;
|
|
31
|
+
variants?: BlockVariantDefinition[];
|
|
29
32
|
dataSources?: string[];
|
|
30
33
|
validate?: (props: P) => ValidationIssue[];
|
|
31
34
|
}
|
|
35
|
+
interface BlockVariantDefinition {
|
|
36
|
+
id: string;
|
|
37
|
+
label: string;
|
|
38
|
+
theme?: ThemeTokens;
|
|
39
|
+
}
|
|
32
40
|
interface FieldDefinition<T = unknown> {
|
|
33
41
|
type: string;
|
|
34
42
|
component: ComponentType<FieldProps<T>>;
|
|
@@ -65,13 +73,18 @@ interface DataSourceDefinition<P = any, R = unknown> {
|
|
|
65
73
|
live: (params: P) => Promise<R>;
|
|
66
74
|
validateParams?: (params: P) => ValidationIssue[];
|
|
67
75
|
}
|
|
76
|
+
type TemplateSource = "built-in" | "marketplace" | "custom";
|
|
68
77
|
interface TemplateDefinition {
|
|
69
78
|
id: string;
|
|
70
79
|
version: number;
|
|
71
80
|
name: string;
|
|
72
81
|
target: RenderTarget;
|
|
82
|
+
source: TemplateSource;
|
|
73
83
|
thumbnail?: string;
|
|
74
84
|
create(): PageDocument;
|
|
85
|
+
/** Block types that must be registered before this template can be used. */
|
|
86
|
+
requiredBlocks?: string[];
|
|
87
|
+
theme?: ThemeTokens;
|
|
75
88
|
}
|
|
76
89
|
interface LifecycleHooks {
|
|
77
90
|
onChange?(document: PageDocument): void;
|
|
@@ -106,7 +119,7 @@ type ExtensionRegistryOptions = {
|
|
|
106
119
|
disabled?: string[];
|
|
107
120
|
};
|
|
108
121
|
|
|
109
|
-
type ExtensionRegistryErrorCode = "duplicate-extension" | "duplicate-definition" | "invalid-identifier" | "invalid-target" | "missing-dependency" | "dependency-cycle";
|
|
122
|
+
type ExtensionRegistryErrorCode = "duplicate-extension" | "duplicate-definition" | "invalid-identifier" | "invalid-target" | "missing-dependency" | "missing-template-dependency" | "dependency-cycle";
|
|
110
123
|
declare class ExtensionRegistryError extends Error {
|
|
111
124
|
readonly code: ExtensionRegistryErrorCode;
|
|
112
125
|
constructor(code: ExtensionRegistryErrorCode, message: string);
|
|
@@ -114,6 +127,14 @@ declare class ExtensionRegistryError extends Error {
|
|
|
114
127
|
type Registered<T> = T & {
|
|
115
128
|
extension: string;
|
|
116
129
|
};
|
|
130
|
+
/** Immutable template view with explicit source and block dependency validation. */
|
|
131
|
+
declare class TemplateRegistry {
|
|
132
|
+
private readonly templateMap;
|
|
133
|
+
private constructor();
|
|
134
|
+
get templates(): readonly Registered<TemplateDefinition>[];
|
|
135
|
+
get(id: string): Registered<TemplateDefinition> | undefined;
|
|
136
|
+
static create(templates: readonly Registered<TemplateDefinition>[], blocks: readonly BlockDefinition[]): TemplateRegistry;
|
|
137
|
+
}
|
|
117
138
|
/** Immutable compiled view of all enabled extensions. */
|
|
118
139
|
declare class ExtensionRegistry {
|
|
119
140
|
readonly extensions: readonly PageBuilderExtension[];
|
|
@@ -123,6 +144,7 @@ declare class ExtensionRegistry {
|
|
|
123
144
|
private readonly rendererMap;
|
|
124
145
|
private readonly dataSourceMap;
|
|
125
146
|
private readonly templateMap;
|
|
147
|
+
readonly templateRegistry: TemplateRegistry;
|
|
126
148
|
private readonly slotMap;
|
|
127
149
|
private readonly hooks;
|
|
128
150
|
private constructor();
|
|
@@ -144,5 +166,6 @@ declare class ExtensionRegistry {
|
|
|
144
166
|
static create(extensions: PageBuilderExtension[], options?: ExtensionRegistryOptions): ExtensionRegistry;
|
|
145
167
|
}
|
|
146
168
|
declare function createExtensionRegistry(extensions: PageBuilderExtension[], options?: ExtensionRegistryOptions): ExtensionRegistry;
|
|
169
|
+
declare function createTemplateRegistry(templates: TemplateDefinition[], blocks?: BlockDefinition[]): TemplateRegistry;
|
|
147
170
|
|
|
148
|
-
export { type BlockDefinition, type DataSourceDefinition, type EditorAction, type EditorActionPosition, type ExtensionActionContext, ExtensionRegistry, ExtensionRegistryError, type ExtensionRegistryErrorCode, type ExtensionRegistryOptions, type ExtensionTarget, type FieldConfig, type FieldDefinition, type FieldProps, type LifecycleHooks, type PageBuilderExtension, type RendererDefinition, type TemplateDefinition, type UISlotContribution, type UISlotName, type ValidationIssue, createExtensionRegistry };
|
|
171
|
+
export { type BlockDefinition, type BlockVariantDefinition, type DataSourceDefinition, type EditorAction, type EditorActionPosition, type ExtensionActionContext, ExtensionRegistry, ExtensionRegistryError, type ExtensionRegistryErrorCode, type ExtensionRegistryOptions, type ExtensionTarget, type FieldConfig, type FieldDefinition, type FieldProps, type LifecycleHooks, type PageBuilderExtension, type RendererDefinition, type TemplateDefinition, TemplateRegistry, type TemplateSource, type UISlotContribution, type UISlotName, type ValidationIssue, createExtensionRegistry, createTemplateRegistry };
|
package/dist/extensions.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ExtensionRegistry,
|
|
3
3
|
ExtensionRegistryError,
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
TemplateRegistry,
|
|
5
|
+
createExtensionRegistry,
|
|
6
|
+
createTemplateRegistry
|
|
7
|
+
} from "./chunk-PUTYZI7B.js";
|
|
6
8
|
export {
|
|
7
9
|
ExtensionRegistry,
|
|
8
10
|
ExtensionRegistryError,
|
|
9
|
-
|
|
11
|
+
TemplateRegistry,
|
|
12
|
+
createExtensionRegistry,
|
|
13
|
+
createTemplateRegistry
|
|
10
14
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { ExtensionRegistry } from './extensions.js';
|
|
4
|
-
export { BlockDefinition, DataSourceDefinition, EditorAction, EditorActionPosition, ExtensionActionContext, ExtensionRegistryError, ExtensionRegistryErrorCode, ExtensionRegistryOptions, ExtensionTarget, FieldConfig, FieldDefinition, FieldProps, LifecycleHooks, PageBuilderExtension, RendererDefinition, TemplateDefinition, UISlotContribution, UISlotName, ValidationIssue, createExtensionRegistry } from './extensions.js';
|
|
4
|
+
export { BlockDefinition, BlockVariantDefinition, DataSourceDefinition, EditorAction, EditorActionPosition, ExtensionActionContext, ExtensionRegistryError, ExtensionRegistryErrorCode, ExtensionRegistryOptions, ExtensionTarget, FieldConfig, FieldDefinition, FieldProps, LifecycleHooks, PageBuilderExtension, RendererDefinition, TemplateDefinition, TemplateRegistry, TemplateSource, UISlotContribution, UISlotName, ValidationIssue, createExtensionRegistry, createTemplateRegistry } from './extensions.js';
|
|
5
5
|
import { PageDocument, BlockNode, JsonValue } from './schema.js';
|
|
6
|
-
export { DataBinding, PageDocumentIssue, PageDocumentMigration, PageSettings, RenderTarget, createPageDocument, migratePageDocument, validatePageDocument } from './schema.js';
|
|
6
|
+
export { BlockStyleOverrides, DataBinding, PageDocumentIssue, PageDocumentMigration, PageDocumentSchemaVersion, PageSettings, RenderTarget, createPageDocument, migratePageDocument, validatePageDocument } from './schema.js';
|
|
7
|
+
export { ThemeTokenName, ThemeTokens, mergeThemeTokens, normalizeThemeTokens, systemThemeTokens, toThemeStyle } from './theme.js';
|
|
7
8
|
import { Data } from '@puckeditor/core';
|
|
8
9
|
export { WebRenderer, WebRendererProps } from './renderer.js';
|
|
9
10
|
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ExtensionRegistry,
|
|
3
3
|
ExtensionRegistryError,
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
TemplateRegistry,
|
|
5
|
+
createExtensionRegistry,
|
|
6
|
+
createTemplateRegistry
|
|
7
|
+
} from "./chunk-PUTYZI7B.js";
|
|
6
8
|
import {
|
|
7
9
|
WebRenderer
|
|
8
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-KYXIXIWK.js";
|
|
9
11
|
import {
|
|
10
12
|
createPageDocument,
|
|
11
13
|
migratePageDocument,
|
|
12
14
|
validatePageDocument
|
|
13
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-OBN4DMOR.js";
|
|
16
|
+
import {
|
|
17
|
+
mergeThemeTokens,
|
|
18
|
+
normalizeThemeTokens,
|
|
19
|
+
systemThemeTokens,
|
|
20
|
+
toThemeStyle
|
|
21
|
+
} from "./chunk-YK2AUHF6.js";
|
|
14
22
|
|
|
15
23
|
// src/editor/shell/EditorShell.tsx
|
|
16
24
|
import { Puck } from "@puckeditor/core";
|
|
@@ -399,7 +407,7 @@ function toEngineBlock(block, registry) {
|
|
|
399
407
|
}
|
|
400
408
|
function toEngineData(document, registry) {
|
|
401
409
|
return {
|
|
402
|
-
root: { ...document.root },
|
|
410
|
+
root: { props: { ...document.root } },
|
|
403
411
|
content: document.blocks.map((block) => toEngineBlock(block, registry))
|
|
404
412
|
};
|
|
405
413
|
}
|
|
@@ -416,6 +424,8 @@ function fromEngineData(data, base, registry) {
|
|
|
416
424
|
type,
|
|
417
425
|
version: previous?.version ?? 1,
|
|
418
426
|
props,
|
|
427
|
+
variant: previous?.variant ?? registry?.getBlock(type)?.defaultVariant ?? "default",
|
|
428
|
+
style: previous?.style ?? {},
|
|
419
429
|
...previous?.slots ? { slots: previous.slots } : {},
|
|
420
430
|
...previous?.binding ? { binding: previous.binding } : {}
|
|
421
431
|
}];
|
|
@@ -452,11 +462,11 @@ function uniqueBlockId(type, blocks) {
|
|
|
452
462
|
return `${prefix}-${index}`;
|
|
453
463
|
}
|
|
454
464
|
function defaultBlock(type, blocks, registry) {
|
|
455
|
-
if (type === "core.text") return { id: uniqueBlockId(type, blocks), type, version: 1, props: { content: "New text block" } };
|
|
456
|
-
if (type === "core.image") return { id: uniqueBlockId(type, blocks), type, version: 1, props: { src: "https://images.unsplash.com/photo-1580674684081-7617fbf3d745?auto=format&fit=crop&w=1200&q=80", alt: "" } };
|
|
465
|
+
if (type === "core.text") return { id: uniqueBlockId(type, blocks), type, version: 1, props: { content: "New text block" }, variant: "default", style: {} };
|
|
466
|
+
if (type === "core.image") return { id: uniqueBlockId(type, blocks), type, version: 1, props: { src: "https://images.unsplash.com/photo-1580674684081-7617fbf3d745?auto=format&fit=crop&w=1200&q=80", alt: "" }, variant: "default", style: {} };
|
|
457
467
|
const definition = registry?.getBlock(type);
|
|
458
468
|
if (!definition) throw new Error(`Unknown PageDocument block type: ${type}`);
|
|
459
|
-
return { id: uniqueBlockId(type, blocks), type, version: definition.version, props: definition.defaultProps };
|
|
469
|
+
return { id: uniqueBlockId(type, blocks), type, version: definition.version, props: definition.defaultProps, variant: definition.defaultVariant ?? "default", style: {} };
|
|
460
470
|
}
|
|
461
471
|
function EditorProvider({ initialDocument, registry, loadState = "ready", leaveWarning = "You have unsaved changes.", onDocumentChange, children }) {
|
|
462
472
|
const [history, dispatch] = useReducer(historyReducer, initialDocument, (document) => ({ document, selectedBlockId: document.blocks[0]?.id ?? null, past: [], future: [], device: "desktop", savedDocument: document }));
|
|
@@ -889,7 +899,7 @@ function DocumentInspector({ block, registry, disabled, onChange }) {
|
|
|
889
899
|
] }) : null,
|
|
890
900
|
definition ? Object.entries(definition.fields).map(([name, field]) => {
|
|
891
901
|
const Field = registry?.getField(field.field)?.component;
|
|
892
|
-
return Field ? /* @__PURE__ */ jsx5(Field, { value: block.props[name], onChange: (value) => onChange({ [name]: value }) }, name) : null;
|
|
902
|
+
return Field ? /* @__PURE__ */ jsx5(Field, { value: block.props[name], onChange: (value) => onChange({ ...block.props, [name]: value }) }, name) : null;
|
|
893
903
|
}) : null
|
|
894
904
|
] });
|
|
895
905
|
}
|
|
@@ -899,13 +909,19 @@ export {
|
|
|
899
909
|
ExtensionRegistry,
|
|
900
910
|
ExtensionRegistryError,
|
|
901
911
|
PageDocumentEditorShell,
|
|
912
|
+
TemplateRegistry,
|
|
902
913
|
WebRenderer,
|
|
903
914
|
createAdminI18n,
|
|
904
915
|
createExtensionRegistry,
|
|
905
916
|
createPageDocument,
|
|
917
|
+
createTemplateRegistry,
|
|
906
918
|
fromEngineData,
|
|
919
|
+
mergeThemeTokens,
|
|
907
920
|
migratePageDocument,
|
|
921
|
+
normalizeThemeTokens,
|
|
922
|
+
systemThemeTokens,
|
|
908
923
|
toEngineData,
|
|
924
|
+
toThemeStyle,
|
|
909
925
|
useEditorContext,
|
|
910
926
|
validatePageDocument
|
|
911
927
|
};
|
package/dist/renderer.d.ts
CHANGED
package/dist/renderer.js
CHANGED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { WebRenderer, WebRendererProps } from './renderer.js';
|
|
2
|
+
export { BlockDefinition, BlockVariantDefinition, DataSourceDefinition, EditorAction, EditorActionPosition, ExtensionActionContext, ExtensionRegistry, ExtensionRegistryError, ExtensionRegistryErrorCode, ExtensionRegistryOptions, ExtensionTarget, FieldConfig, FieldDefinition, FieldProps, LifecycleHooks, PageBuilderExtension, RendererDefinition, TemplateDefinition, TemplateRegistry, TemplateSource, UISlotContribution, UISlotName, ValidationIssue, createExtensionRegistry, createTemplateRegistry } from './extensions.js';
|
|
3
|
+
export { BlockNode, BlockStyleOverrides, DataBinding, JsonPrimitive, JsonValue, PageDocument, PageDocumentIssue, PageDocumentMigration, PageDocumentSchemaVersion, PageDocumentValidation, PageSettings, RenderTarget, createPageDocument, migratePageDocument, validatePageDocument } from './schema.js';
|
|
4
|
+
export { ThemeTokenName, ThemeTokenValidation, ThemeTokens, mergeThemeTokens, normalizeThemeTokens, systemThemeTokens, toThemeStyle } from './theme.js';
|
|
5
|
+
import 'react';
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ExtensionRegistry,
|
|
3
|
+
ExtensionRegistryError,
|
|
4
|
+
TemplateRegistry,
|
|
5
|
+
createExtensionRegistry,
|
|
6
|
+
createTemplateRegistry
|
|
7
|
+
} from "./chunk-PUTYZI7B.js";
|
|
8
|
+
import {
|
|
9
|
+
WebRenderer
|
|
10
|
+
} from "./chunk-KYXIXIWK.js";
|
|
11
|
+
import {
|
|
12
|
+
createPageDocument,
|
|
13
|
+
migratePageDocument,
|
|
14
|
+
validatePageDocument
|
|
15
|
+
} from "./chunk-OBN4DMOR.js";
|
|
16
|
+
import {
|
|
17
|
+
mergeThemeTokens,
|
|
18
|
+
normalizeThemeTokens,
|
|
19
|
+
systemThemeTokens,
|
|
20
|
+
toThemeStyle
|
|
21
|
+
} from "./chunk-YK2AUHF6.js";
|
|
22
|
+
export {
|
|
23
|
+
ExtensionRegistry,
|
|
24
|
+
ExtensionRegistryError,
|
|
25
|
+
TemplateRegistry,
|
|
26
|
+
WebRenderer,
|
|
27
|
+
createExtensionRegistry,
|
|
28
|
+
createPageDocument,
|
|
29
|
+
createTemplateRegistry,
|
|
30
|
+
mergeThemeTokens,
|
|
31
|
+
migratePageDocument,
|
|
32
|
+
normalizeThemeTokens,
|
|
33
|
+
systemThemeTokens,
|
|
34
|
+
toThemeStyle,
|
|
35
|
+
validatePageDocument
|
|
36
|
+
};
|
package/dist/schema.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { ThemeTokens } from './theme.js';
|
|
2
|
+
|
|
1
3
|
type JsonPrimitive = string | number | boolean | null;
|
|
2
4
|
type JsonValue = JsonPrimitive | JsonValue[] | {
|
|
3
5
|
[key: string]: JsonValue;
|
|
4
6
|
};
|
|
5
7
|
type RenderTarget = "web" | "email";
|
|
8
|
+
type PageDocumentSchemaVersion = 1;
|
|
6
9
|
type PageSettings = {
|
|
7
10
|
locale: string;
|
|
8
11
|
seoTitle?: string;
|
|
@@ -11,19 +14,25 @@ type DataBinding = {
|
|
|
11
14
|
source: string;
|
|
12
15
|
params?: Record<string, JsonValue>;
|
|
13
16
|
};
|
|
17
|
+
/** Token-only block styling. Arbitrary CSS properties are deliberately not persisted. */
|
|
18
|
+
type BlockStyleOverrides = ThemeTokens;
|
|
14
19
|
type BlockNode = {
|
|
15
20
|
id: string;
|
|
16
21
|
type: string;
|
|
17
22
|
version: number;
|
|
18
23
|
props: Record<string, JsonValue>;
|
|
24
|
+
variant: string;
|
|
25
|
+
style: BlockStyleOverrides;
|
|
19
26
|
slots?: Record<string, BlockNode[]>;
|
|
20
27
|
binding?: DataBinding;
|
|
21
28
|
};
|
|
22
29
|
type PageDocument = {
|
|
23
|
-
schemaVersion:
|
|
30
|
+
schemaVersion: PageDocumentSchemaVersion;
|
|
24
31
|
pageId: string;
|
|
25
32
|
target: RenderTarget;
|
|
26
33
|
templateId?: string;
|
|
34
|
+
templateVersion?: number;
|
|
35
|
+
theme: ThemeTokens;
|
|
27
36
|
root: Record<string, JsonValue>;
|
|
28
37
|
blocks: BlockNode[];
|
|
29
38
|
settings: PageSettings;
|
|
@@ -47,13 +56,13 @@ type PageDocumentMigration = {
|
|
|
47
56
|
success: false;
|
|
48
57
|
issues: PageDocumentIssue[];
|
|
49
58
|
};
|
|
50
|
-
declare function createPageDocument(input: Partial<PageDocument
|
|
59
|
+
declare function createPageDocument(input: Omit<Partial<PageDocument>, "schemaVersion" | "blocks" | "theme"> & {
|
|
60
|
+
pageId: string;
|
|
61
|
+
blocks?: Array<Omit<BlockNode, "variant" | "style"> & Partial<Pick<BlockNode, "variant" | "style">>>;
|
|
62
|
+
theme?: ThemeTokens;
|
|
63
|
+
}): PageDocument;
|
|
51
64
|
declare function validatePageDocument(value: unknown): PageDocumentValidation;
|
|
52
|
-
/**
|
|
53
|
-
* Accept the pre-versioned shape produced by the early Demo and normalize it
|
|
54
|
-
* to the first persisted PageDocument schema. Future schema migrations belong
|
|
55
|
-
* here so storage callers have one validation boundary.
|
|
56
|
-
*/
|
|
65
|
+
/** V0.6.1 starts from this schema; no pre-integration document compatibility is needed. */
|
|
57
66
|
declare function migratePageDocument(value: unknown): PageDocumentMigration;
|
|
58
67
|
|
|
59
|
-
export { type BlockNode, type DataBinding, type JsonPrimitive, type JsonValue, type PageDocument, type PageDocumentIssue, type PageDocumentMigration, type PageDocumentValidation, type PageSettings, type RenderTarget, createPageDocument, migratePageDocument, validatePageDocument };
|
|
68
|
+
export { type BlockNode, type BlockStyleOverrides, type DataBinding, type JsonPrimitive, type JsonValue, type PageDocument, type PageDocumentIssue, type PageDocumentMigration, type PageDocumentSchemaVersion, type PageDocumentValidation, type PageSettings, type RenderTarget, createPageDocument, migratePageDocument, validatePageDocument };
|
package/dist/schema.js
CHANGED
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type ThemeTokenName = "color.background" | "color.surface" | "color.text" | "color.muted" | "color.primary" | "color.border" | "font.family" | "font.size" | "radius" | "spacing";
|
|
2
|
+
type ThemeTokens = Partial<Record<ThemeTokenName, string>>;
|
|
3
|
+
type ThemeTokenValidation = {
|
|
4
|
+
success: true;
|
|
5
|
+
data: ThemeTokens;
|
|
6
|
+
} | {
|
|
7
|
+
success: false;
|
|
8
|
+
};
|
|
9
|
+
declare const systemThemeTokens: Readonly<Required<ThemeTokens>>;
|
|
10
|
+
declare function normalizeThemeTokens(value: unknown): ThemeTokenValidation;
|
|
11
|
+
declare function mergeThemeTokens(...layers: Array<ThemeTokens | undefined>): Required<ThemeTokens>;
|
|
12
|
+
declare function toThemeStyle(tokens: ThemeTokens): Record<string, string>;
|
|
13
|
+
|
|
14
|
+
export { type ThemeTokenName, type ThemeTokenValidation, type ThemeTokens, mergeThemeTokens, normalizeThemeTokens, systemThemeTokens, toThemeStyle };
|
package/dist/theme.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@standhigher/puck-page-builder",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"description": "React PageDocument editor, extension registry, and web renderer for BestTrack page experiences.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -40,6 +40,14 @@
|
|
|
40
40
|
"types": "./dist/schema.d.ts",
|
|
41
41
|
"import": "./dist/schema.js"
|
|
42
42
|
},
|
|
43
|
+
"./runtime": {
|
|
44
|
+
"types": "./dist/runtime.d.ts",
|
|
45
|
+
"import": "./dist/runtime.js"
|
|
46
|
+
},
|
|
47
|
+
"./theme": {
|
|
48
|
+
"types": "./dist/theme.d.ts",
|
|
49
|
+
"import": "./dist/theme.js"
|
|
50
|
+
},
|
|
43
51
|
"./styles.css": "./src/styles.css"
|
|
44
52
|
},
|
|
45
53
|
"publishConfig": {
|
|
@@ -62,7 +70,7 @@
|
|
|
62
70
|
"typescript": "^5.9.3"
|
|
63
71
|
},
|
|
64
72
|
"scripts": {
|
|
65
|
-
"build": "tsup src/index.ts src/renderer.ts src/extensions.ts src/schema.ts --format esm --dts --clean",
|
|
73
|
+
"build": "tsup src/index.ts src/renderer.ts src/runtime.ts src/extensions.ts src/schema.ts src/theme.ts --format esm --dts --clean && node scripts/assert-runtime-boundary.mjs",
|
|
66
74
|
"typecheck": "tsc --noEmit"
|
|
67
75
|
}
|
|
68
76
|
}
|
package/dist/chunk-72MFV6J7.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// src/renderer/web/WebRenderer.tsx
|
|
2
|
-
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
function WebRenderer({ document, className, registry }) {
|
|
4
|
-
return /* @__PURE__ */ jsx("main", { className: className ?? "pb-web-renderer", "data-page-id": document.pageId, lang: document.settings.locale, children: document.blocks.map((block) => {
|
|
5
|
-
if (block.type === "core.text") return /* @__PURE__ */ jsx("section", { "data-block-id": block.id, className: "pb-web-renderer__text", children: /* @__PURE__ */ jsx("p", { children: typeof block.props.content === "string" ? block.props.content : "" }) }, block.id);
|
|
6
|
-
if (block.type === "core.image") return /* @__PURE__ */ jsx("figure", { "data-block-id": block.id, className: "pb-web-renderer__image", children: /* @__PURE__ */ jsx("img", { src: typeof block.props.src === "string" ? block.props.src : "", alt: typeof block.props.alt === "string" ? block.props.alt : "" }) }, block.id);
|
|
7
|
-
const BlockRenderer = registry?.getBlock(block.type)?.render.web;
|
|
8
|
-
if (BlockRenderer) return /* @__PURE__ */ jsx("section", { "data-block-id": block.id, children: /* @__PURE__ */ jsx(BlockRenderer, { ...block.props }) }, block.id);
|
|
9
|
-
return null;
|
|
10
|
-
}) });
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export {
|
|
14
|
-
WebRenderer
|
|
15
|
-
};
|