@sitecore-content-sdk/react 1.2.0-canary.16 → 1.2.0-canary.17
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.
|
@@ -43,7 +43,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
43
43
|
});
|
|
44
44
|
};
|
|
45
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
-
exports.DesignLibrary = exports.
|
|
46
|
+
exports.DesignLibrary = exports.__mockDependencies = void 0;
|
|
47
47
|
/* eslint-disable jsdoc/require-param */
|
|
48
48
|
/* eslint-disable prefer-const */
|
|
49
49
|
const react_1 = __importStar(require("react"));
|
|
@@ -57,50 +57,25 @@ const __mockDependencies = (mocks) => {
|
|
|
57
57
|
addComponentPreviewHandler = mocks.addComponentPreviewHandler;
|
|
58
58
|
};
|
|
59
59
|
exports.__mockDependencies = __mockDependencies;
|
|
60
|
-
/**
|
|
61
|
-
* This component is used to render the component in preview mode.
|
|
62
|
-
* It is used to send the rendered event to the parent window and render the component.
|
|
63
|
-
* Reacts on the update event from the parent window and re-renders the component.
|
|
64
|
-
*/
|
|
65
|
-
const Preview = () => {
|
|
66
|
-
const { page } = (0, withSitecore_1.useSitecore)();
|
|
67
|
-
const { layout: { sitecore: { route }, }, } = page;
|
|
68
|
-
const [renderKey, setRenderKey] = (0, react_1.useState)(0);
|
|
69
|
-
const [rootUpdate, setRootUpdate] = (0, react_1.useState)(null);
|
|
70
|
-
const rootComponent = route === null || route === void 0 ? void 0 : route.placeholders[layout_1.EDITING_COMPONENT_PLACEHOLDER][0];
|
|
71
|
-
// useEffect may execute multiple times on single render (i.e. in dev) - but we only want to fire ready event once
|
|
72
|
-
let componentReady = false;
|
|
73
|
-
// have an up-to-date layout state between re-renders (SSR re-render excluded)
|
|
74
|
-
const persistedRoot = (0, react_1.useMemo)(() => (Object.assign(Object.assign({}, (rootComponent || {})), rootUpdate)), [rootComponent, rootUpdate]);
|
|
75
|
-
route.placeholders[layout_1.EDITING_COMPONENT_PLACEHOLDER][0] = persistedRoot;
|
|
76
|
-
(0, react_1.useEffect)(() => {
|
|
77
|
-
// useEffect will fire when components are ready - and we inform the whole wide world of it too
|
|
78
|
-
if (!componentReady) {
|
|
79
|
-
componentReady = true;
|
|
80
|
-
window.top.postMessage((0, editing_1.getDesignLibraryStatusEvent)(editing_1.DesignLibraryStatus.READY, rootComponent.uid), '*');
|
|
81
|
-
}
|
|
82
|
-
const unsubscribe = (0, editing_1.addComponentUpdateHandler)(persistedRoot, (updatedRoot) => {
|
|
83
|
-
setRootUpdate(Object.assign({}, updatedRoot));
|
|
84
|
-
setRenderKey((key) => key + 1);
|
|
85
|
-
});
|
|
86
|
-
// useEffect will cleanup event handler on re-render
|
|
87
|
-
return unsubscribe;
|
|
88
|
-
}, []);
|
|
89
|
-
(0, react_1.useEffect)(() => {
|
|
90
|
-
// Send a rendered event only as effect of a component update command
|
|
91
|
-
if (renderKey === 0) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
window.top.postMessage((0, editing_1.getDesignLibraryStatusEvent)(editing_1.DesignLibraryStatus.RENDERED, rootComponent.uid), '*');
|
|
95
|
-
}, [renderKey, rootComponent.uid]);
|
|
96
|
-
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
97
|
-
react_1.default.createElement("main", null,
|
|
98
|
-
react_1.default.createElement("div", { id: layout_1.EDITING_COMPONENT_ID }, route && (react_1.default.createElement(Placeholder_1.Placeholder, { name: layout_1.EDITING_COMPONENT_PLACEHOLDER, rendering: route, key: renderKey }))))));
|
|
99
|
-
};
|
|
100
60
|
const sendErrorEvent = (uid, error, type) => {
|
|
101
61
|
const errorEvent = codegen.getDesignLibraryComponentPreviewErrorEvent(uid, error, type);
|
|
102
62
|
console.error('Component Library: sending error event', errorEvent);
|
|
103
|
-
|
|
63
|
+
if (typeof window !== 'undefined') {
|
|
64
|
+
const target = window.parent && window.parent !== window ? window.parent : window;
|
|
65
|
+
target.postMessage(errorEvent, '*');
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const postToDL = (evt) => {
|
|
69
|
+
if (typeof window === 'undefined')
|
|
70
|
+
return;
|
|
71
|
+
const target = window.parent && window.parent !== window ? window.parent : window;
|
|
72
|
+
try {
|
|
73
|
+
console.log('Component Library: sending event', evt === null || evt === void 0 ? void 0 : evt.name, evt);
|
|
74
|
+
target.postMessage(evt, '*');
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
console.error('Component Library: postMessage failed', err, evt);
|
|
78
|
+
}
|
|
104
79
|
};
|
|
105
80
|
class ErrorBoundary extends react_1.default.Component {
|
|
106
81
|
constructor() {
|
|
@@ -128,36 +103,74 @@ class ErrorBoundary extends react_1.default.Component {
|
|
|
128
103
|
}
|
|
129
104
|
}
|
|
130
105
|
/**
|
|
131
|
-
*
|
|
132
|
-
*
|
|
106
|
+
* Design Library component.
|
|
107
|
+
*
|
|
108
|
+
* Renders the **real** Sitecore component for `library` / `library-metadata` modes and,
|
|
109
|
+
* when generation is enabled (`page.mode.designLibrary.isVariantGeneration === true`),
|
|
110
|
+
* wires the **variant generation** handshake so the parent (DL Studio) can send
|
|
111
|
+
* generated code to preview and iterate on.
|
|
112
|
+
* @param {DesignLibraryProps} props
|
|
113
|
+
* @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.
|
|
114
|
+
* @returns {JSX.Element} The preview surface, or `null` when not in Design Library mode.
|
|
133
115
|
*/
|
|
134
|
-
const
|
|
116
|
+
const DesignLibrary = ({ loadImportMap }) => {
|
|
117
|
+
var _a, _b;
|
|
135
118
|
const { page } = (0, withSitecore_1.useSitecore)();
|
|
136
|
-
const
|
|
137
|
-
const rendering = route === null || route === void 0 ? void 0 : route.placeholders[layout_1.EDITING_COMPONENT_PLACEHOLDER][0];
|
|
119
|
+
const route = page.layout.sitecore.route;
|
|
120
|
+
const rendering = (_a = route === null || route === void 0 ? void 0 : route.placeholders[layout_1.EDITING_COMPONENT_PLACEHOLDER]) === null || _a === void 0 ? void 0 : _a[0];
|
|
121
|
+
const { isDesignLibrary } = page.mode;
|
|
122
|
+
const isVariantGeneration = (_b = page.mode.designLibrary) === null || _b === void 0 ? void 0 : _b.isVariantGeneration;
|
|
123
|
+
const [propsState, setPropsState] = (0, react_1.useState)({
|
|
124
|
+
fields: rendering === null || rendering === void 0 ? void 0 : rendering.fields,
|
|
125
|
+
params: rendering === null || rendering === void 0 ? void 0 : rendering.params,
|
|
126
|
+
});
|
|
138
127
|
const [renderKey, setRenderKey] = (0, react_1.useState)(0);
|
|
139
128
|
const [Component, setComponent] = (0, react_1.useState)(null);
|
|
129
|
+
const isGeneratedComponentActive = !!Component;
|
|
130
|
+
if (!isDesignLibrary)
|
|
131
|
+
return null;
|
|
140
132
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
141
133
|
(0, react_1.useEffect)(() => {
|
|
134
|
+
postToDL((0, editing_1.getDesignLibraryStatusEvent)(editing_1.DesignLibraryStatus.READY, rendering.uid));
|
|
135
|
+
if (!isVariantGeneration) {
|
|
136
|
+
requestAnimationFrame(() => {
|
|
137
|
+
setRenderKey((k) => (k === 0 ? k + 1 : k));
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
const unsubUpdate = (0, editing_1.addComponentUpdateHandler)(rendering, (updated) => {
|
|
141
|
+
setPropsState({ fields: updated.fields, params: updated.params });
|
|
142
|
+
setRenderKey((k) => k + 1);
|
|
143
|
+
});
|
|
144
|
+
// useEffect will cleanup event handler on re-render
|
|
145
|
+
return () => unsubUpdate && unsubUpdate();
|
|
146
|
+
}, [isVariantGeneration, rendering]);
|
|
147
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
148
|
+
(0, react_1.useEffect)(() => {
|
|
149
|
+
// Send a rendered event only as effect of a component update command
|
|
150
|
+
if (renderKey === 0)
|
|
151
|
+
return;
|
|
152
|
+
postToDL((0, editing_1.getDesignLibraryStatusEvent)(editing_1.DesignLibraryStatus.RENDERED, rendering.uid));
|
|
153
|
+
}, [renderKey, rendering]);
|
|
154
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
155
|
+
(0, react_1.useEffect)(() => {
|
|
156
|
+
if (!isDesignLibrary || !isVariantGeneration)
|
|
157
|
+
return undefined;
|
|
142
158
|
let cancelled = false;
|
|
143
159
|
// since import map is loaded lazily, we only need to add preview event handler once the import map is loaded
|
|
144
160
|
// unsubscribe function for useEffect cleanup will also be returned once importMap promise has been resolved or rejected
|
|
145
|
-
let unsubscribe
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (!props.loadImportMap) {
|
|
150
|
-
const errorMessage = 'No loadImportMap prop provided. Please provide a dynamic import map function for DesignLibrary.';
|
|
151
|
-
sendErrorEvent(rendering.uid, errorMessage, codegen.DesignLibraryPreviewError.RenderInit);
|
|
161
|
+
let unsubscribe;
|
|
162
|
+
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
163
|
+
if (!loadImportMap) {
|
|
164
|
+
sendErrorEvent(rendering.uid, 'No loadImportMap provided', codegen.DesignLibraryPreviewError.RenderInit);
|
|
152
165
|
return;
|
|
153
166
|
}
|
|
167
|
+
let importMap;
|
|
154
168
|
try {
|
|
155
|
-
const
|
|
156
|
-
importMap =
|
|
169
|
+
const mod = yield loadImportMap();
|
|
170
|
+
importMap = mod.default;
|
|
157
171
|
}
|
|
158
|
-
catch (
|
|
159
|
-
|
|
160
|
-
sendErrorEvent(rendering.uid, errorMessage, codegen.DesignLibraryPreviewError.RenderInit);
|
|
172
|
+
catch (e) {
|
|
173
|
+
sendErrorEvent(rendering.uid, `Error loading import map: ${e}`, codegen.DesignLibraryPreviewError.RenderInit);
|
|
161
174
|
return;
|
|
162
175
|
}
|
|
163
176
|
// account for component being unmounted while resolving async import map
|
|
@@ -165,56 +178,23 @@ const VariantGeneration = (props) => {
|
|
|
165
178
|
return;
|
|
166
179
|
unsubscribe = addComponentPreviewHandler(importMap, (error, Component) => {
|
|
167
180
|
// Error event is already sent in the addComponentPreviewHandler
|
|
168
|
-
if (error)
|
|
181
|
+
if (error)
|
|
169
182
|
return;
|
|
170
|
-
}
|
|
171
|
-
setRenderKey((key) => key + 1);
|
|
172
183
|
setComponent(() => Component);
|
|
184
|
+
setRenderKey((k) => k + 1);
|
|
173
185
|
});
|
|
174
186
|
const importMapEvent = getDesignLibraryImportMapEvent(rendering.uid, importMap);
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const readyEvent = (0, editing_1.getDesignLibraryStatusEvent)(editing_1.DesignLibraryStatus.READY, rendering.uid);
|
|
181
|
-
console.debug('Component Library: sending event', readyEvent);
|
|
182
|
-
(_a = window.top) === null || _a === void 0 ? void 0 : _a.postMessage(readyEvent, '*');
|
|
183
|
-
});
|
|
184
|
-
init();
|
|
185
|
-
// return function that calls unsubsubribe - if the component was mounted correctly
|
|
187
|
+
postToDL(importMapEvent);
|
|
188
|
+
const propsEvent = getDesignLibraryComponentPropsEvent(rendering.uid, propsState.fields, propsState.params);
|
|
189
|
+
postToDL(propsEvent);
|
|
190
|
+
}))();
|
|
191
|
+
// return function that calls unsubscribe - if the component was mounted correctly
|
|
186
192
|
return () => {
|
|
187
193
|
cancelled = true;
|
|
188
|
-
|
|
189
|
-
unsubscribe();
|
|
190
|
-
}
|
|
194
|
+
unsubscribe && unsubscribe();
|
|
191
195
|
};
|
|
192
|
-
}, []);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
var _a;
|
|
196
|
-
// Send a rendered event only as effect of a component update command
|
|
197
|
-
if (renderKey === 0)
|
|
198
|
-
return undefined;
|
|
199
|
-
const renderedEvent = (0, editing_1.getDesignLibraryStatusEvent)(editing_1.DesignLibraryStatus.RENDERED, rendering.uid);
|
|
200
|
-
console.debug('Component Library: sending event', renderedEvent);
|
|
201
|
-
(_a = window.top) === null || _a === void 0 ? void 0 : _a.postMessage(renderedEvent, '*');
|
|
202
|
-
}, [renderKey, rendering === null || rendering === void 0 ? void 0 : rendering.uid]);
|
|
203
|
-
return (react_1.default.createElement("main", null, Component ? (react_1.default.createElement(ErrorBoundary, { uid: rendering.uid, renderKey: renderKey },
|
|
204
|
-
react_1.default.createElement(Component, { fields: rendering.fields, params: rendering.params, key: renderKey }))) : (react_1.default.createElement("div", null, "Loading preview..."))));
|
|
205
|
-
};
|
|
206
|
-
exports.VariantGeneration = VariantGeneration;
|
|
207
|
-
const DesignLibrary = ({ loadImportMap }) => {
|
|
208
|
-
var _a;
|
|
209
|
-
const { page } = (0, withSitecore_1.useSitecore)();
|
|
210
|
-
const { isDesignLibrary } = page.mode;
|
|
211
|
-
const isVariantGeneration = (_a = page.mode.designLibrary) === null || _a === void 0 ? void 0 : _a.isVariantGeneration;
|
|
212
|
-
if (!isDesignLibrary) {
|
|
213
|
-
return null;
|
|
214
|
-
}
|
|
215
|
-
if (isVariantGeneration) {
|
|
216
|
-
return react_1.default.createElement(exports.VariantGeneration, { loadImportMap: loadImportMap });
|
|
217
|
-
}
|
|
218
|
-
return react_1.default.createElement(Preview, null);
|
|
196
|
+
}, [isVariantGeneration, rendering]);
|
|
197
|
+
return (react_1.default.createElement("main", null, isGeneratedComponentActive ? (react_1.default.createElement(ErrorBoundary, { uid: rendering.uid, renderKey: renderKey },
|
|
198
|
+
react_1.default.createElement(Component, { fields: propsState.fields, params: propsState.params, key: renderKey }))) : (react_1.default.createElement("div", { id: layout_1.EDITING_COMPONENT_ID }, route && (react_1.default.createElement(Placeholder_1.Placeholder, { name: layout_1.EDITING_COMPONENT_PLACEHOLDER, rendering: route, key: renderKey }))))));
|
|
219
199
|
};
|
|
220
200
|
exports.DesignLibrary = DesignLibrary;
|
|
@@ -10,7 +10,7 @@ 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';
|
|
@@ -20,50 +20,25 @@ let { getDesignLibraryImportMapEvent, getDesignLibraryComponentPropsEvent, addCo
|
|
|
20
20
|
export const __mockDependencies = (mocks) => {
|
|
21
21
|
addComponentPreviewHandler = mocks.addComponentPreviewHandler;
|
|
22
22
|
};
|
|
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
23
|
const sendErrorEvent = (uid, error, type) => {
|
|
64
24
|
const errorEvent = codegen.getDesignLibraryComponentPreviewErrorEvent(uid, error, type);
|
|
65
25
|
console.error('Component Library: sending error event', errorEvent);
|
|
66
|
-
|
|
26
|
+
if (typeof window !== 'undefined') {
|
|
27
|
+
const target = window.parent && window.parent !== window ? window.parent : window;
|
|
28
|
+
target.postMessage(errorEvent, '*');
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const postToDL = (evt) => {
|
|
32
|
+
if (typeof window === 'undefined')
|
|
33
|
+
return;
|
|
34
|
+
const target = window.parent && window.parent !== window ? window.parent : window;
|
|
35
|
+
try {
|
|
36
|
+
console.log('Component Library: sending event', evt === null || evt === void 0 ? void 0 : evt.name, evt);
|
|
37
|
+
target.postMessage(evt, '*');
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
console.error('Component Library: postMessage failed', err, evt);
|
|
41
|
+
}
|
|
67
42
|
};
|
|
68
43
|
class ErrorBoundary extends React.Component {
|
|
69
44
|
constructor() {
|
|
@@ -91,36 +66,74 @@ class ErrorBoundary extends React.Component {
|
|
|
91
66
|
}
|
|
92
67
|
}
|
|
93
68
|
/**
|
|
94
|
-
*
|
|
95
|
-
*
|
|
69
|
+
* Design Library component.
|
|
70
|
+
*
|
|
71
|
+
* Renders the **real** Sitecore component for `library` / `library-metadata` modes and,
|
|
72
|
+
* when generation is enabled (`page.mode.designLibrary.isVariantGeneration === true`),
|
|
73
|
+
* wires the **variant generation** handshake so the parent (DL Studio) can send
|
|
74
|
+
* generated code to preview and iterate on.
|
|
75
|
+
* @param {DesignLibraryProps} props
|
|
76
|
+
* @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.
|
|
77
|
+
* @returns {JSX.Element} The preview surface, or `null` when not in Design Library mode.
|
|
96
78
|
*/
|
|
97
|
-
export const
|
|
79
|
+
export const DesignLibrary = ({ loadImportMap }) => {
|
|
80
|
+
var _a, _b;
|
|
98
81
|
const { page } = useSitecore();
|
|
99
|
-
const
|
|
100
|
-
const rendering = route === null || route === void 0 ? void 0 : route.placeholders[EDITING_COMPONENT_PLACEHOLDER][0];
|
|
82
|
+
const route = page.layout.sitecore.route;
|
|
83
|
+
const rendering = (_a = route === null || route === void 0 ? void 0 : route.placeholders[EDITING_COMPONENT_PLACEHOLDER]) === null || _a === void 0 ? void 0 : _a[0];
|
|
84
|
+
const { isDesignLibrary } = page.mode;
|
|
85
|
+
const isVariantGeneration = (_b = page.mode.designLibrary) === null || _b === void 0 ? void 0 : _b.isVariantGeneration;
|
|
86
|
+
const [propsState, setPropsState] = useState({
|
|
87
|
+
fields: rendering === null || rendering === void 0 ? void 0 : rendering.fields,
|
|
88
|
+
params: rendering === null || rendering === void 0 ? void 0 : rendering.params,
|
|
89
|
+
});
|
|
101
90
|
const [renderKey, setRenderKey] = useState(0);
|
|
102
91
|
const [Component, setComponent] = useState(null);
|
|
92
|
+
const isGeneratedComponentActive = !!Component;
|
|
93
|
+
if (!isDesignLibrary)
|
|
94
|
+
return null;
|
|
103
95
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
104
96
|
useEffect(() => {
|
|
97
|
+
postToDL(getDesignLibraryStatusEvent(DesignLibraryStatus.READY, rendering.uid));
|
|
98
|
+
if (!isVariantGeneration) {
|
|
99
|
+
requestAnimationFrame(() => {
|
|
100
|
+
setRenderKey((k) => (k === 0 ? k + 1 : k));
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
const unsubUpdate = addComponentUpdateHandler(rendering, (updated) => {
|
|
104
|
+
setPropsState({ fields: updated.fields, params: updated.params });
|
|
105
|
+
setRenderKey((k) => k + 1);
|
|
106
|
+
});
|
|
107
|
+
// useEffect will cleanup event handler on re-render
|
|
108
|
+
return () => unsubUpdate && unsubUpdate();
|
|
109
|
+
}, [isVariantGeneration, rendering]);
|
|
110
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
// Send a rendered event only as effect of a component update command
|
|
113
|
+
if (renderKey === 0)
|
|
114
|
+
return;
|
|
115
|
+
postToDL(getDesignLibraryStatusEvent(DesignLibraryStatus.RENDERED, rendering.uid));
|
|
116
|
+
}, [renderKey, rendering]);
|
|
117
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
if (!isDesignLibrary || !isVariantGeneration)
|
|
120
|
+
return undefined;
|
|
105
121
|
let cancelled = false;
|
|
106
122
|
// since import map is loaded lazily, we only need to add preview event handler once the import map is loaded
|
|
107
123
|
// 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);
|
|
124
|
+
let unsubscribe;
|
|
125
|
+
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
126
|
+
if (!loadImportMap) {
|
|
127
|
+
sendErrorEvent(rendering.uid, 'No loadImportMap provided', codegen.DesignLibraryPreviewError.RenderInit);
|
|
115
128
|
return;
|
|
116
129
|
}
|
|
130
|
+
let importMap;
|
|
117
131
|
try {
|
|
118
|
-
const
|
|
119
|
-
importMap =
|
|
132
|
+
const mod = yield loadImportMap();
|
|
133
|
+
importMap = mod.default;
|
|
120
134
|
}
|
|
121
|
-
catch (
|
|
122
|
-
|
|
123
|
-
sendErrorEvent(rendering.uid, errorMessage, codegen.DesignLibraryPreviewError.RenderInit);
|
|
135
|
+
catch (e) {
|
|
136
|
+
sendErrorEvent(rendering.uid, `Error loading import map: ${e}`, codegen.DesignLibraryPreviewError.RenderInit);
|
|
124
137
|
return;
|
|
125
138
|
}
|
|
126
139
|
// account for component being unmounted while resolving async import map
|
|
@@ -128,54 +141,22 @@ export const VariantGeneration = (props) => {
|
|
|
128
141
|
return;
|
|
129
142
|
unsubscribe = addComponentPreviewHandler(importMap, (error, Component) => {
|
|
130
143
|
// Error event is already sent in the addComponentPreviewHandler
|
|
131
|
-
if (error)
|
|
144
|
+
if (error)
|
|
132
145
|
return;
|
|
133
|
-
}
|
|
134
|
-
setRenderKey((key) => key + 1);
|
|
135
146
|
setComponent(() => Component);
|
|
147
|
+
setRenderKey((k) => k + 1);
|
|
136
148
|
});
|
|
137
149
|
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
|
|
150
|
+
postToDL(importMapEvent);
|
|
151
|
+
const propsEvent = getDesignLibraryComponentPropsEvent(rendering.uid, propsState.fields, propsState.params);
|
|
152
|
+
postToDL(propsEvent);
|
|
153
|
+
}))();
|
|
154
|
+
// return function that calls unsubscribe - if the component was mounted correctly
|
|
149
155
|
return () => {
|
|
150
156
|
cancelled = true;
|
|
151
|
-
|
|
152
|
-
unsubscribe();
|
|
153
|
-
}
|
|
157
|
+
unsubscribe && unsubscribe();
|
|
154
158
|
};
|
|
155
|
-
}, []);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
var _a;
|
|
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);
|
|
159
|
+
}, [isVariantGeneration, rendering]);
|
|
160
|
+
return (React.createElement("main", null, isGeneratedComponentActive ? (React.createElement(ErrorBoundary, { uid: rendering.uid, renderKey: renderKey },
|
|
161
|
+
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
162
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sitecore-content-sdk/react",
|
|
3
|
-
"version": "1.2.0-canary.
|
|
3
|
+
"version": "1.2.0-canary.17",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -72,12 +72,12 @@
|
|
|
72
72
|
"react-dom": "^19.1.0"
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
|
-
"@sitecore-content-sdk/core": "1.2.0-canary.
|
|
75
|
+
"@sitecore-content-sdk/core": "1.2.0-canary.17",
|
|
76
76
|
"fast-deep-equal": "^3.1.3"
|
|
77
77
|
},
|
|
78
78
|
"description": "",
|
|
79
79
|
"types": "types/index.d.ts",
|
|
80
|
-
"gitHead": "
|
|
80
|
+
"gitHead": "925d2f902a4f4c6f1705e1349377850b80261bc4",
|
|
81
81
|
"files": [
|
|
82
82
|
"dist",
|
|
83
83
|
"types"
|
|
@@ -1,20 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import * as codegen from '@sitecore-content-sdk/core/codegen';
|
|
3
3
|
export declare const __mockDependencies: (mocks: any) => void;
|
|
4
4
|
export type ImportMapImport = {
|
|
5
5
|
default: codegen.ImportEntry[];
|
|
6
6
|
};
|
|
7
|
-
type VariantGenerationProps = {
|
|
8
|
-
/**
|
|
9
|
-
* The import map to be used in variant generation mode.
|
|
10
|
-
*/
|
|
11
|
-
loadImportMap?: () => Promise<ImportMapImport>;
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* This component is used to render the component in variant generation mode.
|
|
15
|
-
* It is used to send the import-map and component-props events to the parent window and render the dynamic component.
|
|
16
|
-
*/
|
|
17
|
-
export declare const VariantGeneration: (props: VariantGenerationProps) => JSX.Element;
|
|
18
7
|
type DesignLibraryProps = {
|
|
19
8
|
/**
|
|
20
9
|
* The dynamic import for import map to be used in variant generation mode.
|
|
@@ -22,5 +11,16 @@ type DesignLibraryProps = {
|
|
|
22
11
|
*/
|
|
23
12
|
loadImportMap?: () => Promise<ImportMapImport>;
|
|
24
13
|
};
|
|
25
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Design Library component.
|
|
16
|
+
*
|
|
17
|
+
* Renders the **real** Sitecore component for `library` / `library-metadata` modes and,
|
|
18
|
+
* when generation is enabled (`page.mode.designLibrary.isVariantGeneration === true`),
|
|
19
|
+
* wires the **variant generation** handshake so the parent (DL Studio) can send
|
|
20
|
+
* generated code to preview and iterate on.
|
|
21
|
+
* @param {DesignLibraryProps} props
|
|
22
|
+
* @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.
|
|
23
|
+
* @returns {JSX.Element} The preview surface, or `null` when not in Design Library mode.
|
|
24
|
+
*/
|
|
25
|
+
export declare const DesignLibrary: ({ loadImportMap }: DesignLibraryProps) => React.JSX.Element;
|
|
26
26
|
export {};
|