@arkcit/engine 0.3.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.
Files changed (42) hide show
  1. package/README.md +68 -0
  2. package/dist/UIEngine.d.ts +6 -0
  3. package/dist/UIEngine.js +3235 -0
  4. package/dist/bindings.d.ts +8 -0
  5. package/dist/bindings.js +146 -0
  6. package/dist/components/index.d.ts +17 -0
  7. package/dist/components/index.js +143 -0
  8. package/dist/core/index.d.ts +4 -0
  9. package/dist/core/index.js +9 -0
  10. package/dist/form/engineFormValidation.d.ts +2 -0
  11. package/dist/form/engineFormValidation.js +241 -0
  12. package/dist/form.d.ts +67 -0
  13. package/dist/form.js +241 -0
  14. package/dist/index.d.ts +15 -0
  15. package/dist/index.js +3336 -0
  16. package/dist/layout.d.ts +6 -0
  17. package/dist/layout.js +82 -0
  18. package/dist/preview/index.d.ts +63 -0
  19. package/dist/preview/index.js +1514 -0
  20. package/dist/react-web/index.d.ts +8 -0
  21. package/dist/react-web/index.js +3246 -0
  22. package/dist/registry.d.ts +2 -0
  23. package/dist/registry.js +0 -0
  24. package/dist/render-layer/index.d.ts +1 -0
  25. package/dist/render-layer/index.js +13 -0
  26. package/dist/renderStudioForm-CPQEzvT7.d.ts +75 -0
  27. package/dist/renderers/index.d.ts +8 -0
  28. package/dist/renderers/index.js +1570 -0
  29. package/dist/runtime/index.d.ts +1 -0
  30. package/dist/runtime/index.js +0 -0
  31. package/dist/schema/index.d.ts +1 -0
  32. package/dist/schema/index.js +0 -0
  33. package/dist/studio-bridge/index.d.ts +501 -0
  34. package/dist/studio-bridge/index.js +2840 -0
  35. package/dist/studioProps.d.ts +8 -0
  36. package/dist/studioProps.js +97 -0
  37. package/dist/types-9TZ2lQDP.d.ts +60 -0
  38. package/dist/types-CyAE6ZLH.d.ts +19 -0
  39. package/dist/types.d.ts +16 -0
  40. package/dist/types.js +0 -0
  41. package/dist/wizardEditingHandlers-D50tR-6n.d.ts +163 -0
  42. package/package.json +160 -0
package/dist/index.js ADDED
@@ -0,0 +1,3336 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+
21
+ // src/react-web/engine/EngineWarningFallback.tsx
22
+ import { EngineWarningFallback } from "@arkcit/engine-react";
23
+
24
+ // src/react-web/engine/NodeErrorBoundary.tsx
25
+ import { NodeErrorBoundary } from "@arkcit/engine-react";
26
+
27
+ // src/react-web/engine/ReactWebEngineRoot.tsx
28
+ import { ReactWebEngineRoot as ReactWebEngineRootImpl } from "@arkcit/engine-react";
29
+
30
+ // src/studio-bridge/inline/InlineTextEditor.tsx
31
+ import { jsx } from "react/jsx-runtime";
32
+ var InlineTextEditor = ({
33
+ editing,
34
+ onChange,
35
+ onCancel,
36
+ onCommit
37
+ }) => editing.multiline ? /* @__PURE__ */ jsx(
38
+ "textarea",
39
+ {
40
+ className: "absolute z-[260] h-full w-full resize-none rounded-md border border-primary/70 bg-background/95 px-2 py-1 text-sm text-foreground outline-none ring-0 cursor-text shadow-lg",
41
+ style: editing.editorStyle,
42
+ value: editing.value,
43
+ autoFocus: true,
44
+ "aria-label": "Inline text editor",
45
+ onChange: (event) => onChange(event.target.value),
46
+ onBlur: onCommit,
47
+ onKeyDown: (event) => {
48
+ if (event.key === "Escape") {
49
+ event.preventDefault();
50
+ onCancel();
51
+ return;
52
+ }
53
+ if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
54
+ event.preventDefault();
55
+ onCommit();
56
+ }
57
+ }
58
+ }
59
+ ) : /* @__PURE__ */ jsx(
60
+ "input",
61
+ {
62
+ className: "absolute z-[260] h-full w-full rounded-md border border-primary/70 bg-background/95 px-2 text-sm text-foreground outline-none ring-0 cursor-text shadow-lg",
63
+ style: editing.editorStyle,
64
+ value: editing.value,
65
+ autoFocus: true,
66
+ "aria-label": "Inline text editor",
67
+ onChange: (event) => onChange(event.target.value),
68
+ onBlur: onCommit,
69
+ onKeyDown: (event) => {
70
+ if (event.key === "Escape") {
71
+ event.preventDefault();
72
+ onCancel();
73
+ return;
74
+ }
75
+ if (event.key === "Enter") {
76
+ event.preventDefault();
77
+ onCommit();
78
+ }
79
+ }
80
+ }
81
+ );
82
+
83
+ // src/studio-bridge/nodes/StudioNodeWrapper.tsx
84
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
85
+ var StudioNodeWrapper = ({
86
+ nodeId,
87
+ wrapperClassName = "",
88
+ cursorClassName = "",
89
+ isSelected,
90
+ allowResizeHandle = true,
91
+ style,
92
+ onClick,
93
+ onDoubleClick,
94
+ onTouchStart,
95
+ onTouchMove,
96
+ onTouchEnd,
97
+ showResizeHandle,
98
+ onResizeMouseDown,
99
+ isInlineEditing,
100
+ preserveContentWhileInlineEditing = false,
101
+ children,
102
+ inlineEditor
103
+ }) => /* @__PURE__ */ jsxs(
104
+ "div",
105
+ {
106
+ "data-node-id": nodeId,
107
+ className: [
108
+ "relative block w-fit min-w-0 max-w-full rounded-md border border-transparent transition-colors",
109
+ wrapperClassName,
110
+ cursorClassName,
111
+ isSelected ? "border-dashed border-primary/60 bg-primary/5" : ""
112
+ ].filter(Boolean).join(" "),
113
+ style: __spreadValues({
114
+ position: "relative"
115
+ }, style != null ? style : {}),
116
+ onTouchStart,
117
+ onTouchMove,
118
+ onTouchEnd,
119
+ onClick,
120
+ onDoubleClick,
121
+ children: [
122
+ allowResizeHandle && showResizeHandle && onResizeMouseDown ? /* @__PURE__ */ jsx2(
123
+ "button",
124
+ {
125
+ type: "button",
126
+ className: "absolute -right-2 -top-2 z-20 inline-flex h-7 w-7 cursor-nwse-resize items-center justify-center rounded-md border border-primary bg-primary text-xs text-primary-foreground shadow-sm transition-colors hover:bg-primary-hover hover:border-primary-hover",
127
+ "aria-label": "Resize node",
128
+ onMouseDown: onResizeMouseDown,
129
+ children: "\u2922"
130
+ }
131
+ ) : null,
132
+ /* @__PURE__ */ jsx2(
133
+ "div",
134
+ {
135
+ className: isInlineEditing && !preserveContentWhileInlineEditing ? "pointer-events-none opacity-0" : void 0,
136
+ children
137
+ }
138
+ ),
139
+ isInlineEditing ? inlineEditor : null
140
+ ]
141
+ },
142
+ nodeId
143
+ );
144
+
145
+ // src/studio-bridge/inline/forceFullWidth.ts
146
+ var shouldForceStudioNodeFullWidth = ({
147
+ widthPct,
148
+ nodeType,
149
+ isStudioRendererContext,
150
+ colSpan
151
+ }) => widthPct === null && (nodeType === "Container" || nodeType === "Grid" || colSpan !== void 0 || isStudioRendererContext && (nodeType === "Form" || nodeType === "FormWizard"));
152
+
153
+ // src/studio-bridge/inline/inlineText.ts
154
+ var getEditableTextValue = ({
155
+ node,
156
+ nodeProps,
157
+ propName,
158
+ runtime,
159
+ resolveTranslationValue
160
+ }) => {
161
+ var _a;
162
+ let value = nodeProps[propName];
163
+ if (node.type === "FormField" && (propName === "label" || propName === "name")) {
164
+ const fieldObject = nodeProps.field && typeof nodeProps.field === "object" && !Array.isArray(nodeProps.field) ? nodeProps.field : null;
165
+ if (value === void 0 && fieldObject) {
166
+ value = fieldObject[propName];
167
+ }
168
+ }
169
+ if (typeof value === "string") return { value, mode: "primitive" };
170
+ if (typeof value === "number" || typeof value === "boolean") {
171
+ return { value: String(value), mode: "primitive" };
172
+ }
173
+ if (value && typeof value === "object") {
174
+ if ("$t" in value && typeof value.$t === "string") {
175
+ const translationValue = value;
176
+ const resolvedValue = resolveTranslationValue(translationValue, runtime);
177
+ return {
178
+ value: typeof resolvedValue === "string" ? resolvedValue : (_a = translationValue.defaultValue) != null ? _a : translationValue.$t,
179
+ mode: "translation"
180
+ };
181
+ }
182
+ try {
183
+ return {
184
+ value: JSON.stringify(value, null, 2),
185
+ mode: "json"
186
+ };
187
+ } catch (e) {
188
+ return null;
189
+ }
190
+ }
191
+ return null;
192
+ };
193
+ var selectCandidateInlineProp = ({
194
+ node,
195
+ isWizardStepNode,
196
+ orderedEditableTextProps,
197
+ getTextValue
198
+ }) => {
199
+ var _a, _b;
200
+ if (node.type === "FormField") {
201
+ if (getTextValue("label")) return "label";
202
+ if (getTextValue("name")) return "name";
203
+ }
204
+ if (node.type === "Button") {
205
+ if (getTextValue("children")) return "children";
206
+ }
207
+ if (node.type === "Form") {
208
+ if (getTextValue("title")) return "title";
209
+ }
210
+ if (isWizardStepNode) {
211
+ if (getTextValue("title")) return "title";
212
+ if (getTextValue("description")) return "description";
213
+ }
214
+ const blockedTypes = /* @__PURE__ */ new Set(["Form", "FormWizard", "Accordion", "ExpandablePanel"]);
215
+ if (node.type === "Cover") {
216
+ const coverTextProps = ["eyebrow", "title", "subtitle", "description", "children"];
217
+ return (_a = coverTextProps.find((propName) => getTextValue(propName) !== null)) != null ? _a : null;
218
+ }
219
+ const sourceProps = blockedTypes.has(node.type) ? [] : orderedEditableTextProps;
220
+ return (_b = sourceProps.find((propName) => getTextValue(propName) !== null)) != null ? _b : null;
221
+ };
222
+ var selectEffectiveInlineProp = ({
223
+ node,
224
+ isWizardStepNode,
225
+ hasRenderableChildren,
226
+ childrenInlineEntry,
227
+ candidateInlineProp
228
+ }) => {
229
+ if (isWizardStepNode) return candidateInlineProp;
230
+ if (node.type === "FormField") return candidateInlineProp;
231
+ if (node.type === "ScrollReveal") {
232
+ if (hasRenderableChildren) return null;
233
+ return childrenInlineEntry ? "children" : null;
234
+ }
235
+ if (node.type === "Cover") return candidateInlineProp;
236
+ if (node.type === "Dropdown" || node.type === "Tooltip" || node.type === "Popin" || node.type === "Drawer") {
237
+ return candidateInlineProp;
238
+ }
239
+ if (hasRenderableChildren) {
240
+ return childrenInlineEntry ? "children" : null;
241
+ }
242
+ return candidateInlineProp;
243
+ };
244
+
245
+ // src/studio-bridge/inline/inlineEditing.ts
246
+ var getValueAtPropPath = (source, propPath) => propPath.split(".").filter(Boolean).reduce((current, segment) => {
247
+ if (!current || typeof current !== "object" || Array.isArray(current)) return void 0;
248
+ return current[segment];
249
+ }, source);
250
+ var computeInlineEditorStyle = ({
251
+ wrapperElement,
252
+ targetElementForEditor
253
+ }) => {
254
+ if (!targetElementForEditor) return { inset: 0 };
255
+ const wrapperRect = wrapperElement.getBoundingClientRect();
256
+ const targetRect = targetElementForEditor.getBoundingClientRect();
257
+ return {
258
+ top: Math.max(0, targetRect.top - wrapperRect.top - 2),
259
+ left: Math.max(0, targetRect.left - wrapperRect.left - 2),
260
+ width: Math.max(48, targetRect.width + 4),
261
+ height: Math.max(32, targetRect.height + 4)
262
+ };
263
+ };
264
+ var shouldUseMultilineInlineEditor = ({
265
+ mode,
266
+ value
267
+ }) => mode === "json" || value.length > 64;
268
+ var applyInlineEditingValue = ({
269
+ editingState,
270
+ rawValue,
271
+ schemaNodes,
272
+ onInlineTextEdit,
273
+ findNodeById: findNodeById2
274
+ }) => {
275
+ var _a;
276
+ if (!onInlineTextEdit) return;
277
+ const isFormFieldLabelOrName = editingState.propName === "label" || editingState.propName === "name";
278
+ const applyFormFieldValue = (nextValue) => {
279
+ var _a2;
280
+ const targetNode2 = findNodeById2(editingState.nodeId, schemaNodes);
281
+ const targetProps2 = (_a2 = targetNode2 == null ? void 0 : targetNode2.props) != null ? _a2 : {};
282
+ const currentField = targetProps2.field && typeof targetProps2.field === "object" && !Array.isArray(targetProps2.field) ? targetProps2.field : {};
283
+ if ((targetNode2 == null ? void 0 : targetNode2.type) === "FormField" && isFormFieldLabelOrName) {
284
+ onInlineTextEdit(editingState.nodeId, "field", __spreadProps(__spreadValues({}, currentField), {
285
+ [editingState.propName]: nextValue
286
+ }));
287
+ }
288
+ };
289
+ const targetNode = findNodeById2(editingState.nodeId, schemaNodes);
290
+ const targetProps = (_a = targetNode == null ? void 0 : targetNode.props) != null ? _a : {};
291
+ const currentValue = getValueAtPropPath(targetProps, editingState.propName);
292
+ if (editingState.mode === "translation" && currentValue && typeof currentValue === "object" && !Array.isArray(currentValue) && typeof currentValue.$t === "string") {
293
+ onInlineTextEdit(editingState.nodeId, editingState.propName, __spreadProps(__spreadValues({}, currentValue), {
294
+ $t: rawValue,
295
+ defaultValue: rawValue
296
+ }));
297
+ return;
298
+ }
299
+ if (editingState.mode === "json") {
300
+ try {
301
+ const parsed = JSON.parse(rawValue);
302
+ applyFormFieldValue(parsed);
303
+ onInlineTextEdit(editingState.nodeId, editingState.propName, parsed);
304
+ return;
305
+ } catch (e) {
306
+ applyFormFieldValue(rawValue);
307
+ onInlineTextEdit(editingState.nodeId, editingState.propName, rawValue);
308
+ return;
309
+ }
310
+ }
311
+ const trimmed = rawValue.trim();
312
+ if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) {
313
+ try {
314
+ const parsed = JSON.parse(trimmed);
315
+ applyFormFieldValue(parsed);
316
+ onInlineTextEdit(editingState.nodeId, editingState.propName, parsed);
317
+ return;
318
+ } catch (e) {
319
+ }
320
+ }
321
+ applyFormFieldValue(rawValue);
322
+ onInlineTextEdit(editingState.nodeId, editingState.propName, rawValue);
323
+ };
324
+
325
+ // src/studio-bridge/inline/inlineEditorOpening.ts
326
+ var openInlineEditorFromDoubleClick = ({
327
+ event,
328
+ nodeId,
329
+ nodeType,
330
+ effectiveCandidateInlineProp,
331
+ getTextValue,
332
+ setInlineEditing
333
+ }) => {
334
+ var _a;
335
+ const targetElement = event.target;
336
+ const targetInlineProp = (_a = targetElement == null ? void 0 : targetElement.closest("[data-inline-prop]")) == null ? void 0 : _a.getAttribute("data-inline-prop");
337
+ const chosenProp = nodeType === "Cover" && targetInlineProp ? targetInlineProp : targetInlineProp && targetInlineProp !== "children" ? targetInlineProp : effectiveCandidateInlineProp;
338
+ if (!chosenProp) return false;
339
+ const initialEntry = getTextValue(chosenProp);
340
+ if (initialEntry === null) return false;
341
+ const targetElementForEditor = targetInlineProp ? targetElement == null ? void 0 : targetElement.closest("[data-inline-prop]") : null;
342
+ const wrapperElement = event.currentTarget;
343
+ const editorStyle = computeInlineEditorStyle({
344
+ wrapperElement,
345
+ targetElementForEditor
346
+ });
347
+ event.preventDefault();
348
+ event.stopPropagation();
349
+ setInlineEditing({
350
+ nodeId,
351
+ propName: chosenProp,
352
+ value: initialEntry.value,
353
+ multiline: shouldUseMultilineInlineEditor({
354
+ mode: initialEntry.mode,
355
+ value: initialEntry.value
356
+ }),
357
+ mode: initialEntry.mode,
358
+ editorStyle
359
+ });
360
+ return true;
361
+ };
362
+
363
+ // src/studio-bridge/inline/resolveInlineEditingTarget.ts
364
+ var INLINE_TECHNICAL_TEXT_PROPS = /* @__PURE__ */ new Set(["className", "rootMargin"]);
365
+ var PREFERRED_INLINE_TEXT_PROPS = [
366
+ "children",
367
+ "label",
368
+ "title",
369
+ "description",
370
+ "placeholder",
371
+ "name",
372
+ "text"
373
+ ];
374
+ var resolveInlineEditingTarget = ({
375
+ node,
376
+ nodeProps,
377
+ runtime,
378
+ editableTextProps,
379
+ resolveTranslationValue
380
+ }) => {
381
+ var _a, _b, _c, _d, _e;
382
+ const isWizardStepNode = node.type === "Container" && String((_a = nodeProps.cardSection) != null ? _a : "") !== "header" && String((_b = nodeProps.cardSection) != null ? _b : "") !== "body" && String((_c = nodeProps.cardSection) != null ? _c : "") !== "footer" && (nodeProps.layout && typeof nodeProps.layout === "object" && !Array.isArray(nodeProps.layout) ? Boolean(nodeProps.layout.wizardStep) : false);
383
+ const canResolveInlineText = isWizardStepNode || editableTextProps.length > 0;
384
+ const orderedEditableTextProps = canResolveInlineText ? [
385
+ ...PREFERRED_INLINE_TEXT_PROPS.filter((prop) => editableTextProps.includes(prop)),
386
+ ...editableTextProps.filter(
387
+ (prop) => !PREFERRED_INLINE_TEXT_PROPS.includes(prop) && !INLINE_TECHNICAL_TEXT_PROPS.has(prop)
388
+ )
389
+ ] : [];
390
+ const getTextValue = canResolveInlineText ? (propName) => getEditableTextValue({
391
+ node,
392
+ nodeProps,
393
+ propName,
394
+ runtime,
395
+ resolveTranslationValue
396
+ }) : () => null;
397
+ const candidateInlineProp = canResolveInlineText ? selectCandidateInlineProp({
398
+ node,
399
+ isWizardStepNode,
400
+ orderedEditableTextProps,
401
+ getTextValue
402
+ }) : null;
403
+ const effectiveCandidateInlineProp = canResolveInlineText ? selectEffectiveInlineProp({
404
+ node,
405
+ isWizardStepNode,
406
+ hasRenderableChildren: ((_e = (_d = node.children) == null ? void 0 : _d.length) != null ? _e : 0) > 0,
407
+ childrenInlineEntry: getTextValue("children"),
408
+ candidateInlineProp
409
+ }) : null;
410
+ return {
411
+ canResolveInlineText,
412
+ isWizardStepNode,
413
+ orderedEditableTextProps,
414
+ getTextValue,
415
+ effectiveCandidateInlineProp
416
+ };
417
+ };
418
+
419
+ // src/studio-bridge/interactions/studioClick.ts
420
+ var isInteractiveSelectionTarget = ({
421
+ targetElement,
422
+ nodeType,
423
+ isFormInteractiveTarget
424
+ }) => isFormInteractiveTarget(targetElement) && nodeType !== "Button" && nodeType !== "Link";
425
+ var resolveButtonOverlayTarget = ({
426
+ clickEvent,
427
+ boundTargetNodeId,
428
+ overlayCandidates
429
+ }) => {
430
+ var _a, _b, _c;
431
+ const actionLabel = clickEvent && typeof clickEvent === "object" ? "id" in clickEvent ? String((_a = clickEvent.id) != null ? _a : "") : "type" in clickEvent ? String((_b = clickEvent.type) != null ? _b : "") : "" : "";
432
+ const payload = clickEvent && typeof clickEvent === "object" && "payload" in clickEvent && clickEvent.payload && typeof clickEvent.payload === "object" ? clickEvent.payload : null;
433
+ const requestedTargetNodeId = String((_c = payload == null ? void 0 : payload.targetNodeId) != null ? _c : boundTargetNodeId).trim();
434
+ const targetNodeId = requestedTargetNodeId || (overlayCandidates.length === 1 ? overlayCandidates[0] : "");
435
+ return {
436
+ actionLabel,
437
+ payload,
438
+ targetNodeId
439
+ };
440
+ };
441
+ var buildNormalizedActionRef = ({
442
+ clickEvent,
443
+ payload,
444
+ targetNodeId
445
+ }) => {
446
+ const basePayload = payload && typeof payload === "object" ? payload : {};
447
+ const normalizedPayload = targetNodeId && !("targetNodeId" in basePayload) ? __spreadProps(__spreadValues({}, basePayload), { targetNodeId }) : basePayload;
448
+ return clickEvent && typeof clickEvent === "object" && "id" in clickEvent ? __spreadProps(__spreadValues({}, clickEvent), { payload: normalizedPayload }) : clickEvent && typeof clickEvent === "object" && "type" in clickEvent ? __spreadProps(__spreadValues({}, clickEvent), { payload: normalizedPayload }) : clickEvent;
449
+ };
450
+ var syncOverlayStateFromAction = ({
451
+ targetNodeId,
452
+ actionLabel,
453
+ runtime,
454
+ onInlineTextEdit,
455
+ findNodeById: findNodeById2,
456
+ schemaNodes
457
+ }) => {
458
+ if (!targetNodeId || !onInlineTextEdit) return;
459
+ const targetNode = findNodeById2(targetNodeId, schemaNodes);
460
+ if (!targetNode) return;
461
+ const overlaysRaw = runtime.get("overlays.byNodeId");
462
+ const overlaysByNodeId = overlaysRaw && typeof overlaysRaw === "object" ? overlaysRaw : {};
463
+ if (!actionLabel) {
464
+ if (targetNode.type === "Popin") {
465
+ onInlineTextEdit(targetNodeId, "displayedPopin", true);
466
+ } else if (targetNode.type === "Drawer") {
467
+ onInlineTextEdit(targetNodeId, "open", true);
468
+ }
469
+ runtime.dispatch({
470
+ id: "overlay.open",
471
+ payload: { targetNodeId }
472
+ });
473
+ return;
474
+ }
475
+ if (targetNode.type === "Popin") {
476
+ if (actionLabel === "overlay.open") {
477
+ onInlineTextEdit(targetNodeId, "displayedPopin", true);
478
+ } else if (actionLabel === "overlay.close") {
479
+ onInlineTextEdit(targetNodeId, "displayedPopin", false);
480
+ } else if (actionLabel === "overlay.toggle") {
481
+ const current = Boolean(overlaysByNodeId[targetNodeId]);
482
+ onInlineTextEdit(targetNodeId, "displayedPopin", !current);
483
+ }
484
+ }
485
+ if (targetNode.type === "Drawer") {
486
+ if (actionLabel === "overlay.open") {
487
+ onInlineTextEdit(targetNodeId, "open", true);
488
+ } else if (actionLabel === "overlay.close") {
489
+ onInlineTextEdit(targetNodeId, "open", false);
490
+ } else if (actionLabel === "overlay.toggle") {
491
+ const current = Boolean(overlaysByNodeId[targetNodeId]);
492
+ onInlineTextEdit(targetNodeId, "open", !current);
493
+ }
494
+ }
495
+ };
496
+ var resolveClickedNodeId = ({
497
+ targetElement,
498
+ fallbackNodeId
499
+ }) => {
500
+ var _a;
501
+ const closestNode = targetElement == null ? void 0 : targetElement.closest("[data-node-id]");
502
+ return (_a = closestNode == null ? void 0 : closestNode.dataset.nodeId) != null ? _a : fallbackNodeId;
503
+ };
504
+
505
+ // src/studio-bridge/nodes/studioNodeEditing.ts
506
+ var suppressStudioClickUntil = 0;
507
+ var shouldSuppressStudioClick = () => Date.now() <= suppressStudioClickUntil;
508
+
509
+ // src/utils/schemaTraversal.ts
510
+ var findNodeById = (nodeId, nodes) => {
511
+ var _a;
512
+ for (const candidate of nodes) {
513
+ if (candidate.id === nodeId) return candidate;
514
+ const nested = findNodeById(nodeId, (_a = candidate.children) != null ? _a : []);
515
+ if (nested) return nested;
516
+ }
517
+ return null;
518
+ };
519
+ var buildAncestorTypeMembership = (nodes, ancestorTypes) => {
520
+ const lookup = Object.fromEntries(
521
+ ancestorTypes.map((type) => [type, /* @__PURE__ */ new Set()])
522
+ );
523
+ const walk = (items, lineage = []) => {
524
+ var _a;
525
+ for (const item of items) {
526
+ for (const ancestorType of ancestorTypes) {
527
+ if (lineage.includes(ancestorType)) {
528
+ lookup[ancestorType].add(item.id);
529
+ }
530
+ }
531
+ if ((_a = item.children) == null ? void 0 : _a.length) {
532
+ walk(item.children, [...lineage, item.type]);
533
+ }
534
+ }
535
+ };
536
+ walk(nodes);
537
+ return lookup;
538
+ };
539
+ var collectOverlayNodeIds = (nodes) => {
540
+ const ids = [];
541
+ const walk = (items) => {
542
+ var _a;
543
+ for (const item of items) {
544
+ if (item.type === "Popin" || item.type === "Drawer") ids.push(item.id);
545
+ if ((_a = item.children) == null ? void 0 : _a.length) walk(item.children);
546
+ }
547
+ };
548
+ walk(nodes);
549
+ return ids;
550
+ };
551
+
552
+ // src/studio-bridge/interactions/resizeStudio.ts
553
+ var computeMouseResizeSize = ({
554
+ state,
555
+ clientX,
556
+ clientY,
557
+ minWidthPct,
558
+ minHeightPct,
559
+ minHeightPx
560
+ }) => {
561
+ const deltaX = clientX - state.startX;
562
+ const deltaY = clientY - state.startY;
563
+ const nextWidth = state.startWidthPct + deltaX / state.containerWidth * 100;
564
+ const nextHeight = state.startHeightPct + deltaY / state.containerHeight * 100;
565
+ const nextHeightPx = state.startHeightPx + deltaY;
566
+ return {
567
+ widthPct: Math.max(minWidthPct, Math.min(100, Number(nextWidth.toFixed(2)))),
568
+ heightPct: Math.max(minHeightPct, Math.min(100, Number(nextHeight.toFixed(2)))),
569
+ heightPx: Math.max(minHeightPx, Number(nextHeightPx.toFixed(0)))
570
+ };
571
+ };
572
+ var computePinchResizeSize = ({
573
+ state,
574
+ distance,
575
+ minWidthPct,
576
+ minHeightPct
577
+ }) => {
578
+ if (!state.startDistance) return null;
579
+ const scale = distance / state.startDistance;
580
+ const nextWidth = state.startWidthPct * scale;
581
+ const nextHeight = state.startHeightPct * scale;
582
+ return {
583
+ widthPct: Math.max(minWidthPct, Math.min(100, Number(nextWidth.toFixed(2)))),
584
+ heightPct: Math.max(minHeightPct, Math.min(100, Number(nextHeight.toFixed(2))))
585
+ };
586
+ };
587
+ var createMouseResizeState = ({
588
+ nodeId,
589
+ clientX,
590
+ clientY,
591
+ widthPct,
592
+ heightPct,
593
+ heightPx,
594
+ elementRect,
595
+ parentRect,
596
+ minHeightPx
597
+ }) => ({
598
+ nodeId,
599
+ startX: clientX,
600
+ startY: clientY,
601
+ startWidthPct: widthPct != null ? widthPct : elementRect.width / Math.max(parentRect.width, 1) * 100,
602
+ startHeightPct: heightPct != null ? heightPct : elementRect.height / Math.max(parentRect.height, 1) * 100,
603
+ startHeightPx: heightPx != null ? heightPx : Math.max(minHeightPx, elementRect.height),
604
+ containerWidth: Math.max(parentRect.width, 1),
605
+ containerHeight: Math.max(parentRect.height, 1)
606
+ });
607
+ var createPinchResizeState = ({
608
+ nodeId,
609
+ widthPct,
610
+ heightPct,
611
+ distance
612
+ }) => ({
613
+ nodeId,
614
+ startDistance: distance,
615
+ startWidthPct: widthPct != null ? widthPct : 100,
616
+ startHeightPct: heightPct != null ? heightPct : 100
617
+ });
618
+
619
+ // src/studio-bridge/nodes/nodeWrapperHandlers.ts
620
+ var createTouchResizeHandlers = ({
621
+ node,
622
+ widthPct,
623
+ heightPct,
624
+ onNodeResize,
625
+ onNodeResizeStart,
626
+ onNodeResizeEnd,
627
+ pinchStateRef,
628
+ minWidthPct,
629
+ minHeightPct
630
+ }) => ({
631
+ onTouchStart: (event) => {
632
+ if (!onNodeResize) return;
633
+ if (event.touches.length < 2) return;
634
+ onNodeResizeStart == null ? void 0 : onNodeResizeStart(node.id);
635
+ const [firstTouch, secondTouch] = [event.touches[0], event.touches[1]];
636
+ const dx = secondTouch.clientX - firstTouch.clientX;
637
+ const dy = secondTouch.clientY - firstTouch.clientY;
638
+ const distance = Math.hypot(dx, dy);
639
+ pinchStateRef.current = createPinchResizeState({
640
+ nodeId: node.id,
641
+ widthPct,
642
+ heightPct,
643
+ distance
644
+ });
645
+ },
646
+ onTouchMove: (event) => {
647
+ if (!onNodeResize) return;
648
+ const state = pinchStateRef.current;
649
+ if (!state || state.nodeId !== node.id) return;
650
+ if (event.touches.length < 2) return;
651
+ const [firstTouch, secondTouch] = [event.touches[0], event.touches[1]];
652
+ const dx = secondTouch.clientX - firstTouch.clientX;
653
+ const dy = secondTouch.clientY - firstTouch.clientY;
654
+ const distance = Math.hypot(dx, dy);
655
+ const nextSize = computePinchResizeSize({
656
+ state,
657
+ distance,
658
+ minWidthPct,
659
+ minHeightPct
660
+ });
661
+ if (!nextSize) return;
662
+ pinchStateRef.current = __spreadProps(__spreadValues({}, state), {
663
+ lastSize: nextSize
664
+ });
665
+ onNodeResize(node.id, nextSize);
666
+ },
667
+ onTouchEnd: () => {
668
+ const state = pinchStateRef.current;
669
+ if (state == null ? void 0 : state.lastSize) {
670
+ onNodeResizeEnd == null ? void 0 : onNodeResizeEnd(node.id, state.lastSize);
671
+ }
672
+ pinchStateRef.current = null;
673
+ }
674
+ });
675
+ var createMouseResizeHandler = ({
676
+ node,
677
+ widthPct,
678
+ heightPct,
679
+ heightPx,
680
+ onNodeResize,
681
+ onNodeResizeStart,
682
+ resizeStateRef,
683
+ minHeightPx
684
+ }) => onNodeResize ? (event) => {
685
+ event.preventDefault();
686
+ event.stopPropagation();
687
+ const element = event.currentTarget.closest("[data-node-id]");
688
+ if (!element) return;
689
+ const parent = element.parentElement;
690
+ if (!parent) return;
691
+ const parentRect = parent.getBoundingClientRect();
692
+ const elementRect = element.getBoundingClientRect();
693
+ onNodeResizeStart == null ? void 0 : onNodeResizeStart(node.id);
694
+ resizeStateRef.current = createMouseResizeState({
695
+ nodeId: node.id,
696
+ clientX: event.clientX,
697
+ clientY: event.clientY,
698
+ widthPct,
699
+ heightPct,
700
+ heightPx,
701
+ elementRect,
702
+ parentRect,
703
+ minHeightPx
704
+ });
705
+ } : void 0;
706
+ var createStudioNodeClickHandler = ({
707
+ node,
708
+ nodeProps,
709
+ schemaNodes,
710
+ runtime,
711
+ onNodeClick,
712
+ onInlineTextEdit,
713
+ isInlineEditingNode,
714
+ enableEventOnClick,
715
+ isFormInteractiveTarget
716
+ }) => (event) => {
717
+ var _a, _b;
718
+ if (shouldSuppressStudioClick()) {
719
+ event.preventDefault();
720
+ event.stopPropagation();
721
+ return;
722
+ }
723
+ if (!onNodeClick) return;
724
+ if (isInlineEditingNode) return;
725
+ const targetElement = event.target;
726
+ if (node.type === "Button" && enableEventOnClick && Boolean(targetElement == null ? void 0 : targetElement.closest("button"))) {
727
+ const clickEvent = (_a = node.events) == null ? void 0 : _a.onClick;
728
+ const boundTargetNodeId = String((_b = nodeProps.buttonTargetNodeId) != null ? _b : "").trim();
729
+ const overlayCandidates = collectOverlayNodeIds(schemaNodes);
730
+ const { actionLabel, payload, targetNodeId } = resolveButtonOverlayTarget({
731
+ clickEvent,
732
+ boundTargetNodeId,
733
+ overlayCandidates
734
+ });
735
+ if (clickEvent) {
736
+ const normalizedActionRef = buildNormalizedActionRef({
737
+ clickEvent,
738
+ payload,
739
+ targetNodeId
740
+ });
741
+ runtime.dispatch(normalizedActionRef);
742
+ }
743
+ syncOverlayStateFromAction({
744
+ targetNodeId,
745
+ actionLabel: clickEvent ? actionLabel : "",
746
+ runtime,
747
+ onInlineTextEdit,
748
+ findNodeById,
749
+ schemaNodes
750
+ });
751
+ event.stopPropagation();
752
+ return;
753
+ }
754
+ if (isInteractiveSelectionTarget({
755
+ targetElement,
756
+ nodeType: node.type,
757
+ isFormInteractiveTarget
758
+ })) {
759
+ event.stopPropagation();
760
+ return;
761
+ }
762
+ const clickedNodeId = resolveClickedNodeId({
763
+ targetElement,
764
+ fallbackNodeId: node.id
765
+ });
766
+ if (clickedNodeId && clickedNodeId !== node.id) {
767
+ event.stopPropagation();
768
+ onNodeClick(clickedNodeId);
769
+ return;
770
+ }
771
+ event.stopPropagation();
772
+ onNodeClick(node.id);
773
+ };
774
+ var createStudioNodeDoubleClickHandler = ({
775
+ node,
776
+ onInlineTextEdit,
777
+ effectiveCandidateInlineProp,
778
+ getTextValue,
779
+ setInlineEditing
780
+ }) => (event) => {
781
+ if (!onInlineTextEdit) return;
782
+ openInlineEditorFromDoubleClick({
783
+ event,
784
+ nodeId: node.id,
785
+ nodeType: node.type,
786
+ effectiveCandidateInlineProp,
787
+ getTextValue,
788
+ setInlineEditing
789
+ });
790
+ };
791
+
792
+ // src/studio-bridge/nodes/nodeWrapperStudio.tsx
793
+ import { jsx as jsx3 } from "react/jsx-runtime";
794
+ var getNodeWrapperPresentation = ({
795
+ isOpenStudioOverlayNode,
796
+ wrapperClassName,
797
+ widthPct,
798
+ shouldForceFullWidth
799
+ }) => {
800
+ const wrapperStyle = isOpenStudioOverlayNode ? {
801
+ position: "absolute",
802
+ inset: 0,
803
+ width: "100%",
804
+ height: "100%"
805
+ } : widthPct !== null || shouldForceFullWidth ? { width: `${widthPct != null ? widthPct : 100}%` } : void 0;
806
+ const overlayWrapperClassName = isOpenStudioOverlayNode ? [wrapperClassName, "absolute inset-0 h-full w-full"].filter(Boolean).join(" ") : wrapperClassName;
807
+ return {
808
+ wrapperStyle,
809
+ overlayWrapperClassName,
810
+ requiresPlainWrapper: Boolean(overlayWrapperClassName) || Boolean(wrapperStyle)
811
+ };
812
+ };
813
+ var getStudioNodeInteractionState = ({
814
+ node,
815
+ selectedNodeId,
816
+ effectiveCandidateInlineProp,
817
+ isInlineEditingNode,
818
+ isOpenStudioOverlayNode,
819
+ isInsideForm,
820
+ isInsideFormWizard,
821
+ isInsideStepForm,
822
+ inlinePropName
823
+ }) => {
824
+ var _a, _b, _c;
825
+ const nodeLayoutRecord = node.props && typeof node.props === "object" && !Array.isArray(node.props) && node.props.layout && typeof node.props.layout === "object" && !Array.isArray(node.props.layout) ? node.props.layout : {};
826
+ const isSelected = selectedNodeId === node.id;
827
+ const isFormFieldNode = node.type === "FormField" && String((_a = nodeLayoutRecord.formRole) != null ? _a : "field").trim() === "field";
828
+ const isTitleLikeInternalNode = String((_b = nodeLayoutRecord.formRole) != null ? _b : "").trim() === "title" || String((_c = nodeLayoutRecord.wizardStepRole) != null ? _c : "").trim() === "title" || ["H1", "H2", "H3", "H4", "H5", "H6"].includes(node.type);
829
+ const isActionButtonLikeNode = node.type === "Button" && (isInsideForm || isInsideFormWizard || isInsideStepForm);
830
+ const studioFormFieldWrapperClassName = isFormFieldNode ? "rounded-lg border-dashed border-sky-400/70 bg-sky-500/5 p-2 hover:border-sky-500 hover:bg-sky-500/10" : "";
831
+ const allowNodeHandles = (() => {
832
+ if (isInsideForm) return isFormFieldNode;
833
+ if (isInsideFormWizard || isInsideStepForm) {
834
+ if (isTitleLikeInternalNode) return false;
835
+ if (isActionButtonLikeNode) return false;
836
+ return true;
837
+ }
838
+ return true;
839
+ })();
840
+ return {
841
+ isSelected,
842
+ allowNodeHandles,
843
+ studioFormFieldWrapperClassName,
844
+ cursorClassName: effectiveCandidateInlineProp ? "cursor-text" : "cursor-pointer",
845
+ preserveContentWhileInlineEditing: isInlineEditingNode && isOpenStudioOverlayNode && (inlinePropName === "title" || inlinePropName === "closeText")
846
+ };
847
+ };
848
+ var renderPlainWrappedNode = ({
849
+ nodeId,
850
+ overlayWrapperClassName,
851
+ wrapperStyle,
852
+ nodeContent
853
+ }) => /* @__PURE__ */ jsx3(
854
+ "div",
855
+ {
856
+ "data-node-id": nodeId,
857
+ className: ["relative min-w-0 max-w-full flex-none", overlayWrapperClassName].filter(Boolean).join(" "),
858
+ style: wrapperStyle,
859
+ children: nodeContent
860
+ },
861
+ nodeId
862
+ );
863
+
864
+ // src/render-layer/renderDirectives.ts
865
+ var RENDER_BINDING_PROP_NAMES = /* @__PURE__ */ new Set([
866
+ "bindingEnabled",
867
+ "valueBindingKey",
868
+ "optionsBindingKey",
869
+ "useBindingData",
870
+ "entitiesBindingKey",
871
+ "videoBindingKey",
872
+ "mapBindingKey",
873
+ "productBindingKey",
874
+ "useTranslationKeys",
875
+ "tagContentTranslationKey",
876
+ "tagContentTranslationValue",
877
+ "hrefTranslationKey",
878
+ "hrefTranslationValue",
879
+ "mediaSource",
880
+ "mediaSrc",
881
+ "mediaAlt",
882
+ "rowsBindingKey",
883
+ "columnsBindingKey"
884
+ ]);
885
+ var STUDIO_INTERNAL_PROP_NAMES = /* @__PURE__ */ new Set([
886
+ ...RENDER_BINDING_PROP_NAMES
887
+ ]);
888
+ var getRenderBindingProps = (props) => {
889
+ if (!props || typeof props !== "object" || Array.isArray(props)) {
890
+ return {};
891
+ }
892
+ const source = props;
893
+ const embedded = source.__studio && typeof source.__studio === "object" && !Array.isArray(source.__studio) ? source.__studio : {};
894
+ const legacy = Array.from(RENDER_BINDING_PROP_NAMES).reduce(
895
+ (accumulator, key) => {
896
+ if (source[key] !== void 0) {
897
+ accumulator[key] = source[key];
898
+ }
899
+ return accumulator;
900
+ },
901
+ {}
902
+ );
903
+ return Array.from(RENDER_BINDING_PROP_NAMES).reduce((accumulator, key) => {
904
+ if (legacy[key] !== void 0) {
905
+ accumulator[key] = legacy[key];
906
+ } else if (embedded[key] !== void 0) {
907
+ accumulator[key] = embedded[key];
908
+ }
909
+ return accumulator;
910
+ }, {});
911
+ };
912
+ var getStudioProps = (props) => {
913
+ if (!props || typeof props !== "object" || Array.isArray(props)) {
914
+ return {};
915
+ }
916
+ const source = props;
917
+ const embedded = source.__studio && typeof source.__studio === "object" && !Array.isArray(source.__studio) ? source.__studio : {};
918
+ const legacy = Array.from(STUDIO_INTERNAL_PROP_NAMES).reduce(
919
+ (accumulator, key) => {
920
+ if (source[key] !== void 0) {
921
+ accumulator[key] = source[key];
922
+ }
923
+ return accumulator;
924
+ },
925
+ {}
926
+ );
927
+ return __spreadValues(__spreadValues({}, legacy), embedded);
928
+ };
929
+ var omitStudioProps = (props) => {
930
+ const next = __spreadValues({}, props);
931
+ delete next.__studio;
932
+ for (const propName of STUDIO_INTERNAL_PROP_NAMES) {
933
+ delete next[propName];
934
+ }
935
+ return next;
936
+ };
937
+
938
+ // src/utils/renderChildren.tsx
939
+ import { normalizeRenderableChild, toBoolean } from "@arkcit/engine-react";
940
+
941
+ // src/studio-bridge/overlay/overlayStudio.ts
942
+ var toBoolean2 = (value) => {
943
+ if (typeof value === "boolean") return value;
944
+ if (typeof value === "string") return value.toLowerCase() === "true";
945
+ return Boolean(value);
946
+ };
947
+ var readOverlayState = (runtime) => {
948
+ const overlaysRaw = runtime.get("overlays.byNodeId");
949
+ return overlaysRaw && typeof overlaysRaw === "object" ? overlaysRaw : {};
950
+ };
951
+ var applyStudioOverlayComponentProps = ({
952
+ node,
953
+ componentProps,
954
+ runtime,
955
+ overlaysByNodeId,
956
+ renderBindingProps,
957
+ resolvedChildContent,
958
+ onInlineTextEdit,
959
+ isStudioRendererContext,
960
+ dropdownOpenByNodeId,
961
+ setDropdownOpenByNodeId
962
+ }) => {
963
+ if (node.type === "Popin") {
964
+ const bindingEnabled = toBoolean2(renderBindingProps.bindingEnabled);
965
+ const rawOverlayOpen = overlaysByNodeId[node.id];
966
+ const fallbackOpen = Boolean(componentProps.displayedPopin);
967
+ const isOpen = bindingEnabled ? typeof rawOverlayOpen === "boolean" ? rawOverlayOpen : fallbackOpen : fallbackOpen;
968
+ componentProps.displayedPopin = isOpen;
969
+ componentProps.setDisplayedPopin = (next) => {
970
+ const nextOpen = typeof next === "function" ? next(isOpen) : next;
971
+ onInlineTextEdit == null ? void 0 : onInlineTextEdit(node.id, "displayedPopin", nextOpen);
972
+ if (bindingEnabled) {
973
+ runtime.dispatch({
974
+ id: nextOpen ? "overlay.open" : "overlay.close",
975
+ payload: { targetNodeId: node.id }
976
+ });
977
+ }
978
+ };
979
+ componentProps.children = resolvedChildContent !== null ? resolvedChildContent : normalizeRenderableChild(componentProps.children);
980
+ }
981
+ if (node.type === "Drawer") {
982
+ const bindingEnabled = toBoolean2(renderBindingProps.bindingEnabled);
983
+ const rawOverlayOpen = overlaysByNodeId[node.id];
984
+ const fallbackOpen = Boolean(componentProps.open);
985
+ const isOpen = bindingEnabled ? typeof rawOverlayOpen === "boolean" ? rawOverlayOpen : fallbackOpen : fallbackOpen;
986
+ componentProps.open = isOpen;
987
+ componentProps.onClose = () => {
988
+ onInlineTextEdit == null ? void 0 : onInlineTextEdit(node.id, "open", false);
989
+ if (bindingEnabled) {
990
+ runtime.dispatch({
991
+ id: "overlay.close",
992
+ payload: { targetNodeId: node.id }
993
+ });
994
+ }
995
+ };
996
+ componentProps.children = resolvedChildContent !== null ? resolvedChildContent : normalizeRenderableChild(componentProps.children);
997
+ }
998
+ if (node.type === "Dropdown") {
999
+ const fallbackOpen = Boolean(componentProps.open);
1000
+ const isOpen = isStudioRendererContext && node.id in dropdownOpenByNodeId ? Boolean(dropdownOpenByNodeId[node.id]) : fallbackOpen;
1001
+ componentProps.open = isOpen;
1002
+ componentProps.onOpenChange = (nextOpen) => {
1003
+ setDropdownOpenByNodeId((previous) => __spreadProps(__spreadValues({}, previous), {
1004
+ [node.id]: Boolean(nextOpen)
1005
+ }));
1006
+ onInlineTextEdit == null ? void 0 : onInlineTextEdit(node.id, "open", Boolean(nextOpen));
1007
+ };
1008
+ if (resolvedChildContent !== null) {
1009
+ componentProps.children = resolvedChildContent;
1010
+ }
1011
+ }
1012
+ if (node.type === "Tooltip") {
1013
+ componentProps.children = resolvedChildContent !== null ? resolvedChildContent : normalizeRenderableChild(componentProps.children);
1014
+ }
1015
+ };
1016
+ var getOpenStudioOverlayState = ({
1017
+ node,
1018
+ nodeProps,
1019
+ overlaysByNodeId
1020
+ }) => {
1021
+ const renderBindingProps = getRenderBindingProps(nodeProps);
1022
+ const bindingEnabled = toBoolean2(renderBindingProps.bindingEnabled);
1023
+ return Boolean(
1024
+ node.type === "Popin" && Boolean(bindingEnabled ? overlaysByNodeId[node.id] : nodeProps.displayedPopin) || node.type === "Drawer" && Boolean(bindingEnabled ? overlaysByNodeId[node.id] : nodeProps.open)
1025
+ );
1026
+ };
1027
+
1028
+ // src/studio-bridge/overlay/renderNodeFrame.tsx
1029
+ import { createPortal } from "react-dom";
1030
+ import { jsx as jsx4 } from "react/jsx-runtime";
1031
+ var renderNodeFrame = ({
1032
+ node,
1033
+ nodeProps,
1034
+ nodeContent,
1035
+ selectedNodeId,
1036
+ onNodeClick,
1037
+ onInlineTextEdit,
1038
+ onNodeResize,
1039
+ onNodeResizeStart,
1040
+ onNodeResizeEnd,
1041
+ widthPct,
1042
+ heightPct,
1043
+ heightPx,
1044
+ wrapperClassName,
1045
+ isOpenStudioOverlayNode,
1046
+ shouldForceFullWidth,
1047
+ effectiveCandidateInlineProp,
1048
+ inlineEditing,
1049
+ isInlineEditingNode,
1050
+ ancestorTypeMembership,
1051
+ schemaNodes,
1052
+ runtime,
1053
+ enableEventOnClick,
1054
+ isFormInteractiveTarget,
1055
+ getTextValue,
1056
+ setInlineEditing,
1057
+ inlineEditor,
1058
+ NodeWrapper,
1059
+ overlaysByNodeId,
1060
+ getOpenStudioOverlayState: getOpenStudioOverlayState2,
1061
+ resizeStateRef,
1062
+ pinchStateRef,
1063
+ minWidthPct,
1064
+ minHeightPct,
1065
+ minHeightPx,
1066
+ overlayRootId
1067
+ }) => {
1068
+ var _a;
1069
+ const { wrapperStyle, overlayWrapperClassName, requiresPlainWrapper } = getNodeWrapperPresentation({
1070
+ isOpenStudioOverlayNode,
1071
+ wrapperClassName,
1072
+ widthPct,
1073
+ shouldForceFullWidth
1074
+ });
1075
+ if (!onNodeClick && !selectedNodeId) {
1076
+ if (!requiresPlainWrapper) return nodeContent;
1077
+ return renderPlainWrappedNode({
1078
+ nodeId: node.id,
1079
+ overlayWrapperClassName,
1080
+ wrapperStyle,
1081
+ nodeContent
1082
+ });
1083
+ }
1084
+ const {
1085
+ isSelected,
1086
+ allowNodeHandles,
1087
+ studioFormFieldWrapperClassName,
1088
+ cursorClassName,
1089
+ preserveContentWhileInlineEditing
1090
+ } = getStudioNodeInteractionState({
1091
+ node,
1092
+ selectedNodeId,
1093
+ effectiveCandidateInlineProp,
1094
+ isInlineEditingNode,
1095
+ isOpenStudioOverlayNode,
1096
+ isInsideForm: ancestorTypeMembership.Form.has(node.id),
1097
+ isInsideFormWizard: ancestorTypeMembership.FormWizard.has(node.id),
1098
+ isInsideStepForm: ancestorTypeMembership.StepForm.has(node.id),
1099
+ inlinePropName: inlineEditing == null ? void 0 : inlineEditing.propName
1100
+ });
1101
+ const touchResizeHandlers = createTouchResizeHandlers({
1102
+ node,
1103
+ widthPct,
1104
+ heightPct,
1105
+ onNodeResize,
1106
+ onNodeResizeStart,
1107
+ onNodeResizeEnd,
1108
+ pinchStateRef,
1109
+ minWidthPct,
1110
+ minHeightPct
1111
+ });
1112
+ const onResizeMouseDown = createMouseResizeHandler({
1113
+ node,
1114
+ widthPct,
1115
+ heightPct,
1116
+ heightPx,
1117
+ onNodeResize,
1118
+ onNodeResizeStart,
1119
+ resizeStateRef,
1120
+ minHeightPx
1121
+ });
1122
+ const onClick = createStudioNodeClickHandler({
1123
+ node,
1124
+ nodeProps,
1125
+ schemaNodes,
1126
+ runtime,
1127
+ onNodeClick,
1128
+ onInlineTextEdit,
1129
+ isInlineEditingNode,
1130
+ enableEventOnClick,
1131
+ isFormInteractiveTarget
1132
+ });
1133
+ const onDoubleClick = createStudioNodeDoubleClickHandler({
1134
+ node,
1135
+ onInlineTextEdit,
1136
+ effectiveCandidateInlineProp,
1137
+ getTextValue,
1138
+ setInlineEditing
1139
+ });
1140
+ const wrappedNode = /* @__PURE__ */ jsx4(
1141
+ NodeWrapper,
1142
+ {
1143
+ nodeId: node.id,
1144
+ wrapperClassName: [overlayWrapperClassName, studioFormFieldWrapperClassName].filter(Boolean).join(" "),
1145
+ cursorClassName: onNodeClick ? cursorClassName : "",
1146
+ isSelected,
1147
+ allowDragHandle: allowNodeHandles,
1148
+ allowResizeHandle: allowNodeHandles,
1149
+ style: wrapperStyle,
1150
+ onTouchStart: touchResizeHandlers.onTouchStart,
1151
+ onTouchMove: touchResizeHandlers.onTouchMove,
1152
+ onTouchEnd: touchResizeHandlers.onTouchEnd,
1153
+ onClick,
1154
+ onDoubleClick,
1155
+ showResizeHandle: isSelected && Boolean(onNodeResize) && allowNodeHandles,
1156
+ onResizeMouseDown,
1157
+ isInlineEditing: isInlineEditingNode,
1158
+ preserveContentWhileInlineEditing,
1159
+ inlineEditor,
1160
+ children: nodeContent
1161
+ }
1162
+ );
1163
+ if (getOpenStudioOverlayState2({
1164
+ node,
1165
+ nodeProps,
1166
+ overlaysByNodeId
1167
+ })) {
1168
+ const overlayRoot = (_a = globalThis.document) == null ? void 0 : _a.getElementById(overlayRootId);
1169
+ if (overlayRoot) {
1170
+ return createPortal(wrappedNode, overlayRoot);
1171
+ }
1172
+ }
1173
+ return wrappedNode;
1174
+ };
1175
+
1176
+ // src/studio-bridge/preview-form/previewFormRenderer.tsx
1177
+ import React from "react";
1178
+
1179
+ // src/form/engineFormValidation.ts
1180
+ var EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1181
+ var isEmptyValue = (value) => {
1182
+ if (value == null) return true;
1183
+ if (typeof value === "string") return value.trim().length === 0;
1184
+ if (Array.isArray(value)) return value.length === 0;
1185
+ return false;
1186
+ };
1187
+ var toNumber = (value) => {
1188
+ if (typeof value === "number" && Number.isFinite(value)) return value;
1189
+ if (typeof value === "string") {
1190
+ const parsed = Number(value);
1191
+ return Number.isFinite(parsed) ? parsed : null;
1192
+ }
1193
+ return null;
1194
+ };
1195
+ var defaultDeclarativeValidatorRegistry = {
1196
+ required: (value) => isEmptyValue(value) ? { code: "required" } : null,
1197
+ minLength: (value, params) => {
1198
+ var _a;
1199
+ if (isEmptyValue(value)) return null;
1200
+ const min = toNumber((_a = params == null ? void 0 : params.min) != null ? _a : params == null ? void 0 : params.value);
1201
+ if (min == null) return null;
1202
+ return String(value).length < min ? { code: "minLength", params: { min } } : null;
1203
+ },
1204
+ maxLength: (value, params) => {
1205
+ var _a;
1206
+ if (isEmptyValue(value)) return null;
1207
+ const max = toNumber((_a = params == null ? void 0 : params.max) != null ? _a : params == null ? void 0 : params.value);
1208
+ if (max == null) return null;
1209
+ return String(value).length > max ? { code: "maxLength", params: { max } } : null;
1210
+ },
1211
+ email: (value) => {
1212
+ if (isEmptyValue(value)) return null;
1213
+ return EMAIL_REGEX.test(String(value)) ? null : { code: "email" };
1214
+ },
1215
+ pattern: (value, params) => {
1216
+ var _a, _b;
1217
+ if (isEmptyValue(value)) return null;
1218
+ const rawPattern = String((_b = (_a = params == null ? void 0 : params.pattern) != null ? _a : params == null ? void 0 : params.value) != null ? _b : "").trim();
1219
+ if (!rawPattern) return null;
1220
+ try {
1221
+ const regex = new RegExp(rawPattern);
1222
+ return regex.test(String(value)) ? null : { code: "pattern", params: { pattern: rawPattern } };
1223
+ } catch (e) {
1224
+ return { code: "pattern" };
1225
+ }
1226
+ }
1227
+ };
1228
+ var buildLegacyValidators = (field) => {
1229
+ var _a, _b, _c;
1230
+ const validators = [];
1231
+ if (field.required) {
1232
+ validators.push({
1233
+ id: `${String((_a = field.name) != null ? _a : "field")}:required`,
1234
+ type: "required",
1235
+ stopOnFailure: true
1236
+ });
1237
+ }
1238
+ if (String((_b = field.pattern) != null ? _b : "").trim()) {
1239
+ validators.push({
1240
+ id: `${String((_c = field.name) != null ? _c : "field")}:pattern`,
1241
+ type: "pattern",
1242
+ params: { pattern: String(field.pattern) }
1243
+ });
1244
+ }
1245
+ return validators;
1246
+ };
1247
+ var normalizeValidators = (field, options) => {
1248
+ const explicit = Array.isArray(field.validators) ? field.validators : [];
1249
+ if (explicit.length > 0) return explicit;
1250
+ if (!(options == null ? void 0 : options.useLegacyFieldConstraints)) return [];
1251
+ return buildLegacyValidators(field);
1252
+ };
1253
+ var toIssueArray = (issue) => {
1254
+ if (!issue) return [];
1255
+ return Array.isArray(issue) ? issue : [issue];
1256
+ };
1257
+ var validateFieldWithConfig = (field, value, values, config, registry) => {
1258
+ if (config.enabled === false) return [];
1259
+ const validate = registry[config.type];
1260
+ if (!validate) return [];
1261
+ const baseIssues = toIssueArray(
1262
+ validate(value, config.params, {
1263
+ field,
1264
+ values
1265
+ })
1266
+ );
1267
+ return baseIssues.map((baseIssue) => {
1268
+ var _a, _b, _c, _d, _e;
1269
+ return {
1270
+ field: String((_a = field.name) != null ? _a : ""),
1271
+ validatorId: config.id || baseIssue.validatorId,
1272
+ code: baseIssue.code,
1273
+ messageKey: (_b = baseIssue.messageKey) != null ? _b : config.messageKey,
1274
+ message: (_c = baseIssue.message) != null ? _c : config.message,
1275
+ params: __spreadValues(__spreadValues({}, (_d = config.params) != null ? _d : {}), (_e = baseIssue.params) != null ? _e : {})
1276
+ };
1277
+ });
1278
+ };
1279
+ var resolveIssueMessage = (issue, t) => {
1280
+ const defaultMessageByCode = () => {
1281
+ var _a, _b, _c, _d, _e, _f;
1282
+ switch (issue.code) {
1283
+ case "required":
1284
+ return "This field is required";
1285
+ case "email":
1286
+ return "Invalid email address";
1287
+ case "pattern":
1288
+ return "Invalid format";
1289
+ case "minLength": {
1290
+ const min = (_c = (_a = issue.params) == null ? void 0 : _a.min) != null ? _c : (_b = issue.params) == null ? void 0 : _b.value;
1291
+ return min != null ? `Minimum ${String(min)} characters` : "Value is too short";
1292
+ }
1293
+ case "maxLength": {
1294
+ const max = (_f = (_d = issue.params) == null ? void 0 : _d.max) != null ? _f : (_e = issue.params) == null ? void 0 : _e.value;
1295
+ return max != null ? `Maximum ${String(max)} characters` : "Value is too long";
1296
+ }
1297
+ default:
1298
+ return void 0;
1299
+ }
1300
+ };
1301
+ if (issue.messageKey && t) {
1302
+ const translated = t(issue.messageKey, issue.params);
1303
+ if (typeof translated === "string" && translated.trim().length > 0) {
1304
+ return translated;
1305
+ }
1306
+ }
1307
+ if (issue.message && issue.message.trim().length > 0) return issue.message;
1308
+ if (issue.messageKey && issue.messageKey.trim().length > 0) return issue.messageKey;
1309
+ return defaultMessageByCode();
1310
+ };
1311
+ var validateFormValues = (fields, values, options) => {
1312
+ var _a;
1313
+ const mergedRegistry = __spreadValues(__spreadValues({}, defaultDeclarativeValidatorRegistry), (_a = options == null ? void 0 : options.registry) != null ? _a : {});
1314
+ const issues = [];
1315
+ fields.forEach((field) => {
1316
+ var _a2;
1317
+ const fieldName = String((_a2 = field.name) != null ? _a2 : "").trim();
1318
+ if (!fieldName) return;
1319
+ const fieldValue = values[fieldName];
1320
+ const validators = normalizeValidators(field, options);
1321
+ if (validators.length === 0) return;
1322
+ for (const validatorConfig of validators) {
1323
+ const fieldIssues = validateFieldWithConfig(
1324
+ field,
1325
+ fieldValue,
1326
+ values,
1327
+ validatorConfig,
1328
+ mergedRegistry
1329
+ );
1330
+ if (fieldIssues.length > 0) {
1331
+ issues.push(...fieldIssues);
1332
+ if (validatorConfig.stopOnFailure) break;
1333
+ }
1334
+ }
1335
+ });
1336
+ const errors = {};
1337
+ issues.forEach((issue) => {
1338
+ if (errors[issue.field]) return;
1339
+ errors[issue.field] = resolveIssueMessage(issue, options == null ? void 0 : options.t);
1340
+ });
1341
+ return { issues, errors };
1342
+ };
1343
+
1344
+ // src/utils/formStudio.ts
1345
+ var getLayoutRecord = (props) => {
1346
+ if (!props) return {};
1347
+ const layout = props.layout;
1348
+ if (!layout || typeof layout !== "object" || Array.isArray(layout)) {
1349
+ return {};
1350
+ }
1351
+ return layout;
1352
+ };
1353
+ var normalizeStudioFormChild = (child) => {
1354
+ var _a, _b, _c, _d, _e;
1355
+ const childProps = (_a = child.props) != null ? _a : {};
1356
+ const childLayout = getLayoutRecord(childProps);
1357
+ if (child.type === "__studio_form_field") {
1358
+ return __spreadProps(__spreadValues({}, child), {
1359
+ type: "FormField",
1360
+ props: __spreadProps(__spreadValues({}, childProps), {
1361
+ layout: __spreadProps(__spreadValues({}, childLayout), {
1362
+ formRole: "field"
1363
+ })
1364
+ })
1365
+ });
1366
+ }
1367
+ if (child.type === "__studio_form_title") {
1368
+ return __spreadProps(__spreadValues({}, child), {
1369
+ type: "Text",
1370
+ props: __spreadProps(__spreadValues({}, childProps), {
1371
+ layout: __spreadProps(__spreadValues({}, childLayout), {
1372
+ formRole: "title"
1373
+ })
1374
+ })
1375
+ });
1376
+ }
1377
+ if (child.type === "__studio_form_submit") {
1378
+ return __spreadProps(__spreadValues({}, child), {
1379
+ type: "Button",
1380
+ props: __spreadProps(__spreadValues({}, childProps), {
1381
+ intent: String((_b = childProps.intent) != null ? _b : "primary"),
1382
+ variant: String((_c = childProps.variant) != null ? _c : "solid"),
1383
+ layout: __spreadProps(__spreadValues({}, childLayout), {
1384
+ formRole: "submit"
1385
+ })
1386
+ })
1387
+ });
1388
+ }
1389
+ if (child.type === "__studio_form_reset") {
1390
+ return __spreadProps(__spreadValues({}, child), {
1391
+ type: "Button",
1392
+ props: __spreadProps(__spreadValues({}, childProps), {
1393
+ intent: String((_d = childProps.intent) != null ? _d : "neutral"),
1394
+ variant: String((_e = childProps.variant) != null ? _e : "outline"),
1395
+ layout: __spreadProps(__spreadValues({}, childLayout), {
1396
+ formRole: "reset"
1397
+ })
1398
+ })
1399
+ });
1400
+ }
1401
+ return child;
1402
+ };
1403
+ var getStudioFormChildRole = (child) => {
1404
+ var _a, _b;
1405
+ if (child.type === "__studio_form_field") return "field";
1406
+ if (child.type === "__studio_form_title") return "title";
1407
+ if (child.type === "__studio_form_submit") return "submit";
1408
+ if (child.type === "__studio_form_reset") return "reset";
1409
+ const layout = getLayoutRecord(
1410
+ (_a = child.props) != null ? _a : {}
1411
+ );
1412
+ return String((_b = layout.formRole) != null ? _b : "").trim();
1413
+ };
1414
+ var buildFormFieldConfig = (rawProps, nestedField = {}) => {
1415
+ var _a, _b, _c, _d;
1416
+ const fieldName = String((_b = (_a = rawProps.name) != null ? _a : nestedField.name) != null ? _b : "").trim();
1417
+ return __spreadProps(__spreadValues(__spreadValues({}, nestedField), rawProps), {
1418
+ name: fieldName,
1419
+ label: String((_d = (_c = rawProps.label) != null ? _c : nestedField.label) != null ? _d : fieldName)
1420
+ });
1421
+ };
1422
+ var buildWizardFieldConfig = (rawProps, nestedField) => {
1423
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
1424
+ const name = String((_b = (_a = rawProps.name) != null ? _a : nestedField.name) != null ? _b : "").trim();
1425
+ return {
1426
+ name,
1427
+ label: String((_d = (_c = rawProps.label) != null ? _c : nestedField.label) != null ? _d : name || "Field"),
1428
+ type: (_e = rawProps.type) != null ? _e : nestedField.type,
1429
+ required: Boolean((_g = (_f = rawProps.required) != null ? _f : nestedField.required) != null ? _g : false),
1430
+ pattern: rawProps.pattern != null ? String(rawProps.pattern) : nestedField.pattern != null ? String(nestedField.pattern) : void 0,
1431
+ placeholder: (_h = rawProps.placeholder) != null ? _h : nestedField.placeholder,
1432
+ validators: Array.isArray(rawProps.validators) && rawProps.validators.length > 0 ? rawProps.validators : Array.isArray(nestedField.validators) && nestedField.validators.length > 0 ? nestedField.validators : void 0,
1433
+ options: (_i = rawProps.options) != null ? _i : nestedField.options,
1434
+ helperText: (_j = rawProps.helperText) != null ? _j : nestedField.helperText,
1435
+ defaultValue: (_k = rawProps.defaultValue) != null ? _k : nestedField.defaultValue,
1436
+ rows: (_l = rawProps.rows) != null ? _l : nestedField.rows,
1437
+ accept: (_m = rawProps.accept) != null ? _m : nestedField.accept
1438
+ };
1439
+ };
1440
+
1441
+ // src/layout/nodeLayout.ts
1442
+ var toPositiveNumber = (value) => {
1443
+ const numeric = Number(value);
1444
+ if (!Number.isFinite(numeric) || numeric <= 0) return void 0;
1445
+ return numeric;
1446
+ };
1447
+ var toColSpan = (value) => {
1448
+ const numeric = Number(value);
1449
+ if (!Number.isInteger(numeric) || numeric < 1 || numeric > 12) return void 0;
1450
+ return numeric;
1451
+ };
1452
+ var toCardSection = (value) => {
1453
+ if (value === "header" || value === "body" || value === "footer") return value;
1454
+ return void 0;
1455
+ };
1456
+ var readNodeLayout = (props) => {
1457
+ var _a, _b, _c, _d, _e, _f, _g;
1458
+ if (!props) return {};
1459
+ const rawLayout = props.layout && typeof props.layout === "object" && !Array.isArray(props.layout) ? props.layout : {};
1460
+ return {
1461
+ widthPct: toPositiveNumber((_a = rawLayout.widthPct) != null ? _a : props.__studioWidthPct),
1462
+ heightPct: toPositiveNumber((_b = rawLayout.heightPct) != null ? _b : props.__studioHeightPct),
1463
+ heightPx: toPositiveNumber((_c = rawLayout.heightPx) != null ? _c : props.__studioHeightPx),
1464
+ colSpan: toColSpan((_d = rawLayout.colSpan) != null ? _d : props.__studioColSpan),
1465
+ wrapperClassName: String(
1466
+ (_f = (_e = rawLayout.wrapperClassName) != null ? _e : props.__studioWrapperClassName) != null ? _f : ""
1467
+ ).trim(),
1468
+ cardSection: toCardSection((_g = rawLayout.cardSection) != null ? _g : props.__studioCardSection)
1469
+ };
1470
+ };
1471
+ var writeNodeLayout = (node, nextLayout) => {
1472
+ var _a;
1473
+ const currentProps = (_a = node.props) != null ? _a : {};
1474
+ const currentLayout = readNodeLayout(currentProps);
1475
+ const mergedLayout = __spreadValues(__spreadValues({}, currentLayout), nextLayout);
1476
+ const cleanLayout = {};
1477
+ if (mergedLayout.widthPct !== void 0) cleanLayout.widthPct = mergedLayout.widthPct;
1478
+ if (mergedLayout.heightPct !== void 0) cleanLayout.heightPct = mergedLayout.heightPct;
1479
+ if (mergedLayout.heightPx !== void 0) cleanLayout.heightPx = mergedLayout.heightPx;
1480
+ if (mergedLayout.colSpan !== void 0) cleanLayout.colSpan = mergedLayout.colSpan;
1481
+ if (mergedLayout.wrapperClassName) cleanLayout.wrapperClassName = mergedLayout.wrapperClassName;
1482
+ if (mergedLayout.cardSection) cleanLayout.cardSection = mergedLayout.cardSection;
1483
+ const nextProps = __spreadValues({}, currentProps);
1484
+ if (Object.keys(cleanLayout).length > 0) {
1485
+ nextProps.layout = cleanLayout;
1486
+ } else {
1487
+ delete nextProps.layout;
1488
+ }
1489
+ delete nextProps.__studioWidthPct;
1490
+ delete nextProps.__studioHeightPct;
1491
+ delete nextProps.__studioHeightPx;
1492
+ delete nextProps.__studioColSpan;
1493
+ delete nextProps.__studioWrapperClassName;
1494
+ delete nextProps.__studioCardSection;
1495
+ return __spreadProps(__spreadValues({}, node), {
1496
+ props: nextProps
1497
+ });
1498
+ };
1499
+
1500
+ // src/studio-bridge/preview-form/previewFormState.ts
1501
+ var resolveStudioFormNextValues = ({
1502
+ formValues,
1503
+ fieldName,
1504
+ nextValue
1505
+ }) => __spreadProps(__spreadValues({}, formValues), {
1506
+ [fieldName]: nextValue
1507
+ });
1508
+ var resolveStudioFormResetValues = (normalizedFormFields) => normalizedFormFields.reduce((accumulator, field) => {
1509
+ var _a, _b;
1510
+ const fieldName = String((_a = field.name) != null ? _a : "").trim();
1511
+ if (!fieldName) return accumulator;
1512
+ accumulator[fieldName] = (_b = field.defaultValue) != null ? _b : "";
1513
+ return accumulator;
1514
+ }, {});
1515
+ var patchStudioFormFieldNode = ({
1516
+ child,
1517
+ formValues,
1518
+ formErrors,
1519
+ formDict,
1520
+ formLoaderType,
1521
+ fieldOnChange
1522
+ }) => {
1523
+ var _a, _b, _c;
1524
+ const rawChildProps = (_a = child.props) != null ? _a : {};
1525
+ const childLayout = readNodeLayout(rawChildProps);
1526
+ const rawLayout = rawChildProps.layout && typeof rawChildProps.layout === "object" && !Array.isArray(rawChildProps.layout) ? __spreadValues({}, rawChildProps.layout) : {};
1527
+ const existingWrapperClassName = String((_b = rawLayout.wrapperClassName) != null ? _b : "").trim();
1528
+ rawLayout.wrapperClassName = [existingWrapperClassName, "w-full", "max-w-full"].filter(Boolean).join(" ");
1529
+ delete rawLayout.widthPct;
1530
+ delete rawLayout.heightPct;
1531
+ delete rawLayout.heightPx;
1532
+ const fieldBasis = childLayout.widthPct !== null ? `${childLayout.widthPct}%` : "100%";
1533
+ const nestedField = rawChildProps.field && typeof rawChildProps.field === "object" && !Array.isArray(rawChildProps.field) ? rawChildProps.field : {};
1534
+ const fieldConfig = buildFormFieldConfig(rawChildProps, nestedField);
1535
+ const fieldName = String((_c = fieldConfig.name) != null ? _c : "").trim();
1536
+ const value = fieldName && fieldName in formValues ? formValues[fieldName] : rawChildProps.defaultValue;
1537
+ const patchedFieldNode = __spreadProps(__spreadValues({}, child), {
1538
+ props: __spreadValues(__spreadProps(__spreadValues({}, rawChildProps), {
1539
+ layout: rawLayout,
1540
+ field: fieldConfig,
1541
+ value,
1542
+ error: fieldName ? formErrors[fieldName] : void 0,
1543
+ onChange: fieldOnChange,
1544
+ dict: formDict
1545
+ }), formLoaderType !== void 0 ? { loaderType: formLoaderType } : {})
1546
+ });
1547
+ return {
1548
+ patchedFieldNode,
1549
+ fieldBasis
1550
+ };
1551
+ };
1552
+
1553
+ // src/studio-bridge/preview-form/previewFormStructure.ts
1554
+ var DEFAULT_FORM_DICT = {
1555
+ submit: "Submit",
1556
+ reset: "Reset",
1557
+ loading: "Loading...",
1558
+ success: "Saved",
1559
+ search: "Search...",
1560
+ noResultToShow: "No result"
1561
+ };
1562
+ var resolveStudioFormStructure = ({
1563
+ componentProps,
1564
+ visibleChildren
1565
+ }) => {
1566
+ const normalizedChildren = visibleChildren.map((child) => normalizeStudioFormChild(child));
1567
+ const titleNode = normalizedChildren.find((child) => getStudioFormChildRole(child) === "title");
1568
+ const fieldNodes = normalizedChildren.filter((child) => getStudioFormChildRole(child) === "field");
1569
+ const submitNode = normalizedChildren.find((child) => getStudioFormChildRole(child) === "submit");
1570
+ const resetNode = normalizedChildren.find((child) => getStudioFormChildRole(child) === "reset");
1571
+ const externalChildren = normalizedChildren.filter((child) => {
1572
+ const role = getStudioFormChildRole(child);
1573
+ return role !== "title" && role !== "field" && role !== "submit" && role !== "reset";
1574
+ });
1575
+ const formValues = componentProps.values && typeof componentProps.values === "object" && !Array.isArray(componentProps.values) ? componentProps.values : {};
1576
+ const formErrors = componentProps.errors && typeof componentProps.errors === "object" && !Array.isArray(componentProps.errors) ? componentProps.errors : {};
1577
+ const formDict = componentProps.dict && typeof componentProps.dict === "object" && !Array.isArray(componentProps.dict) ? componentProps.dict : DEFAULT_FORM_DICT;
1578
+ const normalizedFormFields = fieldNodes.map((child) => {
1579
+ var _a;
1580
+ const rawChildProps = (_a = child.props) != null ? _a : {};
1581
+ const nestedField = rawChildProps.field && typeof rawChildProps.field === "object" && !Array.isArray(rawChildProps.field) ? rawChildProps.field : {};
1582
+ return buildFormFieldConfig(rawChildProps, nestedField);
1583
+ }).filter((field) => {
1584
+ var _a;
1585
+ return String((_a = field.name) != null ? _a : "").trim().length > 0;
1586
+ });
1587
+ return {
1588
+ normalizedChildren,
1589
+ titleNode,
1590
+ fieldNodes,
1591
+ submitNode,
1592
+ resetNode,
1593
+ externalChildren,
1594
+ normalizedFormFields,
1595
+ formValues,
1596
+ formErrors,
1597
+ formDict,
1598
+ formLoaderType: componentProps.loaderType
1599
+ };
1600
+ };
1601
+
1602
+ // src/studio-bridge/preview-form/previewFormRenderer.tsx
1603
+ import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
1604
+ var materializePreviewForm = ({
1605
+ node,
1606
+ componentProps,
1607
+ visibleChildren,
1608
+ runtime,
1609
+ onInlineTextEdit,
1610
+ captureFieldFocus,
1611
+ renderSafeNode: renderSafeNode2
1612
+ }) => {
1613
+ var _a, _b, _c, _d, _e, _f, _g;
1614
+ const {
1615
+ titleNode,
1616
+ fieldNodes,
1617
+ submitNode,
1618
+ resetNode,
1619
+ externalChildren,
1620
+ normalizedFormFields,
1621
+ formValues,
1622
+ formErrors,
1623
+ formDict,
1624
+ formLoaderType
1625
+ } = resolveStudioFormStructure({
1626
+ componentProps,
1627
+ visibleChildren
1628
+ });
1629
+ if (!(fieldNodes.length > 0 || titleNode || submitNode || resetNode)) {
1630
+ return null;
1631
+ }
1632
+ const validateAndSetErrors = (nextValues) => {
1633
+ const validation = validateFormValues(normalizedFormFields, nextValues, {
1634
+ t: runtime.t,
1635
+ useLegacyFieldConstraints: true
1636
+ });
1637
+ onInlineTextEdit == null ? void 0 : onInlineTextEdit(node.id, "errors", validation.errors);
1638
+ return validation;
1639
+ };
1640
+ const fieldOnChange = (event) => {
1641
+ var _a2;
1642
+ captureFieldFocus(event.target);
1643
+ const fieldName = String((_a2 = event.target.name) != null ? _a2 : "").trim();
1644
+ if (!fieldName) return;
1645
+ const target = event.target;
1646
+ const nextValue = target.type === "checkbox" ? Boolean(target.checked) : event.target.value;
1647
+ const nextValues = resolveStudioFormNextValues({
1648
+ formValues,
1649
+ fieldName,
1650
+ nextValue
1651
+ });
1652
+ onInlineTextEdit == null ? void 0 : onInlineTextEdit(node.id, "values", nextValues);
1653
+ validateAndSetErrors(nextValues);
1654
+ };
1655
+ const openInlineEditorForFormDictProp = (propName, fallbackValue) => {
1656
+ onInlineTextEdit == null ? void 0 : onInlineTextEdit(node.id, propName, fallbackValue);
1657
+ };
1658
+ const openInlineEditorForFormNodeProp = (targetNodeId, fallbackValue) => {
1659
+ onInlineTextEdit == null ? void 0 : onInlineTextEdit(targetNodeId, "children", fallbackValue);
1660
+ };
1661
+ return /* @__PURE__ */ jsxs2("div", { className: "mx-auto mt-10 w-full min-w-0 rounded-2xl border border-border bg-background p-6 shadow-sm", children: [
1662
+ titleNode ? /* @__PURE__ */ jsx5("div", { className: "mb-6 text-center", children: renderSafeNode2(__spreadProps(__spreadValues({}, titleNode), {
1663
+ type: "H3",
1664
+ props: __spreadProps(__spreadValues({}, (_a = titleNode.props) != null ? _a : {}), {
1665
+ className: "text-center text-2xl font-semibold text-foreground",
1666
+ layout: __spreadProps(__spreadValues({}, getLayoutRecord(
1667
+ (_b = titleNode.props) != null ? _b : {}
1668
+ )), {
1669
+ formRole: "title"
1670
+ })
1671
+ })
1672
+ })) }) : /* @__PURE__ */ jsx5("h3", { className: "mb-6 text-center text-2xl font-semibold text-foreground", children: String((_c = componentProps.title) != null ? _c : "Form") }),
1673
+ /* @__PURE__ */ jsxs2(
1674
+ "form",
1675
+ {
1676
+ className: "flex flex-wrap items-start gap-x-3 gap-y-3",
1677
+ role: "form",
1678
+ onSubmit: (event) => {
1679
+ event.preventDefault();
1680
+ const validation = validateAndSetErrors(formValues);
1681
+ if (Object.keys(validation.errors).length > 0) return;
1682
+ },
1683
+ children: [
1684
+ fieldNodes.map((child) => {
1685
+ const { patchedFieldNode, fieldBasis } = patchStudioFormFieldNode({
1686
+ child,
1687
+ formValues,
1688
+ formErrors,
1689
+ formDict,
1690
+ formLoaderType,
1691
+ fieldOnChange
1692
+ });
1693
+ return /* @__PURE__ */ jsx5("div", { className: "contents", children: /* @__PURE__ */ jsx5("div", { style: { flex: `0 0 ${fieldBasis}`, maxWidth: fieldBasis }, children: /* @__PURE__ */ jsx5("div", { className: "min-w-0", children: renderSafeNode2(patchedFieldNode) }) }) }, child.id);
1694
+ }),
1695
+ submitNode || resetNode ? /* @__PURE__ */ jsxs2("div", { className: "basis-full flex flex-wrap justify-end gap-3 py-4", children: [
1696
+ submitNode ? renderSafeNode2(__spreadProps(__spreadValues({}, submitNode), {
1697
+ props: __spreadProps(__spreadValues({}, (_d = submitNode.props) != null ? _d : {}), {
1698
+ type: "submit",
1699
+ onDoubleClick: (event) => {
1700
+ var _a2, _b2, _c2;
1701
+ event.preventDefault();
1702
+ event.stopPropagation();
1703
+ openInlineEditorForFormNodeProp(
1704
+ submitNode.id,
1705
+ String(
1706
+ (_c2 = (_b2 = (_a2 = submitNode.props) == null ? void 0 : _a2.children) != null ? _b2 : formDict.submit) != null ? _c2 : "Submit"
1707
+ )
1708
+ );
1709
+ }
1710
+ })
1711
+ })) : null,
1712
+ resetNode ? renderSafeNode2(__spreadProps(__spreadValues({}, resetNode), {
1713
+ props: __spreadProps(__spreadValues({}, (_e = resetNode.props) != null ? _e : {}), {
1714
+ type: "button",
1715
+ onClick: () => {
1716
+ const resetValues = resolveStudioFormResetValues(normalizedFormFields);
1717
+ onInlineTextEdit == null ? void 0 : onInlineTextEdit(node.id, "values", resetValues);
1718
+ onInlineTextEdit == null ? void 0 : onInlineTextEdit(node.id, "errors", {});
1719
+ },
1720
+ onDoubleClick: (event) => {
1721
+ var _a2, _b2, _c2;
1722
+ event.preventDefault();
1723
+ event.stopPropagation();
1724
+ openInlineEditorForFormNodeProp(
1725
+ resetNode.id,
1726
+ String(
1727
+ (_c2 = (_b2 = (_a2 = resetNode.props) == null ? void 0 : _a2.children) != null ? _b2 : formDict.reset) != null ? _c2 : "Reset"
1728
+ )
1729
+ );
1730
+ }
1731
+ })
1732
+ })) : null
1733
+ ] }) : componentProps.onSubmit || componentProps.onReset ? /* @__PURE__ */ jsxs2("div", { className: "basis-full flex flex-wrap justify-end gap-3 py-4", children: [
1734
+ componentProps.onSubmit ? /* @__PURE__ */ jsx5(
1735
+ "button",
1736
+ {
1737
+ type: "submit",
1738
+ className: "inline-flex items-center justify-center rounded-md border border-primary bg-primary px-4 py-2 text-sm font-medium text-primary-foreground",
1739
+ onDoubleClick: (event) => {
1740
+ var _a2;
1741
+ event.preventDefault();
1742
+ event.stopPropagation();
1743
+ openInlineEditorForFormDictProp("dict.submit", String((_a2 = formDict.submit) != null ? _a2 : "Submit"));
1744
+ },
1745
+ children: String((_f = formDict.submit) != null ? _f : "Submit")
1746
+ }
1747
+ ) : null,
1748
+ componentProps.onReset ? /* @__PURE__ */ jsx5(
1749
+ "button",
1750
+ {
1751
+ type: "button",
1752
+ className: "inline-flex items-center justify-center rounded-md border border-border bg-background px-4 py-2 text-sm font-medium text-foreground",
1753
+ onClick: () => {
1754
+ const resetValues = resolveStudioFormResetValues(normalizedFormFields);
1755
+ onInlineTextEdit == null ? void 0 : onInlineTextEdit(node.id, "values", resetValues);
1756
+ onInlineTextEdit == null ? void 0 : onInlineTextEdit(node.id, "errors", {});
1757
+ },
1758
+ onDoubleClick: (event) => {
1759
+ var _a2;
1760
+ event.preventDefault();
1761
+ event.stopPropagation();
1762
+ openInlineEditorForFormDictProp("dict.reset", String((_a2 = formDict.reset) != null ? _a2 : "Reset"));
1763
+ },
1764
+ children: String((_g = formDict.reset) != null ? _g : "Reset")
1765
+ }
1766
+ ) : null
1767
+ ] }) : null,
1768
+ externalChildren.map((child) => /* @__PURE__ */ jsx5(React.Fragment, { children: renderSafeNode2(child) }, child.id))
1769
+ ]
1770
+ }
1771
+ )
1772
+ ] });
1773
+ };
1774
+
1775
+ // src/utils/navigationStudio.tsx
1776
+ import {
1777
+ buildAccordionItems,
1778
+ buildExpandablePanelChildren
1779
+ } from "@arkcit/engine-react";
1780
+
1781
+ // src/runtime/bindings.ts
1782
+ var DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
1783
+ var MISSING_TRANSLATION_FALLBACK = "Lorem ipsum dolor sit amet. (fallback)";
1784
+ var MISSING_REF_FALLBACK = "Lorem ipsum dolor sit amet. (fallback)";
1785
+ var isPlainObject = (value) => {
1786
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
1787
+ const prototype = Object.getPrototypeOf(value);
1788
+ return prototype === Object.prototype || prototype === null;
1789
+ };
1790
+ var isReactElementLike = (value) => isPlainObject(value) && typeof value.$$typeof === "symbol" && "props" in value;
1791
+ var isTranslationValue = (value) => isPlainObject(value) && typeof value.$t === "string";
1792
+ var isRefValue = (value) => isPlainObject(value) && typeof value.$ref === "string";
1793
+ var isExprValue = (value) => isPlainObject(value) && typeof value.$expr === "string";
1794
+ var parseStructuredString = (value) => {
1795
+ if (typeof value !== "string") return value;
1796
+ const trimmed = value.trim();
1797
+ if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) return value;
1798
+ try {
1799
+ const parsed = JSON.parse(trimmed);
1800
+ if (!isPlainObject(parsed)) return value;
1801
+ if ((typeof parsed.$ref === "string" || typeof parsed.$t === "string") && Object.keys(parsed).length >= 1) {
1802
+ return parsed;
1803
+ }
1804
+ return value;
1805
+ } catch (e) {
1806
+ return value;
1807
+ }
1808
+ };
1809
+ var resolveUIValue = (value, runtime) => {
1810
+ const normalizedValue = parseStructuredString(value);
1811
+ if (isTranslationValue(normalizedValue)) {
1812
+ const fallback = typeof normalizedValue.defaultValue === "string" && normalizedValue.defaultValue.trim() ? normalizedValue.defaultValue : normalizedValue.$t;
1813
+ if (!runtime.t) return fallback || MISSING_TRANSLATION_FALLBACK;
1814
+ const translated = runtime.t(normalizedValue.$t, normalizedValue.values);
1815
+ if (typeof translated !== "string") return fallback || MISSING_TRANSLATION_FALLBACK;
1816
+ if (!translated.trim()) return fallback || MISSING_TRANSLATION_FALLBACK;
1817
+ if (translated === normalizedValue.$t) return fallback || MISSING_TRANSLATION_FALLBACK;
1818
+ return translated;
1819
+ }
1820
+ if (isRefValue(normalizedValue)) {
1821
+ const resolved = runtime.get(normalizedValue.$ref);
1822
+ if (resolved == null) return MISSING_REF_FALLBACK;
1823
+ if (typeof resolved === "string" && !resolved.trim()) return MISSING_REF_FALLBACK;
1824
+ return resolved;
1825
+ }
1826
+ if (isExprValue(normalizedValue)) {
1827
+ return void 0;
1828
+ }
1829
+ if (Array.isArray(normalizedValue)) {
1830
+ return normalizedValue.map((item) => resolveUIValue(item, runtime));
1831
+ }
1832
+ if (isReactElementLike(normalizedValue)) {
1833
+ return normalizedValue;
1834
+ }
1835
+ if (isPlainObject(normalizedValue)) {
1836
+ const next = {};
1837
+ Object.entries(normalizedValue).forEach(([key, childValue]) => {
1838
+ if (DANGEROUS_KEYS.has(key)) return;
1839
+ next[key] = resolveUIValue(childValue, runtime);
1840
+ });
1841
+ return next;
1842
+ }
1843
+ return normalizedValue;
1844
+ };
1845
+
1846
+ // src/studio-bridge/preview-navigation/previewTabs.ts
1847
+ var normalizeStudioTabsProps = (props) => {
1848
+ var _a;
1849
+ const rawTabs = Array.isArray(props.tabs) ? props.tabs : [];
1850
+ const tabs = rawTabs.length ? rawTabs.map((tab, index) => {
1851
+ var _a2, _b, _c;
1852
+ const rawTab = tab && typeof tab === "object" && !Array.isArray(tab) ? tab : {};
1853
+ const id = String((_a2 = rawTab.id) != null ? _a2 : `tab-${index + 1}`);
1854
+ const title = (_c = (_b = rawTab.title) != null ? _b : rawTab.label) != null ? _c : `Tab ${index + 1}`;
1855
+ return __spreadProps(__spreadValues({}, rawTab), {
1856
+ id,
1857
+ title,
1858
+ label: title
1859
+ });
1860
+ }) : [
1861
+ {
1862
+ id: "overview",
1863
+ title: "Overview",
1864
+ label: "Overview",
1865
+ content: "Overview content"
1866
+ }
1867
+ ];
1868
+ const rawDict = props.dict && typeof props.dict === "object" && !Array.isArray(props.dict) ? props.dict : {};
1869
+ const rawUrlSync = props.urlSync && typeof props.urlSync === "object" && !Array.isArray(props.urlSync) ? props.urlSync : null;
1870
+ const rawNavigation = (rawUrlSync == null ? void 0 : rawUrlSync.navigation) && typeof rawUrlSync.navigation === "object" && !Array.isArray(rawUrlSync.navigation) ? rawUrlSync.navigation : null;
1871
+ const normalizedUrlSync = rawNavigation && typeof rawNavigation.getSearch === "function" && typeof rawNavigation.replaceSearch === "function" ? __spreadProps(__spreadValues({}, rawUrlSync), {
1872
+ navigation: rawNavigation
1873
+ }) : void 0;
1874
+ return __spreadProps(__spreadValues({}, props), {
1875
+ tabs,
1876
+ dict: __spreadProps(__spreadValues({}, rawDict), {
1877
+ noContentYet: typeof rawDict.noContentYet === "string" && rawDict.noContentYet.trim().length > 0 ? rawDict.noContentYet : "No content yet"
1878
+ }),
1879
+ defaultActive: typeof props.defaultActive === "string" && props.defaultActive.trim().length > 0 ? props.defaultActive : String((_a = tabs[0].id) != null ? _a : "overview"),
1880
+ keepMounted: typeof props.keepMounted === "boolean" ? props.keepMounted : true,
1881
+ urlSync: normalizedUrlSync
1882
+ });
1883
+ };
1884
+ var resolveStudioTabsContent = ({
1885
+ tabItems,
1886
+ rawChildren,
1887
+ runtime,
1888
+ renderChild,
1889
+ normalizeRenderableChild: normalizeRenderableChild2
1890
+ }) => {
1891
+ const childrenByTabId = /* @__PURE__ */ new Map();
1892
+ const unassignedChildren = [];
1893
+ rawChildren.forEach((child) => {
1894
+ var _a, _b, _c;
1895
+ const childProps = (_a = child.props) != null ? _a : {};
1896
+ const rawLayout = childProps.layout && typeof childProps.layout === "object" && !Array.isArray(childProps.layout) ? childProps.layout : {};
1897
+ const tabIdFromLayout = (_b = rawLayout.tabId) != null ? _b : childProps.__studioTabId;
1898
+ const resolvedTabId = resolveUIValue(tabIdFromLayout, runtime);
1899
+ const normalizedTabId = String(resolvedTabId != null ? resolvedTabId : "").trim();
1900
+ if (!normalizedTabId) {
1901
+ unassignedChildren.push(child);
1902
+ return;
1903
+ }
1904
+ const existing = (_c = childrenByTabId.get(normalizedTabId)) != null ? _c : [];
1905
+ existing.push(child);
1906
+ childrenByTabId.set(normalizedTabId, existing);
1907
+ });
1908
+ return tabItems.map((item, index) => {
1909
+ var _a, _b, _c, _d;
1910
+ const rawId = (_a = item.id) != null ? _a : `tab-${index + 1}`;
1911
+ const resolvedId = resolveUIValue(rawId, runtime);
1912
+ const normalizedId = String(
1913
+ resolvedId == null || String(resolvedId).trim().length === 0 ? rawId : resolvedId
1914
+ );
1915
+ const rawTitle = (_b = item.title) != null ? _b : item.label;
1916
+ const resolvedTitle = resolveUIValue(rawTitle, runtime);
1917
+ const normalizedTitle = (_c = resolvedTitle != null ? resolvedTitle : rawTitle) != null ? _c : `Tab ${index + 1}`;
1918
+ const mappedChildren = (_d = childrenByTabId.get(normalizedId)) != null ? _d : [];
1919
+ const fallbackChildren = index === 0 ? unassignedChildren : [];
1920
+ const contentNodes = [...mappedChildren, ...fallbackChildren];
1921
+ const contentFromChildren = contentNodes.length > 0 ? contentNodes.length === 1 ? renderChild(contentNodes[0]) : contentNodes.map((child) => renderChild(child)) : null;
1922
+ return __spreadProps(__spreadValues({}, item), {
1923
+ id: normalizedId,
1924
+ title: normalizedTitle,
1925
+ label: normalizedTitle,
1926
+ content: contentFromChildren != null ? contentFromChildren : normalizeRenderableChild2(item.content)
1927
+ });
1928
+ });
1929
+ };
1930
+ var resolveStudioTabsProps = ({
1931
+ componentProps,
1932
+ tabItems,
1933
+ rawChildren,
1934
+ runtime,
1935
+ renderChild,
1936
+ normalizeRenderableChild: normalizeRenderableChild2
1937
+ }) => {
1938
+ const normalizedProps = normalizeStudioTabsProps(componentProps);
1939
+ const resolvedTabs = resolveStudioTabsContent({
1940
+ tabItems: Array.isArray(normalizedProps.tabs) ? normalizedProps.tabs : tabItems,
1941
+ rawChildren,
1942
+ runtime,
1943
+ renderChild,
1944
+ normalizeRenderableChild: normalizeRenderableChild2
1945
+ });
1946
+ return {
1947
+ normalizedProps,
1948
+ resolvedTabs
1949
+ };
1950
+ };
1951
+
1952
+ // src/studio-bridge/preview-navigation/previewNavigationState.ts
1953
+ var findContainingNodeId = (targetNodeId, candidates, idResolver) => {
1954
+ const containsNode = (candidate) => {
1955
+ var _a;
1956
+ if (candidate.id === targetNodeId) return true;
1957
+ return ((_a = candidate.children) != null ? _a : []).some((nested) => containsNode(nested));
1958
+ };
1959
+ for (const candidate of candidates) {
1960
+ if (containsNode(candidate)) {
1961
+ return idResolver(candidate);
1962
+ }
1963
+ }
1964
+ return null;
1965
+ };
1966
+ var resolveAccordionOpenIds = ({
1967
+ itemIds,
1968
+ persistedOpenIds,
1969
+ selectedItemId,
1970
+ allowMultiple
1971
+ }) => {
1972
+ let effectiveOpenIds = persistedOpenIds.filter((id) => itemIds.includes(id));
1973
+ if (selectedItemId) {
1974
+ effectiveOpenIds = allowMultiple ? Array.from(/* @__PURE__ */ new Set([...effectiveOpenIds, selectedItemId])) : [selectedItemId];
1975
+ } else if (effectiveOpenIds.length === 0 && itemIds[0]) {
1976
+ effectiveOpenIds = [itemIds[0]];
1977
+ }
1978
+ return effectiveOpenIds;
1979
+ };
1980
+ var resolveStudioAccordionState = ({
1981
+ nodeId,
1982
+ accordionChildren,
1983
+ itemIds,
1984
+ selectedNodeId,
1985
+ accordionOpenIdsByNodeId,
1986
+ allowMultiple
1987
+ }) => {
1988
+ var _a;
1989
+ const validItemIds = new Set(itemIds);
1990
+ const persistedOpenIds = ((_a = accordionOpenIdsByNodeId[nodeId]) != null ? _a : []).filter(
1991
+ (id) => validItemIds.has(id)
1992
+ );
1993
+ const selectedItemId = selectedNodeId != null ? findContainingNodeId(
1994
+ selectedNodeId,
1995
+ accordionChildren,
1996
+ (candidate) => {
1997
+ var _a2, _b;
1998
+ return String((_b = ((_a2 = candidate.props) != null ? _a2 : {}).id) != null ? _b : candidate.id);
1999
+ }
2000
+ ) : null;
2001
+ const effectiveOpenIds = resolveAccordionOpenIds({
2002
+ itemIds,
2003
+ persistedOpenIds,
2004
+ selectedItemId,
2005
+ allowMultiple
2006
+ });
2007
+ return {
2008
+ validItemIds,
2009
+ effectiveOpenIds
2010
+ };
2011
+ };
2012
+ var resolveStudioExpandablePanelState = ({
2013
+ nodeId,
2014
+ expandablePanelOpenByNodeId
2015
+ }) => {
2016
+ var _a;
2017
+ return {
2018
+ controlledOpen: (_a = expandablePanelOpenByNodeId[nodeId]) != null ? _a : true,
2019
+ defaultOpen: true,
2020
+ disableAnimation: true
2021
+ };
2022
+ };
2023
+
2024
+ // src/studio-bridge/preview-navigation/previewNavigationConfigurators.tsx
2025
+ var configurePreviewAccordion = ({
2026
+ node,
2027
+ componentProps,
2028
+ accordionChildren,
2029
+ selectedNodeId,
2030
+ accordionOpenIdsByNodeId,
2031
+ setAccordionOpenIdsByNodeId,
2032
+ renderSafeNode: renderSafeNode2
2033
+ }) => {
2034
+ const items = buildAccordionItems(accordionChildren, renderSafeNode2);
2035
+ componentProps.items = items;
2036
+ const { validItemIds, effectiveOpenIds } = resolveStudioAccordionState({
2037
+ nodeId: node.id,
2038
+ accordionChildren,
2039
+ itemIds: items.map((item) => item.id),
2040
+ selectedNodeId,
2041
+ accordionOpenIdsByNodeId,
2042
+ allowMultiple: Boolean(componentProps.allowMultiple)
2043
+ });
2044
+ componentProps.openIds = effectiveOpenIds;
2045
+ componentProps.defaultOpenIds = effectiveOpenIds;
2046
+ componentProps.onOpenIdsChange = (nextOpenIds) => {
2047
+ setAccordionOpenIdsByNodeId((previous) => __spreadProps(__spreadValues({}, previous), {
2048
+ [node.id]: nextOpenIds.filter((id) => validItemIds.has(id))
2049
+ }));
2050
+ };
2051
+ };
2052
+ var configurePreviewExpandablePanel = ({
2053
+ node,
2054
+ componentProps,
2055
+ panelChildren,
2056
+ expandablePanelOpenByNodeId,
2057
+ setExpandablePanelOpenByNodeId,
2058
+ renderSafeNode: renderSafeNode2
2059
+ }) => {
2060
+ const { controlledOpen, defaultOpen, disableAnimation } = resolveStudioExpandablePanelState({
2061
+ nodeId: node.id,
2062
+ expandablePanelOpenByNodeId
2063
+ });
2064
+ componentProps.open = controlledOpen;
2065
+ componentProps.defaultOpen = defaultOpen;
2066
+ componentProps.disableAnimation = disableAnimation;
2067
+ componentProps.onOpenChange = (nextOpen) => {
2068
+ setExpandablePanelOpenByNodeId((previous) => __spreadProps(__spreadValues({}, previous), {
2069
+ [node.id]: Boolean(nextOpen)
2070
+ }));
2071
+ };
2072
+ const panelContent = buildExpandablePanelChildren(panelChildren, renderSafeNode2);
2073
+ if (panelContent) {
2074
+ componentProps.children = panelContent;
2075
+ }
2076
+ };
2077
+ var configurePreviewTabs = ({
2078
+ componentProps,
2079
+ tabItems,
2080
+ rawChildren,
2081
+ runtime,
2082
+ renderSafeNode: renderSafeNode2,
2083
+ normalizeRenderableChild: normalizeRenderableChild2
2084
+ }) => {
2085
+ const { normalizedProps, resolvedTabs } = resolveStudioTabsProps({
2086
+ componentProps,
2087
+ tabItems,
2088
+ rawChildren,
2089
+ runtime,
2090
+ renderChild: renderSafeNode2,
2091
+ normalizeRenderableChild: normalizeRenderableChild2
2092
+ });
2093
+ Object.assign(componentProps, normalizedProps);
2094
+ componentProps.tabs = resolvedTabs;
2095
+ delete componentProps.children;
2096
+ };
2097
+
2098
+ // src/studio-bridge/preview-wizard/previewWizardMaterialization.ts
2099
+ import React2 from "react";
2100
+
2101
+ // src/studio-bridge/preview-wizard/previewWizardFormState.ts
2102
+ var resolveStudioWizardNextValues = ({
2103
+ rawWizardValues,
2104
+ fieldName,
2105
+ nextValue
2106
+ }) => __spreadProps(__spreadValues({}, rawWizardValues), {
2107
+ [fieldName]: nextValue
2108
+ });
2109
+ var resolveStudioWizardActiveStepFields = ({
2110
+ stepId,
2111
+ stepIdToNode
2112
+ }) => {
2113
+ var _a;
2114
+ const activeStepNode = stepIdToNode[stepId];
2115
+ return ((_a = activeStepNode == null ? void 0 : activeStepNode.children) != null ? _a : []).filter((child) => child.type === "FormField").map((child) => {
2116
+ var _a2;
2117
+ const childProps = (_a2 = child.props) != null ? _a2 : {};
2118
+ const childFieldObj = childProps.field && typeof childProps.field === "object" && !Array.isArray(childProps.field) ? childProps.field : {};
2119
+ return buildWizardFieldConfig(childProps, childFieldObj);
2120
+ }).filter((field) => {
2121
+ var _a2;
2122
+ return String((_a2 = field.name) != null ? _a2 : "").trim().length > 0;
2123
+ });
2124
+ };
2125
+ var resolveStudioWizardNextErrors = ({
2126
+ currentWizardErrors,
2127
+ activeStepFields,
2128
+ nextValues,
2129
+ runtime
2130
+ }) => {
2131
+ const validation = validateFormValues(activeStepFields, nextValues, {
2132
+ t: runtime.t,
2133
+ useLegacyFieldConstraints: true
2134
+ });
2135
+ const activeStepFieldNames = new Set(
2136
+ activeStepFields.map((field) => {
2137
+ var _a;
2138
+ return String((_a = field.name) != null ? _a : "").trim();
2139
+ }).filter(Boolean)
2140
+ );
2141
+ const nextErrors = Object.entries(currentWizardErrors).reduce(
2142
+ (accumulator, [key, value]) => {
2143
+ if (activeStepFieldNames.has(key)) return accumulator;
2144
+ accumulator[key] = value;
2145
+ return accumulator;
2146
+ },
2147
+ {}
2148
+ );
2149
+ Object.entries(validation.errors).forEach(([key, value]) => {
2150
+ if (!value) return;
2151
+ nextErrors[key] = value;
2152
+ });
2153
+ return nextErrors;
2154
+ };
2155
+ var patchStudioWizardFieldNode = ({
2156
+ nested,
2157
+ rawWizardValues,
2158
+ currentWizardErrors,
2159
+ fieldOnChange
2160
+ }) => {
2161
+ var _a, _b, _c, _d, _e;
2162
+ const nestedProps = (_a = nested.props) != null ? _a : {};
2163
+ const fieldObj = nestedProps.field && typeof nestedProps.field === "object" && !Array.isArray(nestedProps.field) ? nestedProps.field : {};
2164
+ const fieldName = String((_c = (_b = nestedProps.name) != null ? _b : fieldObj.name) != null ? _c : "").trim();
2165
+ const fieldConfig = __spreadProps(__spreadValues(__spreadValues({}, fieldObj), nestedProps), {
2166
+ name: fieldName,
2167
+ label: String((_e = (_d = nestedProps.label) != null ? _d : fieldObj.label) != null ? _e : fieldName || "Field")
2168
+ });
2169
+ const patchedNode = __spreadProps(__spreadValues({}, nested), {
2170
+ props: __spreadProps(__spreadValues({}, nestedProps), {
2171
+ layout: (() => {
2172
+ var _a2;
2173
+ const rawLayout = nestedProps.layout && typeof nestedProps.layout === "object" && !Array.isArray(nestedProps.layout) ? __spreadValues({}, nestedProps.layout) : {};
2174
+ const existingWrapperClassName = String((_a2 = rawLayout.wrapperClassName) != null ? _a2 : "").trim();
2175
+ rawLayout.wrapperClassName = [existingWrapperClassName, "w-full", "max-w-full"].filter(Boolean).join(" ");
2176
+ delete rawLayout.widthPct;
2177
+ delete rawLayout.heightPct;
2178
+ delete rawLayout.heightPx;
2179
+ return rawLayout;
2180
+ })(),
2181
+ field: fieldConfig,
2182
+ value: fieldName ? rawWizardValues[fieldName] : void 0,
2183
+ error: fieldName ? currentWizardErrors[fieldName] : void 0,
2184
+ onChange: fieldOnChange
2185
+ })
2186
+ });
2187
+ const nestedLayout = readNodeLayout(nestedProps);
2188
+ const fieldBasis = nestedLayout.widthPct !== null ? `${nestedLayout.widthPct}%` : "100%";
2189
+ return {
2190
+ patchedNode,
2191
+ fieldBasis
2192
+ };
2193
+ };
2194
+
2195
+ // src/studio-bridge/preview-wizard/previewWizardMaterialization.ts
2196
+ var renderStudioWizardStepContent = ({
2197
+ step,
2198
+ nodeId,
2199
+ existingFormConfig,
2200
+ rawWizardValues,
2201
+ stepIdToNode,
2202
+ runtime,
2203
+ renderSafeNode: renderSafeNode2,
2204
+ captureFieldFocus,
2205
+ onInlineTextEdit
2206
+ }) => {
2207
+ if (step.contentType === "content") {
2208
+ if (step.contentNode) {
2209
+ return renderSafeNode2(step.contentNode);
2210
+ }
2211
+ return step.contentValue;
2212
+ }
2213
+ if (step.stepRenderableContent.length === 0) {
2214
+ return step.contentValue;
2215
+ }
2216
+ return React2.createElement(
2217
+ "div",
2218
+ { className: "flex flex-wrap items-start gap-x-3 gap-y-3" },
2219
+ step.stepRenderableContent.map((nested) => {
2220
+ if (nested.type !== "FormField") {
2221
+ return React2.createElement(
2222
+ "div",
2223
+ { key: nested.id, className: "basis-full" },
2224
+ renderSafeNode2(nested)
2225
+ );
2226
+ }
2227
+ const currentWizardErrors = existingFormConfig.errors && typeof existingFormConfig.errors === "object" && !Array.isArray(existingFormConfig.errors) ? existingFormConfig.errors : {};
2228
+ const { patchedNode, fieldBasis } = patchStudioWizardFieldNode({
2229
+ nested,
2230
+ rawWizardValues,
2231
+ currentWizardErrors,
2232
+ fieldOnChange: (event) => {
2233
+ var _a;
2234
+ captureFieldFocus(event.target);
2235
+ const nextFieldName = String((_a = event.target.name) != null ? _a : "").trim();
2236
+ if (!nextFieldName) return;
2237
+ const target = event.target;
2238
+ const nextValue = target.type === "checkbox" ? Boolean(target.checked) : event.target.value;
2239
+ const nextValues = resolveStudioWizardNextValues({
2240
+ rawWizardValues,
2241
+ fieldName: nextFieldName,
2242
+ nextValue
2243
+ });
2244
+ const activeStepFields = resolveStudioWizardActiveStepFields({
2245
+ stepId: step.id,
2246
+ stepIdToNode
2247
+ });
2248
+ const nextErrors = resolveStudioWizardNextErrors({
2249
+ currentWizardErrors,
2250
+ activeStepFields,
2251
+ nextValues,
2252
+ runtime
2253
+ });
2254
+ onInlineTextEdit == null ? void 0 : onInlineTextEdit(nodeId, "form.values", nextValues);
2255
+ onInlineTextEdit == null ? void 0 : onInlineTextEdit(nodeId, "form.errors", nextErrors);
2256
+ }
2257
+ });
2258
+ return React2.createElement(
2259
+ "div",
2260
+ {
2261
+ key: nested.id,
2262
+ className: "min-w-0",
2263
+ style: { flex: `0 0 ${fieldBasis}`, maxWidth: fieldBasis }
2264
+ },
2265
+ renderSafeNode2(patchedNode)
2266
+ );
2267
+ })
2268
+ );
2269
+ };
2270
+ var materializeStudioWizardSteps = ({
2271
+ nodeId,
2272
+ currentSteps,
2273
+ existingFormConfig,
2274
+ rawWizardValues,
2275
+ stepIdToNode,
2276
+ runtime,
2277
+ renderSafeNode: renderSafeNode2,
2278
+ captureFieldFocus,
2279
+ onInlineTextEdit
2280
+ }) => currentSteps.map((step) => ({
2281
+ id: step.id,
2282
+ title: step.title,
2283
+ description: step.description,
2284
+ titleNode: step.titleNode ? renderSafeNode2(step.titleNode) : void 0,
2285
+ descriptionNode: step.descriptionNode ? renderSafeNode2(step.descriptionNode) : void 0,
2286
+ isValid: step.isValid,
2287
+ content: renderStudioWizardStepContent({
2288
+ step,
2289
+ nodeId,
2290
+ currentSteps,
2291
+ existingFormConfig,
2292
+ rawWizardValues,
2293
+ stepIdToNode,
2294
+ runtime,
2295
+ renderSafeNode: renderSafeNode2,
2296
+ captureFieldFocus,
2297
+ onInlineTextEdit
2298
+ })
2299
+ }));
2300
+
2301
+ // src/studio-bridge/preview-wizard/wizardEditingHandlers.ts
2302
+ var findWizardStepRoleNode = (stepNode, role) => {
2303
+ var _a;
2304
+ const nestedChildren = Array.isArray(stepNode.children) ? stepNode.children : [];
2305
+ return (_a = nestedChildren.find((child) => {
2306
+ var _a2, _b;
2307
+ const childProps = (_a2 = child.props) != null ? _a2 : {};
2308
+ return String((_b = getLayoutRecord(childProps).wizardStepRole) != null ? _b : "").trim() === role;
2309
+ })) != null ? _a : null;
2310
+ };
2311
+ var createStudioWizardOnStepChange = ({
2312
+ nodeId,
2313
+ stepIdToNode,
2314
+ setWizardActiveStepByNodeId,
2315
+ existingOnStepChange,
2316
+ onNodeClick
2317
+ }) => {
2318
+ return (stepId) => {
2319
+ setWizardActiveStepByNodeId((previous) => {
2320
+ if (previous[nodeId] === stepId) return previous;
2321
+ return __spreadProps(__spreadValues({}, previous), {
2322
+ [nodeId]: stepId
2323
+ });
2324
+ });
2325
+ if (typeof existingOnStepChange === "function") {
2326
+ existingOnStepChange(stepId);
2327
+ }
2328
+ const stepNode = stepIdToNode[stepId];
2329
+ if (stepNode && onNodeClick) {
2330
+ onNodeClick(stepNode.id);
2331
+ }
2332
+ };
2333
+ };
2334
+ var attachStudioWizardEditingHandlers = ({
2335
+ studioConfig,
2336
+ node,
2337
+ stepIdToNode,
2338
+ openInlineEditorForNodeProp
2339
+ }) => {
2340
+ studioConfig.onStepTitleDoubleClick = (stepId) => {
2341
+ var _a, _b, _c, _d, _e;
2342
+ const stepNode = stepIdToNode[stepId];
2343
+ if (!stepNode) return;
2344
+ const stepProps = (_a = stepNode.props) != null ? _a : {};
2345
+ const titleNode = findWizardStepRoleNode(stepNode, "title");
2346
+ if (titleNode) {
2347
+ const titleNodeProps = (_b = titleNode.props) != null ? _b : {};
2348
+ openInlineEditorForNodeProp(
2349
+ titleNode.id,
2350
+ "children",
2351
+ (_d = (_c = titleNodeProps.children) != null ? _c : stepProps.title) != null ? _d : stepId
2352
+ );
2353
+ return;
2354
+ }
2355
+ openInlineEditorForNodeProp(stepNode.id, "title", (_e = stepProps.title) != null ? _e : stepId);
2356
+ };
2357
+ studioConfig.onStepDescriptionDoubleClick = (stepId) => {
2358
+ var _a, _b, _c, _d, _e;
2359
+ const stepNode = stepIdToNode[stepId];
2360
+ if (!stepNode) return;
2361
+ const stepProps = (_a = stepNode.props) != null ? _a : {};
2362
+ const descriptionNode = findWizardStepRoleNode(stepNode, "description");
2363
+ if (descriptionNode) {
2364
+ const descriptionNodeProps = (_b = descriptionNode.props) != null ? _b : {};
2365
+ openInlineEditorForNodeProp(
2366
+ descriptionNode.id,
2367
+ "children",
2368
+ (_d = (_c = descriptionNodeProps.children) != null ? _c : stepProps.description) != null ? _d : ""
2369
+ );
2370
+ return;
2371
+ }
2372
+ openInlineEditorForNodeProp(stepNode.id, "description", (_e = stepProps.description) != null ? _e : "");
2373
+ };
2374
+ studioConfig.onBackLabelDoubleClick = () => {
2375
+ var _a, _b, _c;
2376
+ return openInlineEditorForNodeProp(
2377
+ node.id,
2378
+ "labels.back",
2379
+ (_c = (_b = (_a = node.props) == null ? void 0 : _a.labels) == null ? void 0 : _b.back) != null ? _c : "Back"
2380
+ );
2381
+ };
2382
+ studioConfig.onNextLabelDoubleClick = () => {
2383
+ var _a, _b, _c;
2384
+ return openInlineEditorForNodeProp(
2385
+ node.id,
2386
+ "labels.next",
2387
+ (_c = (_b = (_a = node.props) == null ? void 0 : _a.labels) == null ? void 0 : _b.next) != null ? _c : "Next"
2388
+ );
2389
+ };
2390
+ studioConfig.onFinishLabelDoubleClick = () => {
2391
+ var _a, _b, _c;
2392
+ return openInlineEditorForNodeProp(
2393
+ node.id,
2394
+ "labels.finish",
2395
+ (_c = (_b = (_a = node.props) == null ? void 0 : _a.labels) == null ? void 0 : _b.finish) != null ? _c : "Finish"
2396
+ );
2397
+ };
2398
+ return studioConfig;
2399
+ };
2400
+
2401
+ // src/utils/wizardStudio.ts
2402
+ var getWizardStepRole = (node) => {
2403
+ var _a, _b;
2404
+ const props = (_a = node.props) != null ? _a : {};
2405
+ const layout = getLayoutRecord(props);
2406
+ return String((_b = layout.wizardStepRole) != null ? _b : "").trim();
2407
+ };
2408
+ var getWizardRenderableChildren = (nodes) => nodes.filter((nested) => {
2409
+ const stepRole = getWizardStepRole(nested);
2410
+ return stepRole !== "title" && stepRole !== "description";
2411
+ });
2412
+ var findSelectedWizardStepId = (stepChildren, selectedNodeId) => {
2413
+ var _a, _b, _c;
2414
+ if (!selectedNodeId) return null;
2415
+ const selectedStep = stepChildren.find((stepChild) => {
2416
+ var _a2;
2417
+ if (stepChild.id === selectedNodeId) return true;
2418
+ return ((_a2 = stepChild.children) != null ? _a2 : []).some((nested) => {
2419
+ const stepRole = getWizardStepRole(nested);
2420
+ return nested.id === selectedNodeId && (stepRole === "title" || stepRole === "description");
2421
+ });
2422
+ });
2423
+ if (!selectedStep) return null;
2424
+ const stepProps = (_a = selectedStep.props) != null ? _a : {};
2425
+ return String((_c = (_b = stepProps.id) != null ? _b : selectedStep.id) != null ? _c : "").trim() || null;
2426
+ };
2427
+ var buildFieldsByStep = (stepIdToNode, currentSteps) => currentSteps.reduce((accumulator, step) => {
2428
+ var _a, _b;
2429
+ const stepId = String((_a = step.id) != null ? _a : "").trim();
2430
+ if (!stepId) return accumulator;
2431
+ const stepNode = stepIdToNode[stepId];
2432
+ const stepRenderableChildren = getWizardRenderableChildren((_b = stepNode == null ? void 0 : stepNode.children) != null ? _b : []);
2433
+ const fields = stepRenderableChildren.filter((nested) => nested.type === "FormField").map((nested) => {
2434
+ var _a2;
2435
+ const nestedProps = (_a2 = nested.props) != null ? _a2 : {};
2436
+ const nestedField = nestedProps.field && typeof nestedProps.field === "object" && !Array.isArray(nestedProps.field) ? nestedProps.field : {};
2437
+ return buildWizardFieldConfig(nestedProps, nestedField);
2438
+ }).filter((field) => {
2439
+ var _a2;
2440
+ return String((_a2 = field.name) != null ? _a2 : "").trim().length > 0;
2441
+ });
2442
+ accumulator[stepId] = fields;
2443
+ return accumulator;
2444
+ }, {});
2445
+ var resolveActiveWizardStepId = ({
2446
+ selectedStepId,
2447
+ stepIds,
2448
+ activeStepFromProps,
2449
+ activeStepFromMemory
2450
+ }) => {
2451
+ var _a;
2452
+ if (selectedStepId && stepIds.includes(selectedStepId)) return selectedStepId;
2453
+ if (activeStepFromProps && stepIds.includes(activeStepFromProps)) {
2454
+ return activeStepFromProps;
2455
+ }
2456
+ if (activeStepFromMemory && stepIds.includes(activeStepFromMemory)) {
2457
+ return activeStepFromMemory;
2458
+ }
2459
+ return (_a = stepIds[0]) != null ? _a : "";
2460
+ };
2461
+ var validateWizardStepFields = ({
2462
+ stepRenderableContent,
2463
+ values,
2464
+ runtime
2465
+ }) => {
2466
+ const normalizedFields = stepRenderableContent.filter((nested) => nested.type === "FormField").map((nested) => {
2467
+ var _a;
2468
+ const nestedProps = (_a = nested.props) != null ? _a : {};
2469
+ const fieldObject = nestedProps.field && typeof nestedProps.field === "object" && !Array.isArray(nestedProps.field) ? nestedProps.field : {};
2470
+ return buildWizardFieldConfig(nestedProps, fieldObject);
2471
+ });
2472
+ const filteredFields = normalizedFields.filter((field) => field.name.length > 0);
2473
+ const validation = validateFormValues(filteredFields, values, {
2474
+ t: runtime.t,
2475
+ useLegacyFieldConstraints: true
2476
+ });
2477
+ return validation.issues.length === 0;
2478
+ };
2479
+
2480
+ // src/studio-bridge/preview-wizard/previewWizardStructure.ts
2481
+ var resolveStudioWizardStructure = ({
2482
+ node,
2483
+ componentProps,
2484
+ selectedNodeId,
2485
+ wizardActiveStepByNodeId,
2486
+ runtime,
2487
+ internalStudioNodeTypes
2488
+ }) => {
2489
+ var _a, _b, _c, _d, _e, _f;
2490
+ const existingFormConfig = componentProps.form && typeof componentProps.form === "object" && !Array.isArray(componentProps.form) ? __spreadValues({}, componentProps.form) : {};
2491
+ const existingStudioConfig = componentProps.studio && typeof componentProps.studio === "object" && !Array.isArray(componentProps.studio) ? __spreadValues({}, componentProps.studio) : {};
2492
+ const stepChildren = ((_a = node.children) != null ? _a : []).filter((child) => {
2493
+ var _a2;
2494
+ const childProps = (_a2 = child.props) != null ? _a2 : {};
2495
+ const layout = getLayoutRecord(childProps);
2496
+ const isWizardStepFlag = layout.wizardStep === true;
2497
+ const isSupportedStepType = child.type === "Container" || child.type === "StepForm";
2498
+ return isSupportedStepType && isWizardStepFlag;
2499
+ });
2500
+ const stepIdToNode = stepChildren.reduce(
2501
+ (accumulator, stepChild) => {
2502
+ var _a2, _b2, _c2;
2503
+ const stepProps = (_a2 = stepChild.props) != null ? _a2 : {};
2504
+ const stepId = String((_b2 = stepProps.id) != null ? _b2 : "").trim();
2505
+ const fallbackId = String((_c2 = stepChild.id) != null ? _c2 : "").trim();
2506
+ if (stepId) accumulator[stepId] = stepChild;
2507
+ if (fallbackId) accumulator[fallbackId] = stepChild;
2508
+ return accumulator;
2509
+ },
2510
+ {}
2511
+ );
2512
+ const selectedStepId = findSelectedWizardStepId(stepChildren, selectedNodeId);
2513
+ const rawWizardValues = existingFormConfig.values && typeof existingFormConfig.values === "object" && !Array.isArray(existingFormConfig.values) ? existingFormConfig.values : {};
2514
+ const currentSteps = stepChildren.map((stepChild) => {
2515
+ var _a2, _b2, _c2, _d2, _e2, _f2, _g, _h, _i, _j, _k;
2516
+ const stepProps = (_a2 = stepChild.props) != null ? _a2 : {};
2517
+ const stepId = String((_b2 = stepProps.id) != null ? _b2 : "").trim() || stepChild.id;
2518
+ const stepContent = ((_c2 = stepChild.children) != null ? _c2 : []).filter(
2519
+ (nested) => !internalStudioNodeTypes.has(nested.type)
2520
+ );
2521
+ const stepTitleNode = stepContent.find(
2522
+ (nested) => {
2523
+ var _a3, _b3;
2524
+ return String(
2525
+ (_b3 = getLayoutRecord((_a3 = nested.props) != null ? _a3 : {}).wizardStepRole) != null ? _b3 : ""
2526
+ ).trim() === "title";
2527
+ }
2528
+ );
2529
+ const stepDescriptionNode = stepContent.find(
2530
+ (nested) => {
2531
+ var _a3, _b3;
2532
+ return String(
2533
+ (_b3 = getLayoutRecord((_a3 = nested.props) != null ? _a3 : {}).wizardStepRole) != null ? _b3 : ""
2534
+ ).trim() === "description";
2535
+ }
2536
+ );
2537
+ const stepTitleNodeValue = (_d2 = stepTitleNode == null ? void 0 : stepTitleNode.props) == null ? void 0 : _d2.children;
2538
+ const stepDescriptionNodeValue = (_e2 = stepDescriptionNode == null ? void 0 : stepDescriptionNode.props) == null ? void 0 : _e2.children;
2539
+ const title = resolveUIValue((_f2 = stepTitleNodeValue != null ? stepTitleNodeValue : stepProps.title) != null ? _f2 : stepId, runtime);
2540
+ const description = resolveUIValue((_g = stepDescriptionNodeValue != null ? stepDescriptionNodeValue : stepProps.description) != null ? _g : "", runtime);
2541
+ const rawContentType = String((_h = stepProps.contentType) != null ? _h : "content");
2542
+ const stepRenderableContent = getWizardRenderableChildren(stepContent);
2543
+ const hasFieldChildren = stepRenderableContent.some((nested) => {
2544
+ var _a3, _b3;
2545
+ if (nested.type !== "FormField") return false;
2546
+ const nestedProps = (_a3 = nested.props) != null ? _a3 : {};
2547
+ return String((_b3 = getLayoutRecord(nestedProps).formRole) != null ? _b3 : "field").trim() === "field";
2548
+ });
2549
+ const contentType = hasFieldChildren ? "form" : rawContentType;
2550
+ const isValid = !hasFieldChildren ? stepProps.isValid !== false : validateWizardStepFields({
2551
+ stepRenderableContent,
2552
+ values: rawWizardValues,
2553
+ runtime
2554
+ });
2555
+ const explicitContentNode = stepRenderableContent.find(
2556
+ (nested) => {
2557
+ var _a3;
2558
+ return getLayoutRecord((_a3 = nested.props) != null ? _a3 : {}).wizardContent === true;
2559
+ }
2560
+ );
2561
+ const contentNode = explicitContentNode != null ? explicitContentNode : contentType === "content" ? stepRenderableContent[0] : void 0;
2562
+ return {
2563
+ id: stepId,
2564
+ title,
2565
+ description,
2566
+ titleNode: stepTitleNode,
2567
+ descriptionNode: stepDescriptionNode,
2568
+ contentNode,
2569
+ isValid,
2570
+ contentType,
2571
+ stepRenderableContent,
2572
+ contentValue: contentType === "content" ? resolveUIValue(
2573
+ (_k = (_j = (_i = contentNode == null ? void 0 : contentNode.props) == null ? void 0 : _i.children) != null ? _j : stepProps.content) != null ? _k : title,
2574
+ runtime
2575
+ ) : null
2576
+ };
2577
+ });
2578
+ const normalizedFieldsByStep = buildFieldsByStep(
2579
+ stepIdToNode,
2580
+ currentSteps
2581
+ );
2582
+ const stepIds = currentSteps.map((step) => step.id).filter(Boolean);
2583
+ const activeStepFromMemory = String((_b = wizardActiveStepByNodeId[node.id]) != null ? _b : "").trim();
2584
+ const activeStepFromProps = String(
2585
+ (_f = (_e = (_c = node.props) == null ? void 0 : _c.activeStepId) != null ? _e : (_d = node.props) == null ? void 0 : _d.initialStepId) != null ? _f : ""
2586
+ ).trim();
2587
+ const resolvedActiveStepId = resolveActiveWizardStepId({
2588
+ selectedStepId,
2589
+ stepIds,
2590
+ activeStepFromProps,
2591
+ activeStepFromMemory
2592
+ });
2593
+ return {
2594
+ stepChildren,
2595
+ stepIdToNode,
2596
+ selectedStepId,
2597
+ currentSteps,
2598
+ normalizedFieldsByStep,
2599
+ resolvedActiveStepId,
2600
+ existingFormConfig,
2601
+ existingStudioConfig
2602
+ };
2603
+ };
2604
+
2605
+ // src/studio-bridge/preview-wizard/previewWizardConfigurator.ts
2606
+ var configurePreviewFormWizard = ({
2607
+ node,
2608
+ componentProps,
2609
+ isStudioRendererContext,
2610
+ selectedNodeId,
2611
+ wizardActiveStepByNodeId,
2612
+ runtime,
2613
+ setWizardActiveStepByNodeId,
2614
+ onNodeClick,
2615
+ onInlineTextEdit,
2616
+ renderSafeNode: renderSafeNode2,
2617
+ captureFieldFocus,
2618
+ openInlineEditorForNodeProp,
2619
+ internalStudioNodeTypes
2620
+ }) => {
2621
+ var _a;
2622
+ if (isStudioRendererContext) {
2623
+ const existingClassName = String((_a = componentProps.className) != null ? _a : "").trim();
2624
+ componentProps.className = [
2625
+ existingClassName,
2626
+ "w-full",
2627
+ "[&_[data-step-form-wrapper]>section]:max-w-full",
2628
+ "[&_[data-step-form-wrapper]>section]:mx-0"
2629
+ ].filter(Boolean).join(" ");
2630
+ }
2631
+ const {
2632
+ existingFormConfig,
2633
+ existingStudioConfig,
2634
+ currentSteps,
2635
+ normalizedFieldsByStep,
2636
+ resolvedActiveStepId,
2637
+ stepIdToNode
2638
+ } = resolveStudioWizardStructure({
2639
+ node,
2640
+ componentProps,
2641
+ selectedNodeId,
2642
+ wizardActiveStepByNodeId,
2643
+ runtime,
2644
+ internalStudioNodeTypes
2645
+ });
2646
+ const rawWizardValues = existingFormConfig.values && typeof existingFormConfig.values === "object" && !Array.isArray(existingFormConfig.values) ? existingFormConfig.values : {};
2647
+ const materializedSteps = materializeStudioWizardSteps({
2648
+ nodeId: node.id,
2649
+ currentSteps,
2650
+ existingFormConfig,
2651
+ rawWizardValues,
2652
+ stepIdToNode,
2653
+ runtime,
2654
+ renderSafeNode: renderSafeNode2,
2655
+ captureFieldFocus,
2656
+ onInlineTextEdit
2657
+ });
2658
+ if (materializedSteps.length > 0) {
2659
+ componentProps.steps = materializedSteps;
2660
+ }
2661
+ existingFormConfig.fieldsByStep = normalizedFieldsByStep;
2662
+ if (resolvedActiveStepId) {
2663
+ componentProps.activeStepId = resolvedActiveStepId;
2664
+ }
2665
+ componentProps.onStepChange = createStudioWizardOnStepChange({
2666
+ nodeId: node.id,
2667
+ stepIdToNode,
2668
+ setWizardActiveStepByNodeId,
2669
+ existingOnStepChange: componentProps.onStepChange,
2670
+ onNodeClick
2671
+ });
2672
+ attachStudioWizardEditingHandlers({
2673
+ studioConfig: existingStudioConfig,
2674
+ node,
2675
+ stepIdToNode,
2676
+ openInlineEditorForNodeProp
2677
+ });
2678
+ componentProps.form = isStudioRendererContext ? void 0 : existingFormConfig;
2679
+ componentProps.studio = existingStudioConfig;
2680
+ };
2681
+
2682
+ // src/utils/nodeResetToken.ts
2683
+ import { buildNodeResetToken } from "@arkcit/engine-react";
2684
+
2685
+ // src/studio-bridge/overlay/renderSafeNode.tsx
2686
+ import { jsx as jsx6 } from "react/jsx-runtime";
2687
+ var FallbackInlineTextEditor = ({
2688
+ editing,
2689
+ onChange,
2690
+ onCancel,
2691
+ onCommit
2692
+ }) => editing.multiline ? /* @__PURE__ */ jsx6(
2693
+ "textarea",
2694
+ {
2695
+ style: editing.editorStyle,
2696
+ value: editing.value,
2697
+ autoFocus: true,
2698
+ "aria-label": "Inline text editor",
2699
+ onChange: (event) => onChange(event.target.value),
2700
+ onBlur: onCommit,
2701
+ onKeyDown: (event) => {
2702
+ if (event.key === "Escape") {
2703
+ event.preventDefault();
2704
+ onCancel();
2705
+ return;
2706
+ }
2707
+ if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
2708
+ event.preventDefault();
2709
+ onCommit();
2710
+ }
2711
+ }
2712
+ }
2713
+ ) : /* @__PURE__ */ jsx6(
2714
+ "input",
2715
+ {
2716
+ style: editing.editorStyle,
2717
+ value: editing.value,
2718
+ autoFocus: true,
2719
+ "aria-label": "Inline text editor",
2720
+ onChange: (event) => onChange(event.target.value),
2721
+ onBlur: onCommit,
2722
+ onKeyDown: (event) => {
2723
+ if (event.key === "Escape") {
2724
+ event.preventDefault();
2725
+ onCancel();
2726
+ return;
2727
+ }
2728
+ if (event.key === "Enter") {
2729
+ event.preventDefault();
2730
+ onCommit();
2731
+ }
2732
+ }
2733
+ }
2734
+ );
2735
+ var renderSafeNode = ({
2736
+ node,
2737
+ registry,
2738
+ runtime,
2739
+ schemaNodes,
2740
+ renderNode,
2741
+ isStudioRendererContext,
2742
+ overlaysByNodeId,
2743
+ selectedNodeId,
2744
+ onNodeClick,
2745
+ onInlineTextEdit,
2746
+ onNodeResize,
2747
+ onNodeResizeStart,
2748
+ onNodeResizeEnd,
2749
+ inlineEditing,
2750
+ setInlineEditing,
2751
+ ancestorTypeMembership,
2752
+ resizeStateRef,
2753
+ pinchStateRef,
2754
+ minWidthPct,
2755
+ minHeightPct,
2756
+ minHeightPx,
2757
+ overlayRootId,
2758
+ NodeWrapper,
2759
+ InlineTextEditorComponent,
2760
+ isFormInteractiveTarget
2761
+ }) => {
2762
+ var _a, _b, _c, _d, _e, _f, _g;
2763
+ const nodeProps = (_a = node.props) != null ? _a : {};
2764
+ const nodeLayout = readNodeLayout(nodeProps);
2765
+ const wrapperClassName = (_b = nodeLayout.wrapperClassName) != null ? _b : "";
2766
+ const resetToken = buildNodeResetToken(node);
2767
+ const widthPct = (_c = nodeLayout.widthPct) != null ? _c : null;
2768
+ const heightPct = (_d = nodeLayout.heightPct) != null ? _d : null;
2769
+ const heightPx = (_e = nodeLayout.heightPx) != null ? _e : null;
2770
+ const isOpenStudioOverlayNode = isStudioRendererContext && getOpenStudioOverlayState({
2771
+ node,
2772
+ nodeProps,
2773
+ overlaysByNodeId
2774
+ });
2775
+ const shouldForceFullWidth = shouldForceStudioNodeFullWidth({
2776
+ widthPct,
2777
+ nodeType: node.type,
2778
+ isStudioRendererContext,
2779
+ colSpan: nodeLayout.colSpan
2780
+ });
2781
+ const enableEventOnClick = toBoolean(nodeProps.buttonEnableEventOnClick);
2782
+ const nodeRegistryMeta = (_f = registry[node.type]) == null ? void 0 : _f.meta;
2783
+ const editableTextProps = ((_g = nodeRegistryMeta == null ? void 0 : nodeRegistryMeta.editableTextProps) != null ? _g : []).filter(
2784
+ (propName) => propName !== "className"
2785
+ );
2786
+ const { getTextValue, effectiveCandidateInlineProp } = resolveInlineEditingTarget({
2787
+ node,
2788
+ nodeProps,
2789
+ runtime,
2790
+ editableTextProps,
2791
+ resolveTranslationValue: resolveUIValue
2792
+ });
2793
+ const isInlineEditingNode = (inlineEditing == null ? void 0 : inlineEditing.nodeId) === node.id;
2794
+ const nodeContent = /* @__PURE__ */ jsx6(NodeErrorBoundary, { nodeId: node.id, nodeType: node.type, resetToken, children: renderNode(node, { widthPct, heightPct, heightPx }) }, node.id);
2795
+ const commitInlineEditing = () => {
2796
+ if (!inlineEditing) return;
2797
+ applyInlineEditingValue({
2798
+ editingState: inlineEditing,
2799
+ rawValue: inlineEditing.value,
2800
+ schemaNodes,
2801
+ onInlineTextEdit,
2802
+ findNodeById
2803
+ });
2804
+ setInlineEditing(null);
2805
+ };
2806
+ const InlineEditorComponent = InlineTextEditorComponent != null ? InlineTextEditorComponent : FallbackInlineTextEditor;
2807
+ const inlineEditor = isInlineEditingNode && inlineEditing ? /* @__PURE__ */ jsx6(
2808
+ InlineEditorComponent,
2809
+ {
2810
+ editing: inlineEditing,
2811
+ onChange: (value) => setInlineEditing((previous) => {
2812
+ if (!previous) return previous;
2813
+ return __spreadProps(__spreadValues({}, previous), {
2814
+ value
2815
+ });
2816
+ }),
2817
+ onCancel: () => setInlineEditing(null),
2818
+ onCommit: commitInlineEditing
2819
+ }
2820
+ ) : null;
2821
+ return renderNodeFrame({
2822
+ node,
2823
+ nodeProps,
2824
+ nodeContent,
2825
+ selectedNodeId,
2826
+ onNodeClick,
2827
+ onInlineTextEdit,
2828
+ onNodeResize,
2829
+ onNodeResizeStart,
2830
+ onNodeResizeEnd,
2831
+ widthPct,
2832
+ heightPct,
2833
+ heightPx,
2834
+ wrapperClassName,
2835
+ isOpenStudioOverlayNode,
2836
+ shouldForceFullWidth,
2837
+ effectiveCandidateInlineProp,
2838
+ inlineEditing,
2839
+ isInlineEditingNode,
2840
+ ancestorTypeMembership,
2841
+ schemaNodes,
2842
+ runtime,
2843
+ enableEventOnClick,
2844
+ isFormInteractiveTarget,
2845
+ getTextValue,
2846
+ setInlineEditing,
2847
+ inlineEditor,
2848
+ NodeWrapper,
2849
+ overlaysByNodeId,
2850
+ getOpenStudioOverlayState,
2851
+ resizeStateRef,
2852
+ pinchStateRef,
2853
+ minWidthPct,
2854
+ minHeightPct,
2855
+ minHeightPx,
2856
+ overlayRootId
2857
+ });
2858
+ };
2859
+
2860
+ // src/react-web/hooks/useUIEngineEffects.ts
2861
+ import { useUIEngineEffects as useUIEngineEffectsImpl } from "@arkcit/engine-react";
2862
+
2863
+ // src/react-web/previewLinkBehavior.ts
2864
+ import { configurePreviewLinkBehavior } from "@arkcit/engine-react";
2865
+
2866
+ // src/renderers/preview/configureStudioLink.ts
2867
+ var configureStudioLink = configurePreviewLinkBehavior;
2868
+
2869
+ // src/react-web/materializeBoundTable.tsx
2870
+ import { materializeBoundTable } from "@arkcit/engine-react";
2871
+
2872
+ // src/renderers/preview/renderBoundTable.tsx
2873
+ var renderBoundTable = ({
2874
+ nodeId,
2875
+ componentProps,
2876
+ runtime,
2877
+ TableComponent
2878
+ }) => materializeBoundTable({
2879
+ nodeId,
2880
+ componentProps,
2881
+ runtime,
2882
+ TableComponent
2883
+ });
2884
+
2885
+ // src/renderers/preview/renderStudioForm.tsx
2886
+ var renderStudioForm = materializePreviewForm;
2887
+
2888
+ // src/renderers/preview/configureStudioFormWizard.tsx
2889
+ var configureStudioFormWizard = configurePreviewFormWizard;
2890
+
2891
+ // src/renderers/studio/configureStudioNavigation.tsx
2892
+ var configureStudioAccordion = configurePreviewAccordion;
2893
+ var configureStudioExpandablePanel = configurePreviewExpandablePanel;
2894
+ var configureStudioTabs = configurePreviewTabs;
2895
+
2896
+ // src/utils/contentStudio.tsx
2897
+ import {
2898
+ buildCoverContent,
2899
+ buildCoverMedia,
2900
+ buildScrollRevealChildren
2901
+ } from "@arkcit/engine-react";
2902
+
2903
+ // src/utils/dataBinding.ts
2904
+ var applyRowsAndColumnsBinding = ({
2905
+ componentProps,
2906
+ runtime,
2907
+ rowsBindingKey,
2908
+ columnsBindingKey
2909
+ }) => {
2910
+ if (rowsBindingKey && columnsBindingKey) {
2911
+ const boundRows = runtime.get(rowsBindingKey);
2912
+ if (Array.isArray(boundRows)) {
2913
+ componentProps.rows = boundRows;
2914
+ }
2915
+ const boundColumns = runtime.get(columnsBindingKey);
2916
+ if (Array.isArray(boundColumns)) {
2917
+ componentProps.columns = boundColumns;
2918
+ }
2919
+ }
2920
+ };
2921
+ var filterRowsByRuntimeQuery = ({
2922
+ nodeId,
2923
+ componentProps,
2924
+ runtime
2925
+ }) => {
2926
+ var _a, _b;
2927
+ const tableQueriesRaw = runtime.get("table.queriesByNodeId");
2928
+ const tableQueries = tableQueriesRaw && typeof tableQueriesRaw === "object" ? tableQueriesRaw : {};
2929
+ const queryRaw = String((_b = (_a = tableQueries[nodeId]) != null ? _a : tableQueries.__all__) != null ? _b : "").trim().toLowerCase();
2930
+ if (queryRaw.length === 0) return;
2931
+ const rows = Array.isArray(componentProps.rows) ? componentProps.rows : [];
2932
+ const columns = Array.isArray(componentProps.columns) ? componentProps.columns : [];
2933
+ const filteredRows = rows.filter((row) => {
2934
+ if (columns.length > 0) {
2935
+ return columns.some((column) => {
2936
+ var _a2, _b2;
2937
+ const key = String((_a2 = column.key) != null ? _a2 : "").trim();
2938
+ if (!key) return false;
2939
+ return String((_b2 = row[key]) != null ? _b2 : "").toLowerCase().includes(queryRaw);
2940
+ });
2941
+ }
2942
+ return Object.values(row).some(
2943
+ (value) => String(value != null ? value : "").toLowerCase().includes(queryRaw)
2944
+ );
2945
+ });
2946
+ componentProps.rows = filteredRows;
2947
+ };
2948
+ var applyObjectBinding = ({
2949
+ componentProps,
2950
+ runtime,
2951
+ bindingKey
2952
+ }) => {
2953
+ if (!bindingKey) return;
2954
+ const boundObject = runtime.get(bindingKey);
2955
+ if (boundObject && typeof boundObject === "object" && !Array.isArray(boundObject)) {
2956
+ Object.assign(componentProps, boundObject);
2957
+ }
2958
+ };
2959
+ var applyDecodeTranslationBinding = ({
2960
+ componentProps,
2961
+ runtime,
2962
+ tagContentTranslationKey,
2963
+ tagContentTranslationValue,
2964
+ hrefTranslationKey,
2965
+ hrefTranslationValue
2966
+ }) => {
2967
+ if (tagContentTranslationKey) {
2968
+ componentProps.tagContent = runtime.t ? runtime.t(tagContentTranslationKey, { value: tagContentTranslationValue }) : tagContentTranslationValue || tagContentTranslationKey;
2969
+ }
2970
+ if (hrefTranslationKey) {
2971
+ componentProps.href = runtime.t ? runtime.t(hrefTranslationKey, { value: hrefTranslationValue }) : hrefTranslationValue || hrefTranslationKey;
2972
+ }
2973
+ };
2974
+
2975
+ // src/utils/fieldFocus.ts
2976
+ var capturePendingFieldFocus = (target) => {
2977
+ if (!(target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement)) {
2978
+ return null;
2979
+ }
2980
+ return {
2981
+ id: target.id || null,
2982
+ name: target.name || null,
2983
+ selectionStart: target.selectionStart,
2984
+ selectionEnd: target.selectionEnd
2985
+ };
2986
+ };
2987
+ var escapeCss = (value) => typeof CSS !== "undefined" && typeof CSS.escape === "function" ? CSS.escape(value) : value.replace(/([\\.#:[\\],>+~*'"()])/g, "\\$1");
2988
+ var restorePendingFieldFocus = (pending) => {
2989
+ var _a;
2990
+ if (!pending) return false;
2991
+ let target = null;
2992
+ if (pending.id) {
2993
+ target = document.getElementById(pending.id);
2994
+ }
2995
+ if (!target && pending.name) {
2996
+ target = document.querySelector(
2997
+ `[name="${escapeCss(pending.name)}"]`
2998
+ );
2999
+ }
3000
+ if (!target) return false;
3001
+ target.focus({ preventScroll: true });
3002
+ if ("setSelectionRange" in target && typeof target.setSelectionRange === "function" && pending.selectionStart !== null) {
3003
+ const start = pending.selectionStart;
3004
+ const end = (_a = pending.selectionEnd) != null ? _a : start;
3005
+ try {
3006
+ target.setSelectionRange(start, end);
3007
+ } catch (e) {
3008
+ }
3009
+ }
3010
+ return true;
3011
+ };
3012
+
3013
+ // src/react-web/hooks/useUIEngineEffects.ts
3014
+ var useUIEngineEffects = ({
3015
+ schema,
3016
+ runtime,
3017
+ onNodeResize,
3018
+ onNodeResizeEnd,
3019
+ resizeStateRef,
3020
+ pendingFieldFocusRef,
3021
+ setVersion,
3022
+ minWidthPct,
3023
+ minHeightPct,
3024
+ minHeightPx
3025
+ }) => {
3026
+ return useUIEngineEffectsImpl({
3027
+ schema,
3028
+ runtime,
3029
+ onNodeResize,
3030
+ onNodeResizeEnd,
3031
+ resizeStateRef,
3032
+ pendingFieldFocusRef,
3033
+ setVersion,
3034
+ minWidthPct,
3035
+ minHeightPct,
3036
+ minHeightPx,
3037
+ dependencies: {
3038
+ buildAncestorTypeMembership,
3039
+ readOverlayState,
3040
+ capturePendingFieldFocus,
3041
+ restorePendingFieldFocus: (pending) => restorePendingFieldFocus(pending),
3042
+ computeMouseResizeSize: (args) => computeMouseResizeSize(__spreadProps(__spreadValues({}, args), {
3043
+ state: args.state
3044
+ }))
3045
+ }
3046
+ });
3047
+ };
3048
+
3049
+ // src/react-web/applyContentComposition.tsx
3050
+ import { applyContentComposition as applyContentCompositionImpl } from "@arkcit/engine-react";
3051
+
3052
+ // src/react-web/resolveContentCompositionPlan.ts
3053
+ import { resolveContentCompositionPlan } from "@arkcit/engine-render-layer";
3054
+
3055
+ // src/react-web/applyContentComposition.tsx
3056
+ var applyContentComposition = ({
3057
+ node,
3058
+ componentProps,
3059
+ isStudioRendererContext,
3060
+ internalStudioNodeTypes,
3061
+ schemaNodes,
3062
+ onInlineTextEdit,
3063
+ captureFieldFocus,
3064
+ renderSafeNode: renderSafeNode2,
3065
+ normalizeRenderableChild: normalizeRenderableChild2,
3066
+ findNodeById: findNodeById2,
3067
+ runtime,
3068
+ plans: providedPlans
3069
+ }) => {
3070
+ return applyContentCompositionImpl({
3071
+ node,
3072
+ componentProps,
3073
+ isStudioRendererContext,
3074
+ internalStudioNodeTypes,
3075
+ schemaNodes,
3076
+ onInlineTextEdit,
3077
+ captureFieldFocus,
3078
+ renderSafeNode: renderSafeNode2,
3079
+ normalizeRenderableChild: normalizeRenderableChild2,
3080
+ findNodeById: findNodeById2,
3081
+ runtime,
3082
+ plans: providedPlans,
3083
+ dependencies: {
3084
+ resolveContentCompositionPlan,
3085
+ renderStudioForm,
3086
+ buildScrollRevealChildren: (args) => buildScrollRevealChildren(__spreadProps(__spreadValues({}, args), {
3087
+ rawChildren: args.rawChildren
3088
+ }))
3089
+ }
3090
+ });
3091
+ };
3092
+
3093
+ // src/react-web/applyNavigationComposition.tsx
3094
+ import { applyNavigationComposition as applyNavigationCompositionImpl } from "@arkcit/engine-react";
3095
+
3096
+ // src/react-web/resolveNavigationCompositionPlan.ts
3097
+ import { resolveNavigationCompositionPlan } from "@arkcit/engine-render-layer";
3098
+
3099
+ // src/react-web/applyNavigationComposition.tsx
3100
+ var applyNavigationComposition = ({
3101
+ node,
3102
+ componentProps,
3103
+ isStudioRendererContext,
3104
+ selectedNodeId,
3105
+ wizardActiveStepByNodeId,
3106
+ accordionOpenIdsByNodeId,
3107
+ expandablePanelOpenByNodeId,
3108
+ runtime,
3109
+ setWizardActiveStepByNodeId,
3110
+ setAccordionOpenIdsByNodeId,
3111
+ setExpandablePanelOpenByNodeId,
3112
+ onNodeClick,
3113
+ onInlineTextEdit,
3114
+ renderSafeNode: renderSafeNode2,
3115
+ normalizeRenderableChild: normalizeRenderableChild2,
3116
+ captureFieldFocus,
3117
+ setInlineEditing,
3118
+ internalStudioNodeTypes,
3119
+ plans: providedPlans
3120
+ }) => {
3121
+ return applyNavigationCompositionImpl({
3122
+ node,
3123
+ componentProps,
3124
+ isStudioRendererContext,
3125
+ selectedNodeId,
3126
+ wizardActiveStepByNodeId,
3127
+ accordionOpenIdsByNodeId,
3128
+ expandablePanelOpenByNodeId,
3129
+ runtime,
3130
+ setWizardActiveStepByNodeId,
3131
+ setAccordionOpenIdsByNodeId,
3132
+ setExpandablePanelOpenByNodeId,
3133
+ onNodeClick,
3134
+ onInlineTextEdit,
3135
+ renderSafeNode: renderSafeNode2,
3136
+ normalizeRenderableChild: normalizeRenderableChild2,
3137
+ captureFieldFocus,
3138
+ setInlineEditing,
3139
+ internalStudioNodeTypes,
3140
+ plans: providedPlans,
3141
+ dependencies: {
3142
+ resolveNavigationCompositionPlan,
3143
+ createInlineEditingState,
3144
+ configureStudioFormWizard,
3145
+ configureStudioAccordion,
3146
+ configureStudioExpandablePanel,
3147
+ configureStudioTabs: (args) => configureStudioTabs(__spreadProps(__spreadValues({}, args), {
3148
+ rawChildren: normalizeNavigationChildren(args.rawChildren)
3149
+ }))
3150
+ }
3151
+ });
3152
+ };
3153
+
3154
+ // src/react-web/applyRenderDirectives.ts
3155
+ import { applyRenderDirectives as applyRenderDirectivesImpl } from "@arkcit/engine-react";
3156
+
3157
+ // src/react-web/resolveRenderDirectivePlan.ts
3158
+ import { resolveRenderDirectivePlan } from "@arkcit/engine-render-layer";
3159
+
3160
+ // src/react-web/applyRenderDirectives.ts
3161
+ var applyRenderDirectives = ({
3162
+ node,
3163
+ componentProps,
3164
+ renderBindingProps,
3165
+ runtime,
3166
+ plans: providedPlans
3167
+ }) => {
3168
+ return applyRenderDirectivesImpl({
3169
+ node,
3170
+ componentProps,
3171
+ renderBindingProps,
3172
+ runtime,
3173
+ plans: providedPlans,
3174
+ dependencies: {
3175
+ resolveRenderDirectivePlan,
3176
+ applyRowsAndColumnsBinding,
3177
+ filterRowsByRuntimeQuery,
3178
+ buildCoverMedia: (args) => buildCoverMedia({
3179
+ mediaSource: args.mediaSource,
3180
+ mediaSrc: args.mediaSrc,
3181
+ mediaAlt: args.mediaAlt
3182
+ }),
3183
+ applyObjectBinding,
3184
+ applyDecodeTranslationBinding: (args) => {
3185
+ var _a, _b, _c, _d;
3186
+ return applyDecodeTranslationBinding({
3187
+ componentProps: args.componentProps,
3188
+ runtime,
3189
+ tagContentTranslationKey: (_a = args.tagContentTranslationKey) != null ? _a : "",
3190
+ tagContentTranslationValue: (_b = args.tagContentTranslationValue) != null ? _b : "",
3191
+ hrefTranslationKey: (_c = args.hrefTranslationKey) != null ? _c : "",
3192
+ hrefTranslationValue: (_d = args.hrefTranslationValue) != null ? _d : ""
3193
+ });
3194
+ }
3195
+ }
3196
+ });
3197
+ };
3198
+
3199
+ // src/react-web/finalizeRenderedNode.tsx
3200
+ import { finalizeRenderedNode as finalizeRenderedNodeImpl } from "@arkcit/engine-react";
3201
+
3202
+ // src/react-web/resolveFinalRenderPlan.ts
3203
+ import { resolveFinalRenderPlan } from "@arkcit/engine-render-layer";
3204
+
3205
+ // src/react-web/finalizeRenderedNode.tsx
3206
+ var finalizeRenderedNode = ({
3207
+ node,
3208
+ children,
3209
+ componentProps,
3210
+ registryComponent,
3211
+ runtime,
3212
+ isStudioRendererContext,
3213
+ studioSizing,
3214
+ plans: providedPlans
3215
+ }) => {
3216
+ return finalizeRenderedNodeImpl({
3217
+ node,
3218
+ children,
3219
+ componentProps,
3220
+ registryComponent,
3221
+ runtime,
3222
+ isStudioRendererContext,
3223
+ studioSizing,
3224
+ plans: providedPlans,
3225
+ dependencies: {
3226
+ resolveFinalRenderPlan,
3227
+ omitStudioProps
3228
+ }
3229
+ });
3230
+ };
3231
+
3232
+ // src/react-web/renderReactNodeDependencies.ts
3233
+ var createRenderReactNodeDependencies = () => ({
3234
+ applyStudioOverlayComponentProps,
3235
+ applyContentComposition,
3236
+ applyRenderDirectives,
3237
+ applyNavigationComposition,
3238
+ finalizeRenderedNode,
3239
+ normalizeRenderableChild,
3240
+ findNodeById
3241
+ });
3242
+ var createInlineEditingState = (targetNodeId, propName, rawValue) => {
3243
+ let mode = "primitive";
3244
+ let value = "";
3245
+ if (typeof rawValue === "string") {
3246
+ value = rawValue;
3247
+ } else if (typeof rawValue === "number" || typeof rawValue === "boolean") {
3248
+ value = String(rawValue);
3249
+ } else if (rawValue && typeof rawValue === "object") {
3250
+ if (!Array.isArray(rawValue) && typeof rawValue.$t === "string") {
3251
+ const translationValue = rawValue;
3252
+ mode = "translation";
3253
+ value = translationValue.$t;
3254
+ } else {
3255
+ mode = "json";
3256
+ try {
3257
+ value = JSON.stringify(rawValue, null, 2);
3258
+ } catch (e) {
3259
+ value = "";
3260
+ }
3261
+ }
3262
+ }
3263
+ return {
3264
+ nodeId: targetNodeId,
3265
+ propName,
3266
+ value,
3267
+ multiline: mode === "json" || value.length > 64,
3268
+ mode
3269
+ };
3270
+ };
3271
+ var normalizeNavigationChildren = (rawChildren) => Array.isArray(rawChildren) ? rawChildren : [];
3272
+
3273
+ // src/react-web/engine/rootDependencies.ts
3274
+ var createReactWebEngineRootDependencies = () => ({
3275
+ useUIEngineEffects: (args) => useUIEngineEffects(__spreadProps(__spreadValues({}, args), {
3276
+ resizeStateRef: args.resizeStateRef,
3277
+ pendingFieldFocusRef: args.pendingFieldFocusRef
3278
+ })),
3279
+ renderSafeNode: (args) => renderSafeNode(__spreadProps(__spreadValues({}, args), {
3280
+ resizeStateRef: args.resizeStateRef,
3281
+ pinchStateRef: args.pinchStateRef
3282
+ })),
3283
+ InlineTextEditor,
3284
+ StudioNodeWrapper,
3285
+ renderReactNodeDependencies: createRenderReactNodeDependencies()
3286
+ });
3287
+
3288
+ // src/react-web/engine/ReactWebEngineRoot.tsx
3289
+ import { jsx as jsx7 } from "react/jsx-runtime";
3290
+ var ReactWebEngineRoot = (props) => {
3291
+ return /* @__PURE__ */ jsx7(
3292
+ ReactWebEngineRootImpl,
3293
+ __spreadProps(__spreadValues({}, props), {
3294
+ dependencies: createReactWebEngineRootDependencies()
3295
+ })
3296
+ );
3297
+ };
3298
+
3299
+ // src/engine/UIEngine.tsx
3300
+ import { jsx as jsx8 } from "react/jsx-runtime";
3301
+ var UIEngine = (props) => /* @__PURE__ */ jsx8(ReactWebEngineRoot, __spreadValues({}, props));
3302
+ var UIEngine_default = UIEngine;
3303
+
3304
+ // src/preview/react/index.ts
3305
+ import {
3306
+ configurePreviewLinkBehavior as configurePreviewLinkBehavior2,
3307
+ materializeBoundTable as materializeBoundTable2,
3308
+ resolveBoundTableData
3309
+ } from "@arkcit/engine-react";
3310
+ export {
3311
+ EngineWarningFallback,
3312
+ NodeErrorBoundary,
3313
+ RENDER_BINDING_PROP_NAMES,
3314
+ ReactWebEngineRoot,
3315
+ STUDIO_INTERNAL_PROP_NAMES,
3316
+ UIEngine_default as UIEngine,
3317
+ configurePreviewAccordion,
3318
+ configurePreviewExpandablePanel,
3319
+ configurePreviewFormWizard,
3320
+ configurePreviewLinkBehavior2 as configurePreviewLinkBehavior,
3321
+ configurePreviewTabs,
3322
+ configureStudioAccordion,
3323
+ configureStudioExpandablePanel,
3324
+ configureStudioFormWizard,
3325
+ configureStudioLink,
3326
+ configureStudioTabs,
3327
+ getRenderBindingProps,
3328
+ getStudioProps,
3329
+ materializeBoundTable2 as materializeBoundTable,
3330
+ materializePreviewForm,
3331
+ omitStudioProps,
3332
+ readNodeLayout,
3333
+ renderBoundTable,
3334
+ renderStudioForm,
3335
+ writeNodeLayout
3336
+ };