@arkcit/engine-react 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/engine.d.ts CHANGED
@@ -4,6 +4,7 @@ import { UIEngineProps, UINodeSize, UINodeWrapperProps } from '@arkcit/engine-co
4
4
  import { UINode } from '@arkcit/engine-schema';
5
5
  import { UIRuntimeAdapter } from '@arkcit/engine-runtime';
6
6
  import { r as renderReactNode } from './renderReactNode-DmxD8hot.js';
7
+ export { StaticReactWebEngineRoot } from './static-engine.js';
7
8
  import '@arkcit/engine-render-layer';
8
9
 
9
10
  type EngineWarningFallbackProps = {
package/dist/engine.js CHANGED
@@ -501,8 +501,104 @@ var ReactWebEngineRoot = ({
501
501
  });
502
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
503
  };
504
+
505
+ // src/engine/StaticReactWebEngineRoot.tsx
506
+ import React5 from "react";
507
+ import { jsx as jsx7 } from "react/jsx-runtime";
508
+ var INTERNAL_STUDIO_NODE_TYPES2 = /* @__PURE__ */ new Set();
509
+ var STUDIO_CANVAS_OVERLAY_ROOT_ID2 = "studio-canvas-overlay-root";
510
+ var STUDIO_MIN_WIDTH_PCT2 = 5;
511
+ var STUDIO_MIN_HEIGHT_PCT2 = 5;
512
+ var STUDIO_MIN_HEIGHT_PX2 = 20;
513
+ var NOOP_RUNTIME2 = {
514
+ get: () => void 0,
515
+ dispatch: () => void 0
516
+ };
517
+ var EMPTY_UI_REGISTRY2 = {};
518
+ var EMPTY_INLINE_MEMBERSHIP = Object.freeze({
519
+ Form: /* @__PURE__ */ new Set(),
520
+ FormWizard: /* @__PURE__ */ new Set(),
521
+ StepForm: /* @__PURE__ */ new Set()
522
+ });
523
+ var isFormInteractiveTarget2 = (_target) => false;
524
+ var createStaticRef = (value) => ({
525
+ current: value
526
+ });
527
+ var NOOP_SETTER = (_value) => void 0;
528
+ var StaticReactWebEngineRoot = ({
529
+ schema,
530
+ registry = EMPTY_UI_REGISTRY2,
531
+ store,
532
+ nodeWrapper,
533
+ dependencies
534
+ }) => {
535
+ const runtime = store != null ? store : NOOP_RUNTIME2;
536
+ const NodeWrapper = nodeWrapper != null ? nodeWrapper : dependencies.StudioNodeWrapper;
537
+ const setInlineEditing = NOOP_SETTER;
538
+ const setDropdownOpenByNodeId = NOOP_SETTER;
539
+ const setWizardActiveStepByNodeId = NOOP_SETTER;
540
+ const setAccordionOpenIdsByNodeId = NOOP_SETTER;
541
+ const setExpandablePanelOpenByNodeId = NOOP_SETTER;
542
+ const resizeStateRef = createStaticRef(null);
543
+ const pinchStateRef = createStaticRef(null);
544
+ const overlaysByNodeId = {};
545
+ const isStudioRendererContext = false;
546
+ const renderNode = (node, studioSizing) => renderReactNode({
547
+ node,
548
+ runtime,
549
+ registry,
550
+ schemaNodes: schema.nodes,
551
+ renderSafeNode: renderSafeEngineNode,
552
+ internalStudioNodeTypes: INTERNAL_STUDIO_NODE_TYPES2,
553
+ overlaysByNodeId,
554
+ onInlineTextEdit: void 0,
555
+ isStudioRendererContext,
556
+ dropdownOpenByNodeId: {},
557
+ setDropdownOpenByNodeId,
558
+ captureFieldFocus: () => void 0,
559
+ selectedNodeId: null,
560
+ wizardActiveStepByNodeId: {},
561
+ accordionOpenIdsByNodeId: {},
562
+ expandablePanelOpenByNodeId: {},
563
+ setWizardActiveStepByNodeId,
564
+ setAccordionOpenIdsByNodeId,
565
+ setExpandablePanelOpenByNodeId,
566
+ onNodeClick: void 0,
567
+ setInlineEditing,
568
+ studioSizing,
569
+ dependencies: dependencies.renderReactNodeDependencies
570
+ });
571
+ const renderSafeEngineNode = (node) => dependencies.renderSafeNode({
572
+ node,
573
+ registry,
574
+ runtime,
575
+ schemaNodes: schema.nodes,
576
+ renderNode,
577
+ isStudioRendererContext,
578
+ overlaysByNodeId,
579
+ selectedNodeId: null,
580
+ onNodeClick: void 0,
581
+ onInlineTextEdit: void 0,
582
+ onNodeResize: void 0,
583
+ onNodeResizeStart: void 0,
584
+ onNodeResizeEnd: void 0,
585
+ inlineEditing: null,
586
+ setInlineEditing,
587
+ ancestorTypeMembership: EMPTY_INLINE_MEMBERSHIP,
588
+ resizeStateRef,
589
+ pinchStateRef,
590
+ minWidthPct: STUDIO_MIN_WIDTH_PCT2,
591
+ minHeightPct: STUDIO_MIN_HEIGHT_PCT2,
592
+ minHeightPx: STUDIO_MIN_HEIGHT_PX2,
593
+ overlayRootId: STUDIO_CANVAS_OVERLAY_ROOT_ID2,
594
+ NodeWrapper,
595
+ isFormInteractiveTarget: isFormInteractiveTarget2
596
+ });
597
+ return /* @__PURE__ */ jsx7("div", { className: "flex h-full min-w-0 w-full flex-wrap content-start items-start gap-3", children: schema.nodes.map((node) => /* @__PURE__ */ jsx7(React5.Fragment, { children: renderSafeEngineNode(node) }, node.id)) });
598
+ };
504
599
  export {
505
600
  EngineWarningFallback_default as EngineWarningFallback,
506
601
  NodeErrorBoundary,
507
- ReactWebEngineRoot
602
+ ReactWebEngineRoot,
603
+ StaticReactWebEngineRoot
508
604
  };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { applyContentComposition, applyNavigationComposition } from './composition.js';
2
2
  export { applyRenderDirectives } from './directives.js';
3
3
  export { EngineWarningFallback, NodeErrorBoundary, ReactWebEngineRoot } from './engine.js';
4
+ export { StaticReactWebEngineRoot } from './static-engine.js';
4
5
  export { useUIEngineEffects, useUIEngineState } from './hooks.js';
5
6
  export { buildAccordionItems, buildCoverContent, buildCoverMedia, buildExpandablePanelChildren, buildScrollRevealChildren, materializeAccordionItems, materializeBoundTable, materializeChildContent, materializeCoverContent, materializeExpandablePanelContent, materializeTabsContent } from './materialization.js';
6
7
  export { BoundTableColumn, BoundTableRow, ReactNodeRenderPlan, ResolvedBoundTableData, ResolvedReactNode, buildNodeResetToken, configurePreviewLinkBehavior, finalizeRenderedNode, getGridItemWrapperProps, normalizeRenderableChild, prepareRenderableChildren, resolveBoundTableData, resolveReactNodePlan, resolveResolvedReactNode, toBoolean } from './rendering.js';
package/dist/index.js CHANGED
@@ -879,6 +879,101 @@ var ReactWebEngineRoot = ({
879
879
  return /* @__PURE__ */ jsx9("div", { className: "flex h-full min-w-0 w-full flex-wrap content-start items-start gap-3", children: schema.nodes.map((node) => /* @__PURE__ */ jsx9(React7.Fragment, { children: renderSafeEngineNode(node) }, node.id)) });
880
880
  };
881
881
 
882
+ // src/engine/StaticReactWebEngineRoot.tsx
883
+ import React8 from "react";
884
+ import { jsx as jsx10 } from "react/jsx-runtime";
885
+ var INTERNAL_STUDIO_NODE_TYPES2 = /* @__PURE__ */ new Set();
886
+ var STUDIO_CANVAS_OVERLAY_ROOT_ID2 = "studio-canvas-overlay-root";
887
+ var STUDIO_MIN_WIDTH_PCT2 = 5;
888
+ var STUDIO_MIN_HEIGHT_PCT2 = 5;
889
+ var STUDIO_MIN_HEIGHT_PX2 = 20;
890
+ var NOOP_RUNTIME2 = {
891
+ get: () => void 0,
892
+ dispatch: () => void 0
893
+ };
894
+ var EMPTY_UI_REGISTRY2 = {};
895
+ var EMPTY_INLINE_MEMBERSHIP = Object.freeze({
896
+ Form: /* @__PURE__ */ new Set(),
897
+ FormWizard: /* @__PURE__ */ new Set(),
898
+ StepForm: /* @__PURE__ */ new Set()
899
+ });
900
+ var isFormInteractiveTarget2 = (_target) => false;
901
+ var createStaticRef = (value) => ({
902
+ current: value
903
+ });
904
+ var NOOP_SETTER = (_value) => void 0;
905
+ var StaticReactWebEngineRoot = ({
906
+ schema,
907
+ registry = EMPTY_UI_REGISTRY2,
908
+ store,
909
+ nodeWrapper,
910
+ dependencies
911
+ }) => {
912
+ const runtime = store != null ? store : NOOP_RUNTIME2;
913
+ const NodeWrapper = nodeWrapper != null ? nodeWrapper : dependencies.StudioNodeWrapper;
914
+ const setInlineEditing = NOOP_SETTER;
915
+ const setDropdownOpenByNodeId = NOOP_SETTER;
916
+ const setWizardActiveStepByNodeId = NOOP_SETTER;
917
+ const setAccordionOpenIdsByNodeId = NOOP_SETTER;
918
+ const setExpandablePanelOpenByNodeId = NOOP_SETTER;
919
+ const resizeStateRef = createStaticRef(null);
920
+ const pinchStateRef = createStaticRef(null);
921
+ const overlaysByNodeId = {};
922
+ const isStudioRendererContext = false;
923
+ const renderNode = (node, studioSizing) => renderReactNode({
924
+ node,
925
+ runtime,
926
+ registry,
927
+ schemaNodes: schema.nodes,
928
+ renderSafeNode: renderSafeEngineNode,
929
+ internalStudioNodeTypes: INTERNAL_STUDIO_NODE_TYPES2,
930
+ overlaysByNodeId,
931
+ onInlineTextEdit: void 0,
932
+ isStudioRendererContext,
933
+ dropdownOpenByNodeId: {},
934
+ setDropdownOpenByNodeId,
935
+ captureFieldFocus: () => void 0,
936
+ selectedNodeId: null,
937
+ wizardActiveStepByNodeId: {},
938
+ accordionOpenIdsByNodeId: {},
939
+ expandablePanelOpenByNodeId: {},
940
+ setWizardActiveStepByNodeId,
941
+ setAccordionOpenIdsByNodeId,
942
+ setExpandablePanelOpenByNodeId,
943
+ onNodeClick: void 0,
944
+ setInlineEditing,
945
+ studioSizing,
946
+ dependencies: dependencies.renderReactNodeDependencies
947
+ });
948
+ const renderSafeEngineNode = (node) => dependencies.renderSafeNode({
949
+ node,
950
+ registry,
951
+ runtime,
952
+ schemaNodes: schema.nodes,
953
+ renderNode,
954
+ isStudioRendererContext,
955
+ overlaysByNodeId,
956
+ selectedNodeId: null,
957
+ onNodeClick: void 0,
958
+ onInlineTextEdit: void 0,
959
+ onNodeResize: void 0,
960
+ onNodeResizeStart: void 0,
961
+ onNodeResizeEnd: void 0,
962
+ inlineEditing: null,
963
+ setInlineEditing,
964
+ ancestorTypeMembership: EMPTY_INLINE_MEMBERSHIP,
965
+ resizeStateRef,
966
+ pinchStateRef,
967
+ minWidthPct: STUDIO_MIN_WIDTH_PCT2,
968
+ minHeightPct: STUDIO_MIN_HEIGHT_PCT2,
969
+ minHeightPx: STUDIO_MIN_HEIGHT_PX2,
970
+ overlayRootId: STUDIO_CANVAS_OVERLAY_ROOT_ID2,
971
+ NodeWrapper,
972
+ isFormInteractiveTarget: isFormInteractiveTarget2
973
+ });
974
+ return /* @__PURE__ */ jsx10("div", { className: "flex h-full min-w-0 w-full flex-wrap content-start items-start gap-3", children: schema.nodes.map((node) => /* @__PURE__ */ jsx10(React8.Fragment, { children: renderSafeEngineNode(node) }, node.id)) });
975
+ };
976
+
882
977
  // src/hooks/useUIEngineEffects.ts
883
978
  import { useEffect, useLayoutEffect, useMemo } from "react";
884
979
  var useUIEngineEffects = ({
@@ -968,8 +1063,8 @@ var useUIEngineEffects = ({
968
1063
  };
969
1064
 
970
1065
  // src/materialization/contentStudio.tsx
971
- import React8 from "react";
972
- import { Fragment as Fragment3, jsx as jsx10 } from "react/jsx-runtime";
1066
+ import React9 from "react";
1067
+ import { Fragment as Fragment3, jsx as jsx11 } from "react/jsx-runtime";
973
1068
  var COVER_MEDIA_FRAME_CLASSNAME = "h-56 w-full overflow-hidden rounded-xl bg-surface ring-1 ring-border/60";
974
1069
  var buildCoverMedia = ({
975
1070
  mediaSource,
@@ -978,7 +1073,7 @@ var buildCoverMedia = ({
978
1073
  }) => {
979
1074
  if (mediaSource === "none") return void 0;
980
1075
  if (mediaSource === "image" && mediaSrc) {
981
- return /* @__PURE__ */ jsx10("div", { className: COVER_MEDIA_FRAME_CLASSNAME, children: /* @__PURE__ */ jsx10(
1076
+ return /* @__PURE__ */ jsx11("div", { className: COVER_MEDIA_FRAME_CLASSNAME, children: /* @__PURE__ */ jsx11(
982
1077
  "img",
983
1078
  {
984
1079
  src: mediaSrc,
@@ -988,7 +1083,7 @@ var buildCoverMedia = ({
988
1083
  ) });
989
1084
  }
990
1085
  if (mediaSource === "video" && mediaSrc) {
991
- return /* @__PURE__ */ jsx10("div", { className: COVER_MEDIA_FRAME_CLASSNAME, children: /* @__PURE__ */ jsx10(
1086
+ return /* @__PURE__ */ jsx11("div", { className: COVER_MEDIA_FRAME_CLASSNAME, children: /* @__PURE__ */ jsx11(
992
1087
  "video",
993
1088
  {
994
1089
  src: mediaSrc,
@@ -1006,11 +1101,11 @@ var buildCoverContent = ({
1006
1101
  }) => {
1007
1102
  const actionChildren = rawChildren.filter((child) => child.type === "Button" || child.type === "Link");
1008
1103
  const contentChildren = rawChildren.filter((child) => child.type !== "Button" && child.type !== "Link");
1009
- const resolvedActionChildren = actionChildren.map((child) => /* @__PURE__ */ jsx10("span", { className: "inline-flex align-middle", children: renderSafeNode(child) }, child.id));
1010
- const resolvedContentChildren = contentChildren.map((child) => /* @__PURE__ */ jsx10(React8.Fragment, { children: renderSafeNode(child) }, child.id));
1104
+ const resolvedActionChildren = actionChildren.map((child) => /* @__PURE__ */ jsx11("span", { className: "inline-flex align-middle", children: renderSafeNode(child) }, child.id));
1105
+ const resolvedContentChildren = contentChildren.map((child) => /* @__PURE__ */ jsx11(React9.Fragment, { children: renderSafeNode(child) }, child.id));
1011
1106
  return {
1012
- actions: resolvedActionChildren.length > 0 ? resolvedActionChildren.length === 1 ? resolvedActionChildren[0] : /* @__PURE__ */ jsx10(Fragment3, { children: resolvedActionChildren }) : void 0,
1013
- children: resolvedContentChildren.length > 0 ? resolvedContentChildren.length === 1 ? resolvedContentChildren[0] : /* @__PURE__ */ jsx10(Fragment3, { children: resolvedContentChildren }) : null
1107
+ actions: resolvedActionChildren.length > 0 ? resolvedActionChildren.length === 1 ? resolvedActionChildren[0] : /* @__PURE__ */ jsx11(Fragment3, { children: resolvedActionChildren }) : void 0,
1108
+ children: resolvedContentChildren.length > 0 ? resolvedContentChildren.length === 1 ? resolvedContentChildren[0] : /* @__PURE__ */ jsx11(Fragment3, { children: resolvedContentChildren }) : null
1014
1109
  };
1015
1110
  };
1016
1111
  var buildScrollRevealChildren = ({
@@ -1020,13 +1115,13 @@ var buildScrollRevealChildren = ({
1020
1115
  fallbackChildren
1021
1116
  }) => {
1022
1117
  if (rawChildren.length > 0) {
1023
- return rawChildren.length === 1 ? /* @__PURE__ */ jsx10(React8.Fragment, { children: renderSafeNode(rawChildren[0]) }, rawChildren[0].id) : /* @__PURE__ */ jsx10(Fragment3, { children: rawChildren.map((child) => /* @__PURE__ */ jsx10(React8.Fragment, { children: renderSafeNode(child) }, child.id)) });
1118
+ return rawChildren.length === 1 ? /* @__PURE__ */ jsx11(React9.Fragment, { children: renderSafeNode(rawChildren[0]) }, rawChildren[0].id) : /* @__PURE__ */ jsx11(Fragment3, { children: rawChildren.map((child) => /* @__PURE__ */ jsx11(React9.Fragment, { children: renderSafeNode(child) }, child.id)) });
1024
1119
  }
1025
1120
  return normalizeRenderableChild2(fallbackChildren);
1026
1121
  };
1027
1122
 
1028
1123
  // src/materialization/materializeBoundTable.tsx
1029
- import React9 from "react";
1124
+ import React10 from "react";
1030
1125
 
1031
1126
  // src/rendering/resolveBoundTableData.ts
1032
1127
  var resolveBoundTableData = ({
@@ -1117,16 +1212,16 @@ var materializeBoundTable = ({
1117
1212
  delete componentProps.useBindingData;
1118
1213
  if (columns.length === 0) return null;
1119
1214
  delete componentProps.children;
1120
- const headerNode = React9.createElement(
1215
+ const headerNode = React10.createElement(
1121
1216
  TableComponent.Header,
1122
1217
  null,
1123
- React9.createElement(
1218
+ React10.createElement(
1124
1219
  TableComponent.Row,
1125
1220
  null,
1126
1221
  ...columns.map(
1127
1222
  (column, columnIndex) => {
1128
1223
  var _a, _b, _c;
1129
- return React9.createElement(
1224
+ return React10.createElement(
1130
1225
  TableComponent.Head,
1131
1226
  { key: `table-head-${String((_a = column.key) != null ? _a : columnIndex)}` },
1132
1227
  String((_c = (_b = column.header) != null ? _b : column.key) != null ? _c : `Column ${columnIndex + 1}`)
@@ -1135,20 +1230,20 @@ var materializeBoundTable = ({
1135
1230
  )
1136
1231
  )
1137
1232
  );
1138
- const bodyNode = React9.createElement(
1233
+ const bodyNode = React10.createElement(
1139
1234
  TableComponent.Body,
1140
1235
  null,
1141
1236
  ...pagedRows.map(
1142
1237
  (row, rowIndex) => {
1143
1238
  var _a;
1144
- return React9.createElement(
1239
+ return React10.createElement(
1145
1240
  TableComponent.Row,
1146
1241
  { key: `table-row-${String((_a = row.id) != null ? _a : rowIndex)}` },
1147
1242
  ...columns.map((column, columnIndex) => {
1148
1243
  var _a2, _b;
1149
1244
  const key = String((_a2 = column.key) != null ? _a2 : "").trim();
1150
1245
  const value = key ? row[key] : "";
1151
- return React9.createElement(
1246
+ return React10.createElement(
1152
1247
  TableComponent.Cell,
1153
1248
  { key: `table-cell-${String((_b = row.id) != null ? _b : rowIndex)}-${key || columnIndex}` },
1154
1249
  value == null ? "" : String(value)
@@ -1158,7 +1253,7 @@ var materializeBoundTable = ({
1158
1253
  }
1159
1254
  )
1160
1255
  );
1161
- return React9.createElement(
1256
+ return React10.createElement(
1162
1257
  TableComponent,
1163
1258
  omitInternalProps(componentProps),
1164
1259
  headerNode,
@@ -1167,25 +1262,25 @@ var materializeBoundTable = ({
1167
1262
  };
1168
1263
 
1169
1264
  // src/materialization/navigationStudio.tsx
1170
- import React10 from "react";
1171
- import { jsx as jsx11 } from "react/jsx-runtime";
1265
+ import React11 from "react";
1266
+ import { jsx as jsx12 } from "react/jsx-runtime";
1172
1267
  var buildAccordionItems = (accordionChildren, renderSafeNode) => accordionChildren.map((child, index) => {
1173
1268
  var _a, _b, _c, _d, _e, _f, _g;
1174
1269
  const childProps = (_a = child.props) != null ? _a : {};
1175
1270
  return {
1176
1271
  id: String((_c = (_b = childProps.id) != null ? _b : child.id) != null ? _c : `item-${index + 1}`),
1177
1272
  title: String((_d = childProps.title) != null ? _d : `Section ${index + 1}`),
1178
- content: ((_e = child.children) != null ? _e : []).length > 0 ? /* @__PURE__ */ jsx11("div", { className: "space-y-2", children: ((_f = child.children) != null ? _f : []).map((nested) => /* @__PURE__ */ jsx11(React10.Fragment, { children: renderSafeNode(nested) }, nested.id)) }) : String((_g = childProps.content) != null ? _g : ""),
1273
+ content: ((_e = child.children) != null ? _e : []).length > 0 ? /* @__PURE__ */ jsx12("div", { className: "space-y-2", children: ((_f = child.children) != null ? _f : []).map((nested) => /* @__PURE__ */ jsx12(React11.Fragment, { children: renderSafeNode(nested) }, nested.id)) }) : String((_g = childProps.content) != null ? _g : ""),
1179
1274
  disabled: Boolean(childProps.disabled)
1180
1275
  };
1181
1276
  });
1182
1277
  var buildExpandablePanelChildren = (panelChildren, renderSafeNode) => {
1183
1278
  if (panelChildren.length === 0) return void 0;
1184
- return /* @__PURE__ */ jsx11("div", { className: "space-y-2", children: panelChildren.map((child) => /* @__PURE__ */ jsx11(React10.Fragment, { children: renderSafeNode(child) }, child.id)) });
1279
+ return /* @__PURE__ */ jsx12("div", { className: "space-y-2", children: panelChildren.map((child) => /* @__PURE__ */ jsx12(React11.Fragment, { children: renderSafeNode(child) }, child.id)) });
1185
1280
  };
1186
1281
 
1187
1282
  // src/rendering/finalizeRenderedNode.tsx
1188
- import React11 from "react";
1283
+ import React12 from "react";
1189
1284
 
1190
1285
  // src/rendering/previewLinkBehavior.ts
1191
1286
  var configurePreviewLinkBehavior = (componentProps) => {
@@ -1199,6 +1294,11 @@ var configurePreviewLinkBehavior = (componentProps) => {
1199
1294
  };
1200
1295
 
1201
1296
  // src/rendering/finalizeRenderedNode.tsx
1297
+ var RESPONSIVE_MEDIA_NODE_TYPES = /* @__PURE__ */ new Set(["Image", "Video", "EmbeddedVideo", "Cover"]);
1298
+ var RESPONSIVE_MEDIA_CLASS_NAME = "max-md:!w-full max-md:![flex-basis:100%!important] max-md:!h-auto";
1299
+ var hasExplicitStudioSizing = (studioSizing) => Boolean(
1300
+ studioSizing && (studioSizing.widthPct !== null || studioSizing.heightPct !== null || studioSizing.heightPx !== null)
1301
+ );
1202
1302
  var finalizeRenderedNode = ({
1203
1303
  node,
1204
1304
  children,
@@ -1210,6 +1310,10 @@ var finalizeRenderedNode = ({
1210
1310
  plans: providedPlans,
1211
1311
  dependencies
1212
1312
  }) => {
1313
+ if (RESPONSIVE_MEDIA_NODE_TYPES.has(node.type) && hasExplicitStudioSizing(studioSizing)) {
1314
+ const currentClassName = typeof componentProps.className === "string" ? componentProps.className : "";
1315
+ componentProps.className = [currentClassName, RESPONSIVE_MEDIA_CLASS_NAME].filter(Boolean).join(" ");
1316
+ }
1213
1317
  const plans = providedPlans != null ? providedPlans : dependencies.resolveFinalRenderPlan({
1214
1318
  node,
1215
1319
  componentProps,
@@ -1247,11 +1351,11 @@ var finalizeRenderedNode = ({
1247
1351
  const finalComponentProps = dependencies.omitStudioProps(componentProps);
1248
1352
  if (children && children.length > 0) {
1249
1353
  if (node.type === "Cover" || node.type === "Tabs" || node.type === "Accordion") {
1250
- return React11.createElement(registryComponent, finalComponentProps);
1354
+ return React12.createElement(registryComponent, finalComponentProps);
1251
1355
  }
1252
- return React11.createElement(registryComponent, finalComponentProps, children);
1356
+ return React12.createElement(registryComponent, finalComponentProps, children);
1253
1357
  }
1254
- return React11.createElement(registryComponent, finalComponentProps);
1358
+ return React12.createElement(registryComponent, finalComponentProps);
1255
1359
  };
1256
1360
 
1257
1361
  // src/rendering/nodeResetToken.ts
@@ -1283,8 +1387,8 @@ var buildNodeResetToken = (node) => {
1283
1387
  };
1284
1388
 
1285
1389
  // src/rendering/renderChildren.tsx
1286
- import React12, { isValidElement as isValidElement2 } from "react";
1287
- import { jsx as jsx12 } from "react/jsx-runtime";
1390
+ import React13, { isValidElement as isValidElement2 } from "react";
1391
+ import { jsx as jsx13 } from "react/jsx-runtime";
1288
1392
  var toBoolean = (value) => {
1289
1393
  if (typeof value === "boolean") return value;
1290
1394
  if (typeof value === "string") return value.toLowerCase() === "true";
@@ -1295,7 +1399,7 @@ var normalizeRenderableChild = (value) => {
1295
1399
  if (typeof value === "string" || typeof value === "number") return value;
1296
1400
  if (isValidElement2(value)) return value;
1297
1401
  if (Array.isArray(value)) {
1298
- return value.map((item, index) => /* @__PURE__ */ jsx12(React12.Fragment, { children: normalizeRenderableChild(item) }, `normalized-child-${index}`));
1402
+ return value.map((item, index) => /* @__PURE__ */ jsx13(React13.Fragment, { children: normalizeRenderableChild(item) }, `normalized-child-${index}`));
1299
1403
  }
1300
1404
  if (value && typeof value === "object") {
1301
1405
  const candidate = value;
@@ -1342,6 +1446,7 @@ export {
1342
1446
  EngineWarningFallback_default as EngineWarningFallback,
1343
1447
  NodeErrorBoundary,
1344
1448
  ReactWebEngineRoot,
1449
+ StaticReactWebEngineRoot,
1345
1450
  applyContentComposition,
1346
1451
  applyNavigationComposition,
1347
1452
  applyRenderDirectives,
package/dist/rendering.js CHANGED
@@ -174,6 +174,11 @@ var materializeBoundTable = ({
174
174
  };
175
175
 
176
176
  // src/rendering/finalizeRenderedNode.tsx
177
+ var RESPONSIVE_MEDIA_NODE_TYPES = /* @__PURE__ */ new Set(["Image", "Video", "EmbeddedVideo", "Cover"]);
178
+ var RESPONSIVE_MEDIA_CLASS_NAME = "max-md:!w-full max-md:![flex-basis:100%!important] max-md:!h-auto";
179
+ var hasExplicitStudioSizing = (studioSizing) => Boolean(
180
+ studioSizing && (studioSizing.widthPct !== null || studioSizing.heightPct !== null || studioSizing.heightPx !== null)
181
+ );
177
182
  var finalizeRenderedNode = ({
178
183
  node,
179
184
  children,
@@ -185,6 +190,10 @@ var finalizeRenderedNode = ({
185
190
  plans: providedPlans,
186
191
  dependencies
187
192
  }) => {
193
+ if (RESPONSIVE_MEDIA_NODE_TYPES.has(node.type) && hasExplicitStudioSizing(studioSizing)) {
194
+ const currentClassName = typeof componentProps.className === "string" ? componentProps.className : "";
195
+ componentProps.className = [currentClassName, RESPONSIVE_MEDIA_CLASS_NAME].filter(Boolean).join(" ");
196
+ }
188
197
  const plans = providedPlans != null ? providedPlans : dependencies.resolveFinalRenderPlan({
189
198
  node,
190
199
  componentProps,
@@ -0,0 +1,49 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React__default from 'react';
3
+ import { UIEngineProps, 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 RenderSafeNodeArgs<TInlineEditing> = {
10
+ node: UINode;
11
+ registry: NonNullable<UIEngineProps["registry"]>;
12
+ runtime: UIRuntimeAdapter;
13
+ schemaNodes: UINode[];
14
+ renderNode: (node: UINode, studioSizing?: {
15
+ widthPct: number | null;
16
+ heightPct: number | null;
17
+ heightPx: number | null;
18
+ }) => React__default.ReactNode;
19
+ isStudioRendererContext: boolean;
20
+ overlaysByNodeId: Record<string, unknown>;
21
+ selectedNodeId: string | null;
22
+ onNodeClick: UIEngineProps["onNodeClick"];
23
+ onInlineTextEdit: UIEngineProps["onInlineTextEdit"];
24
+ onNodeResize: UIEngineProps["onNodeResize"];
25
+ onNodeResizeStart: UIEngineProps["onNodeResizeStart"];
26
+ onNodeResizeEnd: UIEngineProps["onNodeResizeEnd"];
27
+ inlineEditing: TInlineEditing | null;
28
+ setInlineEditing: React__default.Dispatch<React__default.SetStateAction<TInlineEditing | null>>;
29
+ ancestorTypeMembership: Record<string, Set<string>>;
30
+ resizeStateRef: React__default.MutableRefObject<unknown>;
31
+ pinchStateRef: React__default.MutableRefObject<unknown>;
32
+ minWidthPct: number;
33
+ minHeightPct: number;
34
+ minHeightPx: number;
35
+ overlayRootId: string;
36
+ NodeWrapper: React__default.ComponentType<UINodeWrapperProps>;
37
+ isFormInteractiveTarget: (target: HTMLElement | null) => boolean;
38
+ };
39
+ type StaticReactWebEngineRootDependencies<TInlineEditing> = {
40
+ renderSafeNode: (args: RenderSafeNodeArgs<TInlineEditing>) => React__default.ReactNode;
41
+ StudioNodeWrapper: React__default.ComponentType<UINodeWrapperProps>;
42
+ renderReactNodeDependencies: Parameters<typeof renderReactNode<TInlineEditing>>[0]["dependencies"];
43
+ };
44
+ type StaticReactWebEngineRootArgs<TInlineEditing> = UIEngineProps & {
45
+ dependencies: StaticReactWebEngineRootDependencies<TInlineEditing>;
46
+ };
47
+ declare const StaticReactWebEngineRoot: <TInlineEditing = unknown>({ schema, registry, store, nodeWrapper, dependencies, }: StaticReactWebEngineRootArgs<TInlineEditing>) => react_jsx_runtime.JSX.Element;
48
+
49
+ export { StaticReactWebEngineRoot };
@@ -0,0 +1,375 @@
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/StaticReactWebEngineRoot.tsx
22
+ import React3 from "react";
23
+
24
+ // src/engine/EngineWarningFallback.tsx
25
+ import { jsx } from "react/jsx-runtime";
26
+ var EngineWarningFallback = ({ message }) => /* @__PURE__ */ jsx(
27
+ "div",
28
+ {
29
+ role: "alert",
30
+ className: "rounded-md border border-amber-300 bg-amber-50 px-3 py-2 text-sm text-amber-900",
31
+ children: message
32
+ }
33
+ );
34
+ var EngineWarningFallback_default = EngineWarningFallback;
35
+
36
+ // src/rendering/resolveResolvedReactNode.ts
37
+ import {
38
+ resolveResolvedNode
39
+ } from "@arkcit/engine-render-layer";
40
+
41
+ // src/rendering/prepareRenderableChildren.tsx
42
+ import React2 from "react";
43
+ import {
44
+ resolveChildContentDescriptor,
45
+ resolveChildDescriptors
46
+ } from "@arkcit/engine-render-layer";
47
+
48
+ // src/rendering/gridItemWrapperProps.ts
49
+ var getGridItemWrapperProps = (colSpan) => ({
50
+ className: "w-full min-w-0",
51
+ style: {
52
+ gridColumn: `span ${colSpan} / span ${colSpan}`
53
+ }
54
+ });
55
+
56
+ // src/materialization/materializeChildContent.tsx
57
+ import React from "react";
58
+ import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
59
+ var materializeChildContent = ({
60
+ descriptor,
61
+ renderSafeNode
62
+ }) => {
63
+ if (descriptor.kind === "empty") {
64
+ return null;
65
+ }
66
+ const renderDescriptor = (childDescriptor) => {
67
+ if (childDescriptor.kind === "grid-item") {
68
+ return /* @__PURE__ */ jsx2("div", __spreadProps(__spreadValues({}, getGridItemWrapperProps(childDescriptor.colSpan)), { children: renderSafeNode(childDescriptor.child) }), childDescriptor.child.id);
69
+ }
70
+ return /* @__PURE__ */ jsx2(React.Fragment, { children: renderSafeNode(childDescriptor.child) }, childDescriptor.child.id);
71
+ };
72
+ if (descriptor.kind === "single") {
73
+ return renderDescriptor(descriptor.child);
74
+ }
75
+ return /* @__PURE__ */ jsx2(Fragment, { children: descriptor.children.map(renderDescriptor) });
76
+ };
77
+
78
+ // src/rendering/prepareRenderableChildren.tsx
79
+ import { jsx as jsx3 } from "react/jsx-runtime";
80
+ var prepareRenderableChildren = ({
81
+ node,
82
+ internalStudioNodeTypes,
83
+ renderSafeNode,
84
+ childDescriptors,
85
+ childContentDescriptor
86
+ }) => {
87
+ const resolvedDescriptors = childDescriptors != null ? childDescriptors : resolveChildDescriptors({
88
+ node,
89
+ internalStudioNodeTypes
90
+ });
91
+ const children = resolvedDescriptors.map((descriptor) => {
92
+ if (descriptor.kind === "grid-item") {
93
+ return /* @__PURE__ */ jsx3("div", __spreadProps(__spreadValues({}, getGridItemWrapperProps(descriptor.colSpan)), { children: renderSafeNode(descriptor.child) }), descriptor.child.id);
94
+ }
95
+ return /* @__PURE__ */ jsx3(React2.Fragment, { children: renderSafeNode(descriptor.child) }, descriptor.child.id);
96
+ });
97
+ const resolvedChildContentDescriptor = childContentDescriptor != null ? childContentDescriptor : resolveChildContentDescriptor({
98
+ childDescriptors: resolvedDescriptors
99
+ });
100
+ const resolvedChildContent = materializeChildContent({
101
+ descriptor: resolvedChildContentDescriptor,
102
+ renderSafeNode
103
+ });
104
+ return {
105
+ children,
106
+ resolvedChildContent,
107
+ childDescriptors: resolvedDescriptors,
108
+ childContentDescriptor: resolvedChildContentDescriptor
109
+ };
110
+ };
111
+
112
+ // src/rendering/resolveResolvedReactNode.ts
113
+ var resolveResolvedReactNode = ({
114
+ node,
115
+ runtime,
116
+ registry,
117
+ internalStudioNodeTypes,
118
+ renderSafeNode,
119
+ isStudioRendererContext,
120
+ studioSizing
121
+ }) => {
122
+ const registryEntry = registry[node.type];
123
+ if (!registryEntry) {
124
+ return null;
125
+ }
126
+ const resolvedNode = resolveResolvedNode({
127
+ node,
128
+ runtime,
129
+ internalStudioNodeTypes,
130
+ isStudioRendererContext,
131
+ studioSizing
132
+ });
133
+ const { children, resolvedChildContent } = prepareRenderableChildren({
134
+ node,
135
+ internalStudioNodeTypes,
136
+ renderSafeNode,
137
+ childDescriptors: resolvedNode.childDescriptors,
138
+ childContentDescriptor: resolvedNode.childContentDescriptor
139
+ });
140
+ return __spreadProps(__spreadValues({}, resolvedNode), {
141
+ registryEntry,
142
+ children,
143
+ resolvedChildContent
144
+ });
145
+ };
146
+
147
+ // src/rendering/renderReactNode.tsx
148
+ import { jsx as jsx4 } from "react/jsx-runtime";
149
+ var renderReactNode = ({
150
+ node,
151
+ runtime,
152
+ registry,
153
+ schemaNodes,
154
+ renderSafeNode,
155
+ internalStudioNodeTypes,
156
+ overlaysByNodeId,
157
+ onInlineTextEdit,
158
+ isStudioRendererContext,
159
+ dropdownOpenByNodeId,
160
+ setDropdownOpenByNodeId,
161
+ captureFieldFocus,
162
+ selectedNodeId,
163
+ wizardActiveStepByNodeId,
164
+ accordionOpenIdsByNodeId,
165
+ expandablePanelOpenByNodeId,
166
+ setWizardActiveStepByNodeId,
167
+ setAccordionOpenIdsByNodeId,
168
+ setExpandablePanelOpenByNodeId,
169
+ onNodeClick,
170
+ setInlineEditing,
171
+ studioSizing,
172
+ dependencies
173
+ }) => {
174
+ try {
175
+ const resolvedNode = resolveResolvedReactNode({
176
+ node,
177
+ runtime,
178
+ registry,
179
+ internalStudioNodeTypes,
180
+ renderSafeNode,
181
+ isStudioRendererContext,
182
+ studioSizing
183
+ });
184
+ if (!resolvedNode) {
185
+ return /* @__PURE__ */ jsx4(
186
+ EngineWarningFallback_default,
187
+ {
188
+ message: `Unknown component type "${node.type}" for node "${node.id}".`
189
+ }
190
+ );
191
+ }
192
+ const {
193
+ registryEntry,
194
+ componentProps,
195
+ renderBindingProps,
196
+ children,
197
+ resolvedChildContent,
198
+ contentPlans,
199
+ navigationPlans,
200
+ renderDirectivePlans,
201
+ finalRenderPlans
202
+ } = resolvedNode;
203
+ dependencies.applyStudioOverlayComponentProps({
204
+ node,
205
+ componentProps,
206
+ runtime,
207
+ overlaysByNodeId,
208
+ renderBindingProps,
209
+ resolvedChildContent,
210
+ onInlineTextEdit,
211
+ isStudioRendererContext,
212
+ dropdownOpenByNodeId,
213
+ setDropdownOpenByNodeId
214
+ });
215
+ const contentNode = dependencies.applyContentComposition({
216
+ node,
217
+ componentProps,
218
+ isStudioRendererContext,
219
+ internalStudioNodeTypes,
220
+ schemaNodes,
221
+ onInlineTextEdit,
222
+ captureFieldFocus,
223
+ renderSafeNode,
224
+ normalizeRenderableChild: dependencies.normalizeRenderableChild,
225
+ findNodeById: dependencies.findNodeById,
226
+ runtime,
227
+ plans: contentPlans
228
+ });
229
+ if (contentNode) {
230
+ return contentNode;
231
+ }
232
+ dependencies.applyRenderDirectives({
233
+ node,
234
+ componentProps,
235
+ renderBindingProps,
236
+ runtime,
237
+ plans: renderDirectivePlans
238
+ });
239
+ dependencies.applyNavigationComposition({
240
+ node,
241
+ componentProps,
242
+ isStudioRendererContext,
243
+ selectedNodeId: selectedNodeId != null ? selectedNodeId : null,
244
+ wizardActiveStepByNodeId,
245
+ accordionOpenIdsByNodeId,
246
+ expandablePanelOpenByNodeId,
247
+ runtime,
248
+ setWizardActiveStepByNodeId,
249
+ setAccordionOpenIdsByNodeId,
250
+ setExpandablePanelOpenByNodeId,
251
+ onNodeClick,
252
+ onInlineTextEdit,
253
+ renderSafeNode,
254
+ normalizeRenderableChild: dependencies.normalizeRenderableChild,
255
+ captureFieldFocus,
256
+ setInlineEditing,
257
+ internalStudioNodeTypes,
258
+ plans: navigationPlans
259
+ });
260
+ return dependencies.finalizeRenderedNode({
261
+ node,
262
+ children,
263
+ componentProps,
264
+ registryComponent: registryEntry.Component,
265
+ runtime,
266
+ isStudioRendererContext,
267
+ studioSizing,
268
+ plans: finalRenderPlans
269
+ });
270
+ } catch (e) {
271
+ return /* @__PURE__ */ jsx4(
272
+ EngineWarningFallback_default,
273
+ {
274
+ message: `Renderer fallback: node "${node.type}" (${node.id}) could not be resolved.`
275
+ }
276
+ );
277
+ }
278
+ };
279
+
280
+ // src/engine/StaticReactWebEngineRoot.tsx
281
+ import { jsx as jsx5 } from "react/jsx-runtime";
282
+ var INTERNAL_STUDIO_NODE_TYPES = /* @__PURE__ */ new Set();
283
+ var STUDIO_CANVAS_OVERLAY_ROOT_ID = "studio-canvas-overlay-root";
284
+ var STUDIO_MIN_WIDTH_PCT = 5;
285
+ var STUDIO_MIN_HEIGHT_PCT = 5;
286
+ var STUDIO_MIN_HEIGHT_PX = 20;
287
+ var NOOP_RUNTIME = {
288
+ get: () => void 0,
289
+ dispatch: () => void 0
290
+ };
291
+ var EMPTY_UI_REGISTRY = {};
292
+ var EMPTY_INLINE_MEMBERSHIP = Object.freeze({
293
+ Form: /* @__PURE__ */ new Set(),
294
+ FormWizard: /* @__PURE__ */ new Set(),
295
+ StepForm: /* @__PURE__ */ new Set()
296
+ });
297
+ var isFormInteractiveTarget = (_target) => false;
298
+ var createStaticRef = (value) => ({
299
+ current: value
300
+ });
301
+ var NOOP_SETTER = (_value) => void 0;
302
+ var StaticReactWebEngineRoot = ({
303
+ schema,
304
+ registry = EMPTY_UI_REGISTRY,
305
+ store,
306
+ nodeWrapper,
307
+ dependencies
308
+ }) => {
309
+ const runtime = store != null ? store : NOOP_RUNTIME;
310
+ const NodeWrapper = nodeWrapper != null ? nodeWrapper : dependencies.StudioNodeWrapper;
311
+ const setInlineEditing = NOOP_SETTER;
312
+ const setDropdownOpenByNodeId = NOOP_SETTER;
313
+ const setWizardActiveStepByNodeId = NOOP_SETTER;
314
+ const setAccordionOpenIdsByNodeId = NOOP_SETTER;
315
+ const setExpandablePanelOpenByNodeId = NOOP_SETTER;
316
+ const resizeStateRef = createStaticRef(null);
317
+ const pinchStateRef = createStaticRef(null);
318
+ const overlaysByNodeId = {};
319
+ const isStudioRendererContext = false;
320
+ const renderNode = (node, studioSizing) => renderReactNode({
321
+ node,
322
+ runtime,
323
+ registry,
324
+ schemaNodes: schema.nodes,
325
+ renderSafeNode: renderSafeEngineNode,
326
+ internalStudioNodeTypes: INTERNAL_STUDIO_NODE_TYPES,
327
+ overlaysByNodeId,
328
+ onInlineTextEdit: void 0,
329
+ isStudioRendererContext,
330
+ dropdownOpenByNodeId: {},
331
+ setDropdownOpenByNodeId,
332
+ captureFieldFocus: () => void 0,
333
+ selectedNodeId: null,
334
+ wizardActiveStepByNodeId: {},
335
+ accordionOpenIdsByNodeId: {},
336
+ expandablePanelOpenByNodeId: {},
337
+ setWizardActiveStepByNodeId,
338
+ setAccordionOpenIdsByNodeId,
339
+ setExpandablePanelOpenByNodeId,
340
+ onNodeClick: void 0,
341
+ setInlineEditing,
342
+ studioSizing,
343
+ dependencies: dependencies.renderReactNodeDependencies
344
+ });
345
+ const renderSafeEngineNode = (node) => dependencies.renderSafeNode({
346
+ node,
347
+ registry,
348
+ runtime,
349
+ schemaNodes: schema.nodes,
350
+ renderNode,
351
+ isStudioRendererContext,
352
+ overlaysByNodeId,
353
+ selectedNodeId: null,
354
+ onNodeClick: void 0,
355
+ onInlineTextEdit: void 0,
356
+ onNodeResize: void 0,
357
+ onNodeResizeStart: void 0,
358
+ onNodeResizeEnd: void 0,
359
+ inlineEditing: null,
360
+ setInlineEditing,
361
+ ancestorTypeMembership: EMPTY_INLINE_MEMBERSHIP,
362
+ resizeStateRef,
363
+ pinchStateRef,
364
+ minWidthPct: STUDIO_MIN_WIDTH_PCT,
365
+ minHeightPct: STUDIO_MIN_HEIGHT_PCT,
366
+ minHeightPx: STUDIO_MIN_HEIGHT_PX,
367
+ overlayRootId: STUDIO_CANVAS_OVERLAY_ROOT_ID,
368
+ NodeWrapper,
369
+ isFormInteractiveTarget
370
+ });
371
+ return /* @__PURE__ */ jsx5("div", { className: "flex h-full min-w-0 w-full flex-wrap content-start items-start gap-3", children: schema.nodes.map((node) => /* @__PURE__ */ jsx5(React3.Fragment, { children: renderSafeEngineNode(node) }, node.id)) });
372
+ };
373
+ export {
374
+ StaticReactWebEngineRoot
375
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@arkcit/engine-react",
3
3
  "private": false,
4
- "version": "0.3.2",
4
+ "version": "0.3.4",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "description": "React-specific renderer package for the Arkcit engine platform.",
@@ -35,6 +35,11 @@
35
35
  "import": "./dist/engine.js",
36
36
  "default": "./dist/engine.js"
37
37
  },
38
+ "./static-engine": {
39
+ "types": "./dist/static-engine.d.ts",
40
+ "import": "./dist/static-engine.js",
41
+ "default": "./dist/static-engine.js"
42
+ },
38
43
  "./hooks": {
39
44
  "types": "./dist/hooks.d.ts",
40
45
  "import": "./dist/hooks.js",