@arkcit/engine-react 0.3.8 → 0.3.10
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 +18 -46
- package/dist/composition.js +1 -0
- package/dist/engine.d.ts +3 -4
- package/dist/engine.js +128 -3
- package/dist/index.d.ts +0 -1
- package/dist/index.js +199 -13
- package/dist/materialization.d.ts +11 -11
- package/dist/materialization.js +1 -0
- package/dist/rendering.d.ts +1 -2
- package/dist/rendering.js +81 -21
- package/dist/static-engine.d.ts +1 -2
- package/dist/static-engine.js +8 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,51 +1,23 @@
|
|
|
1
|
-
#
|
|
1
|
+
# arkcit-engine-react
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Adapter React du moteur Arkcit.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Comprendre le projet
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@arkcit/engine
|
|
16
|
-
↓
|
|
17
|
-
@arkcit/react-ui
|
|
18
|
-
@arkcit/studio preview adapters
|
|
19
|
-
@arkcit/docs-shell
|
|
20
|
-
```
|
|
7
|
+
- [SUMMARY.md](docs/SUMMARY.md) - explication courte du projet et liens architecture.
|
|
8
|
+
- [ARCHITECTURE.md](docs/ARCHITECTURE.md) - carte visuelle, couches et flux.
|
|
9
|
+
- [DECOUPLING.md](docs/DECOUPLING.md) - refactor, decouplage, couverture et risques.
|
|
10
|
+
- [ROADMAP.md](docs/ROADMAP.md) - reste-a-faire uniquement.
|
|
11
|
+
- [NOTES.md](docs/NOTES.md) - log nettoyable des acquis et decisions.
|
|
12
|
+
- [ENVIRONNEMENT.md](docs/ENVIRONNEMENT.md) - variables d'environnement detectees.
|
|
13
|
+
- [GOUVERNANCE.md](docs/GOUVERNANCE.md) - maintenance, validation et production.
|
|
14
|
+
- [AGENTS.md](AGENTS.md) - consignes de travail pour Codex et agents.
|
|
21
15
|
|
|
22
|
-
##
|
|
16
|
+
## Commandes utiles
|
|
23
17
|
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
|
|
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`
|
|
18
|
+
- `npm run typecheck`
|
|
19
|
+
- `npm run test`
|
|
20
|
+
- `npm run test:smoke`
|
|
21
|
+
- `npm run test:unit`
|
|
22
|
+
- `npm run test:coverage`
|
|
23
|
+
- `npm run build`
|
package/dist/composition.js
CHANGED
package/dist/engine.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
1
|
import React__default from 'react';
|
|
3
2
|
import { UIEngineProps, UINodeSize, UINodeWrapperProps } from '@arkcit/engine-core';
|
|
4
3
|
import { UINode } from '@arkcit/engine-schema';
|
|
@@ -10,7 +9,7 @@ import '@arkcit/engine-render-layer';
|
|
|
10
9
|
type EngineWarningFallbackProps = {
|
|
11
10
|
message: string;
|
|
12
11
|
};
|
|
13
|
-
declare const EngineWarningFallback: ({ message }: EngineWarningFallbackProps) =>
|
|
12
|
+
declare const EngineWarningFallback: ({ message }: EngineWarningFallbackProps) => React__default.JSX.Element;
|
|
14
13
|
|
|
15
14
|
type NodeErrorBoundaryProps = {
|
|
16
15
|
nodeId: string;
|
|
@@ -27,7 +26,7 @@ declare class NodeErrorBoundary extends React__default.Component<NodeErrorBounda
|
|
|
27
26
|
componentDidUpdate(prevProps: Readonly<{
|
|
28
27
|
resetToken: string;
|
|
29
28
|
}>): void;
|
|
30
|
-
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> |
|
|
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__default.JSX.Element | null | undefined;
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
type ReactWebUseUIEngineEffectsArgs = {
|
|
@@ -92,6 +91,6 @@ type ReactWebEngineRootDependencies<TInlineEditing = unknown> = {
|
|
|
92
91
|
type ReactWebEngineRootArgs<TInlineEditing = unknown> = UIEngineProps & {
|
|
93
92
|
dependencies: ReactWebEngineRootDependencies<TInlineEditing>;
|
|
94
93
|
};
|
|
95
|
-
declare const ReactWebEngineRoot: <TInlineEditing = unknown>({ schema, registry, store, onNodeClick, onInlineTextEdit, onNodeResize, onNodeResizeStart, onNodeResizeEnd, onNodeDragStart, onNodeDragOverTarget, onNodeDropTarget, selectedNodeId, nodeWrapper, dependencies, }: ReactWebEngineRootArgs<TInlineEditing>) =>
|
|
94
|
+
declare const ReactWebEngineRoot: <TInlineEditing = unknown>({ schema, registry, store, onNodeClick, onInlineTextEdit, onNodeResize, onNodeResizeStart, onNodeResizeEnd, onNodeDragStart, onNodeDragOverTarget, onNodeDropTarget, selectedNodeId, nodeWrapper, dependencies, }: ReactWebEngineRootArgs<TInlineEditing>) => React__default.JSX.Element;
|
|
96
95
|
|
|
97
96
|
export { EngineWarningFallback, NodeErrorBoundary, ReactWebEngineRoot, type ReactWebEngineRootArgs, type ReactWebEngineRootDependencies, type ReactWebRenderSafeNodeArgs, type ReactWebUseUIEngineEffectsArgs, type ReactWebUseUIEngineEffectsResult };
|
package/dist/engine.js
CHANGED
|
@@ -58,7 +58,7 @@ var NodeErrorBoundary = class extends React.Component {
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
// src/engine/ReactWebEngineRoot.tsx
|
|
61
|
-
import React4, { useRef, useState as useState2 } from "react";
|
|
61
|
+
import React4, { useEffect, useRef, useState as useState2 } from "react";
|
|
62
62
|
|
|
63
63
|
// src/rendering/resolveResolvedReactNode.ts
|
|
64
64
|
import {
|
|
@@ -387,6 +387,111 @@ var useUIEngineState = () => {
|
|
|
387
387
|
};
|
|
388
388
|
};
|
|
389
389
|
|
|
390
|
+
// src/engine/tablistController.ts
|
|
391
|
+
var TAB_ACTION_SELECTOR = '[role="tab"],[data-saas-preview-tab-panel-id]';
|
|
392
|
+
var asHTMLElement = (value) => value instanceof HTMLElement ? value : null;
|
|
393
|
+
var closestHTMLElement = (target, selector) => {
|
|
394
|
+
const element = target;
|
|
395
|
+
return typeof (element == null ? void 0 : element.closest) === "function" ? asHTMLElement(element.closest(selector)) : null;
|
|
396
|
+
};
|
|
397
|
+
var queryByIdOrNodeId = (root, id) => {
|
|
398
|
+
var _a, _b;
|
|
399
|
+
if (!id) return null;
|
|
400
|
+
if (typeof CSS !== "undefined" && typeof CSS.escape === "function") {
|
|
401
|
+
const escapedId = CSS.escape(id);
|
|
402
|
+
return asHTMLElement(root.querySelector(`#${escapedId},[data-node-id="${escapedId}"]`));
|
|
403
|
+
}
|
|
404
|
+
return (_b = (_a = Array.from(root.querySelectorAll("[id]")).find((element) => element.id === id)) != null ? _a : Array.from(root.querySelectorAll("[data-node-id]")).find(
|
|
405
|
+
(element) => element.getAttribute("data-node-id") === id
|
|
406
|
+
)) != null ? _b : null;
|
|
407
|
+
};
|
|
408
|
+
var readHashTargetId = (element) => {
|
|
409
|
+
var _a, _b;
|
|
410
|
+
const href = (_b = (_a = element.getAttribute("href")) == null ? void 0 : _a.trim()) != null ? _b : "";
|
|
411
|
+
const hashIndex = href.indexOf("#");
|
|
412
|
+
return hashIndex >= 0 ? href.slice(hashIndex + 1).trim() : "";
|
|
413
|
+
};
|
|
414
|
+
var readTabPanelId = (element) => {
|
|
415
|
+
var _a, _b;
|
|
416
|
+
return ((_a = element.getAttribute("data-saas-preview-tab-panel-id")) == null ? void 0 : _a.trim()) || ((_b = element.getAttribute("aria-controls")) == null ? void 0 : _b.trim()) || readHashTargetId(element);
|
|
417
|
+
};
|
|
418
|
+
var readTabSectionId = (element) => {
|
|
419
|
+
var _a, _b, _c;
|
|
420
|
+
return ((_a = element.getAttribute("data-saas-preview-tab-section-id")) == null ? void 0 : _a.trim()) || ((_c = (_b = element.closest("[data-saas-preview-tab-section-id]")) == null ? void 0 : _b.getAttribute("data-saas-preview-tab-section-id")) == null ? void 0 : _c.trim()) || "";
|
|
421
|
+
};
|
|
422
|
+
var isDisabledTabAction = (element) => element.getAttribute("aria-disabled") === "true" || element instanceof HTMLButtonElement && element.disabled;
|
|
423
|
+
var getTabListTabs = (tabList) => Array.from(tabList.querySelectorAll('[role="tab"]')).filter(
|
|
424
|
+
(tab) => tab.closest('[role="tablist"]') === tabList
|
|
425
|
+
);
|
|
426
|
+
var findMatchingTab = (root, action) => {
|
|
427
|
+
var _a;
|
|
428
|
+
const panelId = readTabPanelId(action);
|
|
429
|
+
if (!panelId) return null;
|
|
430
|
+
const sectionId = readTabSectionId(action);
|
|
431
|
+
return (_a = Array.from(root.querySelectorAll('[role="tab"]')).find((tab) => {
|
|
432
|
+
if (readTabPanelId(tab) !== panelId) return false;
|
|
433
|
+
return !sectionId || readTabSectionId(tab) === sectionId;
|
|
434
|
+
})) != null ? _a : null;
|
|
435
|
+
};
|
|
436
|
+
var applyTablistSelection = (root, activeTab) => {
|
|
437
|
+
const tabList = activeTab.closest('[role="tablist"]');
|
|
438
|
+
if (!tabList || !root.contains(tabList)) return false;
|
|
439
|
+
const tabs = getTabListTabs(tabList);
|
|
440
|
+
if (!tabs.includes(activeTab) || isDisabledTabAction(activeTab)) return true;
|
|
441
|
+
const panelByTab = /* @__PURE__ */ new Map();
|
|
442
|
+
for (const tab of tabs) {
|
|
443
|
+
const panel = queryByIdOrNodeId(root, readTabPanelId(tab));
|
|
444
|
+
if (panel) {
|
|
445
|
+
panelByTab.set(tab, panel);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
const activePanel = panelByTab.get(activeTab);
|
|
449
|
+
if (!activePanel || panelByTab.size === 0) return false;
|
|
450
|
+
for (const tab of tabs) {
|
|
451
|
+
const selected = tab === activeTab;
|
|
452
|
+
tab.setAttribute("aria-selected", selected ? "true" : "false");
|
|
453
|
+
tab.tabIndex = selected ? 0 : -1;
|
|
454
|
+
}
|
|
455
|
+
for (const panel of panelByTab.values()) {
|
|
456
|
+
const selected = panel === activePanel;
|
|
457
|
+
panel.hidden = !selected;
|
|
458
|
+
panel.setAttribute("aria-hidden", selected ? "false" : "true");
|
|
459
|
+
if (selected) {
|
|
460
|
+
panel.style.removeProperty("display");
|
|
461
|
+
} else {
|
|
462
|
+
panel.style.display = "none";
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return true;
|
|
466
|
+
};
|
|
467
|
+
var initializeTablistPanels = (root) => {
|
|
468
|
+
var _a, _b;
|
|
469
|
+
const tabLists = Array.from(root.querySelectorAll('[role="tablist"]'));
|
|
470
|
+
for (const tabList of tabLists) {
|
|
471
|
+
const tabs = getTabListTabs(tabList);
|
|
472
|
+
const activeTab = (_b = (_a = tabs.find(
|
|
473
|
+
(tab) => tab.getAttribute("aria-selected") === "true" && !isDisabledTabAction(tab)
|
|
474
|
+
)) != null ? _a : tabs.find((tab) => !isDisabledTabAction(tab))) != null ? _b : null;
|
|
475
|
+
if (activeTab) {
|
|
476
|
+
applyTablistSelection(root, activeTab);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
var bindTablistController = (root) => {
|
|
481
|
+
initializeTablistPanels(root);
|
|
482
|
+
const handleClick = (event) => {
|
|
483
|
+
const action = closestHTMLElement(event.target, TAB_ACTION_SELECTOR);
|
|
484
|
+
if (!action || !root.contains(action) || isDisabledTabAction(action)) return;
|
|
485
|
+
const tab = action.getAttribute("role") === "tab" ? action : findMatchingTab(root, action);
|
|
486
|
+
if (!tab || !applyTablistSelection(root, tab)) return;
|
|
487
|
+
event.preventDefault();
|
|
488
|
+
};
|
|
489
|
+
root.addEventListener("click", handleClick, true);
|
|
490
|
+
return () => {
|
|
491
|
+
root.removeEventListener("click", handleClick, true);
|
|
492
|
+
};
|
|
493
|
+
};
|
|
494
|
+
|
|
390
495
|
// src/engine/ReactWebEngineRoot.tsx
|
|
391
496
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
392
497
|
var INTERNAL_STUDIO_NODE_TYPES = /* @__PURE__ */ new Set();
|
|
@@ -494,6 +599,7 @@ var ReactWebEngineRoot = ({
|
|
|
494
599
|
const resizeStateRef = useRef(null);
|
|
495
600
|
const pinchStateRef = useRef(null);
|
|
496
601
|
const pendingFieldFocusRef = useRef(null);
|
|
602
|
+
const rootRef = useRef(null);
|
|
497
603
|
const { ancestorTypeMembership, overlaysByNodeId, captureFieldFocus } = dependencies.useUIEngineEffects({
|
|
498
604
|
schema,
|
|
499
605
|
runtime,
|
|
@@ -558,7 +664,19 @@ var ReactWebEngineRoot = ({
|
|
|
558
664
|
InlineTextEditorComponent: InlineTextEditor,
|
|
559
665
|
isFormInteractiveTarget
|
|
560
666
|
});
|
|
561
|
-
|
|
667
|
+
useEffect(() => {
|
|
668
|
+
const root = rootRef.current;
|
|
669
|
+
return root ? bindTablistController(root) : void 0;
|
|
670
|
+
}, [schema]);
|
|
671
|
+
return /* @__PURE__ */ jsx6(
|
|
672
|
+
"div",
|
|
673
|
+
{
|
|
674
|
+
ref: rootRef,
|
|
675
|
+
"data-arkcit-engine-root": true,
|
|
676
|
+
className: "flex min-w-0 w-full flex-wrap content-start items-start gap-3",
|
|
677
|
+
children: schema.nodes.map((node) => /* @__PURE__ */ jsx6(React4.Fragment, { children: renderSafeEngineNode(node) }, node.id))
|
|
678
|
+
}
|
|
679
|
+
);
|
|
562
680
|
};
|
|
563
681
|
|
|
564
682
|
// src/engine/StaticReactWebEngineRoot.tsx
|
|
@@ -653,7 +771,14 @@ var StaticReactWebEngineRoot = ({
|
|
|
653
771
|
NodeWrapper,
|
|
654
772
|
isFormInteractiveTarget: isFormInteractiveTarget2
|
|
655
773
|
});
|
|
656
|
-
return /* @__PURE__ */ jsx7(
|
|
774
|
+
return /* @__PURE__ */ jsx7(
|
|
775
|
+
"div",
|
|
776
|
+
{
|
|
777
|
+
"data-arkcit-engine-root": true,
|
|
778
|
+
className: "flex min-w-0 w-full flex-wrap content-start items-start gap-3",
|
|
779
|
+
children: schema.nodes.map((node) => /* @__PURE__ */ jsx7(React5.Fragment, { children: renderSafeEngineNode(node) }, node.id))
|
|
780
|
+
}
|
|
781
|
+
);
|
|
657
782
|
};
|
|
658
783
|
export {
|
|
659
784
|
EngineWarningFallback_default as EngineWarningFallback,
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -219,6 +219,7 @@ var materializeTabsContent = ({
|
|
|
219
219
|
renderSafeNode,
|
|
220
220
|
normalizeRenderableChild: normalizeRenderableChild2
|
|
221
221
|
}) => tabs.map((tab) => ({
|
|
222
|
+
disabled: Boolean(tab.disabled),
|
|
222
223
|
id: tab.id,
|
|
223
224
|
title: tab.title,
|
|
224
225
|
label: tab.label,
|
|
@@ -435,7 +436,7 @@ var NodeErrorBoundary = class extends React4.Component {
|
|
|
435
436
|
};
|
|
436
437
|
|
|
437
438
|
// src/engine/ReactWebEngineRoot.tsx
|
|
438
|
-
import React7, { useRef, useState as useState2 } from "react";
|
|
439
|
+
import React7, { useEffect, useRef, useState as useState2 } from "react";
|
|
439
440
|
|
|
440
441
|
// src/rendering/resolveResolvedReactNode.ts
|
|
441
442
|
import {
|
|
@@ -764,6 +765,111 @@ var useUIEngineState = () => {
|
|
|
764
765
|
};
|
|
765
766
|
};
|
|
766
767
|
|
|
768
|
+
// src/engine/tablistController.ts
|
|
769
|
+
var TAB_ACTION_SELECTOR = '[role="tab"],[data-saas-preview-tab-panel-id]';
|
|
770
|
+
var asHTMLElement = (value) => value instanceof HTMLElement ? value : null;
|
|
771
|
+
var closestHTMLElement = (target, selector) => {
|
|
772
|
+
const element = target;
|
|
773
|
+
return typeof (element == null ? void 0 : element.closest) === "function" ? asHTMLElement(element.closest(selector)) : null;
|
|
774
|
+
};
|
|
775
|
+
var queryByIdOrNodeId = (root, id) => {
|
|
776
|
+
var _a, _b;
|
|
777
|
+
if (!id) return null;
|
|
778
|
+
if (typeof CSS !== "undefined" && typeof CSS.escape === "function") {
|
|
779
|
+
const escapedId = CSS.escape(id);
|
|
780
|
+
return asHTMLElement(root.querySelector(`#${escapedId},[data-node-id="${escapedId}"]`));
|
|
781
|
+
}
|
|
782
|
+
return (_b = (_a = Array.from(root.querySelectorAll("[id]")).find((element) => element.id === id)) != null ? _a : Array.from(root.querySelectorAll("[data-node-id]")).find(
|
|
783
|
+
(element) => element.getAttribute("data-node-id") === id
|
|
784
|
+
)) != null ? _b : null;
|
|
785
|
+
};
|
|
786
|
+
var readHashTargetId = (element) => {
|
|
787
|
+
var _a, _b;
|
|
788
|
+
const href = (_b = (_a = element.getAttribute("href")) == null ? void 0 : _a.trim()) != null ? _b : "";
|
|
789
|
+
const hashIndex = href.indexOf("#");
|
|
790
|
+
return hashIndex >= 0 ? href.slice(hashIndex + 1).trim() : "";
|
|
791
|
+
};
|
|
792
|
+
var readTabPanelId = (element) => {
|
|
793
|
+
var _a, _b;
|
|
794
|
+
return ((_a = element.getAttribute("data-saas-preview-tab-panel-id")) == null ? void 0 : _a.trim()) || ((_b = element.getAttribute("aria-controls")) == null ? void 0 : _b.trim()) || readHashTargetId(element);
|
|
795
|
+
};
|
|
796
|
+
var readTabSectionId = (element) => {
|
|
797
|
+
var _a, _b, _c;
|
|
798
|
+
return ((_a = element.getAttribute("data-saas-preview-tab-section-id")) == null ? void 0 : _a.trim()) || ((_c = (_b = element.closest("[data-saas-preview-tab-section-id]")) == null ? void 0 : _b.getAttribute("data-saas-preview-tab-section-id")) == null ? void 0 : _c.trim()) || "";
|
|
799
|
+
};
|
|
800
|
+
var isDisabledTabAction = (element) => element.getAttribute("aria-disabled") === "true" || element instanceof HTMLButtonElement && element.disabled;
|
|
801
|
+
var getTabListTabs = (tabList) => Array.from(tabList.querySelectorAll('[role="tab"]')).filter(
|
|
802
|
+
(tab) => tab.closest('[role="tablist"]') === tabList
|
|
803
|
+
);
|
|
804
|
+
var findMatchingTab = (root, action) => {
|
|
805
|
+
var _a;
|
|
806
|
+
const panelId = readTabPanelId(action);
|
|
807
|
+
if (!panelId) return null;
|
|
808
|
+
const sectionId = readTabSectionId(action);
|
|
809
|
+
return (_a = Array.from(root.querySelectorAll('[role="tab"]')).find((tab) => {
|
|
810
|
+
if (readTabPanelId(tab) !== panelId) return false;
|
|
811
|
+
return !sectionId || readTabSectionId(tab) === sectionId;
|
|
812
|
+
})) != null ? _a : null;
|
|
813
|
+
};
|
|
814
|
+
var applyTablistSelection = (root, activeTab) => {
|
|
815
|
+
const tabList = activeTab.closest('[role="tablist"]');
|
|
816
|
+
if (!tabList || !root.contains(tabList)) return false;
|
|
817
|
+
const tabs = getTabListTabs(tabList);
|
|
818
|
+
if (!tabs.includes(activeTab) || isDisabledTabAction(activeTab)) return true;
|
|
819
|
+
const panelByTab = /* @__PURE__ */ new Map();
|
|
820
|
+
for (const tab of tabs) {
|
|
821
|
+
const panel = queryByIdOrNodeId(root, readTabPanelId(tab));
|
|
822
|
+
if (panel) {
|
|
823
|
+
panelByTab.set(tab, panel);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
const activePanel = panelByTab.get(activeTab);
|
|
827
|
+
if (!activePanel || panelByTab.size === 0) return false;
|
|
828
|
+
for (const tab of tabs) {
|
|
829
|
+
const selected = tab === activeTab;
|
|
830
|
+
tab.setAttribute("aria-selected", selected ? "true" : "false");
|
|
831
|
+
tab.tabIndex = selected ? 0 : -1;
|
|
832
|
+
}
|
|
833
|
+
for (const panel of panelByTab.values()) {
|
|
834
|
+
const selected = panel === activePanel;
|
|
835
|
+
panel.hidden = !selected;
|
|
836
|
+
panel.setAttribute("aria-hidden", selected ? "false" : "true");
|
|
837
|
+
if (selected) {
|
|
838
|
+
panel.style.removeProperty("display");
|
|
839
|
+
} else {
|
|
840
|
+
panel.style.display = "none";
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
return true;
|
|
844
|
+
};
|
|
845
|
+
var initializeTablistPanels = (root) => {
|
|
846
|
+
var _a, _b;
|
|
847
|
+
const tabLists = Array.from(root.querySelectorAll('[role="tablist"]'));
|
|
848
|
+
for (const tabList of tabLists) {
|
|
849
|
+
const tabs = getTabListTabs(tabList);
|
|
850
|
+
const activeTab = (_b = (_a = tabs.find(
|
|
851
|
+
(tab) => tab.getAttribute("aria-selected") === "true" && !isDisabledTabAction(tab)
|
|
852
|
+
)) != null ? _a : tabs.find((tab) => !isDisabledTabAction(tab))) != null ? _b : null;
|
|
853
|
+
if (activeTab) {
|
|
854
|
+
applyTablistSelection(root, activeTab);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
};
|
|
858
|
+
var bindTablistController = (root) => {
|
|
859
|
+
initializeTablistPanels(root);
|
|
860
|
+
const handleClick = (event) => {
|
|
861
|
+
const action = closestHTMLElement(event.target, TAB_ACTION_SELECTOR);
|
|
862
|
+
if (!action || !root.contains(action) || isDisabledTabAction(action)) return;
|
|
863
|
+
const tab = action.getAttribute("role") === "tab" ? action : findMatchingTab(root, action);
|
|
864
|
+
if (!tab || !applyTablistSelection(root, tab)) return;
|
|
865
|
+
event.preventDefault();
|
|
866
|
+
};
|
|
867
|
+
root.addEventListener("click", handleClick, true);
|
|
868
|
+
return () => {
|
|
869
|
+
root.removeEventListener("click", handleClick, true);
|
|
870
|
+
};
|
|
871
|
+
};
|
|
872
|
+
|
|
767
873
|
// src/engine/ReactWebEngineRoot.tsx
|
|
768
874
|
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
769
875
|
var INTERNAL_STUDIO_NODE_TYPES = /* @__PURE__ */ new Set();
|
|
@@ -871,6 +977,7 @@ var ReactWebEngineRoot = ({
|
|
|
871
977
|
const resizeStateRef = useRef(null);
|
|
872
978
|
const pinchStateRef = useRef(null);
|
|
873
979
|
const pendingFieldFocusRef = useRef(null);
|
|
980
|
+
const rootRef = useRef(null);
|
|
874
981
|
const { ancestorTypeMembership, overlaysByNodeId, captureFieldFocus } = dependencies.useUIEngineEffects({
|
|
875
982
|
schema,
|
|
876
983
|
runtime,
|
|
@@ -935,7 +1042,19 @@ var ReactWebEngineRoot = ({
|
|
|
935
1042
|
InlineTextEditorComponent: InlineTextEditor,
|
|
936
1043
|
isFormInteractiveTarget
|
|
937
1044
|
});
|
|
938
|
-
|
|
1045
|
+
useEffect(() => {
|
|
1046
|
+
const root = rootRef.current;
|
|
1047
|
+
return root ? bindTablistController(root) : void 0;
|
|
1048
|
+
}, [schema]);
|
|
1049
|
+
return /* @__PURE__ */ jsx9(
|
|
1050
|
+
"div",
|
|
1051
|
+
{
|
|
1052
|
+
ref: rootRef,
|
|
1053
|
+
"data-arkcit-engine-root": true,
|
|
1054
|
+
className: "flex min-w-0 w-full flex-wrap content-start items-start gap-3",
|
|
1055
|
+
children: schema.nodes.map((node) => /* @__PURE__ */ jsx9(React7.Fragment, { children: renderSafeEngineNode(node) }, node.id))
|
|
1056
|
+
}
|
|
1057
|
+
);
|
|
939
1058
|
};
|
|
940
1059
|
|
|
941
1060
|
// src/engine/StaticReactWebEngineRoot.tsx
|
|
@@ -1030,11 +1149,18 @@ var StaticReactWebEngineRoot = ({
|
|
|
1030
1149
|
NodeWrapper,
|
|
1031
1150
|
isFormInteractiveTarget: isFormInteractiveTarget2
|
|
1032
1151
|
});
|
|
1033
|
-
return /* @__PURE__ */ jsx10(
|
|
1152
|
+
return /* @__PURE__ */ jsx10(
|
|
1153
|
+
"div",
|
|
1154
|
+
{
|
|
1155
|
+
"data-arkcit-engine-root": true,
|
|
1156
|
+
className: "flex min-w-0 w-full flex-wrap content-start items-start gap-3",
|
|
1157
|
+
children: schema.nodes.map((node) => /* @__PURE__ */ jsx10(React8.Fragment, { children: renderSafeEngineNode(node) }, node.id))
|
|
1158
|
+
}
|
|
1159
|
+
);
|
|
1034
1160
|
};
|
|
1035
1161
|
|
|
1036
1162
|
// src/hooks/useUIEngineEffects.ts
|
|
1037
|
-
import { useEffect, useLayoutEffect, useMemo } from "react";
|
|
1163
|
+
import { useEffect as useEffect2, useLayoutEffect, useMemo } from "react";
|
|
1038
1164
|
var useUIEngineEffects = ({
|
|
1039
1165
|
schema,
|
|
1040
1166
|
runtime,
|
|
@@ -1062,13 +1188,13 @@ var useUIEngineEffects = ({
|
|
|
1062
1188
|
pendingFieldFocusRef.current = null;
|
|
1063
1189
|
dependencies.restorePendingFieldFocus(pending);
|
|
1064
1190
|
}, [dependencies, schema, pendingFieldFocusRef]);
|
|
1065
|
-
|
|
1191
|
+
useEffect2(() => {
|
|
1066
1192
|
if (!runtime.subscribe) return;
|
|
1067
1193
|
return runtime.subscribe(() => {
|
|
1068
1194
|
setVersion((previous) => previous + 1);
|
|
1069
1195
|
});
|
|
1070
1196
|
}, [runtime, setVersion]);
|
|
1071
|
-
|
|
1197
|
+
useEffect2(() => {
|
|
1072
1198
|
if (!onNodeResize) return;
|
|
1073
1199
|
const handleMouseMove = (event) => {
|
|
1074
1200
|
const state = resizeStateRef.current;
|
|
@@ -1344,7 +1470,10 @@ import React12 from "react";
|
|
|
1344
1470
|
var configurePreviewLinkBehavior = (componentProps) => {
|
|
1345
1471
|
const existingOnClick = componentProps.onClick;
|
|
1346
1472
|
componentProps.onClick = (event) => {
|
|
1347
|
-
|
|
1473
|
+
const href = componentProps.href;
|
|
1474
|
+
if (!(typeof href === "string" && href.startsWith("#"))) {
|
|
1475
|
+
event.preventDefault();
|
|
1476
|
+
}
|
|
1348
1477
|
if (typeof existingOnClick === "function") {
|
|
1349
1478
|
existingOnClick(event);
|
|
1350
1479
|
}
|
|
@@ -1352,6 +1481,7 @@ var configurePreviewLinkBehavior = (componentProps) => {
|
|
|
1352
1481
|
};
|
|
1353
1482
|
|
|
1354
1483
|
// src/rendering/finalizeRenderedNode.tsx
|
|
1484
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1355
1485
|
var RESPONSIVE_MEDIA_NODE_TYPES = /* @__PURE__ */ new Set(["Image", "Video", "EmbeddedVideo", "Cover", "Document"]);
|
|
1356
1486
|
var RESPONSIVE_MEDIA_CLASS_NAME = "max-md:!w-full max-md:![flex-basis:100%!important] max-md:!h-auto";
|
|
1357
1487
|
var RESPONSIVE_TEXT_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -1394,6 +1524,45 @@ var RESPONSIVE_TEXT_CLASS_NAME = "max-md:!h-auto";
|
|
|
1394
1524
|
var hasExplicitStudioSizing = (studioSizing) => Boolean(
|
|
1395
1525
|
studioSizing && (studioSizing.widthPct !== null || studioSizing.heightPct !== null || studioSizing.heightPx !== null)
|
|
1396
1526
|
);
|
|
1527
|
+
var buildExplicitSizingWrapperStyle = (studioSizing) => {
|
|
1528
|
+
if (!hasExplicitStudioSizing(studioSizing)) return null;
|
|
1529
|
+
return __spreadValues(__spreadValues(__spreadValues({}, (studioSizing == null ? void 0 : studioSizing.widthPct) !== null && (studioSizing == null ? void 0 : studioSizing.widthPct) !== void 0 ? {
|
|
1530
|
+
width: `${studioSizing.widthPct}%`,
|
|
1531
|
+
flexBasis: `${studioSizing.widthPct}%`,
|
|
1532
|
+
maxWidth: "100%"
|
|
1533
|
+
} : {}), (studioSizing == null ? void 0 : studioSizing.heightPx) !== null && (studioSizing == null ? void 0 : studioSizing.heightPx) !== void 0 ? { height: `${studioSizing.heightPx}px` } : {}), (studioSizing == null ? void 0 : studioSizing.heightPx) === null && (studioSizing == null ? void 0 : studioSizing.heightPct) !== null && (studioSizing == null ? void 0 : studioSizing.heightPct) !== void 0 ? { height: `${studioSizing.heightPct}%` } : {});
|
|
1534
|
+
};
|
|
1535
|
+
var removeExplicitSizingFromComponentStyle = (componentProps, shouldWrapExplicitSizing) => {
|
|
1536
|
+
if (!shouldWrapExplicitSizing) return;
|
|
1537
|
+
const currentStyle = componentProps.style && typeof componentProps.style === "object" ? __spreadValues({}, componentProps.style) : null;
|
|
1538
|
+
if (!currentStyle) return;
|
|
1539
|
+
delete currentStyle.width;
|
|
1540
|
+
delete currentStyle.flexBasis;
|
|
1541
|
+
delete currentStyle.maxWidth;
|
|
1542
|
+
delete currentStyle.height;
|
|
1543
|
+
componentProps.style = currentStyle;
|
|
1544
|
+
};
|
|
1545
|
+
var removeInternalLayoutProps = (componentProps) => {
|
|
1546
|
+
delete componentProps.fullBleed;
|
|
1547
|
+
};
|
|
1548
|
+
var wrapExplicitlySizedNode = ({
|
|
1549
|
+
nodeId,
|
|
1550
|
+
nodeType,
|
|
1551
|
+
element,
|
|
1552
|
+
wrapperStyle
|
|
1553
|
+
}) => {
|
|
1554
|
+
if (!wrapperStyle) return element;
|
|
1555
|
+
return /* @__PURE__ */ jsx13(
|
|
1556
|
+
"div",
|
|
1557
|
+
{
|
|
1558
|
+
"data-node-id": nodeId,
|
|
1559
|
+
"data-node-type": nodeType,
|
|
1560
|
+
className: "relative min-w-0 max-w-full flex-none",
|
|
1561
|
+
style: wrapperStyle,
|
|
1562
|
+
children: /* @__PURE__ */ jsx13("div", { className: "min-w-0 max-w-full", style: { width: "100%", height: "100%" }, children: element })
|
|
1563
|
+
}
|
|
1564
|
+
);
|
|
1565
|
+
};
|
|
1397
1566
|
var finalizeRenderedNode = ({
|
|
1398
1567
|
node,
|
|
1399
1568
|
children,
|
|
@@ -1436,6 +1605,9 @@ var finalizeRenderedNode = ({
|
|
|
1436
1605
|
delete componentProps.layout;
|
|
1437
1606
|
}
|
|
1438
1607
|
}
|
|
1608
|
+
const explicitSizingWrapperStyle = !isStudioRendererContext ? buildExplicitSizingWrapperStyle(studioSizing) : null;
|
|
1609
|
+
removeExplicitSizingFromComponentStyle(componentProps, explicitSizingWrapperStyle !== null);
|
|
1610
|
+
removeInternalLayoutProps(componentProps);
|
|
1439
1611
|
if (plans.some((plan) => plan.kind === "table-fallback")) {
|
|
1440
1612
|
const tableNode = materializeBoundTable({
|
|
1441
1613
|
nodeId: node.id,
|
|
@@ -1444,17 +1616,31 @@ var finalizeRenderedNode = ({
|
|
|
1444
1616
|
TableComponent: registryComponent
|
|
1445
1617
|
});
|
|
1446
1618
|
if (tableNode) {
|
|
1447
|
-
return
|
|
1619
|
+
return wrapExplicitlySizedNode({
|
|
1620
|
+
nodeId: node.id,
|
|
1621
|
+
nodeType: node.type,
|
|
1622
|
+
element: tableNode,
|
|
1623
|
+
wrapperStyle: explicitSizingWrapperStyle
|
|
1624
|
+
});
|
|
1448
1625
|
}
|
|
1449
1626
|
}
|
|
1450
1627
|
const finalComponentProps = dependencies.omitStudioProps(componentProps);
|
|
1628
|
+
let renderedElement;
|
|
1451
1629
|
if (children && children.length > 0) {
|
|
1452
1630
|
if (node.type === "Cover" || node.type === "Tabs" || node.type === "Accordion") {
|
|
1453
|
-
|
|
1631
|
+
renderedElement = React12.createElement(registryComponent, finalComponentProps);
|
|
1632
|
+
} else {
|
|
1633
|
+
renderedElement = React12.createElement(registryComponent, finalComponentProps, children);
|
|
1454
1634
|
}
|
|
1455
|
-
|
|
1635
|
+
} else {
|
|
1636
|
+
renderedElement = React12.createElement(registryComponent, finalComponentProps);
|
|
1456
1637
|
}
|
|
1457
|
-
return
|
|
1638
|
+
return wrapExplicitlySizedNode({
|
|
1639
|
+
nodeId: node.id,
|
|
1640
|
+
nodeType: node.type,
|
|
1641
|
+
element: renderedElement,
|
|
1642
|
+
wrapperStyle: explicitSizingWrapperStyle
|
|
1643
|
+
});
|
|
1458
1644
|
};
|
|
1459
1645
|
|
|
1460
1646
|
// src/rendering/nodeResetToken.ts
|
|
@@ -1487,7 +1673,7 @@ var buildNodeResetToken = (node) => {
|
|
|
1487
1673
|
|
|
1488
1674
|
// src/rendering/renderChildren.tsx
|
|
1489
1675
|
import React13, { isValidElement as isValidElement2 } from "react";
|
|
1490
|
-
import { jsx as
|
|
1676
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
1491
1677
|
var toBoolean = (value) => {
|
|
1492
1678
|
if (typeof value === "boolean") return value;
|
|
1493
1679
|
if (typeof value === "string") return value.toLowerCase() === "true";
|
|
@@ -1498,7 +1684,7 @@ var normalizeRenderableChild = (value) => {
|
|
|
1498
1684
|
if (typeof value === "string" || typeof value === "number") return value;
|
|
1499
1685
|
if (isValidElement2(value)) return value;
|
|
1500
1686
|
if (Array.isArray(value)) {
|
|
1501
|
-
return value.map((item, index) => /* @__PURE__ */
|
|
1687
|
+
return value.map((item, index) => /* @__PURE__ */ jsx14(React13.Fragment, { children: normalizeRenderableChild(item) }, `normalized-child-${index}`));
|
|
1502
1688
|
}
|
|
1503
1689
|
if (value && typeof value === "object") {
|
|
1504
1690
|
const candidate = value;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
1
|
import React__default from 'react';
|
|
3
2
|
import { UINode } from '@arkcit/engine-schema';
|
|
4
3
|
import { UIRuntimeAdapter } from '@arkcit/engine-runtime';
|
|
@@ -13,15 +12,15 @@ declare const buildCoverContent: ({ rawChildren, renderSafeNode, }: {
|
|
|
13
12
|
rawChildren: UINode[];
|
|
14
13
|
renderSafeNode: (node: UINode) => React__default.ReactNode;
|
|
15
14
|
}) => {
|
|
16
|
-
actions:
|
|
17
|
-
children:
|
|
15
|
+
actions: React__default.JSX.Element | undefined;
|
|
16
|
+
children: React__default.JSX.Element | null;
|
|
18
17
|
};
|
|
19
18
|
declare const buildScrollRevealChildren: ({ rawChildren, renderSafeNode, normalizeRenderableChild, fallbackChildren, }: {
|
|
20
19
|
rawChildren: UINode[];
|
|
21
20
|
renderSafeNode: (node: UINode) => React__default.ReactNode;
|
|
22
21
|
normalizeRenderableChild: (value: unknown) => React__default.ReactNode;
|
|
23
22
|
fallbackChildren: unknown;
|
|
24
|
-
}) => 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> |
|
|
23
|
+
}) => 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__default.JSX.Element | null | undefined;
|
|
25
24
|
|
|
26
25
|
type TableComponentShape = {
|
|
27
26
|
Header: React__default.ComponentType<Record<string, unknown>>;
|
|
@@ -46,8 +45,8 @@ declare const materializeCoverContent: ({ descriptor, renderSafeNode, }: {
|
|
|
46
45
|
descriptor: CoverContentDescriptor;
|
|
47
46
|
renderSafeNode: (node: UINode) => React__default.ReactNode;
|
|
48
47
|
}) => {
|
|
49
|
-
actions:
|
|
50
|
-
children:
|
|
48
|
+
actions: React__default.JSX.Element | undefined;
|
|
49
|
+
children: React__default.JSX.Element | null;
|
|
51
50
|
};
|
|
52
51
|
|
|
53
52
|
declare const materializeAccordionItems: ({ items, renderSafeNode, }: {
|
|
@@ -57,30 +56,31 @@ declare const materializeAccordionItems: ({ items, renderSafeNode, }: {
|
|
|
57
56
|
id: string;
|
|
58
57
|
title: string;
|
|
59
58
|
disabled: boolean;
|
|
60
|
-
content: string |
|
|
59
|
+
content: string | React__default.JSX.Element;
|
|
61
60
|
}[];
|
|
62
61
|
declare const materializeExpandablePanelContent: ({ descriptor, renderSafeNode, }: {
|
|
63
62
|
descriptor: ExpandablePanelContentDescriptor;
|
|
64
63
|
renderSafeNode: (node: UINode) => React__default.ReactNode;
|
|
65
|
-
}) =>
|
|
64
|
+
}) => React__default.JSX.Element | undefined;
|
|
66
65
|
|
|
67
66
|
declare const materializeTabsContent: ({ tabs, renderSafeNode, normalizeRenderableChild, }: {
|
|
68
67
|
tabs: TabsContentDescriptor[];
|
|
69
68
|
renderSafeNode: (node: UINode) => React__default.ReactNode;
|
|
70
69
|
normalizeRenderableChild: (value: unknown) => React__default.ReactNode;
|
|
71
70
|
}) => {
|
|
71
|
+
disabled: boolean;
|
|
72
72
|
id: string;
|
|
73
73
|
title: unknown;
|
|
74
74
|
label: unknown;
|
|
75
|
-
content: string | number | bigint | boolean | React__default.ReactElement<unknown, string | React__default.JSXElementConstructor<any>> | 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> |
|
|
75
|
+
content: string | number | bigint | boolean | React__default.ReactElement<unknown, string | React__default.JSXElementConstructor<any>> | 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__default.JSX.Element[] | null | undefined;
|
|
76
76
|
}[];
|
|
77
77
|
|
|
78
78
|
declare const buildAccordionItems: (accordionChildren: UINode[], renderSafeNode: (node: UINode) => React__default.ReactNode) => {
|
|
79
79
|
id: string;
|
|
80
80
|
title: string;
|
|
81
|
-
content: string |
|
|
81
|
+
content: string | React__default.JSX.Element;
|
|
82
82
|
disabled: boolean;
|
|
83
83
|
}[];
|
|
84
|
-
declare const buildExpandablePanelChildren: (panelChildren: UINode[], renderSafeNode: (node: UINode) => React__default.ReactNode) =>
|
|
84
|
+
declare const buildExpandablePanelChildren: (panelChildren: UINode[], renderSafeNode: (node: UINode) => React__default.ReactNode) => React__default.JSX.Element | undefined;
|
|
85
85
|
|
|
86
86
|
export { buildAccordionItems, buildCoverContent, buildCoverMedia, buildExpandablePanelChildren, buildScrollRevealChildren, materializeAccordionItems, materializeBoundTable, materializeChildContent, materializeCoverContent, materializeExpandablePanelContent, materializeTabsContent };
|
package/dist/materialization.js
CHANGED
package/dist/rendering.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import React__default from 'react';
|
|
|
2
2
|
import { FinalRenderPlan, ResolvedNodeChildDescriptor, ResolvedNodeContentDescriptor, ResolvedNodeBase, ResolvedEngineNode } from '@arkcit/engine-render-layer';
|
|
3
3
|
import { UINode } from '@arkcit/engine-schema';
|
|
4
4
|
import { UIRuntimeAdapter } from '@arkcit/engine-runtime';
|
|
5
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
6
5
|
export { R as RenderReactNodeArgs, a as RenderReactNodeDependencies, r as renderReactNode } from './renderReactNode-xwA81IXf.js';
|
|
7
6
|
import { ComponentRegistry } from '@arkcit/engine-core';
|
|
8
7
|
|
|
@@ -56,7 +55,7 @@ type PrepareRenderableChildrenArgs = {
|
|
|
56
55
|
childContentDescriptor?: ResolvedNodeContentDescriptor;
|
|
57
56
|
};
|
|
58
57
|
declare const prepareRenderableChildren: ({ node, internalStudioNodeTypes, renderSafeNode, childDescriptors, childContentDescriptor, }: PrepareRenderableChildrenArgs) => {
|
|
59
|
-
children:
|
|
58
|
+
children: React__default.JSX.Element[];
|
|
60
59
|
resolvedChildContent: React__default.ReactNode;
|
|
61
60
|
childDescriptors: ResolvedNodeChildDescriptor[];
|
|
62
61
|
childContentDescriptor: ResolvedNodeContentDescriptor;
|
package/dist/rendering.js
CHANGED
|
@@ -25,7 +25,10 @@ import React2 from "react";
|
|
|
25
25
|
var configurePreviewLinkBehavior = (componentProps) => {
|
|
26
26
|
const existingOnClick = componentProps.onClick;
|
|
27
27
|
componentProps.onClick = (event) => {
|
|
28
|
-
|
|
28
|
+
const href = componentProps.href;
|
|
29
|
+
if (!(typeof href === "string" && href.startsWith("#"))) {
|
|
30
|
+
event.preventDefault();
|
|
31
|
+
}
|
|
29
32
|
if (typeof existingOnClick === "function") {
|
|
30
33
|
existingOnClick(event);
|
|
31
34
|
}
|
|
@@ -174,6 +177,7 @@ var materializeBoundTable = ({
|
|
|
174
177
|
};
|
|
175
178
|
|
|
176
179
|
// src/rendering/finalizeRenderedNode.tsx
|
|
180
|
+
import { jsx } from "react/jsx-runtime";
|
|
177
181
|
var RESPONSIVE_MEDIA_NODE_TYPES = /* @__PURE__ */ new Set(["Image", "Video", "EmbeddedVideo", "Cover", "Document"]);
|
|
178
182
|
var RESPONSIVE_MEDIA_CLASS_NAME = "max-md:!w-full max-md:![flex-basis:100%!important] max-md:!h-auto";
|
|
179
183
|
var RESPONSIVE_TEXT_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -216,6 +220,45 @@ var RESPONSIVE_TEXT_CLASS_NAME = "max-md:!h-auto";
|
|
|
216
220
|
var hasExplicitStudioSizing = (studioSizing) => Boolean(
|
|
217
221
|
studioSizing && (studioSizing.widthPct !== null || studioSizing.heightPct !== null || studioSizing.heightPx !== null)
|
|
218
222
|
);
|
|
223
|
+
var buildExplicitSizingWrapperStyle = (studioSizing) => {
|
|
224
|
+
if (!hasExplicitStudioSizing(studioSizing)) return null;
|
|
225
|
+
return __spreadValues(__spreadValues(__spreadValues({}, (studioSizing == null ? void 0 : studioSizing.widthPct) !== null && (studioSizing == null ? void 0 : studioSizing.widthPct) !== void 0 ? {
|
|
226
|
+
width: `${studioSizing.widthPct}%`,
|
|
227
|
+
flexBasis: `${studioSizing.widthPct}%`,
|
|
228
|
+
maxWidth: "100%"
|
|
229
|
+
} : {}), (studioSizing == null ? void 0 : studioSizing.heightPx) !== null && (studioSizing == null ? void 0 : studioSizing.heightPx) !== void 0 ? { height: `${studioSizing.heightPx}px` } : {}), (studioSizing == null ? void 0 : studioSizing.heightPx) === null && (studioSizing == null ? void 0 : studioSizing.heightPct) !== null && (studioSizing == null ? void 0 : studioSizing.heightPct) !== void 0 ? { height: `${studioSizing.heightPct}%` } : {});
|
|
230
|
+
};
|
|
231
|
+
var removeExplicitSizingFromComponentStyle = (componentProps, shouldWrapExplicitSizing) => {
|
|
232
|
+
if (!shouldWrapExplicitSizing) return;
|
|
233
|
+
const currentStyle = componentProps.style && typeof componentProps.style === "object" ? __spreadValues({}, componentProps.style) : null;
|
|
234
|
+
if (!currentStyle) return;
|
|
235
|
+
delete currentStyle.width;
|
|
236
|
+
delete currentStyle.flexBasis;
|
|
237
|
+
delete currentStyle.maxWidth;
|
|
238
|
+
delete currentStyle.height;
|
|
239
|
+
componentProps.style = currentStyle;
|
|
240
|
+
};
|
|
241
|
+
var removeInternalLayoutProps = (componentProps) => {
|
|
242
|
+
delete componentProps.fullBleed;
|
|
243
|
+
};
|
|
244
|
+
var wrapExplicitlySizedNode = ({
|
|
245
|
+
nodeId,
|
|
246
|
+
nodeType,
|
|
247
|
+
element,
|
|
248
|
+
wrapperStyle
|
|
249
|
+
}) => {
|
|
250
|
+
if (!wrapperStyle) return element;
|
|
251
|
+
return /* @__PURE__ */ jsx(
|
|
252
|
+
"div",
|
|
253
|
+
{
|
|
254
|
+
"data-node-id": nodeId,
|
|
255
|
+
"data-node-type": nodeType,
|
|
256
|
+
className: "relative min-w-0 max-w-full flex-none",
|
|
257
|
+
style: wrapperStyle,
|
|
258
|
+
children: /* @__PURE__ */ jsx("div", { className: "min-w-0 max-w-full", style: { width: "100%", height: "100%" }, children: element })
|
|
259
|
+
}
|
|
260
|
+
);
|
|
261
|
+
};
|
|
219
262
|
var finalizeRenderedNode = ({
|
|
220
263
|
node,
|
|
221
264
|
children,
|
|
@@ -258,6 +301,9 @@ var finalizeRenderedNode = ({
|
|
|
258
301
|
delete componentProps.layout;
|
|
259
302
|
}
|
|
260
303
|
}
|
|
304
|
+
const explicitSizingWrapperStyle = !isStudioRendererContext ? buildExplicitSizingWrapperStyle(studioSizing) : null;
|
|
305
|
+
removeExplicitSizingFromComponentStyle(componentProps, explicitSizingWrapperStyle !== null);
|
|
306
|
+
removeInternalLayoutProps(componentProps);
|
|
261
307
|
if (plans.some((plan) => plan.kind === "table-fallback")) {
|
|
262
308
|
const tableNode = materializeBoundTable({
|
|
263
309
|
nodeId: node.id,
|
|
@@ -266,17 +312,31 @@ var finalizeRenderedNode = ({
|
|
|
266
312
|
TableComponent: registryComponent
|
|
267
313
|
});
|
|
268
314
|
if (tableNode) {
|
|
269
|
-
return
|
|
315
|
+
return wrapExplicitlySizedNode({
|
|
316
|
+
nodeId: node.id,
|
|
317
|
+
nodeType: node.type,
|
|
318
|
+
element: tableNode,
|
|
319
|
+
wrapperStyle: explicitSizingWrapperStyle
|
|
320
|
+
});
|
|
270
321
|
}
|
|
271
322
|
}
|
|
272
323
|
const finalComponentProps = dependencies.omitStudioProps(componentProps);
|
|
324
|
+
let renderedElement;
|
|
273
325
|
if (children && children.length > 0) {
|
|
274
326
|
if (node.type === "Cover" || node.type === "Tabs" || node.type === "Accordion") {
|
|
275
|
-
|
|
327
|
+
renderedElement = React2.createElement(registryComponent, finalComponentProps);
|
|
328
|
+
} else {
|
|
329
|
+
renderedElement = React2.createElement(registryComponent, finalComponentProps, children);
|
|
276
330
|
}
|
|
277
|
-
|
|
331
|
+
} else {
|
|
332
|
+
renderedElement = React2.createElement(registryComponent, finalComponentProps);
|
|
278
333
|
}
|
|
279
|
-
return
|
|
334
|
+
return wrapExplicitlySizedNode({
|
|
335
|
+
nodeId: node.id,
|
|
336
|
+
nodeType: node.type,
|
|
337
|
+
element: renderedElement,
|
|
338
|
+
wrapperStyle: explicitSizingWrapperStyle
|
|
339
|
+
});
|
|
280
340
|
};
|
|
281
341
|
|
|
282
342
|
// src/rendering/gridItemWrapperProps.ts
|
|
@@ -353,7 +413,7 @@ import {
|
|
|
353
413
|
|
|
354
414
|
// src/materialization/materializeChildContent.tsx
|
|
355
415
|
import React3 from "react";
|
|
356
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
416
|
+
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
357
417
|
var materializeChildContent = ({
|
|
358
418
|
descriptor,
|
|
359
419
|
renderSafeNode
|
|
@@ -363,7 +423,7 @@ var materializeChildContent = ({
|
|
|
363
423
|
}
|
|
364
424
|
const renderDescriptor = (childDescriptor) => {
|
|
365
425
|
if (childDescriptor.kind === "grid-item") {
|
|
366
|
-
return /* @__PURE__ */
|
|
426
|
+
return /* @__PURE__ */ jsx2(
|
|
367
427
|
"div",
|
|
368
428
|
__spreadProps(__spreadValues({}, getGridItemWrapperProps(
|
|
369
429
|
childDescriptor.colSpan,
|
|
@@ -376,22 +436,22 @@ var materializeChildContent = ({
|
|
|
376
436
|
childDescriptor.child.id
|
|
377
437
|
);
|
|
378
438
|
}
|
|
379
|
-
return /* @__PURE__ */
|
|
439
|
+
return /* @__PURE__ */ jsx2(React3.Fragment, { children: renderSafeNode(childDescriptor.child) }, childDescriptor.child.id);
|
|
380
440
|
};
|
|
381
441
|
if (descriptor.kind === "single") {
|
|
382
442
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
383
|
-
descriptor.child.kind === "grid-item" ? /* @__PURE__ */
|
|
443
|
+
descriptor.child.kind === "grid-item" ? /* @__PURE__ */ jsx2("style", { children: GRID_ITEM_RESPONSIVE_STYLE }) : null,
|
|
384
444
|
renderDescriptor(descriptor.child)
|
|
385
445
|
] });
|
|
386
446
|
}
|
|
387
447
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
388
|
-
descriptor.children.some((child) => child.kind === "grid-item") ? /* @__PURE__ */
|
|
448
|
+
descriptor.children.some((child) => child.kind === "grid-item") ? /* @__PURE__ */ jsx2("style", { children: GRID_ITEM_RESPONSIVE_STYLE }) : null,
|
|
389
449
|
descriptor.children.map(renderDescriptor)
|
|
390
450
|
] });
|
|
391
451
|
};
|
|
392
452
|
|
|
393
453
|
// src/rendering/prepareRenderableChildren.tsx
|
|
394
|
-
import { jsx as
|
|
454
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
395
455
|
var prepareRenderableChildren = ({
|
|
396
456
|
node,
|
|
397
457
|
internalStudioNodeTypes,
|
|
@@ -405,7 +465,7 @@ var prepareRenderableChildren = ({
|
|
|
405
465
|
});
|
|
406
466
|
const children = resolvedDescriptors.map((descriptor) => {
|
|
407
467
|
if (descriptor.kind === "grid-item") {
|
|
408
|
-
return /* @__PURE__ */
|
|
468
|
+
return /* @__PURE__ */ jsx3(
|
|
409
469
|
"div",
|
|
410
470
|
__spreadProps(__spreadValues({}, getGridItemWrapperProps(
|
|
411
471
|
descriptor.colSpan,
|
|
@@ -418,10 +478,10 @@ var prepareRenderableChildren = ({
|
|
|
418
478
|
descriptor.child.id
|
|
419
479
|
);
|
|
420
480
|
}
|
|
421
|
-
return /* @__PURE__ */
|
|
481
|
+
return /* @__PURE__ */ jsx3(React4.Fragment, { children: renderSafeNode(descriptor.child) }, descriptor.child.id);
|
|
422
482
|
});
|
|
423
483
|
const hasGridItems = resolvedDescriptors.some((descriptor) => descriptor.kind === "grid-item");
|
|
424
|
-
const wrappedChildren = hasGridItems ? [/* @__PURE__ */
|
|
484
|
+
const wrappedChildren = hasGridItems ? [/* @__PURE__ */ jsx3("style", { children: GRID_ITEM_RESPONSIVE_STYLE }, "arkcit-grid-item-responsive-style"), ...children] : children;
|
|
425
485
|
const resolvedChildContentDescriptor = childContentDescriptor != null ? childContentDescriptor : resolveChildContentDescriptor({
|
|
426
486
|
childDescriptors: resolvedDescriptors
|
|
427
487
|
});
|
|
@@ -439,7 +499,7 @@ var prepareRenderableChildren = ({
|
|
|
439
499
|
|
|
440
500
|
// src/rendering/renderChildren.tsx
|
|
441
501
|
import React5, { isValidElement as isValidElement2 } from "react";
|
|
442
|
-
import { jsx as
|
|
502
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
443
503
|
var toBoolean = (value) => {
|
|
444
504
|
if (typeof value === "boolean") return value;
|
|
445
505
|
if (typeof value === "string") return value.toLowerCase() === "true";
|
|
@@ -450,7 +510,7 @@ var normalizeRenderableChild = (value) => {
|
|
|
450
510
|
if (typeof value === "string" || typeof value === "number") return value;
|
|
451
511
|
if (isValidElement2(value)) return value;
|
|
452
512
|
if (Array.isArray(value)) {
|
|
453
|
-
return value.map((item, index) => /* @__PURE__ */
|
|
513
|
+
return value.map((item, index) => /* @__PURE__ */ jsx4(React5.Fragment, { children: normalizeRenderableChild(item) }, `normalized-child-${index}`));
|
|
454
514
|
}
|
|
455
515
|
if (value && typeof value === "object") {
|
|
456
516
|
const candidate = value;
|
|
@@ -468,8 +528,8 @@ var normalizeRenderableChild = (value) => {
|
|
|
468
528
|
};
|
|
469
529
|
|
|
470
530
|
// src/engine/EngineWarningFallback.tsx
|
|
471
|
-
import { jsx as
|
|
472
|
-
var EngineWarningFallback = ({ message }) => /* @__PURE__ */
|
|
531
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
532
|
+
var EngineWarningFallback = ({ message }) => /* @__PURE__ */ jsx5(
|
|
473
533
|
"div",
|
|
474
534
|
{
|
|
475
535
|
role: "alert",
|
|
@@ -518,7 +578,7 @@ var resolveResolvedReactNode = ({
|
|
|
518
578
|
};
|
|
519
579
|
|
|
520
580
|
// src/rendering/renderReactNode.tsx
|
|
521
|
-
import { jsx as
|
|
581
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
522
582
|
var renderReactNode = ({
|
|
523
583
|
node,
|
|
524
584
|
runtime,
|
|
@@ -555,7 +615,7 @@ var renderReactNode = ({
|
|
|
555
615
|
studioSizing
|
|
556
616
|
});
|
|
557
617
|
if (!resolvedNode) {
|
|
558
|
-
return /* @__PURE__ */
|
|
618
|
+
return /* @__PURE__ */ jsx6(
|
|
559
619
|
EngineWarningFallback_default,
|
|
560
620
|
{
|
|
561
621
|
message: `Unknown component type "${node.type}" for node "${node.id}".`
|
|
@@ -641,7 +701,7 @@ var renderReactNode = ({
|
|
|
641
701
|
plans: finalRenderPlans
|
|
642
702
|
});
|
|
643
703
|
} catch (e) {
|
|
644
|
-
return /* @__PURE__ */
|
|
704
|
+
return /* @__PURE__ */ jsx6(
|
|
645
705
|
EngineWarningFallback_default,
|
|
646
706
|
{
|
|
647
707
|
message: `Renderer fallback: node "${node.type}" (${node.id}) could not be resolved.`
|
package/dist/static-engine.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
1
|
import React__default from 'react';
|
|
3
2
|
import { UIEngineProps, UINodeWrapperProps } from '@arkcit/engine-core';
|
|
4
3
|
import { UINode } from '@arkcit/engine-schema';
|
|
@@ -44,6 +43,6 @@ type StaticReactWebEngineRootDependencies<TInlineEditing = unknown> = {
|
|
|
44
43
|
type StaticReactWebEngineRootArgs<TInlineEditing = unknown> = UIEngineProps & {
|
|
45
44
|
dependencies: StaticReactWebEngineRootDependencies<TInlineEditing>;
|
|
46
45
|
};
|
|
47
|
-
declare const StaticReactWebEngineRoot: <TInlineEditing = unknown>({ schema, registry, store, nodeWrapper, dependencies, }: StaticReactWebEngineRootArgs<TInlineEditing>) =>
|
|
46
|
+
declare const StaticReactWebEngineRoot: <TInlineEditing = unknown>({ schema, registry, store, nodeWrapper, dependencies, }: StaticReactWebEngineRootArgs<TInlineEditing>) => React__default.JSX.Element;
|
|
48
47
|
|
|
49
48
|
export { StaticReactWebEngineRoot, type StaticReactWebEngineRootArgs, type StaticReactWebEngineRootDependencies, type StaticRenderSafeNodeArgs };
|
package/dist/static-engine.js
CHANGED
|
@@ -427,7 +427,14 @@ var StaticReactWebEngineRoot = ({
|
|
|
427
427
|
NodeWrapper,
|
|
428
428
|
isFormInteractiveTarget
|
|
429
429
|
});
|
|
430
|
-
return /* @__PURE__ */ jsx5(
|
|
430
|
+
return /* @__PURE__ */ jsx5(
|
|
431
|
+
"div",
|
|
432
|
+
{
|
|
433
|
+
"data-arkcit-engine-root": true,
|
|
434
|
+
className: "flex min-w-0 w-full flex-wrap content-start items-start gap-3",
|
|
435
|
+
children: schema.nodes.map((node) => /* @__PURE__ */ jsx5(React3.Fragment, { children: renderSafeEngineNode(node) }, node.id))
|
|
436
|
+
}
|
|
437
|
+
);
|
|
431
438
|
};
|
|
432
439
|
export {
|
|
433
440
|
StaticReactWebEngineRoot
|