@particle-academy/fancy-cms-ui 0.7.1 → 0.8.0
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 +395 -0
- package/LICENSE +21 -0
- package/agent-guide/professional-pages.md +107 -0
- package/dist/{chunk-SYRU2X45.js → chunk-IOMIYI45.js} +6 -4
- package/dist/{chunk-SYRU2X45.js.map → chunk-IOMIYI45.js.map} +1 -1
- package/dist/{chunk-LY6ID2J2.js → chunk-SJYKJ6SG.js} +282 -78
- package/dist/chunk-SJYKJ6SG.js.map +1 -0
- package/dist/{chunk-R7HDS4VG.js → chunk-V6QIOJI7.js} +3 -3
- package/dist/{chunk-R7HDS4VG.js.map → chunk-V6QIOJI7.js.map} +1 -1
- package/dist/editor.cjs +274 -70
- package/dist/editor.cjs.map +1 -1
- package/dist/editor.d.cts +2 -2
- package/dist/editor.d.ts +2 -2
- package/dist/editor.js +3 -3
- package/dist/index.cjs +283 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +4 -4
- package/dist/react.cjs +253 -52
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +2 -2
- package/dist/{registry-CUNaBqTs.d.cts → registry-B4FaQDip.d.cts} +26 -0
- package/dist/{registry-CUNaBqTs.d.ts → registry-B4FaQDip.d.ts} +26 -0
- package/dist/{useEditor-wdlYQMHg.d.cts → useEditor-CIRm2oi-.d.cts} +1 -1
- package/dist/{useEditor-aPH5falI.d.ts → useEditor-DZDD9qpS.d.ts} +1 -1
- package/package.json +107 -105
- package/dist/chunk-LY6ID2J2.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { childrenOf as childrenOf$1, descendantsOf, fractionalKey } from '@particle-academy/fancy-doc-commons';
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
-
import { useMemo, Fragment } from 'react';
|
|
3
|
+
import { createElement, useMemo, Fragment } from 'react';
|
|
4
4
|
|
|
5
5
|
// src/document/types.ts
|
|
6
6
|
function isBinding(v) {
|
|
@@ -26,6 +26,17 @@ function emptyDoc(id, slug = "/") {
|
|
|
26
26
|
nodes: {}
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
|
+
|
|
30
|
+
// src/document/own.ts
|
|
31
|
+
var has = Object.prototype.hasOwnProperty;
|
|
32
|
+
function own(map, key) {
|
|
33
|
+
return map != null && has.call(map, key) ? map[key] : void 0;
|
|
34
|
+
}
|
|
35
|
+
function setOwn(map, key, value) {
|
|
36
|
+
Object.defineProperty(map, key, { value, writable: true, enumerable: true, configurable: true });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/document/reduce.ts
|
|
29
40
|
function childrenOf(doc, parent) {
|
|
30
41
|
return childrenOf$1(doc, parent);
|
|
31
42
|
}
|
|
@@ -41,7 +52,7 @@ function descendantIds(doc, id) {
|
|
|
41
52
|
return descendantsOf(doc, id);
|
|
42
53
|
}
|
|
43
54
|
function patchNode(doc, id, patch) {
|
|
44
|
-
const node = doc.nodes
|
|
55
|
+
const node = own(doc.nodes, id);
|
|
45
56
|
return {
|
|
46
57
|
...doc,
|
|
47
58
|
nodes: { ...doc.nodes, [id]: { ...node, ...patch } },
|
|
@@ -55,8 +66,8 @@ function reduce(doc, op, opts = {}) {
|
|
|
55
66
|
};
|
|
56
67
|
switch (op.t) {
|
|
57
68
|
case "insert_node": {
|
|
58
|
-
if (doc.nodes
|
|
59
|
-
if (op.node.parent !== null && !doc.nodes
|
|
69
|
+
if (own(doc.nodes, op.node.id)) return invalid("node id already exists");
|
|
70
|
+
if (op.node.parent !== null && !own(doc.nodes, op.node.parent)) return invalid("parent not found");
|
|
60
71
|
return {
|
|
61
72
|
...doc,
|
|
62
73
|
nodes: { ...doc.nodes, [op.node.id]: op.node },
|
|
@@ -64,11 +75,11 @@ function reduce(doc, op, opts = {}) {
|
|
|
64
75
|
};
|
|
65
76
|
}
|
|
66
77
|
case "remove_node": {
|
|
67
|
-
if (!doc.nodes
|
|
78
|
+
if (!own(doc.nodes, op.id)) return invalid("node not found");
|
|
68
79
|
const dead = /* @__PURE__ */ new Set([op.id, ...descendantIds(doc, op.id)]);
|
|
69
80
|
const nodes = {};
|
|
70
81
|
for (const id of Object.keys(doc.nodes)) {
|
|
71
|
-
if (!dead.has(id)) nodes
|
|
82
|
+
if (!dead.has(id)) setOwn(nodes, id, own(doc.nodes, id));
|
|
72
83
|
}
|
|
73
84
|
return {
|
|
74
85
|
...doc,
|
|
@@ -77,10 +88,10 @@ function reduce(doc, op, opts = {}) {
|
|
|
77
88
|
};
|
|
78
89
|
}
|
|
79
90
|
case "move_node": {
|
|
80
|
-
const node = doc.nodes
|
|
91
|
+
const node = own(doc.nodes, op.id);
|
|
81
92
|
if (!node) return invalid("node not found");
|
|
82
93
|
if (op.parent === op.id) return invalid("cannot parent a node to itself");
|
|
83
|
-
if (op.parent !== null && !doc.nodes
|
|
94
|
+
if (op.parent !== null && !own(doc.nodes, op.parent)) return invalid("new parent not found");
|
|
84
95
|
if (op.parent !== null && descendantIds(doc, op.id).includes(op.parent)) {
|
|
85
96
|
return invalid("move would create a cycle");
|
|
86
97
|
}
|
|
@@ -91,34 +102,35 @@ function reduce(doc, op, opts = {}) {
|
|
|
91
102
|
};
|
|
92
103
|
}
|
|
93
104
|
case "set_node_props": {
|
|
94
|
-
|
|
105
|
+
const node = own(doc.nodes, op.id);
|
|
106
|
+
if (!node) return invalid("node not found");
|
|
95
107
|
return patchNode(doc, op.id, {
|
|
96
|
-
props: { ...
|
|
108
|
+
props: { ...node.props, ...op.patch }
|
|
97
109
|
});
|
|
98
110
|
}
|
|
99
111
|
case "set_layout": {
|
|
100
|
-
if (!doc.nodes
|
|
112
|
+
if (!own(doc.nodes, op.id)) return invalid("node not found");
|
|
101
113
|
return patchNode(doc, op.id, { layout: op.layout });
|
|
102
114
|
}
|
|
103
115
|
case "set_style": {
|
|
104
|
-
const node = doc.nodes
|
|
116
|
+
const node = own(doc.nodes, op.id);
|
|
105
117
|
if (!node) return invalid("node not found");
|
|
106
|
-
const prev = node.style
|
|
118
|
+
const prev = own(node.style, op.breakpoint) ?? {};
|
|
107
119
|
return patchNode(doc, op.id, {
|
|
108
120
|
style: { ...node.style, [op.breakpoint]: { ...prev, ...op.patch } }
|
|
109
121
|
});
|
|
110
122
|
}
|
|
111
123
|
case "set_constraints": {
|
|
112
|
-
const node = doc.nodes
|
|
124
|
+
const node = own(doc.nodes, op.id);
|
|
113
125
|
if (!node) return invalid("node not found");
|
|
114
126
|
const base = node.constraints ?? { base: { width: "hug", height: "hug" } };
|
|
115
|
-
const prev = base
|
|
127
|
+
const prev = own(base, op.breakpoint) ?? {};
|
|
116
128
|
return patchNode(doc, op.id, {
|
|
117
129
|
constraints: { ...base, [op.breakpoint]: { ...prev, ...op.patch } }
|
|
118
130
|
});
|
|
119
131
|
}
|
|
120
132
|
case "set_animation": {
|
|
121
|
-
const node = doc.nodes
|
|
133
|
+
const node = own(doc.nodes, op.id);
|
|
122
134
|
if (!node) return invalid("node not found");
|
|
123
135
|
const list = node.animations ?? [];
|
|
124
136
|
const idx = list.findIndex((a) => a.id === op.anim.id);
|
|
@@ -127,14 +139,14 @@ function reduce(doc, op, opts = {}) {
|
|
|
127
139
|
});
|
|
128
140
|
}
|
|
129
141
|
case "remove_animation": {
|
|
130
|
-
const node = doc.nodes
|
|
142
|
+
const node = own(doc.nodes, op.id);
|
|
131
143
|
if (!node) return invalid("node not found");
|
|
132
144
|
return patchNode(doc, op.id, {
|
|
133
145
|
animations: (node.animations ?? []).filter((a) => a.id !== op.animId)
|
|
134
146
|
});
|
|
135
147
|
}
|
|
136
148
|
case "set_action": {
|
|
137
|
-
const node = doc.nodes
|
|
149
|
+
const node = own(doc.nodes, op.id);
|
|
138
150
|
if (!node) return invalid("node not found");
|
|
139
151
|
const list = node.actions ?? [];
|
|
140
152
|
let actions;
|
|
@@ -150,13 +162,13 @@ function reduce(doc, op, opts = {}) {
|
|
|
150
162
|
case "reorder_roots": {
|
|
151
163
|
const currentRoots = childrenOf(doc, null);
|
|
152
164
|
const current = new Set(currentRoots.map((n) => n.id));
|
|
153
|
-
const same = op.order.length === currentRoots.length && op.order.every((id) => current.has(id));
|
|
165
|
+
const same = op.order.length === currentRoots.length && new Set(op.order).size === op.order.length && op.order.every((id) => current.has(id));
|
|
154
166
|
if (!same) return invalid("reorder must be a permutation of the current roots");
|
|
155
167
|
const nodes = { ...doc.nodes };
|
|
156
168
|
let prev = null;
|
|
157
169
|
for (const id of op.order) {
|
|
158
170
|
prev = fractionalKey(prev, null);
|
|
159
|
-
nodes
|
|
171
|
+
setOwn(nodes, id, { ...own(nodes, id), order: prev });
|
|
160
172
|
}
|
|
161
173
|
return { ...doc, nodes, seq: doc.seq + 1 };
|
|
162
174
|
}
|
|
@@ -172,17 +184,17 @@ function invert(doc, op) {
|
|
|
172
184
|
case "insert_node":
|
|
173
185
|
return [{ t: "remove_node", id: op.node.id }];
|
|
174
186
|
case "remove_node": {
|
|
175
|
-
const node = doc.nodes
|
|
187
|
+
const node = own(doc.nodes, op.id);
|
|
176
188
|
if (!node) return [];
|
|
177
189
|
const ids = [op.id, ...descendantIds(doc, op.id)];
|
|
178
|
-
const inserts = ids.map((id) => ({ t: "insert_node", node: doc.nodes
|
|
190
|
+
const inserts = ids.map((id) => ({ t: "insert_node", node: own(doc.nodes, id) }));
|
|
179
191
|
if (node.parent === null) {
|
|
180
192
|
inserts.push({ t: "reorder_roots", order: childrenOf(doc, null).map((n) => n.id) });
|
|
181
193
|
}
|
|
182
194
|
return inserts;
|
|
183
195
|
}
|
|
184
196
|
case "move_node": {
|
|
185
|
-
const node = doc.nodes
|
|
197
|
+
const node = own(doc.nodes, op.id);
|
|
186
198
|
if (!node) return [];
|
|
187
199
|
const back = [{ t: "move_node", id: op.id, parent: node.parent, order: node.order }];
|
|
188
200
|
if (node.parent === null) {
|
|
@@ -191,19 +203,19 @@ function invert(doc, op) {
|
|
|
191
203
|
return back;
|
|
192
204
|
}
|
|
193
205
|
case "set_node_props": {
|
|
194
|
-
const node = doc.nodes
|
|
206
|
+
const node = own(doc.nodes, op.id);
|
|
195
207
|
if (!node) return [];
|
|
196
208
|
const prev = {};
|
|
197
209
|
for (const k of Object.keys(op.patch)) prev[k] = node.props[k];
|
|
198
210
|
return [{ t: "set_node_props", id: op.id, patch: prev }];
|
|
199
211
|
}
|
|
200
212
|
case "set_layout": {
|
|
201
|
-
const node = doc.nodes
|
|
213
|
+
const node = own(doc.nodes, op.id);
|
|
202
214
|
if (!node) return [];
|
|
203
215
|
return [{ t: "set_layout", id: op.id, layout: node.layout }];
|
|
204
216
|
}
|
|
205
217
|
case "set_style": {
|
|
206
|
-
const node = doc.nodes
|
|
218
|
+
const node = own(doc.nodes, op.id);
|
|
207
219
|
if (!node) return [];
|
|
208
220
|
const prevBp = node.style[op.breakpoint] ?? {};
|
|
209
221
|
const prev = {};
|
|
@@ -241,7 +253,7 @@ function migrateDocVerbose(input) {
|
|
|
241
253
|
const ordered = [];
|
|
242
254
|
const seen = /* @__PURE__ */ new Set();
|
|
243
255
|
for (const id of sections) {
|
|
244
|
-
if (!normalized.nodes
|
|
256
|
+
if (!own(normalized.nodes, id)) {
|
|
245
257
|
danglingIds.push(id);
|
|
246
258
|
continue;
|
|
247
259
|
}
|
|
@@ -255,7 +267,7 @@ function migrateDocVerbose(input) {
|
|
|
255
267
|
let prev = null;
|
|
256
268
|
for (const id of finalOrder) {
|
|
257
269
|
const key = fractionalKey(prev, null);
|
|
258
|
-
nodes
|
|
270
|
+
setOwn(nodes, id, { ...own(nodes, id), order: key });
|
|
259
271
|
prev = key;
|
|
260
272
|
}
|
|
261
273
|
const { sections: _dropped, ...rest } = legacy;
|
|
@@ -274,15 +286,36 @@ function needsMigration(input) {
|
|
|
274
286
|
}
|
|
275
287
|
|
|
276
288
|
// src/render/css.ts
|
|
277
|
-
|
|
289
|
+
function cssString(value) {
|
|
290
|
+
let out = "";
|
|
291
|
+
for (const ch of value) {
|
|
292
|
+
const code = ch.codePointAt(0);
|
|
293
|
+
if (ch === "\\" || ch === '"') out += `\\${ch}`;
|
|
294
|
+
else if (code < 32 || code === 127 || ch === "<") out += `\\${code.toString(16)} `;
|
|
295
|
+
else out += ch;
|
|
296
|
+
}
|
|
297
|
+
return out;
|
|
298
|
+
}
|
|
299
|
+
var selectorFor = (id) => `[data-cms="${cssString(id)}"]`;
|
|
300
|
+
var UNITS = /* @__PURE__ */ new Set(["px", "%", "vw", "vh", "rem", "fr"]);
|
|
278
301
|
function lengthToCss(len) {
|
|
279
|
-
|
|
302
|
+
if (typeof len !== "object" || len === null) return null;
|
|
303
|
+
const { value, unit } = len;
|
|
304
|
+
if (typeof value !== "number" || !Number.isFinite(value) || typeof unit !== "string" || !UNITS.has(unit)) return null;
|
|
305
|
+
return `${value}${unit}`;
|
|
280
306
|
}
|
|
281
307
|
function sizeToCss(size) {
|
|
282
308
|
if (size === "fill") return "100%";
|
|
283
309
|
if (size === "hug") return "auto";
|
|
284
310
|
return lengthToCss(size);
|
|
285
311
|
}
|
|
312
|
+
function numberToCss(value) {
|
|
313
|
+
return typeof value === "number" && Number.isFinite(value) ? String(value) : null;
|
|
314
|
+
}
|
|
315
|
+
function putLen(d, props, len) {
|
|
316
|
+
const css = lengthToCss(len);
|
|
317
|
+
if (css !== null) for (const p of props) d[p] = css;
|
|
318
|
+
}
|
|
286
319
|
var ALIGN = {
|
|
287
320
|
start: "flex-start",
|
|
288
321
|
center: "center",
|
|
@@ -296,51 +329,150 @@ var JUSTIFY = {
|
|
|
296
329
|
between: "space-between",
|
|
297
330
|
around: "space-around"
|
|
298
331
|
};
|
|
332
|
+
function safeCssValue(value) {
|
|
333
|
+
if (/[{}<]/.test(value)) return null;
|
|
334
|
+
let depth = 0;
|
|
335
|
+
let quote = null;
|
|
336
|
+
for (const ch of value) {
|
|
337
|
+
if (quote) {
|
|
338
|
+
if (ch === quote) quote = null;
|
|
339
|
+
} else if (ch === '"' || ch === "'") {
|
|
340
|
+
quote = ch;
|
|
341
|
+
} else if (ch === "(") {
|
|
342
|
+
depth++;
|
|
343
|
+
} else if (ch === ")") {
|
|
344
|
+
depth = Math.max(0, depth - 1);
|
|
345
|
+
} else if (ch === ";" && depth === 0) {
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return value;
|
|
350
|
+
}
|
|
351
|
+
function put(d, prop, value) {
|
|
352
|
+
if (value === void 0) return;
|
|
353
|
+
const safe = safeCssValue(value);
|
|
354
|
+
if (safe !== null) d[prop] = safe;
|
|
355
|
+
}
|
|
356
|
+
var OVERFLOW = /* @__PURE__ */ new Set(["visible", "hidden", "auto"]);
|
|
357
|
+
var TEXT_TRANSFORM = /* @__PURE__ */ new Set(["none", "uppercase", "lowercase", "capitalize"]);
|
|
358
|
+
var BACKGROUND_SIZE = /* @__PURE__ */ new Set(["cover", "contain", "auto"]);
|
|
359
|
+
var TEXT_ALIGN = /* @__PURE__ */ new Set(["left", "center", "right", "justify"]);
|
|
360
|
+
var DIRECTIONS = /* @__PURE__ */ new Set(["row", "column"]);
|
|
361
|
+
function keyword(map, value) {
|
|
362
|
+
return typeof value === "string" && Object.prototype.hasOwnProperty.call(map, value) ? map[value] : null;
|
|
363
|
+
}
|
|
364
|
+
function inSet(set, value) {
|
|
365
|
+
return typeof value === "string" && set.has(value) ? value : null;
|
|
366
|
+
}
|
|
299
367
|
function styleDecls(style) {
|
|
300
368
|
const d = {};
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
if (style.
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
if (style.
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
if (style.
|
|
317
|
-
|
|
318
|
-
if (
|
|
319
|
-
|
|
369
|
+
putLen(d, ["padding"], style.padding);
|
|
370
|
+
putLen(d, ["padding-left", "padding-right"], style.paddingX);
|
|
371
|
+
putLen(d, ["padding-top", "padding-bottom"], style.paddingY);
|
|
372
|
+
putLen(d, ["margin"], style.margin);
|
|
373
|
+
if (style.marginX === "auto") d["margin-left"] = d["margin-right"] = "auto";
|
|
374
|
+
else putLen(d, ["margin-left", "margin-right"], style.marginX);
|
|
375
|
+
putLen(d, ["margin-top", "margin-bottom"], style.marginY);
|
|
376
|
+
putLen(d, ["border-radius"], style.radius);
|
|
377
|
+
putLen(d, ["max-width"], style.maxWidth);
|
|
378
|
+
putLen(d, ["min-height"], style.minHeight);
|
|
379
|
+
put(d, "aspect-ratio", typeof style.aspectRatio === "string" ? style.aspectRatio : void 0);
|
|
380
|
+
if (style.sticky === true) {
|
|
381
|
+
d["position"] = "sticky";
|
|
382
|
+
d["top"] = "0";
|
|
383
|
+
}
|
|
384
|
+
if (typeof style.zIndex === "number" && Number.isFinite(style.zIndex)) d["z-index"] = String(Math.trunc(style.zIndex));
|
|
385
|
+
const overflow = inSet(OVERFLOW, style.overflow);
|
|
386
|
+
if (overflow) d["overflow"] = overflow;
|
|
387
|
+
put(d, "background", typeof style.background === "string" ? style.background : void 0);
|
|
388
|
+
const backgroundSize = inSet(BACKGROUND_SIZE, style.backgroundSize);
|
|
389
|
+
if (backgroundSize) d["background-size"] = backgroundSize;
|
|
390
|
+
put(d, "background-position", typeof style.backgroundPosition === "string" ? style.backgroundPosition : void 0);
|
|
391
|
+
put(d, "color", typeof style.color === "string" ? style.color : void 0);
|
|
392
|
+
const opacity = numberToCss(style.opacity);
|
|
393
|
+
if (opacity !== null) d["opacity"] = opacity;
|
|
394
|
+
put(d, "font-family", typeof style.fontFamily === "string" ? style.fontFamily : void 0);
|
|
395
|
+
putLen(d, ["font-size"], style.fontSize);
|
|
396
|
+
const fontWeight = numberToCss(style.fontWeight);
|
|
397
|
+
if (fontWeight !== null) d["font-weight"] = fontWeight;
|
|
398
|
+
const lineHeight = numberToCss(style.lineHeight);
|
|
399
|
+
if (lineHeight !== null) d["line-height"] = lineHeight;
|
|
400
|
+
const textAlign = inSet(TEXT_ALIGN, style.textAlign);
|
|
401
|
+
if (textAlign) d["text-align"] = textAlign;
|
|
402
|
+
putLen(d, ["letter-spacing"], style.letterSpacing);
|
|
403
|
+
const textTransform = inSet(TEXT_TRANSFORM, style.textTransform);
|
|
404
|
+
if (textTransform) d["text-transform"] = textTransform;
|
|
405
|
+
put(d, "border", typeof style.border === "string" ? style.border : void 0);
|
|
406
|
+
put(d, "box-shadow", typeof style.boxShadow === "string" ? style.boxShadow : void 0);
|
|
407
|
+
put(d, "transform", typeof style.transform === "string" ? style.transform : void 0);
|
|
408
|
+
put(d, "filter", typeof style.filter === "string" ? style.filter : void 0);
|
|
409
|
+
putLen(d, ["gap"], style.gap);
|
|
410
|
+
const align = keyword(ALIGN, style.align);
|
|
411
|
+
if (align) d["align-items"] = align;
|
|
412
|
+
const justify = keyword(JUSTIFY, style.justify);
|
|
413
|
+
if (justify) d["justify-content"] = justify;
|
|
320
414
|
return d;
|
|
321
415
|
}
|
|
322
|
-
function
|
|
416
|
+
function shownDisplay(node) {
|
|
417
|
+
if (node.layout === "stack") return "flex";
|
|
418
|
+
if (node.layout === "grid") return "grid";
|
|
419
|
+
return "block";
|
|
420
|
+
}
|
|
421
|
+
function gridColumns(style) {
|
|
422
|
+
const min = lengthToCss(style.columnMin);
|
|
423
|
+
if (min !== null) return `repeat(auto-fit, minmax(min(${min}, 100%), 1fr))`;
|
|
424
|
+
if (typeof style.columns === "number" && Number.isFinite(style.columns)) return `repeat(${Math.max(1, Math.trunc(style.columns))}, 1fr)`;
|
|
425
|
+
return void 0;
|
|
426
|
+
}
|
|
427
|
+
function containerDecls(node, style, isBase) {
|
|
323
428
|
const d = {};
|
|
324
429
|
if (node.layout === "stack") {
|
|
325
|
-
d["display"] = "flex";
|
|
326
|
-
|
|
430
|
+
if (isBase) d["display"] = "flex";
|
|
431
|
+
const direction = inSet(DIRECTIONS, style.direction);
|
|
432
|
+
if (isBase || direction) d["flex-direction"] = direction ?? "column";
|
|
433
|
+
if (style.wrap !== void 0) d["flex-wrap"] = style.wrap ? "wrap" : "nowrap";
|
|
327
434
|
} else if (node.layout === "grid") {
|
|
328
|
-
d["display"] = "grid";
|
|
329
|
-
|
|
330
|
-
|
|
435
|
+
if (isBase) d["display"] = "grid";
|
|
436
|
+
const cols = gridColumns(style);
|
|
437
|
+
if (isBase || cols !== void 0) d["grid-template-columns"] = cols ?? "repeat(1, 1fr)";
|
|
438
|
+
} else if (node.layout === "free" && isBase) {
|
|
331
439
|
d["position"] = "relative";
|
|
332
440
|
}
|
|
333
441
|
return d;
|
|
334
442
|
}
|
|
443
|
+
function visibilityDecls(node, style, isBase) {
|
|
444
|
+
if (style.hidden === true) return { display: "none" };
|
|
445
|
+
if (style.hidden === false && !isBase) return { display: shownDisplay(node) };
|
|
446
|
+
return {};
|
|
447
|
+
}
|
|
448
|
+
function themeDecls(theme) {
|
|
449
|
+
const d = {};
|
|
450
|
+
const walk = (value, path) => {
|
|
451
|
+
if (typeof value === "string" || typeof value === "number" && Number.isFinite(value)) {
|
|
452
|
+
const key = path.map((p) => p.toLowerCase().replace(/[^a-z0-9-]/g, "")).filter(Boolean).join("-");
|
|
453
|
+
if (key) put(d, `--cms-${key}`, String(value));
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
457
|
+
for (const [k, v] of Object.entries(value)) walk(v, [...path, k]);
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
if (typeof theme === "object" && theme !== null && !Array.isArray(theme)) {
|
|
461
|
+
for (const [k, v] of Object.entries(theme)) {
|
|
462
|
+
if (k !== "name") walk(v, [k]);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return d;
|
|
466
|
+
}
|
|
335
467
|
function constraintDecls(c, parentFree) {
|
|
336
468
|
const d = {};
|
|
337
469
|
const transforms = [];
|
|
338
470
|
if (parentFree) {
|
|
339
471
|
d["position"] = "absolute";
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
472
|
+
putLen(d, ["left"], c.left);
|
|
473
|
+
putLen(d, ["right"], c.right);
|
|
474
|
+
putLen(d, ["top"], c.top);
|
|
475
|
+
putLen(d, ["bottom"], c.bottom);
|
|
344
476
|
if (c.centerX) {
|
|
345
477
|
d["left"] = "50%";
|
|
346
478
|
transforms.push("translateX(-50%)");
|
|
@@ -351,13 +483,15 @@ function constraintDecls(c, parentFree) {
|
|
|
351
483
|
}
|
|
352
484
|
if (transforms.length) d["transform"] = transforms.join(" ");
|
|
353
485
|
}
|
|
354
|
-
|
|
355
|
-
if (
|
|
486
|
+
const width = sizeToCss(c.width);
|
|
487
|
+
if (width !== null) d["width"] = width;
|
|
488
|
+
const height = sizeToCss(c.height);
|
|
489
|
+
if (height !== null) d["height"] = height;
|
|
356
490
|
return d;
|
|
357
491
|
}
|
|
358
492
|
function isParentFree(doc, node) {
|
|
359
493
|
if (node.parent === null) return false;
|
|
360
|
-
const parent = doc.nodes
|
|
494
|
+
const parent = own(doc.nodes, node.parent);
|
|
361
495
|
return !parent || parent.layout === void 0 || parent.layout === "free";
|
|
362
496
|
}
|
|
363
497
|
function serializeRule(selector, decls, indent) {
|
|
@@ -372,14 +506,17 @@ function emitDocCss(doc) {
|
|
|
372
506
|
if (!hasNodeMap(doc)) return "";
|
|
373
507
|
const breakpointPx = DEFAULT_BREAKPOINTS;
|
|
374
508
|
const blocks = [];
|
|
509
|
+
const themeRule = serializeRule(":root", themeDecls(doc.theme), "");
|
|
510
|
+
if (themeRule) blocks.push(themeRule);
|
|
375
511
|
for (const id of Object.keys(doc.nodes).sort()) {
|
|
376
512
|
const node = doc.nodes[id];
|
|
377
513
|
const selector = selectorFor(id);
|
|
378
514
|
const parentFree = isParentFree(doc, node);
|
|
379
515
|
const base = {
|
|
380
|
-
...
|
|
516
|
+
...containerDecls(node, node.style.base, true),
|
|
381
517
|
...node.constraints ? constraintDecls(node.constraints.base, parentFree) : {},
|
|
382
|
-
...styleDecls(node.style.base)
|
|
518
|
+
...styleDecls(node.style.base),
|
|
519
|
+
...visibilityDecls(node, node.style.base, true)
|
|
383
520
|
};
|
|
384
521
|
const baseRule = serializeRule(selector, base, "");
|
|
385
522
|
if (baseRule) blocks.push(baseRule);
|
|
@@ -387,9 +524,12 @@ function emitDocCss(doc) {
|
|
|
387
524
|
if (bp === "base") continue;
|
|
388
525
|
const px = breakpointPx[bp];
|
|
389
526
|
if (px === void 0) continue;
|
|
527
|
+
const bpStyle = node.style[bp];
|
|
390
528
|
const decls = {
|
|
529
|
+
...bpStyle ? containerDecls(node, bpStyle, false) : {},
|
|
391
530
|
...node.constraints?.[bp] ? constraintDecls(node.constraints[bp], parentFree) : {},
|
|
392
|
-
...
|
|
531
|
+
...bpStyle ? styleDecls(bpStyle) : {},
|
|
532
|
+
...bpStyle ? visibilityDecls(node, bpStyle, false) : {}
|
|
393
533
|
};
|
|
394
534
|
const inner = serializeRule(selector, decls, " ");
|
|
395
535
|
if (inner) blocks.push(`@media (min-width: ${px}px) {
|
|
@@ -407,6 +547,48 @@ function resolveValue(v, data) {
|
|
|
407
547
|
if (isBinding(v)) return getPath(data, v.$bind);
|
|
408
548
|
return v;
|
|
409
549
|
}
|
|
550
|
+
var LANDMARK_TAGS = ["section", "header", "nav", "main", "footer", "article", "aside", "div"];
|
|
551
|
+
var LANDMARKS = new Set(LANDMARK_TAGS);
|
|
552
|
+
var CONTAINERS = /* @__PURE__ */ new Set(["stack", "grid", "frame", "shape", "card"]);
|
|
553
|
+
var SAFE_SCHEMES = /* @__PURE__ */ new Set(["http", "https", "mailto", "tel"]);
|
|
554
|
+
function safeHref(raw) {
|
|
555
|
+
const href = raw.trim();
|
|
556
|
+
if (!href) return null;
|
|
557
|
+
const probe = href.replace(/[\u0000- \u007f]+/g, "");
|
|
558
|
+
const scheme = /^([a-z][a-z0-9+.-]*):/i.exec(probe);
|
|
559
|
+
if (scheme && !SAFE_SCHEMES.has(scheme[1].toLowerCase())) return null;
|
|
560
|
+
return href;
|
|
561
|
+
}
|
|
562
|
+
var ANCHOR_PATTERN = /^[a-z][a-z0-9-]{0,63}$/;
|
|
563
|
+
function anchorFor(node, text) {
|
|
564
|
+
const anchor = text(node.props.anchor);
|
|
565
|
+
return ANCHOR_PATTERN.test(anchor) ? anchor : null;
|
|
566
|
+
}
|
|
567
|
+
function elementFor(node, text) {
|
|
568
|
+
const as = text(node.props.as);
|
|
569
|
+
switch (node.type) {
|
|
570
|
+
case "heading": {
|
|
571
|
+
const level = Number(text(node.props.level) || 2);
|
|
572
|
+
return { tag: Number.isInteger(level) && level >= 1 && level <= 6 ? `h${level}` : "h2" };
|
|
573
|
+
}
|
|
574
|
+
case "text":
|
|
575
|
+
return { tag: "p" };
|
|
576
|
+
case "section":
|
|
577
|
+
return { tag: LANDMARKS.has(as) ? as : "section" };
|
|
578
|
+
case "list":
|
|
579
|
+
return { tag: text(node.props.ordered) === "true" ? "ol" : "ul" };
|
|
580
|
+
case "button":
|
|
581
|
+
case "link": {
|
|
582
|
+
const href = safeHref(text(node.props.href));
|
|
583
|
+
if (href === null) return { tag: node.type === "link" ? "span" : "div" };
|
|
584
|
+
const attrs = { href };
|
|
585
|
+
if (/^https?:\/\//i.test(href)) attrs.rel = "noopener noreferrer";
|
|
586
|
+
return { tag: "a", attrs };
|
|
587
|
+
}
|
|
588
|
+
default:
|
|
589
|
+
return { tag: CONTAINERS.has(node.type) && LANDMARKS.has(as) ? as : "div" };
|
|
590
|
+
}
|
|
591
|
+
}
|
|
410
592
|
var defaultRegistry = {
|
|
411
593
|
section: ({ children }) => children,
|
|
412
594
|
stack: ({ children }) => children,
|
|
@@ -419,7 +601,12 @@ var defaultRegistry = {
|
|
|
419
601
|
// Rich text — inline-formatted HTML (gradient spans, links, <code>, …) that
|
|
420
602
|
// plain `text` can't express. The author owns the markup (it's their content).
|
|
421
603
|
richtext: ({ node, text }) => /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: text(node.props.html) } }),
|
|
422
|
-
|
|
604
|
+
// The [data-cms] element is already the <a> (see elementFor), so a link renders its label only.
|
|
605
|
+
link: ({ node, text }) => text(node.props.content) || "link",
|
|
606
|
+
list: ({ node, resolve }) => {
|
|
607
|
+
const items = resolve(node.props.items);
|
|
608
|
+
return Array.isArray(items) ? items.map((item, i) => /* @__PURE__ */ jsx("li", { children: item === null || item === void 0 ? "" : String(item) }, i)) : null;
|
|
609
|
+
},
|
|
423
610
|
divider: () => /* @__PURE__ */ jsx("hr", { style: { border: "none", borderTop: "1px solid #e2e8f0", margin: 0 } }),
|
|
424
611
|
callout: ({ node, text }) => {
|
|
425
612
|
const tone = { info: "#3b82f6", success: "#10b981", warning: "#f59e0b", danger: "#ef4444" }[text(node.props.variant)] ?? "#3b82f6";
|
|
@@ -431,15 +618,20 @@ var defaultRegistry = {
|
|
|
431
618
|
const variant = text(node.props.variant) || "primary";
|
|
432
619
|
return /* @__PURE__ */ jsx("span", { "data-cms-button": variant, style: buttonStyle(variant), children: label });
|
|
433
620
|
},
|
|
434
|
-
image: ({ node, text }) =>
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
621
|
+
image: ({ node, text }) => {
|
|
622
|
+
const fit = text(node.props.fit);
|
|
623
|
+
return /* @__PURE__ */ jsx(
|
|
624
|
+
"img",
|
|
625
|
+
{
|
|
626
|
+
src: text(node.props.src),
|
|
627
|
+
alt: text(node.props.alt),
|
|
628
|
+
loading: text(node.props.loading) === "eager" ? "eager" : "lazy",
|
|
629
|
+
style: { width: "100%", height: "100%", objectFit: IMAGE_FITS.has(fit) ? fit : "cover", display: "block" }
|
|
630
|
+
}
|
|
631
|
+
);
|
|
632
|
+
}
|
|
442
633
|
};
|
|
634
|
+
var IMAGE_FITS = /* @__PURE__ */ new Set(["cover", "contain", "fill", "none", "scale-down"]);
|
|
443
635
|
function buttonStyle(variant) {
|
|
444
636
|
const base = {
|
|
445
637
|
display: "inline-flex",
|
|
@@ -458,7 +650,7 @@ function buttonStyle(variant) {
|
|
|
458
650
|
return { ...base, background: "#7c3aed", color: "#fff", border: "1px solid #7c3aed" };
|
|
459
651
|
}
|
|
460
652
|
function RenderNode({ doc, id, registry = defaultRegistry, data }) {
|
|
461
|
-
const node = doc.nodes
|
|
653
|
+
const node = own(doc.nodes, id);
|
|
462
654
|
if (!node) return null;
|
|
463
655
|
if (node.type === "repeater") {
|
|
464
656
|
const arr = resolveValue(node.props.items, data);
|
|
@@ -474,7 +666,19 @@ function RenderNode({ doc, id, registry = defaultRegistry, data }) {
|
|
|
474
666
|
};
|
|
475
667
|
const renderer = registry[node.type];
|
|
476
668
|
const inner = renderer ? renderer({ node, doc, children: kids, data, resolve, text }) : node.island ? null : kids;
|
|
477
|
-
|
|
669
|
+
const { tag, attrs } = elementFor(node, text);
|
|
670
|
+
const anchor = anchorFor(node, text);
|
|
671
|
+
return createElement(
|
|
672
|
+
tag,
|
|
673
|
+
{
|
|
674
|
+
"data-cms": node.id,
|
|
675
|
+
"data-cms-island": node.island ? node.type : void 0,
|
|
676
|
+
className: node.className,
|
|
677
|
+
...anchor ? { id: anchor } : {},
|
|
678
|
+
...attrs
|
|
679
|
+
},
|
|
680
|
+
inner
|
|
681
|
+
);
|
|
478
682
|
}
|
|
479
683
|
function CmsPage({
|
|
480
684
|
doc: input,
|
|
@@ -490,5 +694,5 @@ function CmsPage({
|
|
|
490
694
|
}
|
|
491
695
|
|
|
492
696
|
export { CmsPage, DEFAULT_BREAKPOINTS, RenderNode, childrenOf, defaultRegistry, descendantIds, emitDocCss, emptyDoc, getPath, hasNodeMap, invert, isBinding, lastRootId, migrateDoc, migrateDocVerbose, needsMigration, reduce, reduceAll, resolveValue, rootIds };
|
|
493
|
-
//# sourceMappingURL=chunk-
|
|
494
|
-
//# sourceMappingURL=chunk-
|
|
697
|
+
//# sourceMappingURL=chunk-SJYKJ6SG.js.map
|
|
698
|
+
//# sourceMappingURL=chunk-SJYKJ6SG.js.map
|