@arkcit/engine-react 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.
@@ -0,0 +1,96 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React__default from 'react';
3
+ import { UIEngineProps, UINodeSize, UINodeWrapperProps } from '@arkcit/engine-core';
4
+ import { UINode } from '@arkcit/engine-schema';
5
+ import { UIRuntimeAdapter } from '@arkcit/engine-runtime';
6
+ import { r as renderReactNode } from './renderReactNode-DmxD8hot.js';
7
+ import '@arkcit/engine-render-layer';
8
+
9
+ type EngineWarningFallbackProps = {
10
+ message: string;
11
+ };
12
+ declare const EngineWarningFallback: ({ message }: EngineWarningFallbackProps) => react_jsx_runtime.JSX.Element;
13
+
14
+ type NodeErrorBoundaryProps = {
15
+ nodeId: string;
16
+ nodeType: string;
17
+ resetToken: string;
18
+ children: React__default.ReactNode;
19
+ };
20
+ type NodeErrorBoundaryState = {
21
+ hasError: boolean;
22
+ };
23
+ declare class NodeErrorBoundary extends React__default.Component<NodeErrorBoundaryProps, NodeErrorBoundaryState> {
24
+ constructor(props: NodeErrorBoundaryProps);
25
+ static getDerivedStateFromError(): NodeErrorBoundaryState;
26
+ componentDidUpdate(prevProps: Readonly<{
27
+ resetToken: string;
28
+ }>): void;
29
+ render(): string | number | bigint | boolean | Iterable<React__default.ReactNode> | Promise<string | number | bigint | boolean | React__default.ReactPortal | React__default.ReactElement<unknown, string | React__default.JSXElementConstructor<any>> | Iterable<React__default.ReactNode> | null | undefined> | react_jsx_runtime.JSX.Element | null | undefined;
30
+ }
31
+
32
+ type UseUIEngineEffectsArgs = {
33
+ schema: UIEngineProps["schema"];
34
+ runtime: UIRuntimeAdapter;
35
+ onNodeResize?: ((nodeId: string, size: UINodeSize) => void) | undefined;
36
+ onNodeResizeEnd?: ((nodeId: string, size: UINodeSize) => void) | undefined;
37
+ resizeStateRef: React__default.MutableRefObject<unknown>;
38
+ pendingFieldFocusRef: React__default.MutableRefObject<unknown>;
39
+ setVersion: React__default.Dispatch<React__default.SetStateAction<number>>;
40
+ minWidthPct: number;
41
+ minHeightPct: number;
42
+ minHeightPx: number;
43
+ };
44
+ type UseUIEngineEffectsResult = {
45
+ ancestorTypeMembership: Record<string, Set<string>>;
46
+ overlaysByNodeId: Record<string, unknown>;
47
+ captureFieldFocus: (target: EventTarget | null) => void;
48
+ };
49
+ type RenderSafeNodeArgs<TInlineEditing> = {
50
+ node: UINode;
51
+ registry: NonNullable<UIEngineProps["registry"]>;
52
+ runtime: UIRuntimeAdapter;
53
+ schemaNodes: UINode[];
54
+ renderNode: (node: UINode, studioSizing?: {
55
+ widthPct: number | null;
56
+ heightPct: number | null;
57
+ heightPx: number | null;
58
+ }) => React__default.ReactNode;
59
+ isStudioRendererContext: boolean;
60
+ overlaysByNodeId: Record<string, unknown>;
61
+ selectedNodeId: string | null;
62
+ onNodeClick: UIEngineProps["onNodeClick"];
63
+ onInlineTextEdit: UIEngineProps["onInlineTextEdit"];
64
+ onNodeResize: UIEngineProps["onNodeResize"];
65
+ onNodeResizeStart: UIEngineProps["onNodeResizeStart"];
66
+ onNodeResizeEnd: UIEngineProps["onNodeResizeEnd"];
67
+ inlineEditing: TInlineEditing | null;
68
+ setInlineEditing: React__default.Dispatch<React__default.SetStateAction<TInlineEditing | null>>;
69
+ ancestorTypeMembership: Record<string, Set<string>>;
70
+ resizeStateRef: React__default.MutableRefObject<unknown>;
71
+ pinchStateRef: React__default.MutableRefObject<unknown>;
72
+ minWidthPct: number;
73
+ minHeightPct: number;
74
+ minHeightPx: number;
75
+ overlayRootId: string;
76
+ NodeWrapper: React__default.ComponentType<UINodeWrapperProps>;
77
+ isFormInteractiveTarget: (target: HTMLElement | null) => boolean;
78
+ };
79
+ type ReactWebEngineRootDependencies<TInlineEditing> = {
80
+ useUIEngineEffects: (args: UseUIEngineEffectsArgs) => UseUIEngineEffectsResult;
81
+ renderSafeNode: (args: RenderSafeNodeArgs<TInlineEditing>) => React__default.ReactNode;
82
+ InlineTextEditor: React__default.ComponentType<{
83
+ editing: TInlineEditing;
84
+ onChange: (value: string) => void;
85
+ onCancel: () => void;
86
+ onCommit: () => void;
87
+ }>;
88
+ StudioNodeWrapper: React__default.ComponentType<UINodeWrapperProps>;
89
+ renderReactNodeDependencies: Parameters<typeof renderReactNode<TInlineEditing>>[0]["dependencies"];
90
+ };
91
+ type ReactWebEngineRootArgs<TInlineEditing> = UIEngineProps & {
92
+ dependencies: ReactWebEngineRootDependencies<TInlineEditing>;
93
+ };
94
+ declare const ReactWebEngineRoot: <TInlineEditing = unknown>({ schema, registry, store, onNodeClick, onInlineTextEdit, onNodeResize, onNodeResizeStart, onNodeResizeEnd, onNodeDragStart, onNodeDragOverTarget, onNodeDropTarget, selectedNodeId, nodeWrapper, dependencies, }: ReactWebEngineRootArgs<TInlineEditing>) => react_jsx_runtime.JSX.Element;
95
+
96
+ export { EngineWarningFallback, NodeErrorBoundary, ReactWebEngineRoot };
package/dist/engine.js ADDED
@@ -0,0 +1,508 @@
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/engine/EngineWarningFallback.tsx
22
+ import { jsx } from "react/jsx-runtime";
23
+ var EngineWarningFallback = ({ message }) => /* @__PURE__ */ jsx(
24
+ "div",
25
+ {
26
+ role: "alert",
27
+ className: "rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-sm text-amber-900",
28
+ children: message
29
+ }
30
+ );
31
+ var EngineWarningFallback_default = EngineWarningFallback;
32
+
33
+ // src/engine/NodeErrorBoundary.tsx
34
+ import React from "react";
35
+ import { jsx as jsx2 } from "react/jsx-runtime";
36
+ var NodeErrorBoundary = class extends React.Component {
37
+ constructor(props) {
38
+ super(props);
39
+ this.state = { hasError: false };
40
+ }
41
+ static getDerivedStateFromError() {
42
+ return { hasError: true };
43
+ }
44
+ componentDidUpdate(prevProps) {
45
+ if (this.state.hasError && prevProps.resetToken !== this.props.resetToken) {
46
+ this.setState({ hasError: false });
47
+ }
48
+ }
49
+ render() {
50
+ if (!this.state.hasError) return this.props.children;
51
+ return /* @__PURE__ */ jsx2(
52
+ EngineWarningFallback_default,
53
+ {
54
+ message: `Renderer fallback: node "${this.props.nodeType}" (${this.props.nodeId}) failed.`
55
+ }
56
+ );
57
+ }
58
+ };
59
+
60
+ // src/engine/ReactWebEngineRoot.tsx
61
+ import React4, { useRef, useState as useState2 } from "react";
62
+
63
+ // src/rendering/resolveResolvedReactNode.ts
64
+ import {
65
+ resolveResolvedNode
66
+ } from "@arkcit/engine-render-layer";
67
+
68
+ // src/rendering/prepareRenderableChildren.tsx
69
+ import React3 from "react";
70
+ import {
71
+ resolveChildContentDescriptor,
72
+ resolveChildDescriptors
73
+ } from "@arkcit/engine-render-layer";
74
+
75
+ // src/rendering/gridItemWrapperProps.ts
76
+ var getGridItemWrapperProps = (colSpan) => ({
77
+ className: "w-full min-w-0",
78
+ style: {
79
+ gridColumn: `span ${colSpan} / span ${colSpan}`
80
+ }
81
+ });
82
+
83
+ // src/materialization/materializeChildContent.tsx
84
+ import React2 from "react";
85
+ import { Fragment, jsx as jsx3 } from "react/jsx-runtime";
86
+ var materializeChildContent = ({
87
+ descriptor,
88
+ renderSafeNode
89
+ }) => {
90
+ if (descriptor.kind === "empty") {
91
+ return null;
92
+ }
93
+ const renderDescriptor = (childDescriptor) => {
94
+ if (childDescriptor.kind === "grid-item") {
95
+ return /* @__PURE__ */ jsx3("div", __spreadProps(__spreadValues({}, getGridItemWrapperProps(childDescriptor.colSpan)), { children: renderSafeNode(childDescriptor.child) }), childDescriptor.child.id);
96
+ }
97
+ return /* @__PURE__ */ jsx3(React2.Fragment, { children: renderSafeNode(childDescriptor.child) }, childDescriptor.child.id);
98
+ };
99
+ if (descriptor.kind === "single") {
100
+ return renderDescriptor(descriptor.child);
101
+ }
102
+ return /* @__PURE__ */ jsx3(Fragment, { children: descriptor.children.map(renderDescriptor) });
103
+ };
104
+
105
+ // src/rendering/prepareRenderableChildren.tsx
106
+ import { jsx as jsx4 } from "react/jsx-runtime";
107
+ var prepareRenderableChildren = ({
108
+ node,
109
+ internalStudioNodeTypes,
110
+ renderSafeNode,
111
+ childDescriptors,
112
+ childContentDescriptor
113
+ }) => {
114
+ const resolvedDescriptors = childDescriptors != null ? childDescriptors : resolveChildDescriptors({
115
+ node,
116
+ internalStudioNodeTypes
117
+ });
118
+ const children = resolvedDescriptors.map((descriptor) => {
119
+ if (descriptor.kind === "grid-item") {
120
+ return /* @__PURE__ */ jsx4("div", __spreadProps(__spreadValues({}, getGridItemWrapperProps(descriptor.colSpan)), { children: renderSafeNode(descriptor.child) }), descriptor.child.id);
121
+ }
122
+ return /* @__PURE__ */ jsx4(React3.Fragment, { children: renderSafeNode(descriptor.child) }, descriptor.child.id);
123
+ });
124
+ const resolvedChildContentDescriptor = childContentDescriptor != null ? childContentDescriptor : resolveChildContentDescriptor({
125
+ childDescriptors: resolvedDescriptors
126
+ });
127
+ const resolvedChildContent = materializeChildContent({
128
+ descriptor: resolvedChildContentDescriptor,
129
+ renderSafeNode
130
+ });
131
+ return {
132
+ children,
133
+ resolvedChildContent,
134
+ childDescriptors: resolvedDescriptors,
135
+ childContentDescriptor: resolvedChildContentDescriptor
136
+ };
137
+ };
138
+
139
+ // src/rendering/resolveResolvedReactNode.ts
140
+ var resolveResolvedReactNode = ({
141
+ node,
142
+ runtime,
143
+ registry,
144
+ internalStudioNodeTypes,
145
+ renderSafeNode,
146
+ isStudioRendererContext,
147
+ studioSizing
148
+ }) => {
149
+ const registryEntry = registry[node.type];
150
+ if (!registryEntry) {
151
+ return null;
152
+ }
153
+ const resolvedNode = resolveResolvedNode({
154
+ node,
155
+ runtime,
156
+ internalStudioNodeTypes,
157
+ isStudioRendererContext,
158
+ studioSizing
159
+ });
160
+ const { children, resolvedChildContent } = prepareRenderableChildren({
161
+ node,
162
+ internalStudioNodeTypes,
163
+ renderSafeNode,
164
+ childDescriptors: resolvedNode.childDescriptors,
165
+ childContentDescriptor: resolvedNode.childContentDescriptor
166
+ });
167
+ return __spreadProps(__spreadValues({}, resolvedNode), {
168
+ registryEntry,
169
+ children,
170
+ resolvedChildContent
171
+ });
172
+ };
173
+
174
+ // src/rendering/renderReactNode.tsx
175
+ import { jsx as jsx5 } from "react/jsx-runtime";
176
+ var renderReactNode = ({
177
+ node,
178
+ runtime,
179
+ registry,
180
+ schemaNodes,
181
+ renderSafeNode,
182
+ internalStudioNodeTypes,
183
+ overlaysByNodeId,
184
+ onInlineTextEdit,
185
+ isStudioRendererContext,
186
+ dropdownOpenByNodeId,
187
+ setDropdownOpenByNodeId,
188
+ captureFieldFocus,
189
+ selectedNodeId,
190
+ wizardActiveStepByNodeId,
191
+ accordionOpenIdsByNodeId,
192
+ expandablePanelOpenByNodeId,
193
+ setWizardActiveStepByNodeId,
194
+ setAccordionOpenIdsByNodeId,
195
+ setExpandablePanelOpenByNodeId,
196
+ onNodeClick,
197
+ setInlineEditing,
198
+ studioSizing,
199
+ dependencies
200
+ }) => {
201
+ try {
202
+ const resolvedNode = resolveResolvedReactNode({
203
+ node,
204
+ runtime,
205
+ registry,
206
+ internalStudioNodeTypes,
207
+ renderSafeNode,
208
+ isStudioRendererContext,
209
+ studioSizing
210
+ });
211
+ if (!resolvedNode) {
212
+ return /* @__PURE__ */ jsx5(
213
+ EngineWarningFallback_default,
214
+ {
215
+ message: `Unknown component type "${node.type}" for node "${node.id}".`
216
+ }
217
+ );
218
+ }
219
+ const {
220
+ registryEntry,
221
+ componentProps,
222
+ renderBindingProps,
223
+ children,
224
+ resolvedChildContent,
225
+ contentPlans,
226
+ navigationPlans,
227
+ renderDirectivePlans,
228
+ finalRenderPlans
229
+ } = resolvedNode;
230
+ dependencies.applyStudioOverlayComponentProps({
231
+ node,
232
+ componentProps,
233
+ runtime,
234
+ overlaysByNodeId,
235
+ renderBindingProps,
236
+ resolvedChildContent,
237
+ onInlineTextEdit,
238
+ isStudioRendererContext,
239
+ dropdownOpenByNodeId,
240
+ setDropdownOpenByNodeId
241
+ });
242
+ const contentNode = dependencies.applyContentComposition({
243
+ node,
244
+ componentProps,
245
+ isStudioRendererContext,
246
+ internalStudioNodeTypes,
247
+ schemaNodes,
248
+ onInlineTextEdit,
249
+ captureFieldFocus,
250
+ renderSafeNode,
251
+ normalizeRenderableChild: dependencies.normalizeRenderableChild,
252
+ findNodeById: dependencies.findNodeById,
253
+ runtime,
254
+ plans: contentPlans
255
+ });
256
+ if (contentNode) {
257
+ return contentNode;
258
+ }
259
+ dependencies.applyRenderDirectives({
260
+ node,
261
+ componentProps,
262
+ renderBindingProps,
263
+ runtime,
264
+ plans: renderDirectivePlans
265
+ });
266
+ dependencies.applyNavigationComposition({
267
+ node,
268
+ componentProps,
269
+ isStudioRendererContext,
270
+ selectedNodeId: selectedNodeId != null ? selectedNodeId : null,
271
+ wizardActiveStepByNodeId,
272
+ accordionOpenIdsByNodeId,
273
+ expandablePanelOpenByNodeId,
274
+ runtime,
275
+ setWizardActiveStepByNodeId,
276
+ setAccordionOpenIdsByNodeId,
277
+ setExpandablePanelOpenByNodeId,
278
+ onNodeClick,
279
+ onInlineTextEdit,
280
+ renderSafeNode,
281
+ normalizeRenderableChild: dependencies.normalizeRenderableChild,
282
+ captureFieldFocus,
283
+ setInlineEditing,
284
+ internalStudioNodeTypes,
285
+ plans: navigationPlans
286
+ });
287
+ return dependencies.finalizeRenderedNode({
288
+ node,
289
+ children,
290
+ componentProps,
291
+ registryComponent: registryEntry.Component,
292
+ runtime,
293
+ isStudioRendererContext,
294
+ studioSizing,
295
+ plans: finalRenderPlans
296
+ });
297
+ } catch (e) {
298
+ return /* @__PURE__ */ jsx5(
299
+ EngineWarningFallback_default,
300
+ {
301
+ message: `Renderer fallback: node "${node.type}" (${node.id}) could not be resolved.`
302
+ }
303
+ );
304
+ }
305
+ };
306
+
307
+ // src/hooks/useUIEngineState.ts
308
+ import { useState } from "react";
309
+ var useUIEngineState = () => {
310
+ const [inlineEditing, setInlineEditing] = useState(null);
311
+ const [wizardActiveStepByNodeId, setWizardActiveStepByNodeId] = useState({});
312
+ const [expandablePanelOpenByNodeId, setExpandablePanelOpenByNodeId] = useState({});
313
+ const [accordionOpenIdsByNodeId, setAccordionOpenIdsByNodeId] = useState({});
314
+ const [dropdownOpenByNodeId, setDropdownOpenByNodeId] = useState(
315
+ {}
316
+ );
317
+ return {
318
+ inlineEditing,
319
+ setInlineEditing,
320
+ wizardActiveStepByNodeId,
321
+ setWizardActiveStepByNodeId,
322
+ expandablePanelOpenByNodeId,
323
+ setExpandablePanelOpenByNodeId,
324
+ accordionOpenIdsByNodeId,
325
+ setAccordionOpenIdsByNodeId,
326
+ dropdownOpenByNodeId,
327
+ setDropdownOpenByNodeId
328
+ };
329
+ };
330
+
331
+ // src/engine/ReactWebEngineRoot.tsx
332
+ import { jsx as jsx6 } from "react/jsx-runtime";
333
+ var INTERNAL_STUDIO_NODE_TYPES = /* @__PURE__ */ new Set();
334
+ var STUDIO_CANVAS_OVERLAY_ROOT_ID = "studio-canvas-overlay-root";
335
+ var STUDIO_MIN_WIDTH_PCT = 5;
336
+ var STUDIO_MIN_HEIGHT_PCT = 5;
337
+ var STUDIO_MIN_HEIGHT_PX = 20;
338
+ var NOOP_RUNTIME = {
339
+ get: () => void 0,
340
+ dispatch: () => void 0
341
+ };
342
+ var EMPTY_UI_REGISTRY = {};
343
+ var isFormInteractiveTarget = (target) => {
344
+ if (!target) return false;
345
+ const interactive = target.closest(
346
+ "button,input,textarea,select,option,label,[role='button'],[role='link']"
347
+ );
348
+ if (!interactive) return false;
349
+ return true;
350
+ };
351
+ var FallbackInlineTextEditor = ({
352
+ editing,
353
+ onChange,
354
+ onCancel,
355
+ onCommit
356
+ }) => editing.multiline ? /* @__PURE__ */ jsx6(
357
+ "textarea",
358
+ {
359
+ style: editing.editorStyle,
360
+ value: editing.value,
361
+ autoFocus: true,
362
+ "aria-label": "Inline text editor",
363
+ onChange: (event) => onChange(event.target.value),
364
+ onBlur: onCommit,
365
+ onKeyDown: (event) => {
366
+ if (event.key === "Escape") {
367
+ event.preventDefault();
368
+ onCancel();
369
+ return;
370
+ }
371
+ if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
372
+ event.preventDefault();
373
+ onCommit();
374
+ }
375
+ }
376
+ }
377
+ ) : /* @__PURE__ */ jsx6(
378
+ "input",
379
+ {
380
+ style: editing.editorStyle,
381
+ value: editing.value,
382
+ autoFocus: true,
383
+ "aria-label": "Inline text editor",
384
+ onChange: (event) => onChange(event.target.value),
385
+ onBlur: onCommit,
386
+ onKeyDown: (event) => {
387
+ if (event.key === "Escape") {
388
+ event.preventDefault();
389
+ onCancel();
390
+ return;
391
+ }
392
+ if (event.key === "Enter") {
393
+ event.preventDefault();
394
+ onCommit();
395
+ }
396
+ }
397
+ }
398
+ );
399
+ var ReactWebEngineRoot = ({
400
+ schema,
401
+ registry = EMPTY_UI_REGISTRY,
402
+ store,
403
+ onNodeClick,
404
+ onInlineTextEdit,
405
+ onNodeResize,
406
+ onNodeResizeStart,
407
+ onNodeResizeEnd,
408
+ onNodeDragStart,
409
+ onNodeDragOverTarget,
410
+ onNodeDropTarget,
411
+ selectedNodeId = null,
412
+ nodeWrapper,
413
+ dependencies
414
+ }) => {
415
+ var _a;
416
+ const runtime = store != null ? store : NOOP_RUNTIME;
417
+ const NodeWrapper = nodeWrapper != null ? nodeWrapper : dependencies.StudioNodeWrapper;
418
+ const InlineTextEditor = (_a = dependencies.InlineTextEditor) != null ? _a : FallbackInlineTextEditor;
419
+ const isStudioRendererContext = Boolean(
420
+ onNodeClick || onInlineTextEdit || onNodeResize || onNodeDragStart || onNodeDragOverTarget || onNodeDropTarget || selectedNodeId
421
+ );
422
+ const [, setVersion] = useState2(0);
423
+ const {
424
+ inlineEditing,
425
+ setInlineEditing,
426
+ wizardActiveStepByNodeId,
427
+ setWizardActiveStepByNodeId,
428
+ expandablePanelOpenByNodeId,
429
+ setExpandablePanelOpenByNodeId,
430
+ accordionOpenIdsByNodeId,
431
+ setAccordionOpenIdsByNodeId,
432
+ dropdownOpenByNodeId,
433
+ setDropdownOpenByNodeId
434
+ } = useUIEngineState();
435
+ const resizeStateRef = useRef(null);
436
+ const pinchStateRef = useRef(null);
437
+ const pendingFieldFocusRef = useRef(null);
438
+ const { ancestorTypeMembership, overlaysByNodeId, captureFieldFocus } = dependencies.useUIEngineEffects({
439
+ schema,
440
+ runtime,
441
+ onNodeResize,
442
+ onNodeResizeEnd,
443
+ resizeStateRef,
444
+ pendingFieldFocusRef,
445
+ setVersion,
446
+ minWidthPct: STUDIO_MIN_WIDTH_PCT,
447
+ minHeightPct: STUDIO_MIN_HEIGHT_PCT,
448
+ minHeightPx: STUDIO_MIN_HEIGHT_PX
449
+ });
450
+ const renderNode = (node, studioSizing) => renderReactNode({
451
+ node,
452
+ runtime,
453
+ registry,
454
+ schemaNodes: schema.nodes,
455
+ renderSafeNode: renderSafeEngineNode,
456
+ internalStudioNodeTypes: INTERNAL_STUDIO_NODE_TYPES,
457
+ overlaysByNodeId,
458
+ onInlineTextEdit,
459
+ isStudioRendererContext,
460
+ dropdownOpenByNodeId,
461
+ setDropdownOpenByNodeId,
462
+ captureFieldFocus,
463
+ selectedNodeId,
464
+ wizardActiveStepByNodeId,
465
+ accordionOpenIdsByNodeId,
466
+ expandablePanelOpenByNodeId,
467
+ setWizardActiveStepByNodeId,
468
+ setAccordionOpenIdsByNodeId,
469
+ setExpandablePanelOpenByNodeId,
470
+ onNodeClick,
471
+ setInlineEditing,
472
+ studioSizing,
473
+ dependencies: dependencies.renderReactNodeDependencies
474
+ });
475
+ const renderSafeEngineNode = (node) => dependencies.renderSafeNode({
476
+ node,
477
+ registry,
478
+ runtime,
479
+ schemaNodes: schema.nodes,
480
+ renderNode,
481
+ isStudioRendererContext,
482
+ overlaysByNodeId,
483
+ selectedNodeId,
484
+ onNodeClick,
485
+ onInlineTextEdit,
486
+ onNodeResize,
487
+ onNodeResizeStart,
488
+ onNodeResizeEnd,
489
+ inlineEditing,
490
+ setInlineEditing,
491
+ ancestorTypeMembership,
492
+ resizeStateRef,
493
+ pinchStateRef,
494
+ minWidthPct: STUDIO_MIN_WIDTH_PCT,
495
+ minHeightPct: STUDIO_MIN_HEIGHT_PCT,
496
+ minHeightPx: STUDIO_MIN_HEIGHT_PX,
497
+ overlayRootId: STUDIO_CANVAS_OVERLAY_ROOT_ID,
498
+ NodeWrapper,
499
+ InlineTextEditorComponent: InlineTextEditor,
500
+ isFormInteractiveTarget
501
+ });
502
+ return /* @__PURE__ */ jsx6("div", { className: "flex h-full min-w-0 w-full flex-wrap content-start items-start gap-3", children: schema.nodes.map((node) => /* @__PURE__ */ jsx6(React4.Fragment, { children: renderSafeEngineNode(node) }, node.id)) });
503
+ };
504
+ export {
505
+ EngineWarningFallback_default as EngineWarningFallback,
506
+ NodeErrorBoundary,
507
+ ReactWebEngineRoot
508
+ };
@@ -0,0 +1,55 @@
1
+ import { UINodeSize } from '@arkcit/engine-core';
2
+ import { UISchema } from '@arkcit/engine-schema';
3
+ import { UIRuntimeAdapter } from '@arkcit/engine-runtime';
4
+ import * as React$1 from 'react';
5
+
6
+ type UseUIEngineEffectsArgs = {
7
+ schema: UISchema;
8
+ runtime: UIRuntimeAdapter;
9
+ onNodeResize?: ((nodeId: string, size: UINodeSize) => void) | undefined;
10
+ onNodeResizeEnd?: ((nodeId: string, size: UINodeSize) => void) | undefined;
11
+ resizeStateRef: React.MutableRefObject<unknown>;
12
+ pendingFieldFocusRef: React.MutableRefObject<unknown>;
13
+ setVersion: React.Dispatch<React.SetStateAction<number>>;
14
+ minWidthPct: number;
15
+ minHeightPct: number;
16
+ minHeightPx: number;
17
+ dependencies: {
18
+ buildAncestorTypeMembership: (nodes: UISchema["nodes"], ancestorTypes: string[]) => Record<string, Set<string>>;
19
+ readOverlayState: (runtime: UIRuntimeAdapter) => Record<string, unknown>;
20
+ capturePendingFieldFocus: (target: EventTarget | null) => unknown;
21
+ restorePendingFieldFocus: (pending: unknown) => void;
22
+ computeMouseResizeSize: (args: {
23
+ state: unknown;
24
+ clientX: number;
25
+ clientY: number;
26
+ minWidthPct: number;
27
+ minHeightPct: number;
28
+ minHeightPx: number;
29
+ }) => {
30
+ widthPct: number;
31
+ heightPct: number;
32
+ heightPx?: number;
33
+ };
34
+ };
35
+ };
36
+ declare const useUIEngineEffects: ({ schema, runtime, onNodeResize, onNodeResizeEnd, resizeStateRef, pendingFieldFocusRef, setVersion, minWidthPct, minHeightPct, minHeightPx, dependencies, }: UseUIEngineEffectsArgs) => {
37
+ ancestorTypeMembership: Record<string, Set<string>>;
38
+ overlaysByNodeId: Record<string, unknown>;
39
+ captureFieldFocus: (target: EventTarget | null) => void;
40
+ };
41
+
42
+ declare const useUIEngineState: <TInlineEditing = unknown>() => {
43
+ inlineEditing: TInlineEditing | null;
44
+ setInlineEditing: React$1.Dispatch<React$1.SetStateAction<TInlineEditing | null>>;
45
+ wizardActiveStepByNodeId: Record<string, string>;
46
+ setWizardActiveStepByNodeId: React$1.Dispatch<React$1.SetStateAction<Record<string, string>>>;
47
+ expandablePanelOpenByNodeId: Record<string, boolean>;
48
+ setExpandablePanelOpenByNodeId: React$1.Dispatch<React$1.SetStateAction<Record<string, boolean>>>;
49
+ accordionOpenIdsByNodeId: Record<string, string[]>;
50
+ setAccordionOpenIdsByNodeId: React$1.Dispatch<React$1.SetStateAction<Record<string, string[]>>>;
51
+ dropdownOpenByNodeId: Record<string, boolean>;
52
+ setDropdownOpenByNodeId: React$1.Dispatch<React$1.SetStateAction<Record<string, boolean>>>;
53
+ };
54
+
55
+ export { useUIEngineEffects, useUIEngineState };