@sitecore-content-sdk/react 1.2.0-canary.8 → 1.2.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/LICENSE.txt +202 -202
- package/README.md +11 -11
- package/dist/cjs/components/ClientEditingChromesUpdate.js +52 -0
- package/dist/cjs/components/DefaultEmptyFieldEditingComponents.js +4 -4
- package/dist/cjs/components/DesignLibrary.js +85 -103
- package/dist/cjs/components/EditingScripts.js +1 -0
- package/dist/cjs/components/ErrorBoundary.js +1 -0
- package/dist/cjs/components/FEaaS/BYOCServerWrapper.js +28 -0
- package/dist/cjs/components/{BYOCComponent.js → FEaaS/BYOCWrapper.js} +17 -28
- package/dist/cjs/components/FEaaS/FEaaSSeverWrapper.js +34 -0
- package/dist/cjs/components/FEaaS/FEaaSWrapper.js +78 -0
- package/dist/cjs/components/{FEaaSComponent.js → FEaaS/feaas-utils.js} +18 -35
- package/dist/cjs/components/FEaaS/index.js +21 -0
- package/dist/cjs/components/FEaaS/models.js +7 -0
- package/dist/cjs/components/Link.js +1 -1
- package/dist/cjs/components/Placeholder/AppPlaceholder.js +76 -0
- package/dist/cjs/components/Placeholder/ClientComponentWrapper.js +21 -0
- package/dist/cjs/components/Placeholder/Placeholder.js +110 -0
- package/dist/cjs/components/Placeholder/index.js +25 -0
- package/dist/cjs/components/Placeholder/models.js +18 -0
- package/dist/cjs/components/Placeholder/placeholder-utils.js +215 -0
- package/dist/cjs/components/RichText.js +1 -0
- package/dist/cjs/components/Text.js +1 -0
- package/dist/cjs/enhancers/withAppPlaceholder.js +21 -0
- package/dist/cjs/enhancers/withEmptyFieldEditingComponent.js +12 -5
- package/dist/cjs/enhancers/withPlaceholder.js +8 -6
- package/dist/cjs/index.js +17 -11
- package/dist/cjs/rsc-utils/no-rsc.js +5 -0
- package/dist/cjs/rsc-utils/rsc.js +5 -0
- package/dist/esm/components/ClientEditingChromesUpdate.js +15 -0
- package/dist/esm/components/DefaultEmptyFieldEditingComponents.js +4 -4
- package/dist/esm/components/DesignLibrary.js +85 -102
- package/dist/esm/components/EditingScripts.js +1 -0
- package/dist/esm/components/ErrorBoundary.js +1 -0
- package/dist/esm/components/FEaaS/BYOCServerWrapper.js +21 -0
- package/dist/esm/components/{BYOCComponent.js → FEaaS/BYOCWrapper.js} +15 -26
- package/dist/esm/components/FEaaS/FEaaSSeverWrapper.js +27 -0
- package/dist/esm/components/FEaaS/FEaaSWrapper.js +37 -0
- package/dist/esm/components/{FEaaSComponent.js → FEaaS/feaas-utils.js} +16 -30
- package/dist/esm/components/FEaaS/index.js +6 -0
- package/dist/esm/components/FEaaS/models.js +4 -0
- package/dist/esm/components/Link.js +1 -1
- package/dist/esm/components/Placeholder/AppPlaceholder.js +69 -0
- package/dist/esm/components/Placeholder/ClientComponentWrapper.js +14 -0
- package/dist/esm/components/Placeholder/Placeholder.js +103 -0
- package/dist/esm/components/Placeholder/index.js +4 -0
- package/dist/esm/components/Placeholder/models.js +15 -0
- package/dist/esm/components/Placeholder/placeholder-utils.js +203 -0
- package/dist/esm/components/RichText.js +1 -0
- package/dist/esm/components/Text.js +1 -0
- package/dist/esm/enhancers/withAppPlaceholder.js +14 -0
- package/dist/esm/enhancers/withEmptyFieldEditingComponent.js +12 -5
- package/dist/esm/enhancers/withPlaceholder.js +8 -6
- package/dist/esm/index.js +5 -5
- package/dist/esm/rsc-utils/no-rsc.js +2 -0
- package/dist/esm/rsc-utils/rsc.js +2 -0
- package/package.json +16 -4
- package/types/components/ClientEditingChromesUpdate.d.ts +6 -0
- package/types/components/Date.d.ts +1 -1
- package/types/components/DefaultEmptyFieldEditingComponents.d.ts +8 -2
- package/types/components/DesignLibrary.d.ts +13 -13
- package/types/components/ErrorBoundary.d.ts +0 -1
- package/types/components/FEaaS/BYOCServerWrapper.d.ts +3 -0
- package/types/components/FEaaS/BYOCWrapper.d.ts +25 -0
- package/types/components/FEaaS/FEaaSSeverWrapper.d.ts +8 -0
- package/types/components/FEaaS/FEaaSWrapper.d.ts +7 -0
- package/types/components/FEaaS/feaas-utils.d.ts +21 -0
- package/types/components/FEaaS/index.d.ts +6 -0
- package/types/components/FEaaS/models.d.ts +125 -0
- package/types/components/Image.d.ts +1 -1
- package/types/components/Link.d.ts +1 -1
- package/types/components/Placeholder/AppPlaceholder.d.ts +10 -0
- package/types/components/Placeholder/ClientComponentWrapper.d.ts +9 -0
- package/types/components/Placeholder/Placeholder.d.ts +28 -0
- package/types/components/Placeholder/index.d.ts +5 -0
- package/types/components/Placeholder/models.d.ts +140 -0
- package/types/components/Placeholder/placeholder-utils.d.ts +53 -0
- package/types/components/RichText.d.ts +1 -1
- package/types/components/Text.d.ts +1 -1
- package/types/components/sharedTypes/components.d.ts +6 -0
- package/types/components/sharedTypes/props.d.ts +2 -2
- package/types/enhancers/withAppPlaceholder.d.ts +15 -0
- package/types/enhancers/withEmptyFieldEditingComponent.d.ts +3 -3
- package/types/enhancers/withPlaceholder.d.ts +2 -1
- package/types/index.d.ts +4 -5
- package/types/rsc-utils/no-rsc.d.ts +1 -0
- package/types/rsc-utils/rsc.d.ts +1 -0
- package/dist/cjs/components/BYOCWrapper.js +0 -22
- package/dist/cjs/components/FEaaSWrapper.js +0 -19
- package/dist/cjs/components/Placeholder.js +0 -68
- package/dist/cjs/components/PlaceholderCommon.js +0 -176
- package/dist/esm/components/BYOCWrapper.js +0 -15
- package/dist/esm/components/FEaaSWrapper.js +0 -12
- package/dist/esm/components/Placeholder.js +0 -62
- package/dist/esm/components/PlaceholderCommon.js +0 -169
- package/types/components/BYOCComponent.d.ts +0 -93
- package/types/components/BYOCWrapper.d.ts +0 -7
- package/types/components/FEaaSComponent.d.ts +0 -72
- package/types/components/FEaaSWrapper.d.ts +0 -4
- package/types/components/Placeholder.d.ts +0 -20
- package/types/components/PlaceholderCommon.d.ts +0 -89
- /package/dist/cjs/components/{PlaceholderMetadata.js → Placeholder/PlaceholderMetadata.js} +0 -0
- /package/dist/esm/components/{PlaceholderMetadata.js → Placeholder/PlaceholderMetadata.js} +0 -0
- /package/types/components/{PlaceholderMetadata.d.ts → Placeholder/PlaceholderMetadata.d.ts} +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { isEditorActive, resetEditorChromes } from '@sitecore-content-sdk/core/editing';
|
|
3
|
+
import React, { useEffect } from 'react';
|
|
4
|
+
/**
|
|
5
|
+
* Updates editing chromes in app router / RSC context.
|
|
6
|
+
* This ensures all the relevant Pages editing markup is applied once all client components are loaded.
|
|
7
|
+
*/
|
|
8
|
+
export const ClientEditingChromesUpdate = () => {
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (isEditorActive()) {
|
|
11
|
+
resetEditorChromes();
|
|
12
|
+
}
|
|
13
|
+
}, []);
|
|
14
|
+
return React.createElement(React.Fragment, null);
|
|
15
|
+
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
export const DefaultEmptyFieldEditingComponentText = () => {
|
|
3
|
-
return React.createElement(
|
|
2
|
+
export const DefaultEmptyFieldEditingComponentText = (props) => {
|
|
3
|
+
return React.createElement(props.tag || 'span', props, '[No text in field]');
|
|
4
4
|
};
|
|
5
|
-
export const DefaultEmptyFieldEditingComponentImage = () => {
|
|
5
|
+
export const DefaultEmptyFieldEditingComponentImage = (props) => {
|
|
6
6
|
const inlineStyles = {
|
|
7
7
|
minWidth: '48px',
|
|
8
8
|
minHeight: '48px',
|
|
@@ -10,5 +10,5 @@ export const DefaultEmptyFieldEditingComponentImage = () => {
|
|
|
10
10
|
maxHeight: '400px',
|
|
11
11
|
cursor: 'pointer',
|
|
12
12
|
};
|
|
13
|
-
return (React.createElement("img", { alt: "", src: 'data:image/svg+xml,%3Csvg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 240 240" style="enable-background:new 0 0 240 240;" xml:space="preserve"%3E%3Cstyle type="text/css"%3E .st0%7Bfill:none;%7D .st1%7Bfill:%23969696;%7D .st2%7Bfill:%23FFFFFF;%7D .st3%7Bfill:%23FFFFFF;stroke:%23FFFFFF;stroke-width:0.75;stroke-miterlimit:10;%7D%0A%3C/style%3E%3Cg%3E%3Crect class="st0" width="240" height="240"/%3E%3Cg%3E%3Cg%3E%3Crect x="20" y="20" class="st1" width="200" height="200"/%3E%3C/g%3E%3Cg%3E%3Ccircle class="st2" cx="174" cy="67" r="14"/%3E%3Cpath class="st2" d="M174,54c7.17,0,13,5.83,13,13s-5.83,13-13,13s-13-5.83-13-13S166.83,54,174,54 M174,52 c-8.28,0-15,6.72-15,15s6.72,15,15,15s15-6.72,15-15S182.28,52,174,52L174,52z"/%3E%3C/g%3E%3Cpolyline class="st3" points="29.5,179.25 81.32,122.25 95.41,137.75 137.23,91.75 209.5,179.75 "/%3E%3C/g%3E%3C/g%3E%3C/svg%3E', className:
|
|
13
|
+
return (React.createElement("img", Object.assign({}, props, { alt: "", src: 'data:image/svg+xml,%3Csvg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 240 240" style="enable-background:new 0 0 240 240;" xml:space="preserve"%3E%3Cstyle type="text/css"%3E .st0%7Bfill:none;%7D .st1%7Bfill:%23969696;%7D .st2%7Bfill:%23FFFFFF;%7D .st3%7Bfill:%23FFFFFF;stroke:%23FFFFFF;stroke-width:0.75;stroke-miterlimit:10;%7D%0A%3C/style%3E%3Cg%3E%3Crect class="st0" width="240" height="240"/%3E%3Cg%3E%3Cg%3E%3Crect x="20" y="20" class="st1" width="200" height="200"/%3E%3C/g%3E%3Cg%3E%3Ccircle class="st2" cx="174" cy="67" r="14"/%3E%3Cpath class="st2" d="M174,54c7.17,0,13,5.83,13,13s-5.83,13-13,13s-13-5.83-13-13S166.83,54,174,54 M174,52 c-8.28,0-15,6.72-15,15s6.72,15,15,15s15-6.72,15-15S182.28,52,174,52L174,52z"/%3E%3C/g%3E%3Cpolyline class="st3" points="29.5,179.25 81.32,122.25 95.41,137.75 137.23,91.75 209.5,179.75 "/%3E%3C/g%3E%3C/g%3E%3C/svg%3E', className: `scEmptyImage ${props.className || ''}`, style: inlineStyles })));
|
|
14
14
|
};
|
|
@@ -10,60 +10,36 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
/* eslint-disable jsdoc/require-param */
|
|
12
12
|
/* eslint-disable prefer-const */
|
|
13
|
-
import React, { useEffect,
|
|
13
|
+
import React, { useEffect, useState } from 'react';
|
|
14
14
|
import { Placeholder } from './Placeholder';
|
|
15
15
|
import { EDITING_COMPONENT_ID, EDITING_COMPONENT_PLACEHOLDER, } from '@sitecore-content-sdk/core/layout';
|
|
16
16
|
import { DesignLibraryStatus, getDesignLibraryStatusEvent, addComponentUpdateHandler, } from '@sitecore-content-sdk/core/editing';
|
|
17
17
|
import * as codegen from '@sitecore-content-sdk/core/codegen';
|
|
18
18
|
import { useSitecore } from '../enhancers/withSitecore';
|
|
19
|
+
import { PlaceholderMetadata } from './Placeholder';
|
|
19
20
|
let { getDesignLibraryImportMapEvent, getDesignLibraryComponentPropsEvent, addComponentPreviewHandler, } = codegen;
|
|
20
21
|
export const __mockDependencies = (mocks) => {
|
|
21
22
|
addComponentPreviewHandler = mocks.addComponentPreviewHandler;
|
|
22
23
|
};
|
|
23
|
-
/**
|
|
24
|
-
* This component is used to render the component in preview mode.
|
|
25
|
-
* It is used to send the rendered event to the parent window and render the component.
|
|
26
|
-
* Reacts on the update event from the parent window and re-renders the component.
|
|
27
|
-
*/
|
|
28
|
-
const Preview = () => {
|
|
29
|
-
const { page } = useSitecore();
|
|
30
|
-
const { layout: { sitecore: { route }, }, } = page;
|
|
31
|
-
const [renderKey, setRenderKey] = useState(0);
|
|
32
|
-
const [rootUpdate, setRootUpdate] = useState(null);
|
|
33
|
-
const rootComponent = route === null || route === void 0 ? void 0 : route.placeholders[EDITING_COMPONENT_PLACEHOLDER][0];
|
|
34
|
-
// useEffect may execute multiple times on single render (i.e. in dev) - but we only want to fire ready event once
|
|
35
|
-
let componentReady = false;
|
|
36
|
-
// have an up-to-date layout state between re-renders (SSR re-render excluded)
|
|
37
|
-
const persistedRoot = useMemo(() => (Object.assign(Object.assign({}, (rootComponent || {})), rootUpdate)), [rootComponent, rootUpdate]);
|
|
38
|
-
route.placeholders[EDITING_COMPONENT_PLACEHOLDER][0] = persistedRoot;
|
|
39
|
-
useEffect(() => {
|
|
40
|
-
// useEffect will fire when components are ready - and we inform the whole wide world of it too
|
|
41
|
-
if (!componentReady) {
|
|
42
|
-
componentReady = true;
|
|
43
|
-
window.top.postMessage(getDesignLibraryStatusEvent(DesignLibraryStatus.READY, rootComponent.uid), '*');
|
|
44
|
-
}
|
|
45
|
-
const unsubscribe = addComponentUpdateHandler(persistedRoot, (updatedRoot) => {
|
|
46
|
-
setRootUpdate(Object.assign({}, updatedRoot));
|
|
47
|
-
setRenderKey((key) => key + 1);
|
|
48
|
-
});
|
|
49
|
-
// useEffect will cleanup event handler on re-render
|
|
50
|
-
return unsubscribe;
|
|
51
|
-
}, []);
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
// Send a rendered event only as effect of a component update command
|
|
54
|
-
if (renderKey === 0) {
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
window.top.postMessage(getDesignLibraryStatusEvent(DesignLibraryStatus.RENDERED, rootComponent.uid), '*');
|
|
58
|
-
}, [renderKey, rootComponent.uid]);
|
|
59
|
-
return (React.createElement(React.Fragment, null,
|
|
60
|
-
React.createElement("main", null,
|
|
61
|
-
React.createElement("div", { id: EDITING_COMPONENT_ID }, route && (React.createElement(Placeholder, { name: EDITING_COMPONENT_PLACEHOLDER, rendering: route, key: renderKey }))))));
|
|
62
|
-
};
|
|
63
24
|
const sendErrorEvent = (uid, error, type) => {
|
|
64
25
|
const errorEvent = codegen.getDesignLibraryComponentPreviewErrorEvent(uid, error, type);
|
|
65
26
|
console.error('Component Library: sending error event', errorEvent);
|
|
66
|
-
|
|
27
|
+
if (typeof window !== 'undefined') {
|
|
28
|
+
const target = window.parent && window.parent !== window ? window.parent : window;
|
|
29
|
+
target.postMessage(errorEvent, '*');
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const postToDL = (evt) => {
|
|
33
|
+
if (typeof window === 'undefined')
|
|
34
|
+
return;
|
|
35
|
+
const target = window.parent && window.parent !== window ? window.parent : window;
|
|
36
|
+
try {
|
|
37
|
+
console.log('Component Library: sending event', evt === null || evt === void 0 ? void 0 : evt.name, evt);
|
|
38
|
+
target.postMessage(evt, '*');
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
console.error('Component Library: postMessage failed', err, evt);
|
|
42
|
+
}
|
|
67
43
|
};
|
|
68
44
|
class ErrorBoundary extends React.Component {
|
|
69
45
|
constructor() {
|
|
@@ -91,36 +67,74 @@ class ErrorBoundary extends React.Component {
|
|
|
91
67
|
}
|
|
92
68
|
}
|
|
93
69
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
70
|
+
* Design Library component.
|
|
71
|
+
*
|
|
72
|
+
* Renders the **real** Sitecore component for `library` / `library-metadata` modes and,
|
|
73
|
+
* when generation is enabled (`page.mode.designLibrary.isVariantGeneration === true`),
|
|
74
|
+
* wires the **variant generation** handshake so the parent (DL Studio) can send
|
|
75
|
+
* generated code to preview and iterate on.
|
|
76
|
+
* @param {DesignLibraryProps} props
|
|
77
|
+
* @param {() => Promise<{ default: import('../codegen').ImportEntry[] }>} [props.loadImportMap] Optional async loader that resolves to the import-map used to resolve the generated component’s imports. Required when `isVariantGeneration` is true.
|
|
78
|
+
* @returns {JSX.Element} The preview surface, or `null` when not in Design Library mode.
|
|
96
79
|
*/
|
|
97
|
-
export const
|
|
80
|
+
export const DesignLibrary = ({ loadImportMap }) => {
|
|
81
|
+
var _a, _b;
|
|
98
82
|
const { page } = useSitecore();
|
|
99
|
-
const
|
|
100
|
-
const rendering = route === null || route === void 0 ? void 0 : route.placeholders[EDITING_COMPONENT_PLACEHOLDER][0];
|
|
83
|
+
const route = page.layout.sitecore.route;
|
|
84
|
+
const rendering = (_a = route === null || route === void 0 ? void 0 : route.placeholders[EDITING_COMPONENT_PLACEHOLDER]) === null || _a === void 0 ? void 0 : _a[0];
|
|
85
|
+
const { isDesignLibrary } = page.mode;
|
|
86
|
+
const isVariantGeneration = (_b = page.mode.designLibrary) === null || _b === void 0 ? void 0 : _b.isVariantGeneration;
|
|
87
|
+
const [propsState, setPropsState] = useState({
|
|
88
|
+
fields: rendering === null || rendering === void 0 ? void 0 : rendering.fields,
|
|
89
|
+
params: rendering === null || rendering === void 0 ? void 0 : rendering.params,
|
|
90
|
+
});
|
|
101
91
|
const [renderKey, setRenderKey] = useState(0);
|
|
102
92
|
const [Component, setComponent] = useState(null);
|
|
93
|
+
const isGeneratedComponentActive = !!Component;
|
|
94
|
+
if (!isDesignLibrary)
|
|
95
|
+
return null;
|
|
103
96
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
104
97
|
useEffect(() => {
|
|
98
|
+
postToDL(getDesignLibraryStatusEvent(DesignLibraryStatus.READY, rendering.uid));
|
|
99
|
+
if (!isVariantGeneration) {
|
|
100
|
+
requestAnimationFrame(() => {
|
|
101
|
+
setRenderKey((k) => (k === 0 ? k + 1 : k));
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
const unsubUpdate = addComponentUpdateHandler(rendering, (updated) => {
|
|
105
|
+
setPropsState({ fields: updated.fields, params: updated.params });
|
|
106
|
+
setRenderKey((k) => k + 1);
|
|
107
|
+
});
|
|
108
|
+
// useEffect will cleanup event handler on re-render
|
|
109
|
+
return () => unsubUpdate && unsubUpdate();
|
|
110
|
+
}, [isVariantGeneration, rendering]);
|
|
111
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
// Send a rendered event only as effect of a component update command
|
|
114
|
+
if (renderKey === 0)
|
|
115
|
+
return;
|
|
116
|
+
postToDL(getDesignLibraryStatusEvent(DesignLibraryStatus.RENDERED, rendering.uid));
|
|
117
|
+
}, [renderKey, rendering]);
|
|
118
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
if (!isDesignLibrary || !isVariantGeneration)
|
|
121
|
+
return undefined;
|
|
105
122
|
let cancelled = false;
|
|
106
123
|
// since import map is loaded lazily, we only need to add preview event handler once the import map is loaded
|
|
107
124
|
// unsubscribe function for useEffect cleanup will also be returned once importMap promise has been resolved or rejected
|
|
108
|
-
let unsubscribe
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (!props.loadImportMap) {
|
|
113
|
-
const errorMessage = 'No loadImportMap prop provided. Please provide a dynamic import map function for DesignLibrary.';
|
|
114
|
-
sendErrorEvent(rendering.uid, errorMessage, codegen.DesignLibraryPreviewError.RenderInit);
|
|
125
|
+
let unsubscribe;
|
|
126
|
+
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
127
|
+
if (!loadImportMap) {
|
|
128
|
+
sendErrorEvent(rendering.uid, 'No loadImportMap provided', codegen.DesignLibraryPreviewError.RenderInit);
|
|
115
129
|
return;
|
|
116
130
|
}
|
|
131
|
+
let importMap;
|
|
117
132
|
try {
|
|
118
|
-
const
|
|
119
|
-
importMap =
|
|
133
|
+
const mod = yield loadImportMap();
|
|
134
|
+
importMap = mod.default;
|
|
120
135
|
}
|
|
121
|
-
catch (
|
|
122
|
-
|
|
123
|
-
sendErrorEvent(rendering.uid, errorMessage, codegen.DesignLibraryPreviewError.RenderInit);
|
|
136
|
+
catch (e) {
|
|
137
|
+
sendErrorEvent(rendering.uid, `Error loading import map: ${e}`, codegen.DesignLibraryPreviewError.RenderInit);
|
|
124
138
|
return;
|
|
125
139
|
}
|
|
126
140
|
// account for component being unmounted while resolving async import map
|
|
@@ -128,54 +142,23 @@ export const VariantGeneration = (props) => {
|
|
|
128
142
|
return;
|
|
129
143
|
unsubscribe = addComponentPreviewHandler(importMap, (error, Component) => {
|
|
130
144
|
// Error event is already sent in the addComponentPreviewHandler
|
|
131
|
-
if (error)
|
|
145
|
+
if (error)
|
|
132
146
|
return;
|
|
133
|
-
}
|
|
134
|
-
setRenderKey((key) => key + 1);
|
|
135
147
|
setComponent(() => Component);
|
|
148
|
+
setRenderKey((k) => k + 1);
|
|
136
149
|
});
|
|
137
150
|
const importMapEvent = getDesignLibraryImportMapEvent(rendering.uid, importMap);
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const readyEvent = getDesignLibraryStatusEvent(DesignLibraryStatus.READY, rendering.uid);
|
|
144
|
-
console.debug('Component Library: sending event', readyEvent);
|
|
145
|
-
(_a = window.top) === null || _a === void 0 ? void 0 : _a.postMessage(readyEvent, '*');
|
|
146
|
-
});
|
|
147
|
-
init();
|
|
148
|
-
// return function that calls unsubsubribe - if the component was mounted correctly
|
|
151
|
+
postToDL(importMapEvent);
|
|
152
|
+
const propsEvent = getDesignLibraryComponentPropsEvent(rendering.uid, propsState.fields, propsState.params);
|
|
153
|
+
postToDL(propsEvent);
|
|
154
|
+
}))();
|
|
155
|
+
// return function that calls unsubscribe - if the component was mounted correctly
|
|
149
156
|
return () => {
|
|
150
157
|
cancelled = true;
|
|
151
|
-
|
|
152
|
-
unsubscribe();
|
|
153
|
-
}
|
|
158
|
+
unsubscribe && unsubscribe();
|
|
154
159
|
};
|
|
155
|
-
}, []);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
// Send a rendered event only as effect of a component update command
|
|
160
|
-
if (renderKey === 0)
|
|
161
|
-
return undefined;
|
|
162
|
-
const renderedEvent = getDesignLibraryStatusEvent(DesignLibraryStatus.RENDERED, rendering.uid);
|
|
163
|
-
console.debug('Component Library: sending event', renderedEvent);
|
|
164
|
-
(_a = window.top) === null || _a === void 0 ? void 0 : _a.postMessage(renderedEvent, '*');
|
|
165
|
-
}, [renderKey, rendering === null || rendering === void 0 ? void 0 : rendering.uid]);
|
|
166
|
-
return (React.createElement("main", null, Component ? (React.createElement(ErrorBoundary, { uid: rendering.uid, renderKey: renderKey },
|
|
167
|
-
React.createElement(Component, { fields: rendering.fields, params: rendering.params, key: renderKey }))) : (React.createElement("div", null, "Loading preview..."))));
|
|
168
|
-
};
|
|
169
|
-
export const DesignLibrary = ({ loadImportMap }) => {
|
|
170
|
-
var _a;
|
|
171
|
-
const { page } = useSitecore();
|
|
172
|
-
const { isDesignLibrary } = page.mode;
|
|
173
|
-
const isVariantGeneration = (_a = page.mode.designLibrary) === null || _a === void 0 ? void 0 : _a.isVariantGeneration;
|
|
174
|
-
if (!isDesignLibrary) {
|
|
175
|
-
return null;
|
|
176
|
-
}
|
|
177
|
-
if (isVariantGeneration) {
|
|
178
|
-
return React.createElement(VariantGeneration, { loadImportMap: loadImportMap });
|
|
179
|
-
}
|
|
180
|
-
return React.createElement(Preview, null);
|
|
160
|
+
}, [isVariantGeneration, rendering]);
|
|
161
|
+
return (React.createElement("main", null, isGeneratedComponentActive ? (React.createElement(ErrorBoundary, { uid: rendering.uid, renderKey: renderKey },
|
|
162
|
+
React.createElement(PlaceholderMetadata, { rendering: rendering },
|
|
163
|
+
React.createElement(Component, { fields: propsState.fields, params: propsState.params, key: renderKey })))) : (React.createElement("div", { id: EDITING_COMPONENT_ID }, route && (React.createElement(Placeholder, { name: EDITING_COMPONENT_PLACEHOLDER, rendering: route, key: renderKey }))))));
|
|
181
164
|
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import React from 'react';
|
|
11
|
+
import { fetchBYOCComponentServerProps } from './feaas-utils';
|
|
12
|
+
import { BYOCWrapper } from './BYOCWrapper';
|
|
13
|
+
import { nonSerializedPlaceholderProps } from '../Placeholder/models';
|
|
14
|
+
export const BYOCServerWrapper = (props) => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
+
var _a;
|
|
16
|
+
const params = ((_a = props.rendering) === null || _a === void 0 ? void 0 : _a.params) || {};
|
|
17
|
+
// only pass serializable props to the client BYOC component
|
|
18
|
+
const serializableProps = Object.fromEntries(Object.entries(props).filter(([key]) => !nonSerializedPlaceholderProps.includes(key)));
|
|
19
|
+
const finalProps = Object.assign(Object.assign({}, (yield fetchBYOCComponentServerProps(params))), serializableProps);
|
|
20
|
+
return React.createElement(BYOCWrapper, Object.assign({}, finalProps));
|
|
21
|
+
});
|
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
import React from 'react';
|
|
12
|
-
import { getDataFromFields } from '../utils';
|
|
13
|
-
import { MissingComponent } from './MissingComponent';
|
|
14
3
|
import * as FEAAS from '@sitecore-feaas/clientside/react';
|
|
15
|
-
|
|
4
|
+
import { getDataFromFields } from '../../utils';
|
|
5
|
+
import { MissingComponent } from '../MissingComponent';
|
|
16
6
|
const DefaultErrorComponent = (props) => {
|
|
17
7
|
var _a;
|
|
18
8
|
return (React.createElement("div", null,
|
|
@@ -20,11 +10,12 @@ const DefaultErrorComponent = (props) => {
|
|
|
20
10
|
_a.message,
|
|
21
11
|
"."));
|
|
22
12
|
};
|
|
13
|
+
// BYOCComponent remains for backward compatibility and testing purposes
|
|
23
14
|
/**
|
|
24
15
|
* BYOCComponent facilitate the rendering of external components. It manages potential errors,
|
|
25
16
|
* missing components, and customization of error messages or alternative rendering components.
|
|
26
17
|
* @param {ByocComponentProps} props component props
|
|
27
|
-
* @returns
|
|
18
|
+
* @returns dynamically rendered component or Missing Component error frame
|
|
28
19
|
*/
|
|
29
20
|
export class BYOCComponent extends React.Component {
|
|
30
21
|
constructor(props) {
|
|
@@ -76,17 +67,15 @@ export class BYOCComponent extends React.Component {
|
|
|
76
67
|
}
|
|
77
68
|
}
|
|
78
69
|
/**
|
|
79
|
-
*
|
|
80
|
-
* @param {
|
|
70
|
+
* SXA wrapper for BYOC components
|
|
71
|
+
* @param {BYOCComponentProps} props component props
|
|
72
|
+
* @returns wrapped BYOC component
|
|
81
73
|
*/
|
|
82
|
-
export
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
};
|
|
91
|
-
});
|
|
92
|
-
}
|
|
74
|
+
export const BYOCWrapper = (props) => {
|
|
75
|
+
var _a, _b, _c;
|
|
76
|
+
const styles = (_b = (_a = props.params) === null || _a === void 0 ? void 0 : _a.styles) === null || _b === void 0 ? void 0 : _b.trimEnd();
|
|
77
|
+
const id = (_c = props.params) === null || _c === void 0 ? void 0 : _c.RenderingIdentifier;
|
|
78
|
+
return (React.createElement("div", { className: styles ? styles : undefined, id: id ? id : undefined },
|
|
79
|
+
React.createElement("div", { className: "component-content" },
|
|
80
|
+
React.createElement(BYOCComponent, Object.assign({}, props)))));
|
|
81
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import React from 'react';
|
|
11
|
+
import { fetchFEaaSComponentServerProps } from './feaas-utils';
|
|
12
|
+
import { FEaaSWrapper } from './FEaaSWrapper';
|
|
13
|
+
import { nonSerializedPlaceholderProps } from '../Placeholder/models';
|
|
14
|
+
/**
|
|
15
|
+
* Server component for FEaaS. Retrieves server props and renders client FEaaSWrapper.
|
|
16
|
+
* @param {FEaaSComponentProps} props incoming props
|
|
17
|
+
* @returns {Promise<JSX.Element>} rendered FEaaSWrapper component
|
|
18
|
+
*/
|
|
19
|
+
export const FEaaSServerWrapper = (props) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
const params = ((_a = props.rendering) === null || _a === void 0 ? void 0 : _a.params) || {};
|
|
22
|
+
const isPageStateNormal = (_b = props.page) === null || _b === void 0 ? void 0 : _b.mode.isNormal;
|
|
23
|
+
// only pass serializable props to the client FEaaS component
|
|
24
|
+
const serializableProps = Object.fromEntries(Object.entries(props).filter(([key]) => !nonSerializedPlaceholderProps.includes(key)));
|
|
25
|
+
const finalProps = Object.assign(Object.assign({}, (yield fetchFEaaSComponentServerProps(params, isPageStateNormal))), serializableProps);
|
|
26
|
+
return React.createElement(FEaaSWrapper, Object.assign({}, finalProps));
|
|
27
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import * as FEAAS from '@sitecore-feaas/clientside/react';
|
|
4
|
+
import { getDataFromFields } from '../../utils';
|
|
5
|
+
// FEaaSComponent remains for backward compatibility and testing purposes
|
|
6
|
+
/**
|
|
7
|
+
* @param {FEaaSComponentProps} props component props
|
|
8
|
+
*/
|
|
9
|
+
export const FEaaSComponent = (props) => {
|
|
10
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
11
|
+
const computedRevision = ((_a = props.params) === null || _a === void 0 ? void 0 : _a.ComponentRevision) || props.revisionFallback;
|
|
12
|
+
if (!props.template &&
|
|
13
|
+
(!props.params ||
|
|
14
|
+
!props.params.LibraryId ||
|
|
15
|
+
!props.params.ComponentId ||
|
|
16
|
+
!props.params.ComponentVersion ||
|
|
17
|
+
!props.params.ComponentHostName ||
|
|
18
|
+
!computedRevision)) {
|
|
19
|
+
// Missing FEaaS component required props
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
// combine fetchedData from server with datasource data (if present)
|
|
23
|
+
const data = Object.assign(Object.assign({}, props.fetchedData), { _: getDataFromFields((_b = props.fields) !== null && _b !== void 0 ? _b : {}) });
|
|
24
|
+
// FEaaS control would still be hydrated by client
|
|
25
|
+
// we pass all the props as a workaround to avoid hydration error, until we convert all Content SDK components to server side
|
|
26
|
+
// this also allows component to fall back to full client-side rendering when template or src is empty
|
|
27
|
+
// FEAAS should not fetch anything, since Content SDK does the fetching - so we pass empty array into fetch param
|
|
28
|
+
return (React.createElement(FEAAS.Component, { data: data, template: props.template, cdn: (_c = props.params) === null || _c === void 0 ? void 0 : _c.ComponentHostName, library: (_d = props.params) === null || _d === void 0 ? void 0 : _d.LibraryId, version: (_e = props.params) === null || _e === void 0 ? void 0 : _e.ComponentVersion, component: (_f = props.params) === null || _f === void 0 ? void 0 : _f.ComponentId, instance: (_g = props.params) === null || _g === void 0 ? void 0 : _g.ComponentInstanceId, revision: computedRevision, fetch: [] }));
|
|
29
|
+
};
|
|
30
|
+
export const FEaaSWrapper = (props) => {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
const styles = `component feaas ${(_a = props.params) === null || _a === void 0 ? void 0 : _a.styles}`.trimEnd();
|
|
33
|
+
const id = (_b = props.params) === null || _b === void 0 ? void 0 : _b.RenderingIdentifier;
|
|
34
|
+
return (React.createElement("div", { className: styles, id: id ? id : undefined },
|
|
35
|
+
React.createElement("div", { className: "component-content" },
|
|
36
|
+
React.createElement(FEaaSComponent, Object.assign({}, props)))));
|
|
37
|
+
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
'use client';
|
|
2
1
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
2
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
3
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -8,45 +7,32 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
8
|
});
|
|
10
9
|
};
|
|
11
|
-
import React from 'react';
|
|
12
10
|
import * as FEAAS from '@sitecore-feaas/clientside/react';
|
|
13
|
-
import { LayoutServicePageState } from '@sitecore-content-sdk/core/layout';
|
|
14
|
-
import { getDataFromFields } from '../utils';
|
|
15
|
-
export const FEAAS_COMPONENT_RENDERING_NAME = 'FEaaSComponent';
|
|
16
11
|
/**
|
|
17
|
-
*
|
|
12
|
+
* Fetches server component props required for server rendering, based on rendering params.
|
|
13
|
+
* @param {BYOCComponentParams} params component params
|
|
18
14
|
*/
|
|
19
|
-
export
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
// combine fetchedData from server with datasource data (if present)
|
|
33
|
-
const data = Object.assign(Object.assign({}, props.fetchedData), { _: getDataFromFields((_b = props.fields) !== null && _b !== void 0 ? _b : {}) });
|
|
34
|
-
// FEaaS control would still be hydrated by client
|
|
35
|
-
// we pass all the props as a workaround to avoid hydration error, until we convert all Content SDK components to server side
|
|
36
|
-
// this also allows component to fall back to full client-side rendering when template or src is empty
|
|
37
|
-
// FEAAS should not fetch anything, since Content SDK does the fetching - so we pass empty array into fetch param
|
|
38
|
-
return (React.createElement(FEAAS.Component, { data: data, template: props.template, cdn: (_c = props.params) === null || _c === void 0 ? void 0 : _c.ComponentHostName, library: (_d = props.params) === null || _d === void 0 ? void 0 : _d.LibraryId, version: (_e = props.params) === null || _e === void 0 ? void 0 : _e.ComponentVersion, component: (_f = props.params) === null || _f === void 0 ? void 0 : _f.ComponentId, instance: (_g = props.params) === null || _g === void 0 ? void 0 : _g.ComponentInstanceId, revision: computedRevision, fetch: [] }));
|
|
39
|
-
};
|
|
15
|
+
export function fetchBYOCComponentServerProps(params) {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
const fetchDataOptions = params.ComponentDataOverride
|
|
18
|
+
? JSON.parse(params.ComponentDataOverride)
|
|
19
|
+
: {};
|
|
20
|
+
const fetchedData = yield FEAAS.DataSettings.fetch(fetchDataOptions || {});
|
|
21
|
+
return {
|
|
22
|
+
fetchedData,
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
}
|
|
40
26
|
/**
|
|
41
27
|
* Fetches server component props required for server rendering, based on rendering params.
|
|
42
28
|
* Component endpoint will either be retrieved from params or from endpointOverride
|
|
43
29
|
* @param {FEaaSComponentParams} params component params
|
|
44
|
-
* @param {
|
|
30
|
+
* @param {boolean} [isPageStateNormal] whether page is in normal mode
|
|
45
31
|
* @param {string} [endpointOverride] optional override for component endpoint
|
|
46
32
|
*/
|
|
47
|
-
export function fetchFEaaSComponentServerProps(params,
|
|
33
|
+
export function fetchFEaaSComponentServerProps(params, isPageStateNormal, endpointOverride) {
|
|
48
34
|
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
-
const revisionFallback =
|
|
35
|
+
const revisionFallback = isPageStateNormal ? 'published' : 'staged';
|
|
50
36
|
const src = endpointOverride || composeComponentEndpoint(params, revisionFallback);
|
|
51
37
|
let template = '';
|
|
52
38
|
let fetchedData = {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { FEaaSWrapper, FEaaSComponent } from './FEaaSWrapper';
|
|
2
|
+
export { BYOCWrapper, BYOCComponent } from './BYOCWrapper';
|
|
3
|
+
export { FEAAS_COMPONENT_RENDERING_NAME, BYOC_COMPONENT_RENDERING_NAME, FEAAS_WRAPPER_RENDERING_NAME, BYOC_WRAPPER_RENDERING_NAME, } from './models';
|
|
4
|
+
export { FEaaSServerWrapper } from './FEaaSSeverWrapper';
|
|
5
|
+
export { BYOCServerWrapper } from './BYOCServerWrapper';
|
|
6
|
+
export { fetchFEaaSComponentServerProps, fetchBYOCComponentServerProps } from './feaas-utils';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
3
|
var t = {};
|
|
3
4
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -9,7 +10,6 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
10
|
}
|
|
10
11
|
return t;
|
|
11
12
|
};
|
|
12
|
-
/* eslint-disable no-unused-expressions, @typescript-eslint/no-unused-expressions */
|
|
13
13
|
import React, { forwardRef } from 'react';
|
|
14
14
|
import { isFieldValueEmpty } from '@sitecore-content-sdk/core/layout';
|
|
15
15
|
import { withFieldMetadata } from '../enhancers/withFieldMetadata';
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { getAppComponentProps, getComponentForRendering, getPlaceholderRenderings, renderEmptyPlaceholder, } from './placeholder-utils';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { PlaceholderMetadata } from './PlaceholderMetadata';
|
|
4
|
+
import ErrorBoundary from '../ErrorBoundary';
|
|
5
|
+
import { ClientComponentWrapper } from './ClientComponentWrapper';
|
|
6
|
+
import { rsc } from '#rsc-env';
|
|
7
|
+
/**
|
|
8
|
+
* The implemention of placeholder compatible with React Server Components.
|
|
9
|
+
* Renders components from the layout data for the given placeholder name, with consideration for page edit mode.
|
|
10
|
+
* Pulls components from the provided component map.
|
|
11
|
+
* @param {AppPlaceholderProps} props Placeholder props
|
|
12
|
+
* @returns {React.ReactNode | React.ReactElement[]} rendered component(s)
|
|
13
|
+
*/
|
|
14
|
+
export const AppPlaceholder = (props) => {
|
|
15
|
+
const { rendering: parentRendering, componentMap, page } = props;
|
|
16
|
+
const placeholderRenderings = getPlaceholderRenderings(parentRendering, props.name, page.mode.isEditing);
|
|
17
|
+
const components = placeholderRenderings
|
|
18
|
+
.map((rendering, index) => {
|
|
19
|
+
const { component: Component, isEmpty, componentType, dynamic, } = getComponentForRendering(rendering, props.name, componentMap, props.hiddenRenderingComponent, props.missingComponentComponent);
|
|
20
|
+
const isClient = componentType === 'client';
|
|
21
|
+
const key = rendering.uid || `component-${index}`;
|
|
22
|
+
const renderedProps = getAppComponentProps(props, rendering);
|
|
23
|
+
const finalRenderedProps = props.modifyComponentProps
|
|
24
|
+
? props.modifyComponentProps(renderedProps)
|
|
25
|
+
: renderedProps;
|
|
26
|
+
// Client wrapper is required only when component crosses boundary from server to client.
|
|
27
|
+
// It happens when component is marker as client and rendered in RSC context.
|
|
28
|
+
// Also, it is not required when component is hidden or empty, as it will be rendered whthout boundary crossing.
|
|
29
|
+
const useClientWrapper = isClient && rsc && !isEmpty;
|
|
30
|
+
let rendered = useClientWrapper ? (React.createElement(ClientComponentWrapper, { rendering: rendering, componentProps: finalRenderedProps, placeholderName: props.name, key: key })) : (React.createElement(Component, Object.assign({ key: key }, finalRenderedProps, { rendering: rendering, page: page, componentMap: componentMap })));
|
|
31
|
+
if (!isEmpty) {
|
|
32
|
+
const errorBoundaryKey = rendered.type + '-' + index;
|
|
33
|
+
const disableSuspense = props.disableSuspense || false;
|
|
34
|
+
rendered = (React.createElement(ErrorBoundary, { "data-testid": "error-boundary", key: errorBoundaryKey, errorComponent: props.errorComponent, componentLoadingMessage: props.componentLoadingMessage, isDynamic: dynamic, disableSuspense: disableSuspense, rendering: rendered.props.rendering }, rendered));
|
|
35
|
+
}
|
|
36
|
+
// if in edit mode then emit shallow chromes for hydration in Pages
|
|
37
|
+
if (page.mode.isEditing) {
|
|
38
|
+
const key = rendering.uid || `component-${index}`;
|
|
39
|
+
return (React.createElement(PlaceholderMetadata, { key: key, rendering: rendering }, rendered));
|
|
40
|
+
}
|
|
41
|
+
return rendered;
|
|
42
|
+
})
|
|
43
|
+
.filter((element) => element);
|
|
44
|
+
const finalRendering = page.mode.isEditing
|
|
45
|
+
? [
|
|
46
|
+
React.createElement(PlaceholderMetadata, { key: parentRendering.uid, placeholderName: props.name, rendering: parentRendering }, components),
|
|
47
|
+
]
|
|
48
|
+
: components;
|
|
49
|
+
const placeholderEmpty = !placeholderRenderings.length;
|
|
50
|
+
if (placeholderEmpty) {
|
|
51
|
+
const rendered = props.renderEmpty ? props.renderEmpty(finalRendering) : finalRendering;
|
|
52
|
+
return page.mode.isEditing ? renderEmptyPlaceholder(rendered) : rendered;
|
|
53
|
+
}
|
|
54
|
+
if (props.render) {
|
|
55
|
+
return props.render(components, placeholderRenderings, props);
|
|
56
|
+
}
|
|
57
|
+
else if (props.renderEach) {
|
|
58
|
+
const renderEach = props.renderEach;
|
|
59
|
+
return finalRendering.map((component, index) => {
|
|
60
|
+
if (component && component.props && component.props.type === 'text/sitecore') {
|
|
61
|
+
return component;
|
|
62
|
+
}
|
|
63
|
+
return renderEach(component, index);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return finalRendering;
|
|
68
|
+
}
|
|
69
|
+
};
|