@sitecore-content-sdk/react 1.2.0-canary.2 → 1.2.0-canary.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/BYOCComponent.js +1 -0
- package/dist/cjs/components/BYOCWrapper.js +1 -0
- package/dist/cjs/components/DefaultEmptyFieldEditingComponents.js +4 -4
- package/dist/cjs/components/DesignLibrary.js +86 -103
- package/dist/cjs/components/FEaaSComponent.js +1 -0
- package/dist/cjs/components/FEaaSWrapper.js +1 -0
- package/dist/cjs/components/Form.js +1 -0
- package/dist/cjs/components/SitecoreProvider.js +1 -0
- package/dist/cjs/enhancers/withEmptyFieldEditingComponent.js +12 -5
- package/dist/cjs/enhancers/withSitecore.js +1 -0
- package/dist/esm/components/BYOCComponent.js +1 -0
- package/dist/esm/components/BYOCWrapper.js +1 -0
- package/dist/esm/components/DefaultEmptyFieldEditingComponents.js +4 -4
- package/dist/esm/components/DesignLibrary.js +86 -102
- package/dist/esm/components/FEaaSComponent.js +1 -0
- package/dist/esm/components/FEaaSWrapper.js +1 -0
- package/dist/esm/components/Form.js +1 -0
- package/dist/esm/components/SitecoreProvider.js +1 -0
- package/dist/esm/enhancers/withEmptyFieldEditingComponent.js +12 -5
- package/dist/esm/enhancers/withSitecore.js +1 -0
- package/package.json +3 -3
- 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/Image.d.ts +1 -1
- package/types/components/Link.d.ts +1 -1
- package/types/components/RichText.d.ts +1 -1
- package/types/components/Text.d.ts +1 -1
- package/types/components/sharedTypes/props.d.ts +2 -2
- package/types/enhancers/withEmptyFieldEditingComponent.d.ts +3 -3
|
@@ -5,11 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.DefaultEmptyFieldEditingComponentImage = exports.DefaultEmptyFieldEditingComponentText = void 0;
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
|
-
const DefaultEmptyFieldEditingComponentText = () => {
|
|
9
|
-
return react_1.default.createElement(
|
|
8
|
+
const DefaultEmptyFieldEditingComponentText = (props) => {
|
|
9
|
+
return react_1.default.createElement(props.tag || 'span', props, '[No text in field]');
|
|
10
10
|
};
|
|
11
11
|
exports.DefaultEmptyFieldEditingComponentText = DefaultEmptyFieldEditingComponentText;
|
|
12
|
-
const DefaultEmptyFieldEditingComponentImage = () => {
|
|
12
|
+
const DefaultEmptyFieldEditingComponentImage = (props) => {
|
|
13
13
|
const inlineStyles = {
|
|
14
14
|
minWidth: '48px',
|
|
15
15
|
minHeight: '48px',
|
|
@@ -17,6 +17,6 @@ const DefaultEmptyFieldEditingComponentImage = () => {
|
|
|
17
17
|
maxHeight: '400px',
|
|
18
18
|
cursor: 'pointer',
|
|
19
19
|
};
|
|
20
|
-
return (react_1.default.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:
|
|
20
|
+
return (react_1.default.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 })));
|
|
21
21
|
};
|
|
22
22
|
exports.DefaultEmptyFieldEditingComponentImage = DefaultEmptyFieldEditingComponentImage;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
'use client';
|
|
2
3
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
4
|
if (k2 === undefined) k2 = k;
|
|
4
5
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -42,7 +43,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
42
43
|
});
|
|
43
44
|
};
|
|
44
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
exports.DesignLibrary = exports.
|
|
46
|
+
exports.DesignLibrary = exports.__mockDependencies = void 0;
|
|
46
47
|
/* eslint-disable jsdoc/require-param */
|
|
47
48
|
/* eslint-disable prefer-const */
|
|
48
49
|
const react_1 = __importStar(require("react"));
|
|
@@ -51,55 +52,31 @@ const layout_1 = require("@sitecore-content-sdk/core/layout");
|
|
|
51
52
|
const editing_1 = require("@sitecore-content-sdk/core/editing");
|
|
52
53
|
const codegen = __importStar(require("@sitecore-content-sdk/core/codegen"));
|
|
53
54
|
const withSitecore_1 = require("../enhancers/withSitecore");
|
|
55
|
+
const PlaceholderMetadata_1 = require("./PlaceholderMetadata");
|
|
54
56
|
let { getDesignLibraryImportMapEvent, getDesignLibraryComponentPropsEvent, addComponentPreviewHandler, } = codegen;
|
|
55
57
|
const __mockDependencies = (mocks) => {
|
|
56
58
|
addComponentPreviewHandler = mocks.addComponentPreviewHandler;
|
|
57
59
|
};
|
|
58
60
|
exports.__mockDependencies = __mockDependencies;
|
|
59
|
-
/**
|
|
60
|
-
* This component is used to render the component in preview mode.
|
|
61
|
-
* It is used to send the rendered event to the parent window and render the component.
|
|
62
|
-
* Reacts on the update event from the parent window and re-renders the component.
|
|
63
|
-
*/
|
|
64
|
-
const Preview = () => {
|
|
65
|
-
const { page } = (0, withSitecore_1.useSitecore)();
|
|
66
|
-
const { layout: { sitecore: { route }, }, } = page;
|
|
67
|
-
const [renderKey, setRenderKey] = (0, react_1.useState)(0);
|
|
68
|
-
const [rootUpdate, setRootUpdate] = (0, react_1.useState)(null);
|
|
69
|
-
const rootComponent = route === null || route === void 0 ? void 0 : route.placeholders[layout_1.EDITING_COMPONENT_PLACEHOLDER][0];
|
|
70
|
-
// useEffect may execute multiple times on single render (i.e. in dev) - but we only want to fire ready event once
|
|
71
|
-
let componentReady = false;
|
|
72
|
-
// have an up-to-date layout state between re-renders (SSR re-render excluded)
|
|
73
|
-
const persistedRoot = (0, react_1.useMemo)(() => (Object.assign(Object.assign({}, (rootComponent || {})), rootUpdate)), [rootComponent, rootUpdate]);
|
|
74
|
-
route.placeholders[layout_1.EDITING_COMPONENT_PLACEHOLDER][0] = persistedRoot;
|
|
75
|
-
(0, react_1.useEffect)(() => {
|
|
76
|
-
// useEffect will fire when components are ready - and we inform the whole wide world of it too
|
|
77
|
-
if (!componentReady) {
|
|
78
|
-
componentReady = true;
|
|
79
|
-
window.top.postMessage((0, editing_1.getDesignLibraryStatusEvent)(editing_1.DesignLibraryStatus.READY, rootComponent.uid), '*');
|
|
80
|
-
}
|
|
81
|
-
const unsubscribe = (0, editing_1.addComponentUpdateHandler)(persistedRoot, (updatedRoot) => {
|
|
82
|
-
setRootUpdate(Object.assign({}, updatedRoot));
|
|
83
|
-
setRenderKey((key) => key + 1);
|
|
84
|
-
});
|
|
85
|
-
// useEffect will cleanup event handler on re-render
|
|
86
|
-
return unsubscribe;
|
|
87
|
-
}, []);
|
|
88
|
-
(0, react_1.useEffect)(() => {
|
|
89
|
-
// Send a rendered event only as effect of a component update command
|
|
90
|
-
if (renderKey === 0) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
window.top.postMessage((0, editing_1.getDesignLibraryStatusEvent)(editing_1.DesignLibraryStatus.RENDERED, rootComponent.uid), '*');
|
|
94
|
-
}, [renderKey, rootComponent.uid]);
|
|
95
|
-
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
96
|
-
react_1.default.createElement("main", null,
|
|
97
|
-
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 }))))));
|
|
98
|
-
};
|
|
99
61
|
const sendErrorEvent = (uid, error, type) => {
|
|
100
62
|
const errorEvent = codegen.getDesignLibraryComponentPreviewErrorEvent(uid, error, type);
|
|
101
63
|
console.error('Component Library: sending error event', errorEvent);
|
|
102
|
-
|
|
64
|
+
if (typeof window !== 'undefined') {
|
|
65
|
+
const target = window.parent && window.parent !== window ? window.parent : window;
|
|
66
|
+
target.postMessage(errorEvent, '*');
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const postToDL = (evt) => {
|
|
70
|
+
if (typeof window === 'undefined')
|
|
71
|
+
return;
|
|
72
|
+
const target = window.parent && window.parent !== window ? window.parent : window;
|
|
73
|
+
try {
|
|
74
|
+
console.log('Component Library: sending event', evt === null || evt === void 0 ? void 0 : evt.name, evt);
|
|
75
|
+
target.postMessage(evt, '*');
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
console.error('Component Library: postMessage failed', err, evt);
|
|
79
|
+
}
|
|
103
80
|
};
|
|
104
81
|
class ErrorBoundary extends react_1.default.Component {
|
|
105
82
|
constructor() {
|
|
@@ -127,36 +104,74 @@ class ErrorBoundary extends react_1.default.Component {
|
|
|
127
104
|
}
|
|
128
105
|
}
|
|
129
106
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
107
|
+
* Design Library component.
|
|
108
|
+
*
|
|
109
|
+
* Renders the **real** Sitecore component for `library` / `library-metadata` modes and,
|
|
110
|
+
* when generation is enabled (`page.mode.designLibrary.isVariantGeneration === true`),
|
|
111
|
+
* wires the **variant generation** handshake so the parent (DL Studio) can send
|
|
112
|
+
* generated code to preview and iterate on.
|
|
113
|
+
* @param {DesignLibraryProps} props
|
|
114
|
+
* @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.
|
|
115
|
+
* @returns {JSX.Element} The preview surface, or `null` when not in Design Library mode.
|
|
132
116
|
*/
|
|
133
|
-
const
|
|
117
|
+
const DesignLibrary = ({ loadImportMap }) => {
|
|
118
|
+
var _a, _b;
|
|
134
119
|
const { page } = (0, withSitecore_1.useSitecore)();
|
|
135
|
-
const
|
|
136
|
-
const rendering = route === null || route === void 0 ? void 0 : route.placeholders[layout_1.EDITING_COMPONENT_PLACEHOLDER][0];
|
|
120
|
+
const route = page.layout.sitecore.route;
|
|
121
|
+
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];
|
|
122
|
+
const { isDesignLibrary } = page.mode;
|
|
123
|
+
const isVariantGeneration = (_b = page.mode.designLibrary) === null || _b === void 0 ? void 0 : _b.isVariantGeneration;
|
|
124
|
+
const [propsState, setPropsState] = (0, react_1.useState)({
|
|
125
|
+
fields: rendering === null || rendering === void 0 ? void 0 : rendering.fields,
|
|
126
|
+
params: rendering === null || rendering === void 0 ? void 0 : rendering.params,
|
|
127
|
+
});
|
|
137
128
|
const [renderKey, setRenderKey] = (0, react_1.useState)(0);
|
|
138
129
|
const [Component, setComponent] = (0, react_1.useState)(null);
|
|
130
|
+
const isGeneratedComponentActive = !!Component;
|
|
131
|
+
if (!isDesignLibrary)
|
|
132
|
+
return null;
|
|
139
133
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
140
134
|
(0, react_1.useEffect)(() => {
|
|
135
|
+
postToDL((0, editing_1.getDesignLibraryStatusEvent)(editing_1.DesignLibraryStatus.READY, rendering.uid));
|
|
136
|
+
if (!isVariantGeneration) {
|
|
137
|
+
requestAnimationFrame(() => {
|
|
138
|
+
setRenderKey((k) => (k === 0 ? k + 1 : k));
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const unsubUpdate = (0, editing_1.addComponentUpdateHandler)(rendering, (updated) => {
|
|
142
|
+
setPropsState({ fields: updated.fields, params: updated.params });
|
|
143
|
+
setRenderKey((k) => k + 1);
|
|
144
|
+
});
|
|
145
|
+
// useEffect will cleanup event handler on re-render
|
|
146
|
+
return () => unsubUpdate && unsubUpdate();
|
|
147
|
+
}, [isVariantGeneration, rendering]);
|
|
148
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
149
|
+
(0, react_1.useEffect)(() => {
|
|
150
|
+
// Send a rendered event only as effect of a component update command
|
|
151
|
+
if (renderKey === 0)
|
|
152
|
+
return;
|
|
153
|
+
postToDL((0, editing_1.getDesignLibraryStatusEvent)(editing_1.DesignLibraryStatus.RENDERED, rendering.uid));
|
|
154
|
+
}, [renderKey, rendering]);
|
|
155
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
156
|
+
(0, react_1.useEffect)(() => {
|
|
157
|
+
if (!isDesignLibrary || !isVariantGeneration)
|
|
158
|
+
return undefined;
|
|
141
159
|
let cancelled = false;
|
|
142
160
|
// since import map is loaded lazily, we only need to add preview event handler once the import map is loaded
|
|
143
161
|
// unsubscribe function for useEffect cleanup will also be returned once importMap promise has been resolved or rejected
|
|
144
|
-
let unsubscribe
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (!props.loadImportMap) {
|
|
149
|
-
const errorMessage = 'No loadImportMap prop provided. Please provide a dynamic import map function for DesignLibrary.';
|
|
150
|
-
sendErrorEvent(rendering.uid, errorMessage, codegen.DesignLibraryPreviewError.RenderInit);
|
|
162
|
+
let unsubscribe;
|
|
163
|
+
(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
164
|
+
if (!loadImportMap) {
|
|
165
|
+
sendErrorEvent(rendering.uid, 'No loadImportMap provided', codegen.DesignLibraryPreviewError.RenderInit);
|
|
151
166
|
return;
|
|
152
167
|
}
|
|
168
|
+
let importMap;
|
|
153
169
|
try {
|
|
154
|
-
const
|
|
155
|
-
importMap =
|
|
170
|
+
const mod = yield loadImportMap();
|
|
171
|
+
importMap = mod.default;
|
|
156
172
|
}
|
|
157
|
-
catch (
|
|
158
|
-
|
|
159
|
-
sendErrorEvent(rendering.uid, errorMessage, codegen.DesignLibraryPreviewError.RenderInit);
|
|
173
|
+
catch (e) {
|
|
174
|
+
sendErrorEvent(rendering.uid, `Error loading import map: ${e}`, codegen.DesignLibraryPreviewError.RenderInit);
|
|
160
175
|
return;
|
|
161
176
|
}
|
|
162
177
|
// account for component being unmounted while resolving async import map
|
|
@@ -164,56 +179,24 @@ const VariantGeneration = (props) => {
|
|
|
164
179
|
return;
|
|
165
180
|
unsubscribe = addComponentPreviewHandler(importMap, (error, Component) => {
|
|
166
181
|
// Error event is already sent in the addComponentPreviewHandler
|
|
167
|
-
if (error)
|
|
182
|
+
if (error)
|
|
168
183
|
return;
|
|
169
|
-
}
|
|
170
|
-
setRenderKey((key) => key + 1);
|
|
171
184
|
setComponent(() => Component);
|
|
185
|
+
setRenderKey((k) => k + 1);
|
|
172
186
|
});
|
|
173
187
|
const importMapEvent = getDesignLibraryImportMapEvent(rendering.uid, importMap);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
const readyEvent = (0, editing_1.getDesignLibraryStatusEvent)(editing_1.DesignLibraryStatus.READY, rendering.uid);
|
|
180
|
-
console.debug('Component Library: sending event', readyEvent);
|
|
181
|
-
(_a = window.top) === null || _a === void 0 ? void 0 : _a.postMessage(readyEvent, '*');
|
|
182
|
-
});
|
|
183
|
-
init();
|
|
184
|
-
// return function that calls unsubsubribe - if the component was mounted correctly
|
|
188
|
+
postToDL(importMapEvent);
|
|
189
|
+
const propsEvent = getDesignLibraryComponentPropsEvent(rendering.uid, propsState.fields, propsState.params);
|
|
190
|
+
postToDL(propsEvent);
|
|
191
|
+
}))();
|
|
192
|
+
// return function that calls unsubscribe - if the component was mounted correctly
|
|
185
193
|
return () => {
|
|
186
194
|
cancelled = true;
|
|
187
|
-
|
|
188
|
-
unsubscribe();
|
|
189
|
-
}
|
|
195
|
+
unsubscribe && unsubscribe();
|
|
190
196
|
};
|
|
191
|
-
}, []);
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
// Send a rendered event only as effect of a component update command
|
|
196
|
-
if (renderKey === 0)
|
|
197
|
-
return undefined;
|
|
198
|
-
const renderedEvent = (0, editing_1.getDesignLibraryStatusEvent)(editing_1.DesignLibraryStatus.RENDERED, rendering.uid);
|
|
199
|
-
console.debug('Component Library: sending event', renderedEvent);
|
|
200
|
-
(_a = window.top) === null || _a === void 0 ? void 0 : _a.postMessage(renderedEvent, '*');
|
|
201
|
-
}, [renderKey, rendering === null || rendering === void 0 ? void 0 : rendering.uid]);
|
|
202
|
-
return (react_1.default.createElement("main", null, Component ? (react_1.default.createElement(ErrorBoundary, { uid: rendering.uid, renderKey: renderKey },
|
|
203
|
-
react_1.default.createElement(Component, { fields: rendering.fields, params: rendering.params, key: renderKey }))) : (react_1.default.createElement("div", null, "Loading preview..."))));
|
|
204
|
-
};
|
|
205
|
-
exports.VariantGeneration = VariantGeneration;
|
|
206
|
-
const DesignLibrary = ({ loadImportMap }) => {
|
|
207
|
-
var _a;
|
|
208
|
-
const { page } = (0, withSitecore_1.useSitecore)();
|
|
209
|
-
const { isDesignLibrary } = page.mode;
|
|
210
|
-
const isVariantGeneration = (_a = page.mode.designLibrary) === null || _a === void 0 ? void 0 : _a.isVariantGeneration;
|
|
211
|
-
if (!isDesignLibrary) {
|
|
212
|
-
return null;
|
|
213
|
-
}
|
|
214
|
-
if (isVariantGeneration) {
|
|
215
|
-
return react_1.default.createElement(exports.VariantGeneration, { loadImportMap: loadImportMap });
|
|
216
|
-
}
|
|
217
|
-
return react_1.default.createElement(Preview, null);
|
|
197
|
+
}, [isVariantGeneration, rendering]);
|
|
198
|
+
return (react_1.default.createElement("main", null, isGeneratedComponentActive ? (react_1.default.createElement(ErrorBoundary, { uid: rendering.uid, renderKey: renderKey },
|
|
199
|
+
react_1.default.createElement(PlaceholderMetadata_1.PlaceholderMetadata, { rendering: rendering },
|
|
200
|
+
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 }))))));
|
|
218
201
|
};
|
|
219
202
|
exports.DesignLibrary = DesignLibrary;
|
|
@@ -46,18 +46,25 @@ function withEmptyFieldEditingComponent(FieldComponent, options) {
|
|
|
46
46
|
var _a;
|
|
47
47
|
const { editable = true } = props;
|
|
48
48
|
if (((_a = props.field) === null || _a === void 0 ? void 0 : _a.metadata) && editable && (0, layout_1.isFieldValueEmpty)(props.field)) {
|
|
49
|
-
|
|
49
|
+
const Component = props.emptyFieldEditingComponent || options.defaultEmptyFieldEditingComponent;
|
|
50
|
+
let resolvedProps = props;
|
|
51
|
+
// If no custom empty field editing component is provided, we can omit unnecessary props
|
|
52
|
+
// to do not insert them to html
|
|
53
|
+
if (!props.emptyFieldEditingComponent) {
|
|
54
|
+
resolvedProps = Object.assign(Object.assign({}, props), { editable: undefined, field: undefined });
|
|
55
|
+
}
|
|
56
|
+
return react_1.default.createElement(Component, Object.assign({}, resolvedProps));
|
|
50
57
|
}
|
|
51
58
|
return null;
|
|
52
59
|
};
|
|
53
60
|
if (options.isForwardRef) {
|
|
54
61
|
return (0, react_1.forwardRef)((props, ref) => {
|
|
55
|
-
const
|
|
56
|
-
return (
|
|
62
|
+
const emptyFieldEditingComponent = getEmptyFieldEditingComponent(props);
|
|
63
|
+
return (emptyFieldEditingComponent || (react_1.default.createElement(FieldComponent, Object.assign({}, props, { ref: ref }))));
|
|
57
64
|
});
|
|
58
65
|
}
|
|
59
66
|
return (props) => {
|
|
60
|
-
const
|
|
61
|
-
return
|
|
67
|
+
const emptyFieldEditingComponent = getEmptyFieldEditingComponent(props);
|
|
68
|
+
return emptyFieldEditingComponent || react_1.default.createElement(FieldComponent, Object.assign({}, props));
|
|
62
69
|
};
|
|
63
70
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -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
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -9,60 +10,36 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
10
|
};
|
|
10
11
|
/* eslint-disable jsdoc/require-param */
|
|
11
12
|
/* eslint-disable prefer-const */
|
|
12
|
-
import React, { useEffect,
|
|
13
|
+
import React, { useEffect, useState } from 'react';
|
|
13
14
|
import { Placeholder } from './Placeholder';
|
|
14
15
|
import { EDITING_COMPONENT_ID, EDITING_COMPONENT_PLACEHOLDER, } from '@sitecore-content-sdk/core/layout';
|
|
15
16
|
import { DesignLibraryStatus, getDesignLibraryStatusEvent, addComponentUpdateHandler, } from '@sitecore-content-sdk/core/editing';
|
|
16
17
|
import * as codegen from '@sitecore-content-sdk/core/codegen';
|
|
17
18
|
import { useSitecore } from '../enhancers/withSitecore';
|
|
19
|
+
import { PlaceholderMetadata } from './PlaceholderMetadata';
|
|
18
20
|
let { getDesignLibraryImportMapEvent, getDesignLibraryComponentPropsEvent, addComponentPreviewHandler, } = codegen;
|
|
19
21
|
export const __mockDependencies = (mocks) => {
|
|
20
22
|
addComponentPreviewHandler = mocks.addComponentPreviewHandler;
|
|
21
23
|
};
|
|
22
|
-
/**
|
|
23
|
-
* This component is used to render the component in preview mode.
|
|
24
|
-
* It is used to send the rendered event to the parent window and render the component.
|
|
25
|
-
* Reacts on the update event from the parent window and re-renders the component.
|
|
26
|
-
*/
|
|
27
|
-
const Preview = () => {
|
|
28
|
-
const { page } = useSitecore();
|
|
29
|
-
const { layout: { sitecore: { route }, }, } = page;
|
|
30
|
-
const [renderKey, setRenderKey] = useState(0);
|
|
31
|
-
const [rootUpdate, setRootUpdate] = useState(null);
|
|
32
|
-
const rootComponent = route === null || route === void 0 ? void 0 : route.placeholders[EDITING_COMPONENT_PLACEHOLDER][0];
|
|
33
|
-
// useEffect may execute multiple times on single render (i.e. in dev) - but we only want to fire ready event once
|
|
34
|
-
let componentReady = false;
|
|
35
|
-
// have an up-to-date layout state between re-renders (SSR re-render excluded)
|
|
36
|
-
const persistedRoot = useMemo(() => (Object.assign(Object.assign({}, (rootComponent || {})), rootUpdate)), [rootComponent, rootUpdate]);
|
|
37
|
-
route.placeholders[EDITING_COMPONENT_PLACEHOLDER][0] = persistedRoot;
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
// useEffect will fire when components are ready - and we inform the whole wide world of it too
|
|
40
|
-
if (!componentReady) {
|
|
41
|
-
componentReady = true;
|
|
42
|
-
window.top.postMessage(getDesignLibraryStatusEvent(DesignLibraryStatus.READY, rootComponent.uid), '*');
|
|
43
|
-
}
|
|
44
|
-
const unsubscribe = addComponentUpdateHandler(persistedRoot, (updatedRoot) => {
|
|
45
|
-
setRootUpdate(Object.assign({}, updatedRoot));
|
|
46
|
-
setRenderKey((key) => key + 1);
|
|
47
|
-
});
|
|
48
|
-
// useEffect will cleanup event handler on re-render
|
|
49
|
-
return unsubscribe;
|
|
50
|
-
}, []);
|
|
51
|
-
useEffect(() => {
|
|
52
|
-
// Send a rendered event only as effect of a component update command
|
|
53
|
-
if (renderKey === 0) {
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
window.top.postMessage(getDesignLibraryStatusEvent(DesignLibraryStatus.RENDERED, rootComponent.uid), '*');
|
|
57
|
-
}, [renderKey, rootComponent.uid]);
|
|
58
|
-
return (React.createElement(React.Fragment, null,
|
|
59
|
-
React.createElement("main", null,
|
|
60
|
-
React.createElement("div", { id: EDITING_COMPONENT_ID }, route && (React.createElement(Placeholder, { name: EDITING_COMPONENT_PLACEHOLDER, rendering: route, key: renderKey }))))));
|
|
61
|
-
};
|
|
62
24
|
const sendErrorEvent = (uid, error, type) => {
|
|
63
25
|
const errorEvent = codegen.getDesignLibraryComponentPreviewErrorEvent(uid, error, type);
|
|
64
26
|
console.error('Component Library: sending error event', errorEvent);
|
|
65
|
-
|
|
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
|
+
}
|
|
66
43
|
};
|
|
67
44
|
class ErrorBoundary extends React.Component {
|
|
68
45
|
constructor() {
|
|
@@ -90,36 +67,74 @@ class ErrorBoundary extends React.Component {
|
|
|
90
67
|
}
|
|
91
68
|
}
|
|
92
69
|
/**
|
|
93
|
-
*
|
|
94
|
-
*
|
|
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.
|
|
95
79
|
*/
|
|
96
|
-
export const
|
|
80
|
+
export const DesignLibrary = ({ loadImportMap }) => {
|
|
81
|
+
var _a, _b;
|
|
97
82
|
const { page } = useSitecore();
|
|
98
|
-
const
|
|
99
|
-
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
|
+
});
|
|
100
91
|
const [renderKey, setRenderKey] = useState(0);
|
|
101
92
|
const [Component, setComponent] = useState(null);
|
|
93
|
+
const isGeneratedComponentActive = !!Component;
|
|
94
|
+
if (!isDesignLibrary)
|
|
95
|
+
return null;
|
|
102
96
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
103
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;
|
|
104
122
|
let cancelled = false;
|
|
105
123
|
// since import map is loaded lazily, we only need to add preview event handler once the import map is loaded
|
|
106
124
|
// unsubscribe function for useEffect cleanup will also be returned once importMap promise has been resolved or rejected
|
|
107
|
-
let unsubscribe
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (!props.loadImportMap) {
|
|
112
|
-
const errorMessage = 'No loadImportMap prop provided. Please provide a dynamic import map function for DesignLibrary.';
|
|
113
|
-
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);
|
|
114
129
|
return;
|
|
115
130
|
}
|
|
131
|
+
let importMap;
|
|
116
132
|
try {
|
|
117
|
-
const
|
|
118
|
-
importMap =
|
|
133
|
+
const mod = yield loadImportMap();
|
|
134
|
+
importMap = mod.default;
|
|
119
135
|
}
|
|
120
|
-
catch (
|
|
121
|
-
|
|
122
|
-
sendErrorEvent(rendering.uid, errorMessage, codegen.DesignLibraryPreviewError.RenderInit);
|
|
136
|
+
catch (e) {
|
|
137
|
+
sendErrorEvent(rendering.uid, `Error loading import map: ${e}`, codegen.DesignLibraryPreviewError.RenderInit);
|
|
123
138
|
return;
|
|
124
139
|
}
|
|
125
140
|
// account for component being unmounted while resolving async import map
|
|
@@ -127,54 +142,23 @@ export const VariantGeneration = (props) => {
|
|
|
127
142
|
return;
|
|
128
143
|
unsubscribe = addComponentPreviewHandler(importMap, (error, Component) => {
|
|
129
144
|
// Error event is already sent in the addComponentPreviewHandler
|
|
130
|
-
if (error)
|
|
145
|
+
if (error)
|
|
131
146
|
return;
|
|
132
|
-
}
|
|
133
|
-
setRenderKey((key) => key + 1);
|
|
134
147
|
setComponent(() => Component);
|
|
148
|
+
setRenderKey((k) => k + 1);
|
|
135
149
|
});
|
|
136
150
|
const importMapEvent = getDesignLibraryImportMapEvent(rendering.uid, importMap);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const readyEvent = getDesignLibraryStatusEvent(DesignLibraryStatus.READY, rendering.uid);
|
|
143
|
-
console.debug('Component Library: sending event', readyEvent);
|
|
144
|
-
(_a = window.top) === null || _a === void 0 ? void 0 : _a.postMessage(readyEvent, '*');
|
|
145
|
-
});
|
|
146
|
-
init();
|
|
147
|
-
// 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
|
|
148
156
|
return () => {
|
|
149
157
|
cancelled = true;
|
|
150
|
-
|
|
151
|
-
unsubscribe();
|
|
152
|
-
}
|
|
158
|
+
unsubscribe && unsubscribe();
|
|
153
159
|
};
|
|
154
|
-
}, []);
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
// Send a rendered event only as effect of a component update command
|
|
159
|
-
if (renderKey === 0)
|
|
160
|
-
return undefined;
|
|
161
|
-
const renderedEvent = getDesignLibraryStatusEvent(DesignLibraryStatus.RENDERED, rendering.uid);
|
|
162
|
-
console.debug('Component Library: sending event', renderedEvent);
|
|
163
|
-
(_a = window.top) === null || _a === void 0 ? void 0 : _a.postMessage(renderedEvent, '*');
|
|
164
|
-
}, [renderKey, rendering === null || rendering === void 0 ? void 0 : rendering.uid]);
|
|
165
|
-
return (React.createElement("main", null, Component ? (React.createElement(ErrorBoundary, { uid: rendering.uid, renderKey: renderKey },
|
|
166
|
-
React.createElement(Component, { fields: rendering.fields, params: rendering.params, key: renderKey }))) : (React.createElement("div", null, "Loading preview..."))));
|
|
167
|
-
};
|
|
168
|
-
export const DesignLibrary = ({ loadImportMap }) => {
|
|
169
|
-
var _a;
|
|
170
|
-
const { page } = useSitecore();
|
|
171
|
-
const { isDesignLibrary } = page.mode;
|
|
172
|
-
const isVariantGeneration = (_a = page.mode.designLibrary) === null || _a === void 0 ? void 0 : _a.isVariantGeneration;
|
|
173
|
-
if (!isDesignLibrary) {
|
|
174
|
-
return null;
|
|
175
|
-
}
|
|
176
|
-
if (isVariantGeneration) {
|
|
177
|
-
return React.createElement(VariantGeneration, { loadImportMap: loadImportMap });
|
|
178
|
-
}
|
|
179
|
-
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 }))))));
|
|
180
164
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -10,18 +10,25 @@ export function withEmptyFieldEditingComponent(FieldComponent, options) {
|
|
|
10
10
|
var _a;
|
|
11
11
|
const { editable = true } = props;
|
|
12
12
|
if (((_a = props.field) === null || _a === void 0 ? void 0 : _a.metadata) && editable && isFieldValueEmpty(props.field)) {
|
|
13
|
-
|
|
13
|
+
const Component = props.emptyFieldEditingComponent || options.defaultEmptyFieldEditingComponent;
|
|
14
|
+
let resolvedProps = props;
|
|
15
|
+
// If no custom empty field editing component is provided, we can omit unnecessary props
|
|
16
|
+
// to do not insert them to html
|
|
17
|
+
if (!props.emptyFieldEditingComponent) {
|
|
18
|
+
resolvedProps = Object.assign(Object.assign({}, props), { editable: undefined, field: undefined });
|
|
19
|
+
}
|
|
20
|
+
return React.createElement(Component, Object.assign({}, resolvedProps));
|
|
14
21
|
}
|
|
15
22
|
return null;
|
|
16
23
|
};
|
|
17
24
|
if (options.isForwardRef) {
|
|
18
25
|
return forwardRef((props, ref) => {
|
|
19
|
-
const
|
|
20
|
-
return (
|
|
26
|
+
const emptyFieldEditingComponent = getEmptyFieldEditingComponent(props);
|
|
27
|
+
return (emptyFieldEditingComponent || (React.createElement(FieldComponent, Object.assign({}, props, { ref: ref }))));
|
|
21
28
|
});
|
|
22
29
|
}
|
|
23
30
|
return (props) => {
|
|
24
|
-
const
|
|
25
|
-
return
|
|
31
|
+
const emptyFieldEditingComponent = getEmptyFieldEditingComponent(props);
|
|
32
|
+
return emptyFieldEditingComponent || React.createElement(FieldComponent, Object.assign({}, props));
|
|
26
33
|
};
|
|
27
34
|
}
|
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.20",
|
|
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.20",
|
|
76
76
|
"fast-deep-equal": "^3.1.3"
|
|
77
77
|
},
|
|
78
78
|
"description": "",
|
|
79
79
|
"types": "types/index.d.ts",
|
|
80
|
-
"gitHead": "
|
|
80
|
+
"gitHead": "c37f5159bbc1ade9567748eee4ca47e0158e2d89",
|
|
81
81
|
"files": [
|
|
82
82
|
"dist",
|
|
83
83
|
"types"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { EditableFieldProps } from './sharedTypes';
|
|
3
3
|
import { FieldMetadata } from '@sitecore-content-sdk/core/layout';
|
|
4
|
-
export interface DateFieldProps extends EditableFieldProps {
|
|
4
|
+
export interface DateFieldProps extends EditableFieldProps<DateFieldProps> {
|
|
5
5
|
/** The date field data. */
|
|
6
6
|
[htmlAttributes: string]: unknown;
|
|
7
7
|
field: FieldMetadata & {
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
export declare const DefaultEmptyFieldEditingComponentText: React.FC
|
|
3
|
-
|
|
2
|
+
export declare const DefaultEmptyFieldEditingComponentText: React.FC<{
|
|
3
|
+
[key: string]: unknown;
|
|
4
|
+
tag?: string;
|
|
5
|
+
}>;
|
|
6
|
+
export declare const DefaultEmptyFieldEditingComponentImage: React.FC<{
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
className?: string;
|
|
9
|
+
}>;
|
|
@@ -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 {};
|
|
@@ -25,7 +25,7 @@ export interface ImageSizeParameters {
|
|
|
25
25
|
/** Image scale. Defaults to 1.0 */
|
|
26
26
|
sc?: number;
|
|
27
27
|
}
|
|
28
|
-
export interface ImageProps extends EditableFieldProps {
|
|
28
|
+
export interface ImageProps extends EditableFieldProps<ImageProps> {
|
|
29
29
|
[attributeName: string]: unknown;
|
|
30
30
|
/** Image field data (consistent with other field types) */
|
|
31
31
|
field?: (ImageField | ImageFieldValue) & FieldMetadata;
|
|
@@ -16,7 +16,7 @@ export interface LinkFieldValue {
|
|
|
16
16
|
export interface LinkField {
|
|
17
17
|
value: LinkFieldValue;
|
|
18
18
|
}
|
|
19
|
-
export type LinkProps = EditableFieldProps & React.AnchorHTMLAttributes<HTMLAnchorElement> & RefAttributes<HTMLAnchorElement> & {
|
|
19
|
+
export type LinkProps = EditableFieldProps<LinkProps> & React.AnchorHTMLAttributes<HTMLAnchorElement> & RefAttributes<HTMLAnchorElement> & {
|
|
20
20
|
/** The link field data. */
|
|
21
21
|
field: (LinkField | LinkFieldValue) & FieldMetadata;
|
|
22
22
|
/**
|
|
@@ -4,7 +4,7 @@ import { FieldMetadata } from '@sitecore-content-sdk/core/layout';
|
|
|
4
4
|
export interface RichTextField extends FieldMetadata {
|
|
5
5
|
value?: string;
|
|
6
6
|
}
|
|
7
|
-
export interface RichTextProps extends EditableFieldProps {
|
|
7
|
+
export interface RichTextProps extends EditableFieldProps<RichTextProps> {
|
|
8
8
|
[htmlAttributes: string]: unknown;
|
|
9
9
|
/** The rich text field data. */
|
|
10
10
|
field?: RichTextField;
|
|
@@ -4,7 +4,7 @@ import { FieldMetadata } from '@sitecore-content-sdk/core/layout';
|
|
|
4
4
|
export interface TextField extends FieldMetadata {
|
|
5
5
|
value?: string | number;
|
|
6
6
|
}
|
|
7
|
-
export interface TextProps extends EditableFieldProps {
|
|
7
|
+
export interface TextProps extends EditableFieldProps<TextProps> {
|
|
8
8
|
[htmlAttributes: string]: unknown;
|
|
9
9
|
/** The text field data. */
|
|
10
10
|
field?: TextField;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared editing field props
|
|
3
3
|
*/
|
|
4
|
-
export interface EditableFieldProps {
|
|
4
|
+
export interface EditableFieldProps<EmptyFieldEditingComponentProps = unknown> {
|
|
5
5
|
/**
|
|
6
6
|
* Can be used to explicitly disable inline editing.
|
|
7
7
|
* @default true
|
|
@@ -10,5 +10,5 @@ export interface EditableFieldProps {
|
|
|
10
10
|
/**
|
|
11
11
|
* Custom element to render in Pages in edit mode if field value is empty
|
|
12
12
|
*/
|
|
13
|
-
emptyFieldEditingComponent?: React.ComponentClass<
|
|
13
|
+
emptyFieldEditingComponent?: React.ComponentClass<EmptyFieldEditingComponentProps> | React.FC<EmptyFieldEditingComponentProps>;
|
|
14
14
|
}
|
|
@@ -13,15 +13,15 @@ export interface WithEmptyFieldEditingComponentOptions {
|
|
|
13
13
|
*/
|
|
14
14
|
isForwardRef?: boolean;
|
|
15
15
|
}
|
|
16
|
-
interface WithEmptyFieldEditingComponentProps {
|
|
16
|
+
interface WithEmptyFieldEditingComponentProps<Props> {
|
|
17
17
|
field?: (Partial<Field> | GenericFieldValue) & FieldMetadata;
|
|
18
18
|
editable?: boolean;
|
|
19
|
-
emptyFieldEditingComponent?: React.ComponentClass | React.FC
|
|
19
|
+
emptyFieldEditingComponent?: React.ComponentClass<Props> | React.FC<Props>;
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
22
|
* Returns the passed field component or default component in case field value is empty and edit mode is 'metadata'
|
|
23
23
|
* @param {ComponentType<FieldComponentProps>} FieldComponent the field component
|
|
24
24
|
* @param {WithEmptyFieldEditingComponentProps} options the options of the HOC;
|
|
25
25
|
*/
|
|
26
|
-
export declare function withEmptyFieldEditingComponent<FieldComponentProps extends WithEmptyFieldEditingComponentProps
|
|
26
|
+
export declare function withEmptyFieldEditingComponent<FieldComponentProps extends WithEmptyFieldEditingComponentProps<FieldComponentProps>, RefElementType = HTMLElement>(FieldComponent: ComponentType<FieldComponentProps>, options: WithEmptyFieldEditingComponentOptions): React.ForwardRefExoticComponent<React.PropsWithoutRef<FieldComponentProps> & React.RefAttributes<RefElementType>> | ((props: FieldComponentProps) => React.JSX.Element);
|
|
27
27
|
export {};
|