@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.
- package/README.md +51 -0
- package/dist/composition.d.ts +116 -0
- package/dist/composition.js +344 -0
- package/dist/directives.d.ts +49 -0
- package/dist/directives.js +58 -0
- package/dist/engine.d.ts +96 -0
- package/dist/engine.js +508 -0
- package/dist/hooks.d.ts +55 -0
- package/dist/hooks.js +135 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +1371 -0
- package/dist/materialization.d.ts +86 -0
- package/dist/materialization.js +334 -0
- package/dist/renderReactNode-DmxD8hot.d.ts +109 -0
- package/dist/rendering.d.ts +118 -0
- package/dist/rendering.js +582 -0
- package/package.json +91 -0
package/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# @arkcit/engine-react
|
|
2
|
+
|
|
3
|
+
Concrete React renderer package for the Arkcit platform.
|
|
4
|
+
|
|
5
|
+
## Position In The Flow
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
@arkcit/engine-schema
|
|
9
|
+
@arkcit/engine-runtime
|
|
10
|
+
@arkcit/engine-core
|
|
11
|
+
@arkcit/engine-render-layer
|
|
12
|
+
↓
|
|
13
|
+
@arkcit/engine-react
|
|
14
|
+
↓
|
|
15
|
+
@arkcit/engine
|
|
16
|
+
↓
|
|
17
|
+
@arkcit/react-ui
|
|
18
|
+
@arkcit/studio preview adapters
|
|
19
|
+
@arkcit/docs-shell
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## What Goes In
|
|
23
|
+
|
|
24
|
+
- neutral resolved-node contracts
|
|
25
|
+
- shared engine primitives
|
|
26
|
+
- React-specific rendering needs
|
|
27
|
+
|
|
28
|
+
## What Comes Out
|
|
29
|
+
|
|
30
|
+
- React rendering helpers
|
|
31
|
+
- React engine root pieces
|
|
32
|
+
- React-specific composition/materialization utilities
|
|
33
|
+
|
|
34
|
+
## Responsibilities
|
|
35
|
+
|
|
36
|
+
- own React-only rendering behavior
|
|
37
|
+
- keep React-specific utilities out of neutral engine layers
|
|
38
|
+
- expose reusable React renderer seams to `@arkcit/engine`
|
|
39
|
+
|
|
40
|
+
## Do Not Put Here
|
|
41
|
+
|
|
42
|
+
- canonical schema rules
|
|
43
|
+
- runtime contract ownership
|
|
44
|
+
- Angular or React Native behavior
|
|
45
|
+
|
|
46
|
+
## Main Consumers
|
|
47
|
+
|
|
48
|
+
- `@arkcit/engine`
|
|
49
|
+
- `@arkcit/react-ui`
|
|
50
|
+
- `@arkcit/studio`
|
|
51
|
+
- `@arkcit/docs-shell`
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { ContentCompositionPlan, NavigationCompositionPlan } from '@arkcit/engine-render-layer';
|
|
3
|
+
import { UINode } from '@arkcit/engine-schema';
|
|
4
|
+
import { UIRuntimeAdapter } from '@arkcit/engine-runtime';
|
|
5
|
+
|
|
6
|
+
type ApplyContentCompositionParams = {
|
|
7
|
+
node: UINode;
|
|
8
|
+
componentProps: Record<string, unknown>;
|
|
9
|
+
isStudioRendererContext: boolean;
|
|
10
|
+
internalStudioNodeTypes: Set<string>;
|
|
11
|
+
schemaNodes: UINode[];
|
|
12
|
+
onInlineTextEdit?: (nodeId: string, propName: string, value: unknown) => void;
|
|
13
|
+
captureFieldFocus: (target: EventTarget | null) => void;
|
|
14
|
+
renderSafeNode: (node: UINode) => React__default.ReactNode;
|
|
15
|
+
normalizeRenderableChild: (value: unknown) => React__default.ReactNode;
|
|
16
|
+
findNodeById: (nodeId: string, nodes: UINode[]) => UINode | null;
|
|
17
|
+
runtime: UIRuntimeAdapter;
|
|
18
|
+
plans?: ContentCompositionPlan[];
|
|
19
|
+
dependencies: {
|
|
20
|
+
resolveContentCompositionPlan: (args: {
|
|
21
|
+
node: UINode;
|
|
22
|
+
isStudioRendererContext: boolean;
|
|
23
|
+
internalStudioNodeTypes: Set<string>;
|
|
24
|
+
}) => ContentCompositionPlan[];
|
|
25
|
+
renderStudioForm: (args: {
|
|
26
|
+
node: UINode;
|
|
27
|
+
componentProps: Record<string, unknown>;
|
|
28
|
+
visibleChildren: UINode[];
|
|
29
|
+
runtime: UIRuntimeAdapter;
|
|
30
|
+
onInlineTextEdit?: (nodeId: string, propName: string, value: unknown) => void;
|
|
31
|
+
captureFieldFocus: (target: EventTarget | null) => void;
|
|
32
|
+
renderSafeNode: (node: UINode) => React__default.ReactNode;
|
|
33
|
+
}) => React__default.ReactNode | null;
|
|
34
|
+
buildScrollRevealChildren: (args: {
|
|
35
|
+
rawChildren: unknown;
|
|
36
|
+
renderSafeNode: (node: UINode) => React__default.ReactNode;
|
|
37
|
+
normalizeRenderableChild: (value: unknown) => React__default.ReactNode;
|
|
38
|
+
fallbackChildren: unknown;
|
|
39
|
+
}) => React__default.ReactNode;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
declare const applyContentComposition: ({ node, componentProps, isStudioRendererContext, internalStudioNodeTypes, schemaNodes, onInlineTextEdit, captureFieldFocus, renderSafeNode, normalizeRenderableChild, findNodeById, runtime, plans: providedPlans, dependencies, }: ApplyContentCompositionParams) => React__default.ReactNode | null;
|
|
43
|
+
|
|
44
|
+
type ApplyNavigationCompositionParams<TInlineEditing = unknown> = {
|
|
45
|
+
node: UINode;
|
|
46
|
+
componentProps: Record<string, unknown>;
|
|
47
|
+
isStudioRendererContext: boolean;
|
|
48
|
+
selectedNodeId: string | null;
|
|
49
|
+
wizardActiveStepByNodeId: Record<string, string>;
|
|
50
|
+
accordionOpenIdsByNodeId: Record<string, string[]>;
|
|
51
|
+
expandablePanelOpenByNodeId: Record<string, boolean>;
|
|
52
|
+
runtime: UIRuntimeAdapter;
|
|
53
|
+
setWizardActiveStepByNodeId: React__default.Dispatch<React__default.SetStateAction<Record<string, string>>>;
|
|
54
|
+
setAccordionOpenIdsByNodeId: React__default.Dispatch<React__default.SetStateAction<Record<string, string[]>>>;
|
|
55
|
+
setExpandablePanelOpenByNodeId: React__default.Dispatch<React__default.SetStateAction<Record<string, boolean>>>;
|
|
56
|
+
onNodeClick?: (nodeId: string) => void;
|
|
57
|
+
onInlineTextEdit?: (nodeId: string, propName: string, value: unknown) => void;
|
|
58
|
+
renderSafeNode: (node: UINode) => React__default.ReactNode;
|
|
59
|
+
normalizeRenderableChild: (value: unknown) => React__default.ReactNode;
|
|
60
|
+
captureFieldFocus: (target: EventTarget | null) => void;
|
|
61
|
+
setInlineEditing: React__default.Dispatch<React__default.SetStateAction<TInlineEditing | null>>;
|
|
62
|
+
internalStudioNodeTypes: Set<string>;
|
|
63
|
+
plans?: NavigationCompositionPlan[];
|
|
64
|
+
dependencies: {
|
|
65
|
+
resolveNavigationCompositionPlan: (args: {
|
|
66
|
+
node: UINode;
|
|
67
|
+
componentProps: Record<string, unknown>;
|
|
68
|
+
internalStudioNodeTypes: Set<string>;
|
|
69
|
+
runtime: UIRuntimeAdapter;
|
|
70
|
+
}) => NavigationCompositionPlan[];
|
|
71
|
+
createInlineEditingState: (targetNodeId: string, propName: string, rawValue: unknown) => TInlineEditing;
|
|
72
|
+
configureStudioFormWizard: (args: {
|
|
73
|
+
node: UINode;
|
|
74
|
+
componentProps: Record<string, unknown>;
|
|
75
|
+
isStudioRendererContext: boolean;
|
|
76
|
+
selectedNodeId: string | null;
|
|
77
|
+
wizardActiveStepByNodeId: Record<string, string>;
|
|
78
|
+
runtime: UIRuntimeAdapter;
|
|
79
|
+
setWizardActiveStepByNodeId: React__default.Dispatch<React__default.SetStateAction<Record<string, string>>>;
|
|
80
|
+
onNodeClick?: (nodeId: string) => void;
|
|
81
|
+
onInlineTextEdit?: (nodeId: string, propName: string, value: unknown) => void;
|
|
82
|
+
renderSafeNode: (node: UINode) => React__default.ReactNode;
|
|
83
|
+
captureFieldFocus: (target: EventTarget | null) => void;
|
|
84
|
+
openInlineEditorForNodeProp: (targetNodeId: string, propName: string, rawValue: unknown) => void;
|
|
85
|
+
internalStudioNodeTypes: Set<string>;
|
|
86
|
+
}) => void;
|
|
87
|
+
configureStudioAccordion: (args: {
|
|
88
|
+
node: UINode;
|
|
89
|
+
componentProps: Record<string, unknown>;
|
|
90
|
+
accordionChildren: UINode[];
|
|
91
|
+
selectedNodeId: string | null;
|
|
92
|
+
accordionOpenIdsByNodeId: Record<string, string[]>;
|
|
93
|
+
setAccordionOpenIdsByNodeId: React__default.Dispatch<React__default.SetStateAction<Record<string, string[]>>>;
|
|
94
|
+
renderSafeNode: (node: UINode) => React__default.ReactNode;
|
|
95
|
+
}) => void;
|
|
96
|
+
configureStudioExpandablePanel: (args: {
|
|
97
|
+
node: UINode;
|
|
98
|
+
componentProps: Record<string, unknown>;
|
|
99
|
+
panelChildren: UINode[];
|
|
100
|
+
expandablePanelOpenByNodeId: Record<string, boolean>;
|
|
101
|
+
setExpandablePanelOpenByNodeId: React__default.Dispatch<React__default.SetStateAction<Record<string, boolean>>>;
|
|
102
|
+
renderSafeNode: (node: UINode) => React__default.ReactNode;
|
|
103
|
+
}) => void;
|
|
104
|
+
configureStudioTabs: (args: {
|
|
105
|
+
componentProps: Record<string, unknown>;
|
|
106
|
+
tabItems: Array<Record<string, unknown>>;
|
|
107
|
+
rawChildren: unknown;
|
|
108
|
+
runtime: UIRuntimeAdapter;
|
|
109
|
+
renderSafeNode: (node: UINode) => React__default.ReactNode;
|
|
110
|
+
normalizeRenderableChild: (value: unknown) => React__default.ReactNode;
|
|
111
|
+
}) => void;
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
declare const applyNavigationComposition: <TInlineEditing = unknown>({ node, componentProps, isStudioRendererContext, selectedNodeId, wizardActiveStepByNodeId, accordionOpenIdsByNodeId, expandablePanelOpenByNodeId, runtime, setWizardActiveStepByNodeId, setAccordionOpenIdsByNodeId, setExpandablePanelOpenByNodeId, onNodeClick, onInlineTextEdit, renderSafeNode, normalizeRenderableChild, captureFieldFocus, setInlineEditing, internalStudioNodeTypes, plans: providedPlans, dependencies, }: ApplyNavigationCompositionParams<TInlineEditing>) => void;
|
|
115
|
+
|
|
116
|
+
export { applyContentComposition, applyNavigationComposition };
|
|
@@ -0,0 +1,344 @@
|
|
|
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/materialization/materializeCoverContent.tsx
|
|
22
|
+
import React from "react";
|
|
23
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
24
|
+
var materializeCoverContent = ({
|
|
25
|
+
descriptor,
|
|
26
|
+
renderSafeNode
|
|
27
|
+
}) => {
|
|
28
|
+
const resolvedActionChildren = descriptor.actionNodes.map((child) => /* @__PURE__ */ jsx("span", { className: "inline-flex align-middle", children: renderSafeNode(child) }, child.id));
|
|
29
|
+
const resolvedContentChildren = descriptor.contentNodes.map((child) => /* @__PURE__ */ jsx(React.Fragment, { children: renderSafeNode(child) }, child.id));
|
|
30
|
+
return {
|
|
31
|
+
actions: resolvedActionChildren.length > 0 ? resolvedActionChildren.length === 1 ? resolvedActionChildren[0] : /* @__PURE__ */ jsx(Fragment, { children: resolvedActionChildren }) : void 0,
|
|
32
|
+
children: resolvedContentChildren.length > 0 ? resolvedContentChildren.length === 1 ? resolvedContentChildren[0] : /* @__PURE__ */ jsx(Fragment, { children: resolvedContentChildren }) : null
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// src/composition/applyContentComposition.tsx
|
|
37
|
+
var applyContentComposition = ({
|
|
38
|
+
node,
|
|
39
|
+
componentProps,
|
|
40
|
+
isStudioRendererContext,
|
|
41
|
+
internalStudioNodeTypes,
|
|
42
|
+
schemaNodes,
|
|
43
|
+
onInlineTextEdit,
|
|
44
|
+
captureFieldFocus,
|
|
45
|
+
renderSafeNode,
|
|
46
|
+
normalizeRenderableChild,
|
|
47
|
+
findNodeById,
|
|
48
|
+
runtime,
|
|
49
|
+
plans: providedPlans,
|
|
50
|
+
dependencies
|
|
51
|
+
}) => {
|
|
52
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
53
|
+
const plans = providedPlans != null ? providedPlans : dependencies.resolveContentCompositionPlan({
|
|
54
|
+
node,
|
|
55
|
+
isStudioRendererContext,
|
|
56
|
+
internalStudioNodeTypes
|
|
57
|
+
});
|
|
58
|
+
if (plans.some((plan) => plan.kind === "button-toggle" && plan.disableOnClick)) {
|
|
59
|
+
delete componentProps.onClick;
|
|
60
|
+
}
|
|
61
|
+
if (plans.some((plan) => plan.kind === "form-field")) {
|
|
62
|
+
const rawProps = (_a = node.props) != null ? _a : {};
|
|
63
|
+
const existingField = componentProps.field && typeof componentProps.field === "object" && !Array.isArray(componentProps.field) ? componentProps.field : {};
|
|
64
|
+
const fieldName = String((_c = (_b = existingField.name) != null ? _b : rawProps.name) != null ? _c : "").trim();
|
|
65
|
+
const fieldType = String((_e = (_d = existingField.type) != null ? _d : rawProps.type) != null ? _e : "text");
|
|
66
|
+
const fallbackLabel = fieldName || "Field";
|
|
67
|
+
const fieldLabel = String((_g = (_f = existingField.label) != null ? _f : rawProps.label) != null ? _g : fallbackLabel);
|
|
68
|
+
componentProps.field = __spreadProps(__spreadValues(__spreadValues({}, rawProps), existingField), {
|
|
69
|
+
name: fieldName || "field",
|
|
70
|
+
type: fieldType,
|
|
71
|
+
label: fieldLabel
|
|
72
|
+
});
|
|
73
|
+
if (componentProps.value === void 0) {
|
|
74
|
+
componentProps.value = (_i = (_h = rawProps.value) != null ? _h : rawProps.defaultValue) != null ? _i : "";
|
|
75
|
+
}
|
|
76
|
+
if (!componentProps.dict || typeof componentProps.dict !== "object" || Array.isArray(componentProps.dict)) {
|
|
77
|
+
componentProps.dict = {
|
|
78
|
+
submit: "Submit",
|
|
79
|
+
reset: "Reset",
|
|
80
|
+
loading: "Loading...",
|
|
81
|
+
success: "Saved",
|
|
82
|
+
search: "Search...",
|
|
83
|
+
noResultToShow: "No result"
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (!componentProps.onChange) {
|
|
87
|
+
componentProps.onChange = (event) => {
|
|
88
|
+
var _a2;
|
|
89
|
+
captureFieldFocus(event.target);
|
|
90
|
+
const target = event.target;
|
|
91
|
+
const nextValue = target.type === "checkbox" ? Boolean(target.checked) : target.value;
|
|
92
|
+
const findParentFormId = (nodes, targetId, lineage = []) => {
|
|
93
|
+
var _a3, _b2;
|
|
94
|
+
for (const candidate of nodes) {
|
|
95
|
+
const nextLineage = [...lineage, candidate];
|
|
96
|
+
if (candidate.id === targetId) {
|
|
97
|
+
for (let index = nextLineage.length - 2; index >= 0; index -= 1) {
|
|
98
|
+
if (((_a3 = nextLineage[index]) == null ? void 0 : _a3.type) === "Form") {
|
|
99
|
+
return nextLineage[index].id;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
if ((_b2 = candidate.children) == null ? void 0 : _b2.length) {
|
|
105
|
+
const found = findParentFormId(candidate.children, targetId, nextLineage);
|
|
106
|
+
if (found) return found;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
};
|
|
111
|
+
const parentFormId = findParentFormId(schemaNodes, node.id);
|
|
112
|
+
if (parentFormId && onInlineTextEdit && fieldName) {
|
|
113
|
+
const parentForm = findNodeById(parentFormId, schemaNodes);
|
|
114
|
+
const parentProps = (_a2 = parentForm == null ? void 0 : parentForm.props) != null ? _a2 : {};
|
|
115
|
+
const currentValues = parentProps.values && typeof parentProps.values === "object" && !Array.isArray(parentProps.values) ? parentProps.values : {};
|
|
116
|
+
onInlineTextEdit(parentFormId, "values", __spreadProps(__spreadValues({}, currentValues), {
|
|
117
|
+
[fieldName]: nextValue
|
|
118
|
+
}));
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
onInlineTextEdit == null ? void 0 : onInlineTextEdit(node.id, "value", nextValue);
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
const studioFormPlan = plans.find((plan) => plan.kind === "studio-form");
|
|
126
|
+
if ((studioFormPlan == null ? void 0 : studioFormPlan.kind) === "studio-form") {
|
|
127
|
+
return dependencies.renderStudioForm({
|
|
128
|
+
node,
|
|
129
|
+
componentProps,
|
|
130
|
+
visibleChildren: studioFormPlan.visibleChildren,
|
|
131
|
+
runtime,
|
|
132
|
+
onInlineTextEdit,
|
|
133
|
+
captureFieldFocus,
|
|
134
|
+
renderSafeNode
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
if (isStudioRendererContext && node.type === "Form" && onInlineTextEdit) {
|
|
138
|
+
const existingStudioConfig = componentProps.studio && typeof componentProps.studio === "object" && !Array.isArray(componentProps.studio) ? componentProps.studio : {};
|
|
139
|
+
componentProps.studio = __spreadProps(__spreadValues({}, existingStudioConfig), {
|
|
140
|
+
onSubmitLabelDoubleClick: () => {
|
|
141
|
+
var _a2, _b2;
|
|
142
|
+
return onInlineTextEdit(
|
|
143
|
+
node.id,
|
|
144
|
+
"dict.submit",
|
|
145
|
+
String(
|
|
146
|
+
(_b2 = (_a2 = componentProps.dict) == null ? void 0 : _a2.submit) != null ? _b2 : "Submit"
|
|
147
|
+
)
|
|
148
|
+
);
|
|
149
|
+
},
|
|
150
|
+
onResetLabelDoubleClick: () => {
|
|
151
|
+
var _a2, _b2;
|
|
152
|
+
return onInlineTextEdit(
|
|
153
|
+
node.id,
|
|
154
|
+
"dict.reset",
|
|
155
|
+
String(
|
|
156
|
+
(_b2 = (_a2 = componentProps.dict) == null ? void 0 : _a2.reset) != null ? _b2 : "Reset"
|
|
157
|
+
)
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
const coverPlan = plans.find((plan) => plan.kind === "cover-content");
|
|
163
|
+
if ((coverPlan == null ? void 0 : coverPlan.kind) === "cover-content") {
|
|
164
|
+
const content = materializeCoverContent({
|
|
165
|
+
descriptor: coverPlan.descriptor,
|
|
166
|
+
renderSafeNode
|
|
167
|
+
});
|
|
168
|
+
if (content.actions !== void 0) {
|
|
169
|
+
componentProps.actions = content.actions;
|
|
170
|
+
}
|
|
171
|
+
if (content.children !== null) {
|
|
172
|
+
componentProps.children = content.children;
|
|
173
|
+
} else if (componentProps.children === void 0) {
|
|
174
|
+
componentProps.children = null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const scrollRevealPlan = plans.find((plan) => plan.kind === "scroll-reveal");
|
|
178
|
+
if ((scrollRevealPlan == null ? void 0 : scrollRevealPlan.kind) === "scroll-reveal") {
|
|
179
|
+
componentProps.children = dependencies.buildScrollRevealChildren({
|
|
180
|
+
rawChildren: scrollRevealPlan.rawChildren,
|
|
181
|
+
renderSafeNode,
|
|
182
|
+
normalizeRenderableChild,
|
|
183
|
+
fallbackChildren: componentProps.children
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
return null;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
// src/materialization/materializeNavigationContent.tsx
|
|
190
|
+
import React2 from "react";
|
|
191
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
192
|
+
var materializeAccordionItems = ({
|
|
193
|
+
items,
|
|
194
|
+
renderSafeNode
|
|
195
|
+
}) => items.map((item) => {
|
|
196
|
+
var _a;
|
|
197
|
+
return {
|
|
198
|
+
id: item.id,
|
|
199
|
+
title: item.title,
|
|
200
|
+
disabled: item.disabled,
|
|
201
|
+
content: item.contentKind === "nodes" ? /* @__PURE__ */ jsx2("div", { className: "space-y-2", children: item.contentNodes.map((nested) => /* @__PURE__ */ jsx2(React2.Fragment, { children: renderSafeNode(nested) }, nested.id)) }) : (_a = item.contentText) != null ? _a : ""
|
|
202
|
+
};
|
|
203
|
+
});
|
|
204
|
+
var materializeExpandablePanelContent = ({
|
|
205
|
+
descriptor,
|
|
206
|
+
renderSafeNode
|
|
207
|
+
}) => {
|
|
208
|
+
if (descriptor.kind === "empty") {
|
|
209
|
+
return void 0;
|
|
210
|
+
}
|
|
211
|
+
return /* @__PURE__ */ jsx2("div", { className: "space-y-2", children: descriptor.nodes.map((child) => /* @__PURE__ */ jsx2(React2.Fragment, { children: renderSafeNode(child) }, child.id)) });
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
// src/materialization/materializeTabsContent.tsx
|
|
215
|
+
import React3 from "react";
|
|
216
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
217
|
+
var materializeTabsContent = ({
|
|
218
|
+
tabs,
|
|
219
|
+
renderSafeNode,
|
|
220
|
+
normalizeRenderableChild
|
|
221
|
+
}) => tabs.map((tab) => ({
|
|
222
|
+
id: tab.id,
|
|
223
|
+
title: tab.title,
|
|
224
|
+
label: tab.label,
|
|
225
|
+
content: tab.contentKind === "nodes" ? tab.contentNodes.length === 1 ? renderSafeNode(tab.contentNodes[0]) : tab.contentNodes.map((child) => /* @__PURE__ */ jsx3(React3.Fragment, { children: renderSafeNode(child) }, child.id)) : normalizeRenderableChild(tab.fallbackContent)
|
|
226
|
+
}));
|
|
227
|
+
|
|
228
|
+
// src/composition/applyNavigationComposition.tsx
|
|
229
|
+
var applyNavigationComposition = ({
|
|
230
|
+
node,
|
|
231
|
+
componentProps,
|
|
232
|
+
isStudioRendererContext,
|
|
233
|
+
selectedNodeId,
|
|
234
|
+
wizardActiveStepByNodeId,
|
|
235
|
+
accordionOpenIdsByNodeId,
|
|
236
|
+
expandablePanelOpenByNodeId,
|
|
237
|
+
runtime,
|
|
238
|
+
setWizardActiveStepByNodeId,
|
|
239
|
+
setAccordionOpenIdsByNodeId,
|
|
240
|
+
setExpandablePanelOpenByNodeId,
|
|
241
|
+
onNodeClick,
|
|
242
|
+
onInlineTextEdit,
|
|
243
|
+
renderSafeNode,
|
|
244
|
+
normalizeRenderableChild,
|
|
245
|
+
captureFieldFocus,
|
|
246
|
+
setInlineEditing,
|
|
247
|
+
internalStudioNodeTypes,
|
|
248
|
+
plans: providedPlans,
|
|
249
|
+
dependencies
|
|
250
|
+
}) => {
|
|
251
|
+
const plans = providedPlans != null ? providedPlans : dependencies.resolveNavigationCompositionPlan({
|
|
252
|
+
node,
|
|
253
|
+
componentProps,
|
|
254
|
+
internalStudioNodeTypes,
|
|
255
|
+
runtime
|
|
256
|
+
});
|
|
257
|
+
if (plans.some((plan) => plan.kind === "form-wizard")) {
|
|
258
|
+
const openInlineEditorForNodeProp = (targetNodeId, propName, rawValue) => {
|
|
259
|
+
setInlineEditing(dependencies.createInlineEditingState(targetNodeId, propName, rawValue));
|
|
260
|
+
};
|
|
261
|
+
dependencies.configureStudioFormWizard({
|
|
262
|
+
node,
|
|
263
|
+
componentProps,
|
|
264
|
+
isStudioRendererContext,
|
|
265
|
+
selectedNodeId,
|
|
266
|
+
wizardActiveStepByNodeId,
|
|
267
|
+
runtime,
|
|
268
|
+
setWizardActiveStepByNodeId,
|
|
269
|
+
onNodeClick,
|
|
270
|
+
onInlineTextEdit,
|
|
271
|
+
renderSafeNode,
|
|
272
|
+
captureFieldFocus,
|
|
273
|
+
openInlineEditorForNodeProp,
|
|
274
|
+
internalStudioNodeTypes
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
const accordionPlan = plans.find((plan) => plan.kind === "accordion");
|
|
278
|
+
if ((accordionPlan == null ? void 0 : accordionPlan.kind) === "accordion") {
|
|
279
|
+
const accordionChildren = accordionPlan.accordionChildren;
|
|
280
|
+
if (accordionChildren.length > 0) {
|
|
281
|
+
if (isStudioRendererContext) {
|
|
282
|
+
dependencies.configureStudioAccordion({
|
|
283
|
+
node,
|
|
284
|
+
componentProps,
|
|
285
|
+
accordionChildren,
|
|
286
|
+
selectedNodeId,
|
|
287
|
+
accordionOpenIdsByNodeId,
|
|
288
|
+
setAccordionOpenIdsByNodeId,
|
|
289
|
+
renderSafeNode
|
|
290
|
+
});
|
|
291
|
+
} else {
|
|
292
|
+
componentProps.items = materializeAccordionItems({
|
|
293
|
+
items: accordionPlan.itemDescriptors,
|
|
294
|
+
renderSafeNode
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const expandablePanelPlan = plans.find((plan) => plan.kind === "expandable-panel");
|
|
300
|
+
if ((expandablePanelPlan == null ? void 0 : expandablePanelPlan.kind) === "expandable-panel") {
|
|
301
|
+
const panelChildren = expandablePanelPlan.panelChildren;
|
|
302
|
+
if (isStudioRendererContext) {
|
|
303
|
+
dependencies.configureStudioExpandablePanel({
|
|
304
|
+
node,
|
|
305
|
+
componentProps,
|
|
306
|
+
panelChildren,
|
|
307
|
+
expandablePanelOpenByNodeId,
|
|
308
|
+
setExpandablePanelOpenByNodeId,
|
|
309
|
+
renderSafeNode
|
|
310
|
+
});
|
|
311
|
+
} else if (panelChildren.length > 0) {
|
|
312
|
+
componentProps.children = materializeExpandablePanelContent({
|
|
313
|
+
descriptor: expandablePanelPlan.contentDescriptor,
|
|
314
|
+
renderSafeNode
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
const tabsPlan = plans.find((plan) => plan.kind === "tabs");
|
|
319
|
+
if ((tabsPlan == null ? void 0 : tabsPlan.kind) === "tabs") {
|
|
320
|
+
Object.assign(componentProps, tabsPlan.normalizedComponentProps);
|
|
321
|
+
if (isStudioRendererContext) {
|
|
322
|
+
const tabItems = Array.isArray(componentProps.tabs) ? componentProps.tabs : [];
|
|
323
|
+
dependencies.configureStudioTabs({
|
|
324
|
+
componentProps,
|
|
325
|
+
tabItems,
|
|
326
|
+
rawChildren: tabsPlan.rawChildren,
|
|
327
|
+
runtime,
|
|
328
|
+
renderSafeNode,
|
|
329
|
+
normalizeRenderableChild
|
|
330
|
+
});
|
|
331
|
+
} else {
|
|
332
|
+
componentProps.tabs = materializeTabsContent({
|
|
333
|
+
tabs: tabsPlan.tabDescriptors,
|
|
334
|
+
renderSafeNode,
|
|
335
|
+
normalizeRenderableChild
|
|
336
|
+
});
|
|
337
|
+
delete componentProps.children;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
export {
|
|
342
|
+
applyContentComposition,
|
|
343
|
+
applyNavigationComposition
|
|
344
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { RenderDirectivePlan } from '@arkcit/engine-render-layer';
|
|
2
|
+
import { UINode } from '@arkcit/engine-schema';
|
|
3
|
+
import { UIRuntimeAdapter } from '@arkcit/engine-runtime';
|
|
4
|
+
|
|
5
|
+
type ApplyRenderDirectivesParams = {
|
|
6
|
+
node: UINode;
|
|
7
|
+
componentProps: Record<string, unknown>;
|
|
8
|
+
renderBindingProps: Record<string, unknown>;
|
|
9
|
+
runtime: UIRuntimeAdapter;
|
|
10
|
+
plans?: RenderDirectivePlan[];
|
|
11
|
+
dependencies: {
|
|
12
|
+
resolveRenderDirectivePlan: (args: {
|
|
13
|
+
node: UINode;
|
|
14
|
+
renderBindingProps: Record<string, unknown>;
|
|
15
|
+
}) => RenderDirectivePlan[];
|
|
16
|
+
applyRowsAndColumnsBinding: (args: {
|
|
17
|
+
componentProps: Record<string, unknown>;
|
|
18
|
+
runtime: UIRuntimeAdapter;
|
|
19
|
+
rowsBindingKey: string;
|
|
20
|
+
columnsBindingKey: string;
|
|
21
|
+
}) => void;
|
|
22
|
+
filterRowsByRuntimeQuery: (args: {
|
|
23
|
+
nodeId: string;
|
|
24
|
+
componentProps: Record<string, unknown>;
|
|
25
|
+
runtime: UIRuntimeAdapter;
|
|
26
|
+
}) => void;
|
|
27
|
+
buildCoverMedia: (args: {
|
|
28
|
+
mediaSource: unknown;
|
|
29
|
+
mediaSrc: unknown;
|
|
30
|
+
mediaAlt: unknown;
|
|
31
|
+
}) => unknown;
|
|
32
|
+
applyObjectBinding: (args: {
|
|
33
|
+
componentProps: Record<string, unknown>;
|
|
34
|
+
runtime: UIRuntimeAdapter;
|
|
35
|
+
bindingKey: string;
|
|
36
|
+
}) => void;
|
|
37
|
+
applyDecodeTranslationBinding: (args: {
|
|
38
|
+
componentProps: Record<string, unknown>;
|
|
39
|
+
runtime: UIRuntimeAdapter;
|
|
40
|
+
tagContentTranslationKey?: string;
|
|
41
|
+
tagContentTranslationValue?: unknown;
|
|
42
|
+
hrefTranslationKey?: string;
|
|
43
|
+
hrefTranslationValue?: unknown;
|
|
44
|
+
}) => void;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
declare const applyRenderDirectives: ({ node, componentProps, renderBindingProps, runtime, plans: providedPlans, dependencies, }: ApplyRenderDirectivesParams) => void;
|
|
48
|
+
|
|
49
|
+
export { applyRenderDirectives };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// src/directives/applyRenderDirectives.ts
|
|
2
|
+
var applyRenderDirectives = ({
|
|
3
|
+
node,
|
|
4
|
+
componentProps,
|
|
5
|
+
renderBindingProps,
|
|
6
|
+
runtime,
|
|
7
|
+
plans: providedPlans,
|
|
8
|
+
dependencies
|
|
9
|
+
}) => {
|
|
10
|
+
const directives = providedPlans != null ? providedPlans : dependencies.resolveRenderDirectivePlan({
|
|
11
|
+
node,
|
|
12
|
+
renderBindingProps
|
|
13
|
+
});
|
|
14
|
+
for (const directive of directives) {
|
|
15
|
+
if (directive.kind === "rows-columns-binding") {
|
|
16
|
+
dependencies.applyRowsAndColumnsBinding({
|
|
17
|
+
componentProps,
|
|
18
|
+
runtime,
|
|
19
|
+
rowsBindingKey: directive.rowsBindingKey,
|
|
20
|
+
columnsBindingKey: directive.columnsBindingKey
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
if (directive.kind === "filter-rows-by-query") {
|
|
24
|
+
dependencies.filterRowsByRuntimeQuery({
|
|
25
|
+
nodeId: directive.nodeId,
|
|
26
|
+
componentProps,
|
|
27
|
+
runtime
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
if (directive.kind === "cover-media") {
|
|
31
|
+
componentProps.media = dependencies.buildCoverMedia({
|
|
32
|
+
mediaSource: directive.mediaSource,
|
|
33
|
+
mediaSrc: directive.mediaSrc,
|
|
34
|
+
mediaAlt: directive.mediaAlt
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (directive.kind === "object-binding") {
|
|
38
|
+
dependencies.applyObjectBinding({
|
|
39
|
+
componentProps,
|
|
40
|
+
runtime,
|
|
41
|
+
bindingKey: directive.bindingKey
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (directive.kind === "decode-translation-binding") {
|
|
45
|
+
dependencies.applyDecodeTranslationBinding({
|
|
46
|
+
componentProps,
|
|
47
|
+
runtime,
|
|
48
|
+
tagContentTranslationKey: directive.tagContentTranslationKey,
|
|
49
|
+
tagContentTranslationValue: directive.tagContentTranslationValue,
|
|
50
|
+
hrefTranslationKey: directive.hrefTranslationKey,
|
|
51
|
+
hrefTranslationValue: directive.hrefTranslationValue
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
export {
|
|
57
|
+
applyRenderDirectives
|
|
58
|
+
};
|