@nextlyhq/plugin-page-builder 0.0.2-alpha.31

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.
@@ -0,0 +1,483 @@
1
+ import {
2
+ DEFAULT_SLOT,
3
+ defineBlock,
4
+ nodeClass,
5
+ resolveBindings
6
+ } from "./chunk-ABMSYCSD.js";
7
+ import {
8
+ BlockErrorBoundary
9
+ } from "./chunk-E4G7NNXW.js";
10
+
11
+ // src/render/blocks/paragraph.tsx
12
+ import { jsx } from "react/jsx-runtime";
13
+ var paragraph = defineBlock({
14
+ type: "core/paragraph",
15
+ version: 1,
16
+ label: "Paragraph",
17
+ icon: "Type",
18
+ category: "basic",
19
+ defaultProps: { text: "New paragraph" },
20
+ contentFields: [
21
+ { name: "text", type: "textarea", label: "Text", bindable: true }
22
+ ],
23
+ styleControls: [
24
+ { control: "color", styleKey: "color", label: "Text color" },
25
+ { control: "dimension", styleKey: "fontSize", label: "Font size" },
26
+ { control: "align", styleKey: "textAlign", label: "Align" },
27
+ { control: "spacing", styleKey: "padding", label: "Padding" },
28
+ { control: "spacing", styleKey: "margin", label: "Margin" }
29
+ ],
30
+ render: ({ props, className }) => /* @__PURE__ */ jsx("p", { className, children: String(props.text ?? "") })
31
+ });
32
+
33
+ // src/render/blocks/heading.tsx
34
+ import { createElement } from "react";
35
+ var LEVELS = ["h1", "h2", "h3", "h4", "h5", "h6"];
36
+ var heading = defineBlock({
37
+ type: "core/heading",
38
+ version: 1,
39
+ label: "Heading",
40
+ icon: "Heading",
41
+ category: "basic",
42
+ defaultProps: { text: "New heading", level: "h2" },
43
+ contentFields: [
44
+ { name: "text", type: "text", label: "Text", bindable: true },
45
+ {
46
+ name: "level",
47
+ type: "select",
48
+ label: "Level",
49
+ options: LEVELS.map((l) => ({ value: l, label: l.toUpperCase() }))
50
+ }
51
+ ],
52
+ styleControls: [
53
+ { control: "color", styleKey: "color", label: "Text color" },
54
+ { control: "dimension", styleKey: "fontSize", label: "Font size" },
55
+ { control: "align", styleKey: "textAlign", label: "Align" },
56
+ { control: "spacing", styleKey: "padding", label: "Padding" },
57
+ { control: "spacing", styleKey: "margin", label: "Margin" }
58
+ ],
59
+ render: ({ props, className }) => {
60
+ const level = LEVELS.includes(String(props.level)) ? String(props.level) : "h2";
61
+ return createElement(level, { className }, String(props.text ?? ""));
62
+ }
63
+ });
64
+
65
+ // src/render/blocks/util.ts
66
+ function safeUrl(url) {
67
+ if (typeof url !== "string") return void 0;
68
+ const trimmed = url.trim();
69
+ if (!trimmed) return void 0;
70
+ const scheme = trimmed.replace(/[\u0000-\u0020\u007f]+/g, "").toLowerCase();
71
+ if (/^(javascript|vbscript|data):/.test(scheme)) return void 0;
72
+ return trimmed;
73
+ }
74
+
75
+ // src/render/blocks/image.tsx
76
+ import { jsx as jsx2 } from "react/jsx-runtime";
77
+ var image = defineBlock({
78
+ type: "core/image",
79
+ version: 1,
80
+ label: "Image",
81
+ icon: "Image",
82
+ category: "media",
83
+ defaultProps: { url: "", alt: "" },
84
+ contentFields: [
85
+ { name: "media", type: "media", label: "Image", bindable: true }
86
+ ],
87
+ styleControls: [
88
+ { control: "dimension", styleKey: "width", label: "Width" },
89
+ { control: "dimension", styleKey: "borderRadius", label: "Radius" },
90
+ { control: "spacing", styleKey: "margin", label: "Margin" }
91
+ ],
92
+ render: ({ props, className }) => {
93
+ const raw = props.media;
94
+ const media = typeof raw === "string" ? { url: raw } : raw ?? {};
95
+ const src = safeUrl(media.url ?? props.url);
96
+ if (!src) return null;
97
+ const alt = media.alt ?? props.alt;
98
+ const width = media.width ?? props.width;
99
+ const height = media.height ?? props.height;
100
+ return /* @__PURE__ */ jsx2(
101
+ "img",
102
+ {
103
+ className,
104
+ src,
105
+ alt: typeof alt === "string" ? alt : "",
106
+ width: typeof width === "number" ? width : void 0,
107
+ height: typeof height === "number" ? height : void 0,
108
+ loading: "lazy"
109
+ }
110
+ );
111
+ }
112
+ });
113
+
114
+ // src/render/blocks/button.tsx
115
+ import { jsx as jsx3 } from "react/jsx-runtime";
116
+ var button = defineBlock({
117
+ type: "core/button",
118
+ version: 1,
119
+ label: "Button",
120
+ icon: "MousePointerClick",
121
+ category: "basic",
122
+ defaultProps: { text: "Click me", link: { href: "", target: "" } },
123
+ contentFields: [
124
+ { name: "text", type: "text", label: "Label", bindable: true },
125
+ { name: "link", type: "link", label: "Link" }
126
+ ],
127
+ styleControls: [
128
+ { control: "color", styleKey: "color", label: "Text color" },
129
+ { control: "color", styleKey: "backgroundColor", label: "Background" },
130
+ { control: "dimension", styleKey: "borderRadius", label: "Radius" },
131
+ { control: "align", styleKey: "textAlign", label: "Align" },
132
+ { control: "spacing", styleKey: "padding", label: "Padding" },
133
+ { control: "spacing", styleKey: "margin", label: "Margin" }
134
+ ],
135
+ render: ({ props, className }) => {
136
+ const link = props.link ?? {};
137
+ const href = safeUrl(link.href);
138
+ const text = String(props.text ?? "Button");
139
+ if (!href) {
140
+ return /* @__PURE__ */ jsx3("button", { className, type: "button", children: text });
141
+ }
142
+ const target = link.target || void 0;
143
+ return /* @__PURE__ */ jsx3(
144
+ "a",
145
+ {
146
+ className,
147
+ href,
148
+ target,
149
+ rel: target === "_blank" ? "noopener noreferrer" : void 0,
150
+ children: text
151
+ }
152
+ );
153
+ }
154
+ });
155
+
156
+ // src/render/blocks/video.tsx
157
+ import { jsx as jsx4 } from "react/jsx-runtime";
158
+ function embedUrl(provider, id) {
159
+ const safeId = encodeURIComponent(id);
160
+ if (provider === "youtube") return `https://www.youtube.com/embed/${safeId}`;
161
+ if (provider === "vimeo") return `https://player.vimeo.com/video/${safeId}`;
162
+ return null;
163
+ }
164
+ var video = defineBlock({
165
+ type: "core/video",
166
+ version: 1,
167
+ label: "Video",
168
+ icon: "Video",
169
+ category: "media",
170
+ defaultProps: { provider: "youtube", videoId: "" },
171
+ contentFields: [
172
+ {
173
+ name: "provider",
174
+ type: "select",
175
+ label: "Provider",
176
+ options: [
177
+ { value: "youtube", label: "YouTube" },
178
+ { value: "vimeo", label: "Vimeo" }
179
+ ]
180
+ },
181
+ {
182
+ name: "videoId",
183
+ type: "text",
184
+ label: "Video ID",
185
+ placeholder: "e.g. dQw4w9WgXcQ"
186
+ }
187
+ ],
188
+ styleControls: [
189
+ { control: "dimension", styleKey: "maxWidth", label: "Max width" },
190
+ { control: "spacing", styleKey: "margin", label: "Margin" }
191
+ ],
192
+ render: ({ props, className }) => {
193
+ const provider = String(props.provider ?? "");
194
+ const id = typeof props.videoId === "string" ? props.videoId.trim() : "";
195
+ const src = id ? embedUrl(provider, id) : null;
196
+ if (!src) return null;
197
+ return /* @__PURE__ */ jsx4("div", { className, children: /* @__PURE__ */ jsx4(
198
+ "iframe",
199
+ {
200
+ src,
201
+ title: "Embedded video",
202
+ allowFullScreen: true,
203
+ style: { border: 0, width: "100%", aspectRatio: "16 / 9" }
204
+ }
205
+ ) });
206
+ }
207
+ });
208
+
209
+ // src/render/blocks/container.tsx
210
+ import { createElement as createElement2 } from "react";
211
+ var TAGS = ["section", "div", "article", "header", "footer", "aside"];
212
+ var container = defineBlock({
213
+ type: "core/container",
214
+ version: 1,
215
+ label: "Container",
216
+ icon: "Square",
217
+ category: "layout",
218
+ isContainer: true,
219
+ slots: [{ name: "default" }],
220
+ defaultProps: { as: "section" },
221
+ contentFields: [
222
+ {
223
+ name: "as",
224
+ type: "select",
225
+ label: "HTML tag",
226
+ options: TAGS.map((t) => ({ value: t, label: t }))
227
+ }
228
+ ],
229
+ styleControls: [
230
+ { control: "color", styleKey: "backgroundColor", label: "Background" },
231
+ { control: "dimension", styleKey: "maxWidth", label: "Max width" },
232
+ { control: "spacing", styleKey: "padding", label: "Padding" },
233
+ { control: "spacing", styleKey: "margin", label: "Margin" },
234
+ { control: "dimension", styleKey: "borderRadius", label: "Radius" }
235
+ ],
236
+ render: ({ props, slots, className }) => {
237
+ const tag = TAGS.includes(String(props.as)) ? String(props.as) : "section";
238
+ return createElement2(tag, { className }, slots.default);
239
+ }
240
+ });
241
+
242
+ // src/render/blocks/grid.tsx
243
+ import { jsx as jsx5 } from "react/jsx-runtime";
244
+ var grid = defineBlock({
245
+ type: "core/grid",
246
+ version: 1,
247
+ label: "Grid",
248
+ icon: "LayoutGrid",
249
+ category: "layout",
250
+ isContainer: true,
251
+ slots: [{ name: "default" }],
252
+ defaultProps: { columns: 2, gap: "16px" },
253
+ contentFields: [
254
+ { name: "columns", type: "number", label: "Columns" },
255
+ { name: "gap", type: "text", label: "Gap", placeholder: "16px" }
256
+ ],
257
+ styleControls: [
258
+ { control: "color", styleKey: "backgroundColor", label: "Background" },
259
+ { control: "spacing", styleKey: "padding", label: "Padding" },
260
+ { control: "spacing", styleKey: "margin", label: "Margin" }
261
+ ],
262
+ render: ({ props, slots, className }) => {
263
+ const columns = typeof props.columns === "number" && props.columns > 0 ? Math.min(props.columns, 12) : 2;
264
+ const gap = typeof props.gap === "string" ? props.gap : "16px";
265
+ return /* @__PURE__ */ jsx5(
266
+ "div",
267
+ {
268
+ className,
269
+ style: {
270
+ display: "grid",
271
+ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
272
+ gap
273
+ },
274
+ children: slots.default
275
+ }
276
+ );
277
+ }
278
+ });
279
+
280
+ // src/render/query/grid.ts
281
+ function loopGridStyle(props) {
282
+ const raw = typeof props.columns === "number" ? props.columns : 1;
283
+ const columns = raw > 1 ? Math.min(Math.floor(raw), 12) : 0;
284
+ if (!columns) return void 0;
285
+ const gap = typeof props.gap === "string" ? props.gap : "16px";
286
+ return {
287
+ display: "grid",
288
+ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
289
+ gap
290
+ };
291
+ }
292
+
293
+ // src/render/blocks/queryLoop.tsx
294
+ import { jsx as jsx6 } from "react/jsx-runtime";
295
+ var queryLoop = defineBlock({
296
+ type: "core/query-loop",
297
+ version: 1,
298
+ label: "Query Loop",
299
+ icon: "Repeat",
300
+ category: "dynamic",
301
+ isContainer: true,
302
+ slots: [{ name: "default" }],
303
+ defaultProps: {
304
+ collection: "",
305
+ sort: "",
306
+ limit: 10,
307
+ columns: 1,
308
+ gap: "16px"
309
+ },
310
+ styleControls: [
311
+ { control: "spacing", styleKey: "padding", label: "Padding" },
312
+ { control: "spacing", styleKey: "margin", label: "Margin" }
313
+ ],
314
+ render: ({ props, slots, className }) => /* @__PURE__ */ jsx6(
315
+ "div",
316
+ {
317
+ className,
318
+ "data-nx-query-loop": "preview",
319
+ style: loopGridStyle(props),
320
+ children: slots.default
321
+ }
322
+ )
323
+ });
324
+
325
+ // src/render/query/QueryLoopView.tsx
326
+ import { jsx as jsx7 } from "react/jsx-runtime";
327
+ function QueryLoopView({
328
+ node,
329
+ registry,
330
+ dataProvider,
331
+ className,
332
+ result,
333
+ budget
334
+ }) {
335
+ const template = node.slots?.[DEFAULT_SLOT] ?? [];
336
+ if (result.skipped) {
337
+ return /* @__PURE__ */ jsx7("div", { className, "data-nx-query-loop": "config", children: "Configure a collection to load entries." });
338
+ }
339
+ if (result.error) {
340
+ return /* @__PURE__ */ jsx7("div", { className, "data-nx-query-loop": "error", children: "Could not load entries." });
341
+ }
342
+ if (result.items.length === 0) {
343
+ return /* @__PURE__ */ jsx7("div", { className, "data-nx-query-loop": "empty", children: "No entries found." });
344
+ }
345
+ return /* @__PURE__ */ jsx7(
346
+ "div",
347
+ {
348
+ className,
349
+ "data-nx-query-loop": "list",
350
+ style: loopGridStyle(node.props),
351
+ children: result.items.map((item, i) => /* @__PURE__ */ jsx7(
352
+ "div",
353
+ {
354
+ "data-nx-loop-item": i,
355
+ children: template.map((child) => /* @__PURE__ */ jsx7(
356
+ RenderNode,
357
+ {
358
+ node: child,
359
+ registry,
360
+ dataProvider,
361
+ item,
362
+ budget
363
+ },
364
+ child.id
365
+ ))
366
+ },
367
+ typeof item.id === "string" ? item.id : i
368
+ ))
369
+ }
370
+ );
371
+ }
372
+
373
+ // src/render/query/runQuery.ts
374
+ async function runQuery(dataProvider, config, budget) {
375
+ if (!dataProvider || !config.collection) return { items: [], skipped: true };
376
+ if (budget.n <= 0) return { items: [], skipped: true };
377
+ budget.n -= 1;
378
+ try {
379
+ const { items } = await dataProvider.find({
380
+ collection: config.collection,
381
+ where: config.where,
382
+ sort: config.sort,
383
+ limit: typeof config.limit === "number" ? config.limit : void 0,
384
+ populate: config.populate
385
+ });
386
+ return { items: Array.isArray(items) ? items : [] };
387
+ } catch (err) {
388
+ return {
389
+ items: [],
390
+ error: err instanceof Error ? err.message : String(err)
391
+ };
392
+ }
393
+ }
394
+
395
+ // src/render/query/QueryLoop.tsx
396
+ import { jsx as jsx8 } from "react/jsx-runtime";
397
+ async function QueryLoop({
398
+ node,
399
+ registry,
400
+ dataProvider,
401
+ className,
402
+ budget
403
+ }) {
404
+ const config = node.props;
405
+ const result = await runQuery(dataProvider, config, budget);
406
+ return /* @__PURE__ */ jsx8(
407
+ QueryLoopView,
408
+ {
409
+ node,
410
+ registry,
411
+ dataProvider,
412
+ className,
413
+ result,
414
+ budget
415
+ }
416
+ );
417
+ }
418
+
419
+ // src/render/query/types.ts
420
+ var QUERY_LOOP_TYPE = "core/query-loop";
421
+ var DEFAULT_QUERY_BUDGET = 20;
422
+
423
+ // src/render/RenderNode.tsx
424
+ import { jsx as jsx9 } from "react/jsx-runtime";
425
+ function RenderNode({
426
+ node,
427
+ registry,
428
+ dataProvider,
429
+ item,
430
+ budget
431
+ }) {
432
+ const def = registry.get(node.type);
433
+ const className = [nodeClass(node.id), node.customClass].filter(Boolean).join(" ");
434
+ if (!def) {
435
+ return /* @__PURE__ */ jsx9("div", { "data-nx-unknown": node.type, className });
436
+ }
437
+ if (node.type === QUERY_LOOP_TYPE) {
438
+ return /* @__PURE__ */ jsx9(BlockErrorBoundary, { children: /* @__PURE__ */ jsx9(
439
+ QueryLoop,
440
+ {
441
+ node,
442
+ registry,
443
+ dataProvider,
444
+ className,
445
+ budget: budget ?? { n: 0 }
446
+ }
447
+ ) });
448
+ }
449
+ const slots = {};
450
+ if (node.slots) {
451
+ for (const [name, children] of Object.entries(node.slots)) {
452
+ slots[name] = children.map((child) => /* @__PURE__ */ jsx9(
453
+ RenderNode,
454
+ {
455
+ node: child,
456
+ registry,
457
+ dataProvider,
458
+ item,
459
+ budget
460
+ },
461
+ child.id
462
+ ));
463
+ }
464
+ }
465
+ const props = item ? resolveBindings(node, item) : node.props;
466
+ return /* @__PURE__ */ jsx9(BlockErrorBoundary, { children: def.render({ props, node, slots, className }) });
467
+ }
468
+
469
+ export {
470
+ paragraph,
471
+ heading,
472
+ image,
473
+ button,
474
+ video,
475
+ container,
476
+ grid,
477
+ loopGridStyle,
478
+ queryLoop,
479
+ QUERY_LOOP_TYPE,
480
+ DEFAULT_QUERY_BUDGET,
481
+ RenderNode
482
+ };
483
+ //# sourceMappingURL=chunk-R7YHOSL2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/render/blocks/paragraph.tsx","../src/render/blocks/heading.tsx","../src/render/blocks/util.ts","../src/render/blocks/image.tsx","../src/render/blocks/button.tsx","../src/render/blocks/video.tsx","../src/render/blocks/container.tsx","../src/render/blocks/grid.tsx","../src/render/query/grid.ts","../src/render/blocks/queryLoop.tsx","../src/render/query/QueryLoopView.tsx","../src/render/query/runQuery.ts","../src/render/query/QueryLoop.tsx","../src/render/query/types.ts","../src/render/RenderNode.tsx"],"sourcesContent":["import { defineBlock } from \"../../core/registry\";\n\nexport const paragraph = defineBlock({\n type: \"core/paragraph\",\n version: 1,\n label: \"Paragraph\",\n icon: \"Type\",\n category: \"basic\",\n defaultProps: { text: \"New paragraph\" },\n contentFields: [\n { name: \"text\", type: \"textarea\", label: \"Text\", bindable: true },\n ],\n styleControls: [\n { control: \"color\", styleKey: \"color\", label: \"Text color\" },\n { control: \"dimension\", styleKey: \"fontSize\", label: \"Font size\" },\n { control: \"align\", styleKey: \"textAlign\", label: \"Align\" },\n { control: \"spacing\", styleKey: \"padding\", label: \"Padding\" },\n { control: \"spacing\", styleKey: \"margin\", label: \"Margin\" },\n ],\n render: ({ props, className }) => (\n <p className={className}>{String(props.text ?? \"\")}</p>\n ),\n});\n","import { createElement } from \"react\";\n\nimport { defineBlock } from \"../../core/registry\";\n\nconst LEVELS = [\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\"];\n\nexport const heading = defineBlock({\n type: \"core/heading\",\n version: 1,\n label: \"Heading\",\n icon: \"Heading\",\n category: \"basic\",\n defaultProps: { text: \"New heading\", level: \"h2\" },\n contentFields: [\n { name: \"text\", type: \"text\", label: \"Text\", bindable: true },\n {\n name: \"level\",\n type: \"select\",\n label: \"Level\",\n options: LEVELS.map(l => ({ value: l, label: l.toUpperCase() })),\n },\n ],\n styleControls: [\n { control: \"color\", styleKey: \"color\", label: \"Text color\" },\n { control: \"dimension\", styleKey: \"fontSize\", label: \"Font size\" },\n { control: \"align\", styleKey: \"textAlign\", label: \"Align\" },\n { control: \"spacing\", styleKey: \"padding\", label: \"Padding\" },\n { control: \"spacing\", styleKey: \"margin\", label: \"Margin\" },\n ],\n render: ({ props, className }) => {\n const level = LEVELS.includes(String(props.level))\n ? String(props.level)\n : \"h2\";\n return createElement(level, { className }, String(props.text ?? \"\"));\n },\n});\n","/**\n * Reject dangerous URL schemes for image/link/video srcs. Allows http(s)/relative/\n * mailto/tel. Browsers ignore ASCII control chars + whitespace when parsing a scheme\n * (so `java\\tscript:` still executes), so we strip those before testing — matching the\n * raw string alone is an XSS bypass.\n */\nexport function safeUrl(url: unknown): string | undefined {\n if (typeof url !== \"string\") return undefined;\n const trimmed = url.trim();\n if (!trimmed) return undefined;\n // Strip control chars (U+0000–U+0020, U+007F) + whitespace, then test the scheme.\n // eslint-disable-next-line no-control-regex\n const scheme = trimmed.replace(/[\\u0000-\\u0020\\u007f]+/g, \"\").toLowerCase();\n if (/^(javascript|vbscript|data):/.test(scheme)) return undefined;\n return trimmed;\n}\n","import { defineBlock } from \"../../core/registry\";\n\nimport { safeUrl } from \"./util\";\n\ninterface MediaValue {\n mediaId?: string;\n url?: string;\n alt?: string;\n width?: number;\n height?: number;\n}\n\ninterface ImageProps extends MediaValue {\n /** Editor-populated media object (from the media control). */\n media?: MediaValue;\n}\n\nexport const image = defineBlock<ImageProps>({\n type: \"core/image\",\n version: 1,\n label: \"Image\",\n icon: \"Image\",\n category: \"media\",\n defaultProps: { url: \"\", alt: \"\" },\n contentFields: [\n { name: \"media\", type: \"media\", label: \"Image\", bindable: true },\n ],\n styleControls: [\n { control: \"dimension\", styleKey: \"width\", label: \"Width\" },\n { control: \"dimension\", styleKey: \"borderRadius\", label: \"Radius\" },\n { control: \"spacing\", styleKey: \"margin\", label: \"Margin\" },\n ],\n render: ({ props, className }) => {\n // `media` may be the editor's media object, or — when bound to a Query Loop item's\n // field — a `{ url }` object or a plain URL string; normalize all three.\n const raw: unknown = props.media;\n const media: MediaValue =\n typeof raw === \"string\" ? { url: raw } : ((raw as MediaValue) ?? {});\n const src = safeUrl(media.url ?? props.url);\n if (!src) return null;\n const alt = media.alt ?? props.alt;\n const width = media.width ?? props.width;\n const height = media.height ?? props.height;\n return (\n <img\n className={className}\n src={src}\n alt={typeof alt === \"string\" ? alt : \"\"}\n width={typeof width === \"number\" ? width : undefined}\n height={typeof height === \"number\" ? height : undefined}\n loading=\"lazy\"\n />\n );\n },\n});\n","import { defineBlock } from \"../../core/registry\";\n\nimport { safeUrl } from \"./util\";\n\nexport const button = defineBlock({\n type: \"core/button\",\n version: 1,\n label: \"Button\",\n icon: \"MousePointerClick\",\n category: \"basic\",\n defaultProps: { text: \"Click me\", link: { href: \"\", target: \"\" } },\n contentFields: [\n { name: \"text\", type: \"text\", label: \"Label\", bindable: true },\n { name: \"link\", type: \"link\", label: \"Link\" },\n ],\n styleControls: [\n { control: \"color\", styleKey: \"color\", label: \"Text color\" },\n { control: \"color\", styleKey: \"backgroundColor\", label: \"Background\" },\n { control: \"dimension\", styleKey: \"borderRadius\", label: \"Radius\" },\n { control: \"align\", styleKey: \"textAlign\", label: \"Align\" },\n { control: \"spacing\", styleKey: \"padding\", label: \"Padding\" },\n { control: \"spacing\", styleKey: \"margin\", label: \"Margin\" },\n ],\n render: ({ props, className }) => {\n const link = (props.link ?? {}) as { href?: string; target?: string };\n const href = safeUrl(link.href);\n const text = String(props.text ?? \"Button\");\n if (!href) {\n return (\n <button className={className} type=\"button\">\n {text}\n </button>\n );\n }\n const target = link.target || undefined;\n return (\n <a\n className={className}\n href={href}\n target={target}\n rel={target === \"_blank\" ? \"noopener noreferrer\" : undefined}\n >\n {text}\n </a>\n );\n },\n});\n","import { defineBlock } from \"../../core/registry\";\n\nfunction embedUrl(provider: string, id: string): string | null {\n const safeId = encodeURIComponent(id);\n if (provider === \"youtube\") return `https://www.youtube.com/embed/${safeId}`;\n if (provider === \"vimeo\") return `https://player.vimeo.com/video/${safeId}`;\n return null;\n}\n\nexport const video = defineBlock({\n type: \"core/video\",\n version: 1,\n label: \"Video\",\n icon: \"Video\",\n category: \"media\",\n defaultProps: { provider: \"youtube\", videoId: \"\" },\n contentFields: [\n {\n name: \"provider\",\n type: \"select\",\n label: \"Provider\",\n options: [\n { value: \"youtube\", label: \"YouTube\" },\n { value: \"vimeo\", label: \"Vimeo\" },\n ],\n },\n {\n name: \"videoId\",\n type: \"text\",\n label: \"Video ID\",\n placeholder: \"e.g. dQw4w9WgXcQ\",\n },\n ],\n styleControls: [\n { control: \"dimension\", styleKey: \"maxWidth\", label: \"Max width\" },\n { control: \"spacing\", styleKey: \"margin\", label: \"Margin\" },\n ],\n render: ({ props, className }) => {\n const provider = String(props.provider ?? \"\");\n const id = typeof props.videoId === \"string\" ? props.videoId.trim() : \"\";\n const src = id ? embedUrl(provider, id) : null;\n if (!src) return null;\n return (\n <div className={className}>\n <iframe\n src={src}\n title=\"Embedded video\"\n allowFullScreen\n style={{ border: 0, width: \"100%\", aspectRatio: \"16 / 9\" }}\n />\n </div>\n );\n },\n});\n","import { createElement } from \"react\";\n\nimport { defineBlock } from \"../../core/registry\";\n\nconst TAGS = [\"section\", \"div\", \"article\", \"header\", \"footer\", \"aside\"];\n\nexport const container = defineBlock({\n type: \"core/container\",\n version: 1,\n label: \"Container\",\n icon: \"Square\",\n category: \"layout\",\n isContainer: true,\n slots: [{ name: \"default\" }],\n defaultProps: { as: \"section\" },\n contentFields: [\n {\n name: \"as\",\n type: \"select\",\n label: \"HTML tag\",\n options: TAGS.map(t => ({ value: t, label: t })),\n },\n ],\n styleControls: [\n { control: \"color\", styleKey: \"backgroundColor\", label: \"Background\" },\n { control: \"dimension\", styleKey: \"maxWidth\", label: \"Max width\" },\n { control: \"spacing\", styleKey: \"padding\", label: \"Padding\" },\n { control: \"spacing\", styleKey: \"margin\", label: \"Margin\" },\n { control: \"dimension\", styleKey: \"borderRadius\", label: \"Radius\" },\n ],\n render: ({ props, slots, className }) => {\n const tag = TAGS.includes(String(props.as)) ? String(props.as) : \"section\";\n return createElement(tag, { className }, slots.default);\n },\n});\n","import { defineBlock } from \"../../core/registry\";\n\n// Grid layout: the column count + gap are driven by the `columns`/`gap` content fields and\n// applied as an inline grid style (safe: CSS values in a style object are never executed).\n// Colours/spacing/etc. still come from the style compiler via `className`.\ninterface GridProps {\n columns?: number;\n gap?: string;\n}\n\nexport const grid = defineBlock<GridProps>({\n type: \"core/grid\",\n version: 1,\n label: \"Grid\",\n icon: \"LayoutGrid\",\n category: \"layout\",\n isContainer: true,\n slots: [{ name: \"default\" }],\n defaultProps: { columns: 2, gap: \"16px\" },\n contentFields: [\n { name: \"columns\", type: \"number\", label: \"Columns\" },\n { name: \"gap\", type: \"text\", label: \"Gap\", placeholder: \"16px\" },\n ],\n styleControls: [\n { control: \"color\", styleKey: \"backgroundColor\", label: \"Background\" },\n { control: \"spacing\", styleKey: \"padding\", label: \"Padding\" },\n { control: \"spacing\", styleKey: \"margin\", label: \"Margin\" },\n ],\n render: ({ props, slots, className }) => {\n const columns =\n typeof props.columns === \"number\" && props.columns > 0\n ? Math.min(props.columns, 12)\n : 2;\n const gap = typeof props.gap === \"string\" ? props.gap : \"16px\";\n return (\n <div\n className={className}\n style={{\n display: \"grid\",\n gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,\n gap,\n }}\n >\n {slots.default}\n </div>\n );\n },\n});\n","/**\n * Query Loop layout: turn the `columns`/`gap` props into a grid style so the loop reads as\n * a grid (Elementor's Loop Grid). `columns <= 1` returns undefined (plain stacked list, no\n * grid box). Shared by the production view, the design-time preview, and the canvas preview.\n */\nimport type { CSSProperties } from \"react\";\n\nexport function loopGridStyle(\n props: Record<string, unknown>\n): CSSProperties | undefined {\n const raw = typeof props.columns === \"number\" ? props.columns : 1;\n const columns = raw > 1 ? Math.min(Math.floor(raw), 12) : 0;\n if (!columns) return undefined;\n const gap = typeof props.gap === \"string\" ? props.gap : \"16px\";\n return {\n display: \"grid\",\n gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,\n gap,\n };\n}\n","import { defineBlock } from \"../../core/registry\";\nimport { loopGridStyle } from \"../query/grid\";\n\n/**\n * Query Loop block (spec §10/§5). At production render, RenderNode intercepts this type and\n * renders it data-driven via QueryLoop. The editor uses a dedicated settings panel + a live\n * sample-data preview (see admin). This `render` is the plain design-time fallback: the\n * template laid out in the configured column grid.\n *\n * Config lives in `props` (collection / sort / limit / columns / gap / where) and is driven\n * by the admin's QueryLoopSettings panel rather than generic content fields.\n */\nexport const queryLoop = defineBlock({\n type: \"core/query-loop\",\n version: 1,\n label: \"Query Loop\",\n icon: \"Repeat\",\n category: \"dynamic\",\n isContainer: true,\n slots: [{ name: \"default\" }],\n defaultProps: {\n collection: \"\",\n sort: \"\",\n limit: 10,\n columns: 1,\n gap: \"16px\",\n },\n styleControls: [\n { control: \"spacing\", styleKey: \"padding\", label: \"Padding\" },\n { control: \"spacing\", styleKey: \"margin\", label: \"Margin\" },\n ],\n render: ({ props, slots, className }) => (\n <div\n className={className}\n data-nx-query-loop=\"preview\"\n style={loopGridStyle(props)}\n >\n {slots.default}\n </div>\n ),\n});\n","/**\n * Synchronous view for the Query Loop (spec §10). Given an already-resolved QueryResult,\n * it renders the config / error / empty state, or expands the template slot once per item\n * — threading each `item` into RenderNode so bound props resolve at any depth. Sync so it\n * is testable via renderToStaticMarkup; the async fetch lives in QueryLoop.\n */\nimport type { ReactNode } from \"react\";\n\nimport type { BlockRegistry } from \"../../core/registry\";\nimport { DEFAULT_SLOT, type BlockNode } from \"../../core/types\";\nimport type { DataProvider } from \"../dataProvider\";\nimport { RenderNode } from \"../RenderNode\";\n\nimport { loopGridStyle } from \"./grid\";\nimport type { QueryBudget } from \"./runQuery\";\nimport type { QueryResult } from \"./types\";\n\nexport interface QueryLoopViewProps {\n node: BlockNode;\n registry: BlockRegistry;\n dataProvider?: DataProvider;\n className: string;\n result: QueryResult;\n budget: QueryBudget;\n}\n\nexport function QueryLoopView({\n node,\n registry,\n dataProvider,\n className,\n result,\n budget,\n}: QueryLoopViewProps): ReactNode {\n const template = node.slots?.[DEFAULT_SLOT] ?? [];\n\n if (result.skipped) {\n return (\n <div className={className} data-nx-query-loop=\"config\">\n Configure a collection to load entries.\n </div>\n );\n }\n if (result.error) {\n return (\n <div className={className} data-nx-query-loop=\"error\">\n Could not load entries.\n </div>\n );\n }\n if (result.items.length === 0) {\n return (\n <div className={className} data-nx-query-loop=\"empty\">\n No entries found.\n </div>\n );\n }\n\n return (\n <div\n className={className}\n data-nx-query-loop=\"list\"\n style={loopGridStyle(node.props)}\n >\n {result.items.map((item, i) => (\n <div\n key={typeof item.id === \"string\" ? item.id : i}\n data-nx-loop-item={i}\n >\n {template.map(child => (\n <RenderNode\n key={child.id}\n node={child}\n registry={registry}\n dataProvider={dataProvider}\n item={item}\n budget={budget}\n />\n ))}\n </div>\n ))}\n </div>\n );\n}\n","/**\n * Async fetch orchestration for the Query Loop (spec §10). Isolated from React so it is\n * unit-testable. Enforces the per-render query budget, skips when unconfigured, and\n * converts provider failures into an error state instead of throwing.\n */\nimport type { DataProvider } from \"../dataProvider\";\n\nimport type { QueryLoopConfig, QueryResult } from \"./types\";\n\nexport interface QueryBudget {\n n: number;\n}\n\nexport async function runQuery(\n dataProvider: DataProvider | undefined,\n config: QueryLoopConfig,\n budget: QueryBudget\n): Promise<QueryResult> {\n if (!dataProvider || !config.collection) return { items: [], skipped: true };\n if (budget.n <= 0) return { items: [], skipped: true };\n budget.n -= 1;\n try {\n const { items } = await dataProvider.find({\n collection: config.collection,\n where: config.where,\n sort: config.sort,\n limit: typeof config.limit === \"number\" ? config.limit : undefined,\n populate: config.populate,\n });\n return { items: Array.isArray(items) ? items : [] };\n } catch (err) {\n return {\n items: [],\n error: err instanceof Error ? err.message : String(err),\n };\n }\n}\n","/**\n * Async server component for the Query Loop (spec §10). Fetches entries via the injected\n * dataProvider (bounded by the shared query budget), then delegates to the synchronous\n * QueryLoopView. Rendered only on the server (RenderNode intercepts `core/query-loop`);\n * never imports `getNextly`.\n */\nimport type { ReactNode } from \"react\";\n\nimport type { BlockRegistry } from \"../../core/registry\";\nimport type { BlockNode } from \"../../core/types\";\nimport type { DataProvider } from \"../dataProvider\";\n\nimport { QueryLoopView } from \"./QueryLoopView\";\nimport { runQuery, type QueryBudget } from \"./runQuery\";\nimport type { QueryLoopConfig } from \"./types\";\n\nexport interface QueryLoopProps {\n node: BlockNode;\n registry: BlockRegistry;\n dataProvider?: DataProvider;\n className: string;\n budget: QueryBudget;\n}\n\nexport async function QueryLoop({\n node,\n registry,\n dataProvider,\n className,\n budget,\n}: QueryLoopProps): Promise<ReactNode> {\n const config = node.props as QueryLoopConfig;\n const result = await runQuery(dataProvider, config, budget);\n return (\n <QueryLoopView\n node={node}\n registry={registry}\n dataProvider={dataProvider}\n className={className}\n result={result}\n budget={budget}\n />\n );\n}\n","/**\n * Executable Query Loop contracts (spec §10). Kept React-free so the fetch orchestration\n * and config stay unit-testable and import-safe.\n */\nexport const QUERY_LOOP_TYPE = \"core/query-loop\";\n\n/** Max collection fetches per page render — bounds nested loops (with MAX_DEPTH). */\nexport const DEFAULT_QUERY_BUDGET = 20;\n\nexport interface QueryLoopConfig {\n collection?: string;\n sort?: string;\n limit?: number;\n /** Reserved: passed through to the provider's `where`. */\n where?: unknown;\n /** Reserved: relation/media population depth. */\n populate?: unknown;\n}\n\nexport interface QueryResult {\n items: Record<string, unknown>[];\n error?: string;\n /** True when the query was skipped (no provider / no collection / budget spent). */\n skipped?: boolean;\n}\n","/**\n * Recursively renders one block node to React (spec §10). Server-safe: no browser\n * globals, no `getNextly`. The scoped class is applied to the block's OWN root element\n * (the block spreads `className`) so there is no mandatory wrapper `<div>` — grid/flex\n * stay correct. Unknown block types render a safe fallback; each node is isolated by an\n * error boundary so one broken block never takes down the page.\n *\n * Query Loop (spec §10): the current loop `item` is threaded through recursion (NOT React\n * context — Server Components can't consume context), so a bound prop on any nested block\n * at any depth resolves via `resolveBindings`. `core/query-loop` is intercepted and\n * rendered data-driven via `QueryLoop`.\n */\nimport type { ReactNode } from \"react\";\n\nimport { resolveBindings } from \"../core/bindings\";\nimport type { BlockRegistry } from \"../core/registry\";\nimport { nodeClass } from \"../core/style-compiler\";\nimport type { BlockNode } from \"../core/types\";\n\nimport type { DataProvider } from \"./dataProvider\";\nimport { BlockErrorBoundary } from \"./ErrorBoundary\";\nimport { QueryLoop } from \"./query/QueryLoop\";\nimport type { QueryBudget } from \"./query/runQuery\";\nimport { QUERY_LOOP_TYPE } from \"./query/types\";\n\nexport interface RenderNodeProps {\n node: BlockNode;\n registry: BlockRegistry;\n dataProvider?: DataProvider;\n /** Current Query Loop item — threaded to resolve bindings at any depth. */\n item?: Record<string, unknown>;\n /** Remaining query budget shared across nested loops on this page render. */\n budget?: QueryBudget;\n}\n\nexport function RenderNode({\n node,\n registry,\n dataProvider,\n item,\n budget,\n}: RenderNodeProps): ReactNode {\n const def = registry.get(node.type);\n const className = [nodeClass(node.id), node.customClass]\n .filter(Boolean)\n .join(\" \");\n\n if (!def) {\n // Preserve, don't crash: a placeholder that keeps the page rendering.\n return <div data-nx-unknown={node.type} className={className} />;\n }\n\n // Executable Query Loop: intercept and render data-driven (spec §10).\n if (node.type === QUERY_LOOP_TYPE) {\n return (\n <BlockErrorBoundary>\n <QueryLoop\n node={node}\n registry={registry}\n dataProvider={dataProvider}\n className={className}\n budget={budget ?? { n: 0 }}\n />\n </BlockErrorBoundary>\n );\n }\n\n const slots: Record<string, ReactNode> = {};\n if (node.slots) {\n for (const [name, children] of Object.entries(node.slots)) {\n slots[name] = children.map(child => (\n <RenderNode\n key={child.id}\n node={child}\n registry={registry}\n dataProvider={dataProvider}\n item={item}\n budget={budget}\n />\n ));\n }\n }\n\n const props = item ? resolveBindings(node, item) : node.props;\n\n return (\n <BlockErrorBoundary>\n {def.render({ props, node, slots, className })}\n </BlockErrorBoundary>\n );\n}\n"],"mappings":"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","names":["jsx","jsx","jsx","createElement","createElement","jsx","jsx","jsx","jsx","jsx"]}