@bettercms-ai/ui 0.16.0 → 0.17.1
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/blocks.js +1127 -763
- package/dist/blocks.js.map +1 -1
- package/dist/index.js +1124 -980
- package/dist/index.js.map +1 -1
- package/dist/registry.js +368 -106
- package/dist/registry.js.map +1 -1
- package/dist/renderer.d.ts +2 -2
- package/dist/renderer.js +163 -19
- package/dist/renderer.js.map +1 -1
- package/dist/resolve.js +22 -4
- package/dist/resolve.js.map +1 -1
- package/dist/tokens.d.ts +1 -1
- package/dist/tokens.js +3 -0
- package/dist/tokens.js.map +1 -1
- package/package.json +3 -3
package/dist/registry.js
CHANGED
|
@@ -29,10 +29,136 @@ function Heading({
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// src/blocks/portableText.tsx
|
|
32
|
-
import
|
|
32
|
+
import React2 from "react";
|
|
33
33
|
import { PortableText as PT } from "@portabletext/react";
|
|
34
34
|
|
|
35
|
+
// src/renderer.tsx
|
|
36
|
+
import { RESPONSIVE_CSS, hiddenEverywhere, hideOnAttr, splitButtonStyle, usesHideOn, visibleBlocks, windowState } from "@bettercms-ai/types";
|
|
37
|
+
|
|
38
|
+
// src/blockStyle.ts
|
|
39
|
+
import { blockStyleToCss } from "@bettercms-ai/types";
|
|
40
|
+
function blockStyleToReactStyle(style) {
|
|
41
|
+
return blockStyleToCss(style);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// src/renderer.tsx
|
|
45
|
+
import "react";
|
|
46
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
47
|
+
var CONTAINER_TYPES = /* @__PURE__ */ new Set(["columns", "section", "slider", "tabs"]);
|
|
48
|
+
function styleOf(block) {
|
|
49
|
+
if (block.type !== "button") return { wrapper: blockStyleToReactStyle(block.style), paint: {} };
|
|
50
|
+
const { placement, paint } = splitButtonStyle(block.style);
|
|
51
|
+
return { wrapper: blockStyleToReactStyle(placement), paint: paint ? { style: paint } : {} };
|
|
52
|
+
}
|
|
53
|
+
function withHide(block, wrapperStyle, el, stampAt) {
|
|
54
|
+
const hide = hideOnAttr(block.style);
|
|
55
|
+
const state = stampAt ? windowState(block, stampAt) : "live";
|
|
56
|
+
const hidden = !!stampAt && hiddenEverywhere(block);
|
|
57
|
+
if (!wrapperStyle && !hide && state === "live" && !hidden) return el;
|
|
58
|
+
return /* @__PURE__ */ jsx2("div", { style: wrapperStyle, ...hide ? { "data-bcms-hide": hide } : {}, ...state === "live" ? {} : { "data-bcms-window": state }, ...hidden ? { "data-bcms-hidden": "all" } : {}, children: el });
|
|
59
|
+
}
|
|
60
|
+
function bindingProps(block, annotate) {
|
|
61
|
+
if (!annotate || !block.id) return {};
|
|
62
|
+
switch (block.type) {
|
|
63
|
+
case "heading":
|
|
64
|
+
case "button":
|
|
65
|
+
return { "data-bcms-field": `${block.id}__text`, "data-bcms-kind": "text" };
|
|
66
|
+
case "text":
|
|
67
|
+
case "richtext":
|
|
68
|
+
return { "data-bcms-field": `${block.id}__html`, "data-bcms-kind": "richtext" };
|
|
69
|
+
case "image":
|
|
70
|
+
return { "data-bcms-field": `${block.id}__src`, "data-bcms-kind": "image" };
|
|
71
|
+
default:
|
|
72
|
+
return {};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function resolveBlock(block, className, annotate = false, stampAt) {
|
|
76
|
+
const entry = BLOCK_REGISTRY[block.type];
|
|
77
|
+
if (!entry) {
|
|
78
|
+
return /* @__PURE__ */ jsxs(
|
|
79
|
+
"div",
|
|
80
|
+
{
|
|
81
|
+
className: `w-full p-4 border border-dashed border-red-400 bg-red-50 text-red-600 text-sm rounded ${className ?? ""}`,
|
|
82
|
+
children: [
|
|
83
|
+
"Unknown block type: ",
|
|
84
|
+
/* @__PURE__ */ jsx2("code", { children: block.type })
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
const Component = entry.component;
|
|
90
|
+
const { wrapper: blockStyle, paint } = styleOf(block);
|
|
91
|
+
const el = /* @__PURE__ */ jsx2(Component, { ...block.props, ...paint, className, ...bindingProps(block, annotate) });
|
|
92
|
+
return withHide(block, blockStyle, el, stampAt);
|
|
93
|
+
}
|
|
94
|
+
function BlockRenderer({
|
|
95
|
+
block,
|
|
96
|
+
className = "",
|
|
97
|
+
renderBlock,
|
|
98
|
+
annotate = false,
|
|
99
|
+
stampAt
|
|
100
|
+
}) {
|
|
101
|
+
const entry = BLOCK_REGISTRY[block.type];
|
|
102
|
+
if (!entry) {
|
|
103
|
+
return /* @__PURE__ */ jsxs(
|
|
104
|
+
"div",
|
|
105
|
+
{
|
|
106
|
+
className: `w-full p-4 border border-dashed border-red-400 bg-red-50 text-red-600 text-sm rounded ${className}`,
|
|
107
|
+
children: [
|
|
108
|
+
"Unknown block type: ",
|
|
109
|
+
/* @__PURE__ */ jsx2("code", { children: block.type })
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
const Component = entry.component;
|
|
115
|
+
const containerProps = CONTAINER_TYPES.has(block.type) ? { renderBlock: renderBlock ?? ((child) => resolveBlock(child, void 0, annotate, stampAt)) } : {};
|
|
116
|
+
const { wrapper: blockStyle, paint } = styleOf(block);
|
|
117
|
+
const el = /* @__PURE__ */ jsx2(
|
|
118
|
+
Component,
|
|
119
|
+
{
|
|
120
|
+
...block.props,
|
|
121
|
+
...paint,
|
|
122
|
+
className,
|
|
123
|
+
...containerProps,
|
|
124
|
+
...bindingProps(block, annotate)
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
return withHide(block, blockStyle, el, stampAt);
|
|
128
|
+
}
|
|
129
|
+
function BlocksRenderer({
|
|
130
|
+
blocks: all,
|
|
131
|
+
className = "",
|
|
132
|
+
renderBlock,
|
|
133
|
+
annotate = false,
|
|
134
|
+
now
|
|
135
|
+
}) {
|
|
136
|
+
const at = now ?? /* @__PURE__ */ new Date();
|
|
137
|
+
const blocks = annotate ? all : visibleBlocks(all, at);
|
|
138
|
+
if (blocks.length === 0) return null;
|
|
139
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
140
|
+
usesHideOn(blocks) && /* @__PURE__ */ jsx2("style", { dangerouslySetInnerHTML: { __html: RESPONSIVE_CSS } }),
|
|
141
|
+
blocks.map((block) => /* @__PURE__ */ jsx2(
|
|
142
|
+
BlockRenderer,
|
|
143
|
+
{
|
|
144
|
+
block,
|
|
145
|
+
renderBlock,
|
|
146
|
+
annotate,
|
|
147
|
+
stampAt: annotate ? at : void 0
|
|
148
|
+
},
|
|
149
|
+
block.id
|
|
150
|
+
))
|
|
151
|
+
] });
|
|
152
|
+
}
|
|
153
|
+
|
|
35
154
|
// ../richtext/src/types.ts
|
|
155
|
+
function pullQuoteHref(link) {
|
|
156
|
+
if (typeof link === "string") return link.trim();
|
|
157
|
+
if (link && typeof link === "object" && typeof link.href === "string") {
|
|
158
|
+
return link.href.trim();
|
|
159
|
+
}
|
|
160
|
+
return "";
|
|
161
|
+
}
|
|
36
162
|
var PT_TYPES = {
|
|
37
163
|
/** A generic embedded block: `{schemaKey, schemaLabel, fields}`, the successor to Lexical's BlockNode. */
|
|
38
164
|
block: "bcmsBlock",
|
|
@@ -50,6 +176,10 @@ var PT_TYPES = {
|
|
|
50
176
|
video: "video",
|
|
51
177
|
/** A downloadable document — a PDF, a spec sheet. `<a href download>`, nothing more. */
|
|
52
178
|
file: "file",
|
|
179
|
+
/** A pull quote — see `PortableTextPullQuote`. The V2 kit's `<figure data-rt="pullquote">`. */
|
|
180
|
+
pullQuote: "pullQuote",
|
|
181
|
+
/** Key takeaways — see `PortableTextKeyTakeaways`. The V2 kit's `<aside data-rt="takeaways">`. */
|
|
182
|
+
keyTakeaways: "keyTakeaways",
|
|
53
183
|
/**
|
|
54
184
|
* A table. Spelled `table`, unprefixed, because that is what every other Portable Text
|
|
55
185
|
* producer calls one — the Sanity-shaped `{_type:"table", rows}` this platform used to refuse
|
|
@@ -74,8 +204,11 @@ var STORABLE_BLOCK_TYPES = /* @__PURE__ */ new Set([
|
|
|
74
204
|
PT_TYPES.divider,
|
|
75
205
|
PT_TYPES.mention,
|
|
76
206
|
PT_TYPES.video,
|
|
77
|
-
PT_TYPES.file
|
|
207
|
+
PT_TYPES.file,
|
|
208
|
+
PT_TYPES.pullQuote,
|
|
209
|
+
PT_TYPES.keyTakeaways
|
|
78
210
|
]);
|
|
211
|
+
var EMBEDDED_COMPONENT_KEY = "component";
|
|
79
212
|
|
|
80
213
|
// ../richtext/src/styled.ts
|
|
81
214
|
var STYLED_TAGS = [
|
|
@@ -246,7 +379,8 @@ function normalizeCell(raw, at, mint, read) {
|
|
|
246
379
|
content: Array.isArray(raw.content) ? read(raw.content, inner) : textContent(typeof raw.text === "string" ? raw.text : "", inner),
|
|
247
380
|
...raw.header === true ? { header: true } : {},
|
|
248
381
|
...span === void 0 ? {} : { span },
|
|
249
|
-
...rowSpan === void 0 ? {} : { rowSpan }
|
|
382
|
+
...rowSpan === void 0 ? {} : { rowSpan },
|
|
383
|
+
...typeof raw.group === "string" ? { group: raw.group } : {}
|
|
250
384
|
};
|
|
251
385
|
}
|
|
252
386
|
function normalizeRow(raw, at, mint, read) {
|
|
@@ -254,7 +388,8 @@ function normalizeRow(raw, at, mint, read) {
|
|
|
254
388
|
return {
|
|
255
389
|
_key: isRecord(raw) && isValidKey(raw._key) ? raw._key : mint("r", at),
|
|
256
390
|
cells: cells.map((c, col) => normalizeCell(c, [at, col], mint, read)),
|
|
257
|
-
...isRecord(raw) && raw.head === true ? { head: true } : {}
|
|
391
|
+
...isRecord(raw) && raw.head === true ? { head: true } : {},
|
|
392
|
+
...isRecord(raw) && typeof raw.group === "string" ? { group: raw.group } : {}
|
|
258
393
|
};
|
|
259
394
|
}
|
|
260
395
|
function builtInTableToTable(node, key = randomKey) {
|
|
@@ -299,24 +434,93 @@ function migrateTable(node, key = randomKey, read = asIs) {
|
|
|
299
434
|
rows: rows.map((r, i) => normalizeRow(r, i, mint, read)),
|
|
300
435
|
// Carried through: a migrated table that an author saves back is still the same table, and
|
|
301
436
|
// dropping the flag on that save would change the page the next time it renders.
|
|
302
|
-
...node.legacy === true ? { legacy: true } : {}
|
|
437
|
+
...node.legacy === true ? { legacy: true } : {},
|
|
438
|
+
...tableExtras(node)
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
function tableExtras(node) {
|
|
442
|
+
const groups = (list) => Array.isArray(list) ? list.filter((g) => isRecord(g) && typeof g._key === "string" && g._key !== "").map((g) => ({ _key: g._key, label: typeof g.label === "string" ? g.label : "" })) : void 0;
|
|
443
|
+
const rowGroups = groups(node.rowGroups);
|
|
444
|
+
const columnGroups = groups(node.columnGroups);
|
|
445
|
+
return {
|
|
446
|
+
...typeof node.caption === "string" ? { caption: node.caption } : {},
|
|
447
|
+
...typeof node.notes === "string" ? { notes: node.notes } : {},
|
|
448
|
+
...rowGroups ? { rowGroups } : {},
|
|
449
|
+
...columnGroups ? { columnGroups } : {}
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
function tableGroupLayout(table) {
|
|
453
|
+
const rows = Array.isArray(table.rows) ? table.rows : [];
|
|
454
|
+
const labels = (list) => new Map(
|
|
455
|
+
(Array.isArray(list) ? list : []).filter((g) => isRecord(g) && typeof g._key === "string").map((g) => [g._key, typeof g.label === "string" ? g.label : ""])
|
|
456
|
+
);
|
|
457
|
+
const cellsOf = (row) => isRecord(row) && Array.isArray(row.cells) ? row.cells : [];
|
|
458
|
+
const spanOf2 = (cell) => isRecord(cell) && typeof cell.span === "number" && Number.isInteger(cell.span) && cell.span > 1 ? cell.span : 1;
|
|
459
|
+
const width = rows.reduce((max, row) => Math.max(max, cellsOf(row).reduce((n, c) => n + spanOf2(c), 0)), 0);
|
|
460
|
+
const colLabels = labels(table.columnGroups);
|
|
461
|
+
const columns = [];
|
|
462
|
+
for (const cell of cellsOf(rows[0])) {
|
|
463
|
+
const key = isRecord(cell) && typeof cell.group === "string" && colLabels.has(cell.group) ? cell.group : void 0;
|
|
464
|
+
const last = columns[columns.length - 1];
|
|
465
|
+
if (last && last.key === key) last.width += spanOf2(cell);
|
|
466
|
+
else columns.push({ width: spanOf2(cell), ...key === void 0 ? {} : { key, label: colLabels.get(key) } });
|
|
467
|
+
}
|
|
468
|
+
const rowLabels = labels(table.rowGroups);
|
|
469
|
+
const headCount = rows.findIndex((r) => !isRecord(r) || r.head !== true);
|
|
470
|
+
const body = headCount === -1 ? [] : rows.slice(headCount);
|
|
471
|
+
const runs = [];
|
|
472
|
+
for (const row of body) {
|
|
473
|
+
const key = isRecord(row) && typeof row.group === "string" && rowLabels.has(row.group) ? row.group : void 0;
|
|
474
|
+
const last = runs[runs.length - 1];
|
|
475
|
+
if (last && last.key === key) last.rows.push(row);
|
|
476
|
+
else runs.push({ rows: [row], ...key === void 0 ? {} : { key, label: rowLabels.get(key) } });
|
|
477
|
+
}
|
|
478
|
+
return {
|
|
479
|
+
columns: columns.some((r) => r.key !== void 0) ? columns : [],
|
|
480
|
+
rows: runs.some((r) => r.key !== void 0) ? runs : [],
|
|
481
|
+
width
|
|
303
482
|
};
|
|
304
483
|
}
|
|
305
484
|
|
|
306
|
-
// ../richtext/src/
|
|
485
|
+
// ../richtext/src/key-takeaways.ts
|
|
307
486
|
var isRecord2 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
487
|
+
function keyTakeawaysView(value) {
|
|
488
|
+
const v = isRecord2(value) ? value : {};
|
|
489
|
+
const title = typeof v.title === "string" ? v.title.trim() : "";
|
|
490
|
+
const points = (Array.isArray(v.points) ? v.points : []).map((p) => typeof p === "string" ? p.trim() : "").filter(Boolean);
|
|
491
|
+
return { title, points };
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// ../richtext/src/component-copy.ts
|
|
495
|
+
var isRecord3 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
496
|
+
var fieldsOf = (value) => isRecord3(value) && value.schemaKey === EMBEDDED_COMPONENT_KEY && isRecord3(value.fields) ? value.fields : null;
|
|
497
|
+
function detachedComponentCopy(value) {
|
|
498
|
+
const f = fieldsOf(value);
|
|
499
|
+
if (!f || f.detached !== true || !Array.isArray(f.blocks)) return null;
|
|
500
|
+
return {
|
|
501
|
+
id: isRecord3(value) && typeof value._key === "string" ? value._key : "",
|
|
502
|
+
componentId: typeof f.componentId === "string" ? f.componentId : "",
|
|
503
|
+
props: isRecord3(f.props) ? f.props : {},
|
|
504
|
+
blocks: f.blocks,
|
|
505
|
+
...typeof f.sourcePublishedAt === "string" ? { sourcePublishedAt: f.sourcePublishedAt } : {},
|
|
506
|
+
...typeof f.variant === "string" ? { variant: f.variant } : {}
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// ../richtext/src/read.ts
|
|
511
|
+
var isRecord4 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
308
512
|
function normalizePortableText(value, key = randomKey) {
|
|
309
513
|
if (!Array.isArray(value)) return [];
|
|
310
514
|
return value.flatMap((raw) => {
|
|
311
|
-
if (!
|
|
515
|
+
if (!isRecord4(raw) || typeof raw._type !== "string") return [];
|
|
312
516
|
const table = migrateTable(raw, key, (v, cellKey) => normalizePortableText(v, cellKey));
|
|
313
517
|
if (table) return [table];
|
|
314
|
-
const node = { ...raw, _key:
|
|
518
|
+
const node = { ...raw, _key: isRecord4(raw) && typeof raw._key === "string" && raw._key ? raw._key : key() };
|
|
315
519
|
if (node._type === "block") {
|
|
316
520
|
if (!Array.isArray(node.markDefs)) node.markDefs = [];
|
|
317
521
|
if (typeof node.style !== "string") node.style = "normal";
|
|
318
522
|
node.children = (Array.isArray(node.children) ? node.children : []).map((c) => {
|
|
319
|
-
if (!
|
|
523
|
+
if (!isRecord4(c)) return c;
|
|
320
524
|
const child = { ...c, _key: typeof c._key === "string" && c._key ? c._key : key() };
|
|
321
525
|
if (child._type === "span" && !Array.isArray(child.marks)) child.marks = [];
|
|
322
526
|
return child;
|
|
@@ -326,14 +530,14 @@ function normalizePortableText(value, key = randomKey) {
|
|
|
326
530
|
});
|
|
327
531
|
}
|
|
328
532
|
function readStructuredContent(props) {
|
|
329
|
-
if (!
|
|
533
|
+
if (!isRecord4(props)) return null;
|
|
330
534
|
const candidate = props.content ?? props.value;
|
|
331
|
-
const arr = Array.isArray(candidate) ? candidate :
|
|
535
|
+
const arr = Array.isArray(candidate) ? candidate : isRecord4(candidate) ? Array.isArray(candidate.content) ? candidate.content : Array.isArray(candidate.value) ? candidate.value : null : null;
|
|
332
536
|
return arr && arr.length > 0 ? arr : null;
|
|
333
537
|
}
|
|
334
538
|
|
|
335
539
|
// src/blocks/portableText.tsx
|
|
336
|
-
import { Fragment, jsx as
|
|
540
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
337
541
|
var TOKEN = /^[a-z0-9-]+$/i;
|
|
338
542
|
function styleObject(css) {
|
|
339
543
|
const out = {};
|
|
@@ -352,42 +556,63 @@ function Bound({
|
|
|
352
556
|
nodeKey,
|
|
353
557
|
children
|
|
354
558
|
}) {
|
|
355
|
-
if (!base || !nodeKey) return /* @__PURE__ */
|
|
356
|
-
return /* @__PURE__ */
|
|
559
|
+
if (!base || !nodeKey) return /* @__PURE__ */ jsx3(Fragment, { children });
|
|
560
|
+
return /* @__PURE__ */ jsx3("div", { "data-bcms-field": `${base}#${nodeKey}`, "data-bcms-kind": "richtext", children });
|
|
357
561
|
}
|
|
358
562
|
function Table({ value }) {
|
|
359
|
-
const components =
|
|
360
|
-
const inline =
|
|
361
|
-
() => ({ ...components, block: { normal: ({ children }) => /* @__PURE__ */
|
|
563
|
+
const components = React2.useMemo(buildComponents, []);
|
|
564
|
+
const inline = React2.useMemo(
|
|
565
|
+
() => ({ ...components, block: { normal: ({ children }) => /* @__PURE__ */ jsx3(Fragment, { children }) } }),
|
|
362
566
|
[components]
|
|
363
567
|
);
|
|
364
568
|
const rows = Array.isArray(value?.rows) ? value.rows : [];
|
|
365
569
|
if (rows.length === 0) return null;
|
|
366
570
|
const cells = (row) => (Array.isArray(row?.cells) ? row.cells : []).map((cell) => {
|
|
367
571
|
const Tag = cell?.header === true ? "th" : "td";
|
|
368
|
-
const
|
|
572
|
+
const span2 = typeof cell?.span === "number" && cell.span > 1 ? cell.span : void 0;
|
|
369
573
|
const rowSpan = typeof cell?.rowSpan === "number" && cell.rowSpan > 1 ? cell.rowSpan : void 0;
|
|
370
574
|
const content = Array.isArray(cell?.content) ? cell.content : [];
|
|
371
575
|
const lone = content.length === 1 && content[0]._type === "block" && content[0].style === "normal" && !content[0].listItem;
|
|
372
|
-
return /* @__PURE__ */
|
|
576
|
+
return /* @__PURE__ */ jsx3(Tag, { ...span2 ? { colSpan: span2 } : {}, ...rowSpan ? { rowSpan } : {}, children: /* @__PURE__ */ jsx3(PT, { value: content, components: lone ? inline : components }) }, cell?._key);
|
|
373
577
|
});
|
|
374
|
-
const
|
|
578
|
+
const rowEl = (row) => /* @__PURE__ */ jsx3("tr", { children: cells(row) }, row?._key);
|
|
375
579
|
const headCount = rows.findIndex((r) => r?.head !== true);
|
|
376
580
|
const head = headCount === -1 ? rows.length : headCount;
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
581
|
+
const layout = tableGroupLayout(value);
|
|
582
|
+
const caption = typeof value.caption === "string" ? value.caption.trim() : "";
|
|
583
|
+
const notes = typeof value.notes === "string" ? value.notes.trim() : "";
|
|
584
|
+
const notesId = notes && typeof value._key === "string" && value._key ? `${value._key}-notes` : void 0;
|
|
585
|
+
const span = (n) => n > 1 ? n : void 0;
|
|
586
|
+
const groupRow = layout.columns.length ? /* @__PURE__ */ jsx3("tr", { children: layout.columns.flatMap(
|
|
587
|
+
(run, i) => run.label === void 0 ? Array.from({ length: run.width }, (_, k) => /* @__PURE__ */ jsx3("td", {}, `${i}-${k}`)) : [/* @__PURE__ */ jsx3("th", { scope: "colgroup", colSpan: span(run.width), "data-group": run.key, children: run.label }, i)]
|
|
588
|
+
) }) : null;
|
|
589
|
+
const bodies = layout.rows.length ? layout.rows.map((run, i) => /* @__PURE__ */ jsxs2("tbody", { "data-key": run.key, children: [
|
|
590
|
+
run.label !== void 0 && /* @__PURE__ */ jsx3("tr", { children: /* @__PURE__ */ jsx3("th", { scope: "rowgroup", colSpan: span(layout.width), children: run.label }) }),
|
|
591
|
+
run.rows.map(rowEl)
|
|
592
|
+
] }, i)) : head < rows.length && /* @__PURE__ */ jsx3("tbody", { children: rows.slice(head).map(rowEl) });
|
|
593
|
+
const table = /* @__PURE__ */ jsxs2("table", { ...value.legacy === true ? { className: "bcms-table" } : {}, ...notesId ? { "aria-describedby": notesId } : {}, children: [
|
|
594
|
+
caption && /* @__PURE__ */ jsx3("caption", { children: caption }),
|
|
595
|
+
layout.columns.map((run, i) => /* @__PURE__ */ jsx3("colgroup", { span: span(run.width) }, i)),
|
|
596
|
+
(groupRow || head > 0) && /* @__PURE__ */ jsxs2("thead", { children: [
|
|
597
|
+
groupRow,
|
|
598
|
+
rows.slice(0, head).map(rowEl)
|
|
599
|
+
] }),
|
|
600
|
+
bodies
|
|
380
601
|
] });
|
|
602
|
+
return notes ? /* @__PURE__ */ jsxs2("figure", { "data-rt": "table", children: [
|
|
603
|
+
table,
|
|
604
|
+
/* @__PURE__ */ jsx3("p", { "data-notes": "", id: notesId, children: notes })
|
|
605
|
+
] }) : table;
|
|
381
606
|
}
|
|
382
607
|
function buildComponents(renderBlock) {
|
|
383
608
|
return {
|
|
384
609
|
types: {
|
|
385
|
-
[PT_TYPES.divider]: () => /* @__PURE__ */
|
|
386
|
-
[PT_TYPES.table]: ({ value }) => /* @__PURE__ */
|
|
610
|
+
[PT_TYPES.divider]: () => /* @__PURE__ */ jsx3("hr", {}),
|
|
611
|
+
[PT_TYPES.table]: ({ value }) => /* @__PURE__ */ jsx3(Table, { value }),
|
|
387
612
|
[PT_TYPES.code]: ({ value }) => {
|
|
388
613
|
const v = value;
|
|
389
614
|
const lang = typeof v.language === "string" && TOKEN.test(v.language) ? v.language : void 0;
|
|
390
|
-
return /* @__PURE__ */
|
|
615
|
+
return /* @__PURE__ */ jsx3("pre", { children: /* @__PURE__ */ jsx3("code", { className: lang ? `language-${lang}` : void 0, children: typeof v.code === "string" ? v.code : "" }) });
|
|
391
616
|
},
|
|
392
617
|
/**
|
|
393
618
|
* A generic embedded block renders as a marker, not as content: its payload references
|
|
@@ -398,14 +623,51 @@ function buildComponents(renderBlock) {
|
|
|
398
623
|
*/
|
|
399
624
|
[PT_TYPES.block]: ({ value }) => {
|
|
400
625
|
const rendered = renderBlock?.(value);
|
|
401
|
-
if (rendered !== void 0) return /* @__PURE__ */
|
|
626
|
+
if (rendered !== void 0) return /* @__PURE__ */ jsx3(Fragment, { children: rendered });
|
|
627
|
+
const copy = detachedComponentCopy(value);
|
|
628
|
+
if (copy) {
|
|
629
|
+
return /* @__PURE__ */ jsx3("div", { className: "bcms-block bcms-block--component", "data-bcms-component-copy": copy.componentId, "data-bcms-instance": copy.id, children: /* @__PURE__ */ jsx3(BlocksRenderer, { blocks: copy.blocks }) });
|
|
630
|
+
}
|
|
402
631
|
const v = value;
|
|
403
632
|
const key = typeof v.schemaKey === "string" ? v.schemaKey : "block";
|
|
404
|
-
return /* @__PURE__ */
|
|
633
|
+
return /* @__PURE__ */ jsx3("div", { className: "bcms-block", "data-bcms-schema-key": key });
|
|
634
|
+
},
|
|
635
|
+
/**
|
|
636
|
+
* A pull quote — the React half of `portableTextToHtml`'s, and the same DOM: the V2 kit's
|
|
637
|
+
* `<figure data-rt="pullquote">`, the name linked (and the quote cited) only through
|
|
638
|
+
* `safeHref`. pull-quote.test.tsx compares the two.
|
|
639
|
+
*/
|
|
640
|
+
[PT_TYPES.pullQuote]: ({ value }) => {
|
|
641
|
+
const v = value;
|
|
642
|
+
const text = (x) => typeof x === "string" ? x.trim() : "";
|
|
643
|
+
const quote = typeof v.quote === "string" ? v.quote : "";
|
|
644
|
+
const name = text(v.name);
|
|
645
|
+
const role = text(v.role);
|
|
646
|
+
const href = safeHref(pullQuoteHref(v.link)) ?? void 0;
|
|
647
|
+
return /* @__PURE__ */ jsxs2("figure", { "data-rt": "pullquote", children: [
|
|
648
|
+
/* @__PURE__ */ jsx3("blockquote", { cite: href, children: /* @__PURE__ */ jsx3("p", { children: quote }) }),
|
|
649
|
+
name || role ? /* @__PURE__ */ jsxs2("figcaption", { children: [
|
|
650
|
+
name ? href ? /* @__PURE__ */ jsx3("a", { href, "data-name": "", children: name }) : /* @__PURE__ */ jsx3("span", { "data-name": "", children: name }) : null,
|
|
651
|
+
name && role ? ", " : null,
|
|
652
|
+
role ? /* @__PURE__ */ jsx3("span", { "data-role": "", children: role }) : null
|
|
653
|
+
] }) : null
|
|
654
|
+
] });
|
|
655
|
+
},
|
|
656
|
+
/**
|
|
657
|
+
* Key takeaways — the React half of `portableTextToHtml`'s, and the same DOM: the V2 kit's
|
|
658
|
+
* `<aside data-rt="takeaways">`, read through the one `keyTakeawaysView` both renderers share.
|
|
659
|
+
* portable-text-key-takeaways.test.tsx compares the two.
|
|
660
|
+
*/
|
|
661
|
+
[PT_TYPES.keyTakeaways]: ({ value }) => {
|
|
662
|
+
const { title, points } = keyTakeawaysView(value);
|
|
663
|
+
return /* @__PURE__ */ jsxs2("aside", { "data-rt": "takeaways", children: [
|
|
664
|
+
title ? /* @__PURE__ */ jsx3("p", { "data-title": "", children: title }) : null,
|
|
665
|
+
/* @__PURE__ */ jsx3("ul", { children: points.map((p, i) => /* @__PURE__ */ jsx3("li", { children: p }, i)) })
|
|
666
|
+
] });
|
|
405
667
|
},
|
|
406
668
|
[PT_TYPES.mention]: ({ value }) => {
|
|
407
669
|
const v = value;
|
|
408
|
-
return /* @__PURE__ */
|
|
670
|
+
return /* @__PURE__ */ jsx3("span", { className: "bcms-mention", children: typeof v.label === "string" ? v.label : "" });
|
|
409
671
|
}
|
|
410
672
|
},
|
|
411
673
|
marks: {
|
|
@@ -416,9 +678,9 @@ function buildComponents(renderBlock) {
|
|
|
416
678
|
[PT_TYPES.link]: ({ value, children }) => {
|
|
417
679
|
const v = value ?? {};
|
|
418
680
|
const href = typeof v.href === "string" ? safeHref(v.href) : null;
|
|
419
|
-
if (!href) return /* @__PURE__ */
|
|
681
|
+
if (!href) return /* @__PURE__ */ jsx3(Fragment, { children });
|
|
420
682
|
const blank = v.target === "_blank";
|
|
421
|
-
return /* @__PURE__ */
|
|
683
|
+
return /* @__PURE__ */ jsx3("a", { href, ...blank ? { target: "_blank", rel: "noopener noreferrer" } : {}, children });
|
|
422
684
|
},
|
|
423
685
|
/**
|
|
424
686
|
* The site's own inline markup, rendered as itself — the React half of
|
|
@@ -435,12 +697,12 @@ function buildComponents(renderBlock) {
|
|
|
435
697
|
[PT_TYPES.styled]: ({ value, children }) => {
|
|
436
698
|
const v = value ?? {};
|
|
437
699
|
const tag = typeof v.tag === "string" ? v.tag.toLowerCase() : "";
|
|
438
|
-
if (!isStyledTag(tag)) return /* @__PURE__ */
|
|
700
|
+
if (!isStyledTag(tag)) return /* @__PURE__ */ jsx3(Fragment, { children });
|
|
439
701
|
const Tag = tag;
|
|
440
702
|
const className = typeof v.className === "string" && v.className ? v.className : void 0;
|
|
441
703
|
const attrs = styledAttrEntries(v.attrs);
|
|
442
704
|
const style = attrs.find(([name]) => name === "style")?.[1];
|
|
443
|
-
return /* @__PURE__ */
|
|
705
|
+
return /* @__PURE__ */ jsx3(
|
|
444
706
|
Tag,
|
|
445
707
|
{
|
|
446
708
|
className,
|
|
@@ -450,22 +712,22 @@ function buildComponents(renderBlock) {
|
|
|
450
712
|
}
|
|
451
713
|
);
|
|
452
714
|
},
|
|
453
|
-
highlight: ({ children }) => /* @__PURE__ */
|
|
454
|
-
"strike-through": ({ children }) => /* @__PURE__ */
|
|
715
|
+
highlight: ({ children }) => /* @__PURE__ */ jsx3("mark", { children }),
|
|
716
|
+
"strike-through": ({ children }) => /* @__PURE__ */ jsx3("s", { children }),
|
|
455
717
|
/**
|
|
456
718
|
* A colour mark carries a TOKEN name (`color:brand-accent`), never a baked hex, so the
|
|
457
719
|
* consuming site styles it and a rebrand does not orphan the content.
|
|
458
720
|
*/
|
|
459
721
|
color: ({ children, markType }) => {
|
|
460
722
|
const token = markType.startsWith("color:") ? markType.slice(6) : "";
|
|
461
|
-
if (!TOKEN.test(token)) return /* @__PURE__ */
|
|
462
|
-
return /* @__PURE__ */
|
|
723
|
+
if (!TOKEN.test(token)) return /* @__PURE__ */ jsx3(Fragment, { children });
|
|
724
|
+
return /* @__PURE__ */ jsx3("span", { className: `bcms-color-${token}`, children });
|
|
463
725
|
}
|
|
464
726
|
},
|
|
465
727
|
/** Unknown marks and types render their children. Never swallow content. */
|
|
466
|
-
unknownMark: ({ children }) => /* @__PURE__ */
|
|
467
|
-
unknownType: ({ children }) => /* @__PURE__ */
|
|
468
|
-
unknownBlockStyle: ({ children }) => /* @__PURE__ */
|
|
728
|
+
unknownMark: ({ children }) => /* @__PURE__ */ jsx3(Fragment, { children }),
|
|
729
|
+
unknownType: ({ children }) => /* @__PURE__ */ jsx3(Fragment, { children: children ?? null }),
|
|
730
|
+
unknownBlockStyle: ({ children }) => /* @__PURE__ */ jsx3("p", { children })
|
|
469
731
|
};
|
|
470
732
|
}
|
|
471
733
|
var isListItem = (node) => node._type === "block" && typeof node.listItem === "string" && !!node.listItem;
|
|
@@ -479,20 +741,20 @@ function runsOf(blocks) {
|
|
|
479
741
|
return runs;
|
|
480
742
|
}
|
|
481
743
|
function PortableText({ value, bindingBase, renderBlock }) {
|
|
482
|
-
const blocks =
|
|
483
|
-
const components =
|
|
484
|
-
const listComponents =
|
|
744
|
+
const blocks = React2.useMemo(() => normalizePortableText(readValue(value)), [value]);
|
|
745
|
+
const components = React2.useMemo(() => buildComponents(renderBlock), [renderBlock]);
|
|
746
|
+
const listComponents = React2.useMemo(() => {
|
|
485
747
|
if (!bindingBase) return null;
|
|
486
748
|
const keys = new Set(blocks.map((b) => b._key));
|
|
487
749
|
return {
|
|
488
750
|
...components,
|
|
489
|
-
listItem: ({ value: item, children }) => keys.has(item._key) ? /* @__PURE__ */
|
|
751
|
+
listItem: ({ value: item, children }) => keys.has(item._key) ? /* @__PURE__ */ jsx3("li", { "data-bcms-field": `${bindingBase}#${item._key}`, "data-bcms-kind": "richtext", children }) : /* @__PURE__ */ jsx3("li", { children })
|
|
490
752
|
};
|
|
491
753
|
}, [bindingBase, blocks, components]);
|
|
492
754
|
if (blocks.length === 0) return null;
|
|
493
|
-
if (!bindingBase || !listComponents) return /* @__PURE__ */
|
|
494
|
-
return /* @__PURE__ */
|
|
495
|
-
(run) => isListItem(run[0]) ? /* @__PURE__ */
|
|
755
|
+
if (!bindingBase || !listComponents) return /* @__PURE__ */ jsx3(PT, { value: blocks, components });
|
|
756
|
+
return /* @__PURE__ */ jsx3(Fragment, { children: runsOf(blocks).map(
|
|
757
|
+
(run) => isListItem(run[0]) ? /* @__PURE__ */ jsx3(PT, { value: run, components: listComponents }, run[0]._key) : /* @__PURE__ */ jsx3(Bound, { base: bindingBase, nodeKey: run[0]._key, children: /* @__PURE__ */ jsx3(PT, { value: run, components }) }, run[0]._key)
|
|
496
758
|
) });
|
|
497
759
|
}
|
|
498
760
|
function readValue(value) {
|
|
@@ -506,7 +768,7 @@ function readValue(value) {
|
|
|
506
768
|
}
|
|
507
769
|
|
|
508
770
|
// src/blocks/Text.tsx
|
|
509
|
-
import { jsx as
|
|
771
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
510
772
|
function Text({
|
|
511
773
|
html,
|
|
512
774
|
content,
|
|
@@ -522,14 +784,14 @@ function Text({
|
|
|
522
784
|
}[align];
|
|
523
785
|
const cls = `text-muted-foreground leading-relaxed ${alignClass} ${className}`;
|
|
524
786
|
const structured = readStructuredContent({ content });
|
|
525
|
-
return /* @__PURE__ */
|
|
787
|
+
return /* @__PURE__ */ jsx4(
|
|
526
788
|
"div",
|
|
527
789
|
{
|
|
528
790
|
className: cls,
|
|
529
791
|
...structured ? {} : { "data-bcms-field": field, "data-bcms-kind": kind },
|
|
530
|
-
children: structured ? /* @__PURE__ */
|
|
792
|
+
children: structured ? /* @__PURE__ */ jsx4(PortableText, { value: structured, bindingBase: field }) : (
|
|
531
793
|
// eslint-disable-next-line react/no-danger
|
|
532
|
-
/* @__PURE__ */
|
|
794
|
+
/* @__PURE__ */ jsx4("span", { dangerouslySetInnerHTML: { __html: html } })
|
|
533
795
|
)
|
|
534
796
|
}
|
|
535
797
|
);
|
|
@@ -543,7 +805,7 @@ function cn(...inputs) {
|
|
|
543
805
|
}
|
|
544
806
|
|
|
545
807
|
// src/blocks/Image.tsx
|
|
546
|
-
import { jsx as
|
|
808
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
547
809
|
function Image({
|
|
548
810
|
src,
|
|
549
811
|
alt,
|
|
@@ -556,8 +818,8 @@ function Image({
|
|
|
556
818
|
"data-bcms-kind": kind
|
|
557
819
|
}) {
|
|
558
820
|
const sized = typeof width === "number" && width > 0;
|
|
559
|
-
return /* @__PURE__ */
|
|
560
|
-
/* @__PURE__ */
|
|
821
|
+
return /* @__PURE__ */ jsxs3("figure", { className: cn(sized ? "max-w-full" : "w-full", className), children: [
|
|
822
|
+
/* @__PURE__ */ jsx5(
|
|
561
823
|
"img",
|
|
562
824
|
{
|
|
563
825
|
src,
|
|
@@ -572,13 +834,13 @@ function Image({
|
|
|
572
834
|
loading: "lazy"
|
|
573
835
|
}
|
|
574
836
|
),
|
|
575
|
-
caption && /* @__PURE__ */
|
|
837
|
+
caption && /* @__PURE__ */ jsx5("figcaption", { className: "mt-2 text-sm text-muted-foreground text-center italic", children: caption })
|
|
576
838
|
] });
|
|
577
839
|
}
|
|
578
840
|
|
|
579
841
|
// src/blocks/Button.tsx
|
|
580
842
|
import { LINK_RELS, buttonIconOf, buttonIconSvg, buttonVariantOf, isScriptHref } from "@bettercms-ai/types";
|
|
581
|
-
import { jsx as
|
|
843
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
582
844
|
function Button({
|
|
583
845
|
text,
|
|
584
846
|
href,
|
|
@@ -622,13 +884,13 @@ function Button({
|
|
|
622
884
|
const fullClass = fullWidth === true ? "flex w-full justify-center" : "";
|
|
623
885
|
const relTokens = [...newTab === true ? ["noopener", "noreferrer"] : [], ...LINK_RELS.includes(rel) ? [rel] : []];
|
|
624
886
|
if (action === "code") {
|
|
625
|
-
return /* @__PURE__ */
|
|
626
|
-
icon && /* @__PURE__ */
|
|
887
|
+
return /* @__PURE__ */ jsxs4("button", { type: "button", "data-bcms-field": field, "data-bcms-kind": kind, style, className: cn(baseStyles, variantStyles[buttonVariantOf(variant)], alignClass, sizeClass, fullClass, className), children: [
|
|
888
|
+
icon && /* @__PURE__ */ jsx6("span", { className: "mr-2 inline-flex", dangerouslySetInnerHTML: { __html: buttonIconSvg(icon, "bcms-btn-icon") } }),
|
|
627
889
|
text,
|
|
628
|
-
arrow === true && /* @__PURE__ */
|
|
890
|
+
arrow === true && /* @__PURE__ */ jsx6("span", { className: "ml-2 inline-flex", dangerouslySetInnerHTML: { __html: buttonIconSvg("arrow-right", "bcms-btn-arrow") } })
|
|
629
891
|
] });
|
|
630
892
|
}
|
|
631
|
-
return /* @__PURE__ */
|
|
893
|
+
return /* @__PURE__ */ jsxs4(
|
|
632
894
|
"a",
|
|
633
895
|
{
|
|
634
896
|
href: typeof href === "string" && isScriptHref(href) ? "#" : href,
|
|
@@ -639,24 +901,24 @@ function Button({
|
|
|
639
901
|
style,
|
|
640
902
|
className: cn(baseStyles, variantStyles[buttonVariantOf(variant)], alignClass, sizeClass, fullClass, className),
|
|
641
903
|
children: [
|
|
642
|
-
icon && /* @__PURE__ */
|
|
904
|
+
icon && /* @__PURE__ */ jsx6("span", { className: "mr-2 inline-flex", dangerouslySetInnerHTML: { __html: buttonIconSvg(icon, "bcms-btn-icon") } }),
|
|
643
905
|
text,
|
|
644
|
-
arrow === true && /* @__PURE__ */
|
|
906
|
+
arrow === true && /* @__PURE__ */ jsx6("span", { className: "ml-2 inline-flex", dangerouslySetInnerHTML: { __html: buttonIconSvg("arrow-right", "bcms-btn-arrow") } })
|
|
645
907
|
]
|
|
646
908
|
}
|
|
647
909
|
);
|
|
648
910
|
}
|
|
649
911
|
|
|
650
912
|
// src/blocks/Spacer.tsx
|
|
651
|
-
import { jsx as
|
|
913
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
652
914
|
function Spacer({ height = 32, className = "" }) {
|
|
653
|
-
return /* @__PURE__ */
|
|
915
|
+
return /* @__PURE__ */ jsx7(
|
|
654
916
|
"div",
|
|
655
917
|
{
|
|
656
918
|
className: `w-full border border-dashed border-muted-foreground/20 rounded flex items-center justify-center ${className}`,
|
|
657
919
|
style: { height: `${height}px` },
|
|
658
920
|
"aria-hidden": "true",
|
|
659
|
-
children: /* @__PURE__ */
|
|
921
|
+
children: /* @__PURE__ */ jsxs5("span", { className: "text-xs text-muted-foreground/40 select-none", children: [
|
|
660
922
|
height,
|
|
661
923
|
"px"
|
|
662
924
|
] })
|
|
@@ -666,14 +928,14 @@ function Spacer({ height = 32, className = "" }) {
|
|
|
666
928
|
|
|
667
929
|
// src/blocks/Columns.tsx
|
|
668
930
|
import "react";
|
|
669
|
-
import { jsx as
|
|
931
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
670
932
|
function Columns({
|
|
671
933
|
columns,
|
|
672
934
|
gap = 16,
|
|
673
935
|
className = "",
|
|
674
936
|
renderBlock
|
|
675
937
|
}) {
|
|
676
|
-
return /* @__PURE__ */
|
|
938
|
+
return /* @__PURE__ */ jsx8(
|
|
677
939
|
"div",
|
|
678
940
|
{
|
|
679
941
|
className: cn("grid w-full", className),
|
|
@@ -681,14 +943,14 @@ function Columns({
|
|
|
681
943
|
gridTemplateColumns: `repeat(${columns.length}, minmax(0, 1fr))`,
|
|
682
944
|
gap: `${gap}px`
|
|
683
945
|
},
|
|
684
|
-
children: columns.map((columnBlocks, colIndex) => /* @__PURE__ */
|
|
946
|
+
children: columns.map((columnBlocks, colIndex) => /* @__PURE__ */ jsx8("div", { className: "flex flex-col gap-4 min-w-0", children: columnBlocks.map((block) => /* @__PURE__ */ jsx8("span", { children: renderBlock ? renderBlock(block) : null }, block.id)) }, colIndex))
|
|
685
947
|
}
|
|
686
948
|
);
|
|
687
949
|
}
|
|
688
950
|
|
|
689
951
|
// src/blocks/Video.tsx
|
|
690
952
|
import { useState } from "react";
|
|
691
|
-
import { jsx as
|
|
953
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
692
954
|
function getEmbedUrl(url) {
|
|
693
955
|
const ytMatch = url.match(
|
|
694
956
|
/(?:youtube\.com\/(?:watch\?v=|embed\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/
|
|
@@ -718,7 +980,7 @@ function Video({
|
|
|
718
980
|
const [isLoaded, setIsLoaded] = useState(false);
|
|
719
981
|
const { embedUrl, provider } = getEmbedUrl(url);
|
|
720
982
|
if (provider === "unknown") {
|
|
721
|
-
return /* @__PURE__ */
|
|
983
|
+
return /* @__PURE__ */ jsx9(
|
|
722
984
|
"video",
|
|
723
985
|
{
|
|
724
986
|
src: url,
|
|
@@ -731,9 +993,9 @@ function Video({
|
|
|
731
993
|
}
|
|
732
994
|
);
|
|
733
995
|
}
|
|
734
|
-
return /* @__PURE__ */
|
|
996
|
+
return /* @__PURE__ */ jsxs6("div", { className: cn("w-full overflow-hidden rounded-md bg-black aspect-video", className), children: [
|
|
735
997
|
!isLoaded && poster && // eslint-disable-next-line @next/next/no-img-element
|
|
736
|
-
/* @__PURE__ */
|
|
998
|
+
/* @__PURE__ */ jsx9(
|
|
737
999
|
"img",
|
|
738
1000
|
{
|
|
739
1001
|
src: poster,
|
|
@@ -741,7 +1003,7 @@ function Video({
|
|
|
741
1003
|
className: "w-full h-full object-cover absolute inset-0"
|
|
742
1004
|
}
|
|
743
1005
|
),
|
|
744
|
-
/* @__PURE__ */
|
|
1006
|
+
/* @__PURE__ */ jsx9(
|
|
745
1007
|
"iframe",
|
|
746
1008
|
{
|
|
747
1009
|
src: `${embedUrl}?autoplay=${autoplay ? 1 : 0}&loop=${loop ? 1 : 0}&mute=${autoplay ? 1 : 0}`,
|
|
@@ -757,7 +1019,7 @@ function Video({
|
|
|
757
1019
|
|
|
758
1020
|
// src/blocks/Section.tsx
|
|
759
1021
|
import "react";
|
|
760
|
-
import { jsx as
|
|
1022
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
761
1023
|
function Section({
|
|
762
1024
|
children,
|
|
763
1025
|
background,
|
|
@@ -766,24 +1028,24 @@ function Section({
|
|
|
766
1028
|
className = "",
|
|
767
1029
|
renderBlock
|
|
768
1030
|
}) {
|
|
769
|
-
const inner = (children ?? []).map((block) => /* @__PURE__ */
|
|
770
|
-
return /* @__PURE__ */
|
|
1031
|
+
const inner = (children ?? []).map((block) => /* @__PURE__ */ jsx10("span", { children: renderBlock ? renderBlock(block) : null }, block.id));
|
|
1032
|
+
return /* @__PURE__ */ jsx10(
|
|
771
1033
|
"section",
|
|
772
1034
|
{
|
|
773
1035
|
className: cn("w-full", className),
|
|
774
1036
|
style: { background, paddingTop: paddingY, paddingBottom: paddingY },
|
|
775
|
-
children: maxWidth ? /* @__PURE__ */
|
|
1037
|
+
children: maxWidth ? /* @__PURE__ */ jsx10("div", { style: { maxWidth, marginInline: "auto" }, children: inner }) : inner
|
|
776
1038
|
}
|
|
777
1039
|
);
|
|
778
1040
|
}
|
|
779
1041
|
|
|
780
1042
|
// src/blocks/Navbar.tsx
|
|
781
|
-
import { jsx as
|
|
1043
|
+
import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
782
1044
|
function Navbar({ logo, links, cta, className = "" }) {
|
|
783
|
-
return /* @__PURE__ */
|
|
784
|
-
logo?.src ? /* @__PURE__ */
|
|
785
|
-
/* @__PURE__ */
|
|
786
|
-
cta ? /* @__PURE__ */
|
|
1045
|
+
return /* @__PURE__ */ jsxs7("nav", { className: cn("flex items-center gap-6 py-4", className), children: [
|
|
1046
|
+
logo?.src ? /* @__PURE__ */ jsx11("a", { href: logo.href ?? "/", className: "shrink-0", children: /* @__PURE__ */ jsx11("img", { src: logo.src, alt: logo.alt, className: "h-8 w-auto" }) }) : null,
|
|
1047
|
+
/* @__PURE__ */ jsx11("div", { className: "flex flex-1 gap-5", children: (links ?? []).map((l, i) => /* @__PURE__ */ jsx11("a", { href: l.href, className: "text-inherit no-underline", children: l.label }, i)) }),
|
|
1048
|
+
cta ? /* @__PURE__ */ jsx11(
|
|
787
1049
|
"a",
|
|
788
1050
|
{
|
|
789
1051
|
href: cta.href,
|
|
@@ -795,40 +1057,40 @@ function Navbar({ logo, links, cta, className = "" }) {
|
|
|
795
1057
|
}
|
|
796
1058
|
|
|
797
1059
|
// src/blocks/Footer.tsx
|
|
798
|
-
import { jsx as
|
|
1060
|
+
import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
799
1061
|
function Footer({ columns, copyright, className = "" }) {
|
|
800
|
-
return /* @__PURE__ */
|
|
801
|
-
/* @__PURE__ */
|
|
802
|
-
col.heading ? /* @__PURE__ */
|
|
803
|
-
(col.links ?? []).map((l, j) => /* @__PURE__ */
|
|
1062
|
+
return /* @__PURE__ */ jsxs8("footer", { className: cn("mt-12 border-t pt-8", className), children: [
|
|
1063
|
+
/* @__PURE__ */ jsx12("div", { className: "flex flex-wrap gap-12", children: (columns ?? []).map((col, i) => /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-1.5", children: [
|
|
1064
|
+
col.heading ? /* @__PURE__ */ jsx12("h4", { className: "mb-2 font-semibold", children: col.heading }) : null,
|
|
1065
|
+
(col.links ?? []).map((l, j) => /* @__PURE__ */ jsx12("a", { href: l.href, className: "text-neutral-500 no-underline", children: l.label }, j))
|
|
804
1066
|
] }, i)) }),
|
|
805
|
-
copyright ? /* @__PURE__ */
|
|
1067
|
+
copyright ? /* @__PURE__ */ jsx12("p", { className: "mt-6 text-sm text-neutral-500", children: copyright }) : null
|
|
806
1068
|
] });
|
|
807
1069
|
}
|
|
808
1070
|
|
|
809
1071
|
// src/blocks/Slider.tsx
|
|
810
1072
|
import { useState as useState2 } from "react";
|
|
811
|
-
import { jsx as
|
|
1073
|
+
import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
812
1074
|
function Slider({ slides, className = "", renderBlock }) {
|
|
813
1075
|
const [i, setI] = useState2(0);
|
|
814
1076
|
const list = slides ?? [];
|
|
815
1077
|
const go = (n) => setI((n + list.length) % (list.length || 1));
|
|
816
1078
|
const btn = "absolute top-1/2 -translate-y-1/2 flex h-9 w-9 items-center justify-center rounded-full border-0 bg-black/50 text-white cursor-pointer";
|
|
817
|
-
return /* @__PURE__ */
|
|
818
|
-
list.map((s, idx) => /* @__PURE__ */
|
|
819
|
-
/* @__PURE__ */
|
|
820
|
-
/* @__PURE__ */
|
|
1079
|
+
return /* @__PURE__ */ jsxs9("div", { className: cn("relative w-full", className), children: [
|
|
1080
|
+
list.map((s, idx) => /* @__PURE__ */ jsx13("div", { hidden: idx !== i, className: "flex flex-col gap-4", children: (s.children ?? []).map((b) => /* @__PURE__ */ jsx13("span", { children: renderBlock ? renderBlock(b) : null }, b.id)) }, s.id)),
|
|
1081
|
+
/* @__PURE__ */ jsx13("button", { type: "button", "aria-label": "Previous", onClick: () => go(i - 1), className: cn(btn, "left-2"), children: "\u2039" }),
|
|
1082
|
+
/* @__PURE__ */ jsx13("button", { type: "button", "aria-label": "Next", onClick: () => go(i + 1), className: cn(btn, "right-2"), children: "\u203A" })
|
|
821
1083
|
] });
|
|
822
1084
|
}
|
|
823
1085
|
|
|
824
1086
|
// src/blocks/Tabs.tsx
|
|
825
1087
|
import { useState as useState3 } from "react";
|
|
826
|
-
import { jsx as
|
|
1088
|
+
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
827
1089
|
function Tabs({ tabs, className = "", renderBlock }) {
|
|
828
1090
|
const [active, setActive] = useState3(0);
|
|
829
1091
|
const list = tabs ?? [];
|
|
830
|
-
return /* @__PURE__ */
|
|
831
|
-
/* @__PURE__ */
|
|
1092
|
+
return /* @__PURE__ */ jsxs10("div", { className: cn("w-full", className), children: [
|
|
1093
|
+
/* @__PURE__ */ jsx14("div", { role: "tablist", className: "mb-4 flex gap-1 border-b", children: list.map((t, idx) => /* @__PURE__ */ jsx14(
|
|
832
1094
|
"button",
|
|
833
1095
|
{
|
|
834
1096
|
role: "tab",
|
|
@@ -843,38 +1105,38 @@ function Tabs({ tabs, className = "", renderBlock }) {
|
|
|
843
1105
|
},
|
|
844
1106
|
t.id
|
|
845
1107
|
)) }),
|
|
846
|
-
list.map((t, idx) => /* @__PURE__ */
|
|
1108
|
+
list.map((t, idx) => /* @__PURE__ */ jsx14("div", { role: "tabpanel", hidden: idx !== active, className: "flex flex-col gap-4", children: (t.children ?? []).map((b) => /* @__PURE__ */ jsx14("span", { children: renderBlock ? renderBlock(b) : null }, b.id)) }, t.id))
|
|
847
1109
|
] });
|
|
848
1110
|
}
|
|
849
1111
|
|
|
850
1112
|
// src/blocks/Placeholders.tsx
|
|
851
|
-
import { Fragment as Fragment2, jsx as
|
|
1113
|
+
import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
852
1114
|
var box = "rounded border border-dashed border-neutral-300 bg-neutral-50 p-4 text-sm text-neutral-500";
|
|
853
1115
|
function ComponentInstance({
|
|
854
1116
|
componentId,
|
|
855
1117
|
className = ""
|
|
856
1118
|
}) {
|
|
857
|
-
return /* @__PURE__ */
|
|
1119
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn(box, className), children: [
|
|
858
1120
|
"Component instance: ",
|
|
859
|
-
/* @__PURE__ */
|
|
1121
|
+
/* @__PURE__ */ jsx15("code", { children: componentId })
|
|
860
1122
|
] });
|
|
861
1123
|
}
|
|
862
1124
|
function FormPlaceholder({ formId, className = "" }) {
|
|
863
|
-
return /* @__PURE__ */
|
|
1125
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn(box, className), children: [
|
|
864
1126
|
"Form: ",
|
|
865
|
-
/* @__PURE__ */
|
|
1127
|
+
/* @__PURE__ */ jsx15("code", { children: formId })
|
|
866
1128
|
] });
|
|
867
1129
|
}
|
|
868
1130
|
function CollectionPlaceholder({
|
|
869
1131
|
cardComponentId,
|
|
870
1132
|
className = ""
|
|
871
1133
|
}) {
|
|
872
|
-
return /* @__PURE__ */
|
|
1134
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn(box, className), children: [
|
|
873
1135
|
"Collection: entries of this page",
|
|
874
|
-
cardComponentId ? /* @__PURE__ */
|
|
1136
|
+
cardComponentId ? /* @__PURE__ */ jsxs11(Fragment2, { children: [
|
|
875
1137
|
" as ",
|
|
876
|
-
/* @__PURE__ */
|
|
877
|
-
] }) : /* @__PURE__ */
|
|
1138
|
+
/* @__PURE__ */ jsx15("code", { children: cardComponentId })
|
|
1139
|
+
] }) : /* @__PURE__ */ jsx15(Fragment2, { children: " (default card)" })
|
|
878
1140
|
] });
|
|
879
1141
|
}
|
|
880
1142
|
|