@sitecore-content-sdk/react 1.2.0-canary.50 → 1.2.0-canary.52
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/Placeholder/{ServerPlaceholder.js → AppPlaceholder.js} +23 -25
- package/dist/cjs/components/Placeholder/ClientComponentWrapper.js +21 -0
- package/dist/cjs/components/Placeholder/index.js +3 -3
- package/dist/cjs/components/Placeholder/placeholder-utils.js +43 -5
- package/dist/cjs/enhancers/{withServerPlaceholder.js → withAppPlaceholder.js} +5 -5
- package/dist/cjs/enhancers/withPlaceholder.js +4 -2
- package/dist/cjs/index.js +2 -2
- package/dist/esm/components/Placeholder/{ServerPlaceholder.js → AppPlaceholder.js} +22 -24
- package/dist/esm/components/Placeholder/ClientComponentWrapper.js +14 -0
- package/dist/esm/components/Placeholder/index.js +1 -1
- package/dist/esm/components/Placeholder/placeholder-utils.js +41 -5
- package/dist/esm/enhancers/{withServerPlaceholder.js → withAppPlaceholder.js} +3 -3
- package/dist/esm/enhancers/withPlaceholder.js +4 -2
- package/dist/esm/index.js +1 -1
- package/package.json +5 -4
- package/types/components/Placeholder/{ServerPlaceholder.d.ts → AppPlaceholder.d.ts} +4 -4
- package/types/components/Placeholder/ClientComponentWrapper.d.ts +9 -0
- package/types/components/Placeholder/index.d.ts +2 -2
- package/types/components/Placeholder/models.d.ts +56 -19
- package/types/components/Placeholder/placeholder-utils.d.ts +14 -33
- package/types/enhancers/{withServerPlaceholder.d.ts → withAppPlaceholder.d.ts} +3 -3
- package/types/index.d.ts +1 -1
|
@@ -3,63 +3,61 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
const models_1 = require("./models");
|
|
6
|
+
exports.AppPlaceholder = void 0;
|
|
8
7
|
const placeholder_utils_1 = require("./placeholder-utils");
|
|
9
8
|
const react_1 = __importDefault(require("react"));
|
|
10
9
|
const PlaceholderMetadata_1 = require("./PlaceholderMetadata");
|
|
11
10
|
const ErrorBoundary_1 = __importDefault(require("../ErrorBoundary"));
|
|
11
|
+
const ClientComponentWrapper_1 = require("./ClientComponentWrapper");
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* The implemention of placeholder compatible with React Server Components.
|
|
14
14
|
* Renders components from the layout data for the given placeholder name, with consideration for page edit mode.
|
|
15
15
|
* Pulls components from the provided component map.
|
|
16
|
-
* @param {
|
|
16
|
+
* @param {AppPlaceholderProps} props Placeholder props
|
|
17
17
|
* @returns {React.ReactNode | React.ReactElement[]} rendered component(s)
|
|
18
18
|
*/
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
throw new Error('Component map is required for ServerPlaceholder');
|
|
23
|
-
}
|
|
24
|
-
// get serializable props for client rendering
|
|
25
|
-
const serializableProps = models_1.nonSerializedPlaceholderProps.reduce((finalProps, prop) => {
|
|
26
|
-
delete finalProps[prop];
|
|
27
|
-
return finalProps;
|
|
28
|
-
}, Object.assign({}, props));
|
|
29
|
-
const placeholderRenderings = (0, placeholder_utils_1.getPlaceholderRenderings)(props.rendering, props.name, (_a = props.page) === null || _a === void 0 ? void 0 : _a.mode.isEditing);
|
|
19
|
+
const AppPlaceholder = (props) => {
|
|
20
|
+
const { rendering: parentRendering, componentMap, page } = props;
|
|
21
|
+
const placeholderRenderings = (0, placeholder_utils_1.getPlaceholderRenderings)(parentRendering, props.name, page.mode.isEditing);
|
|
30
22
|
const components = placeholderRenderings
|
|
31
23
|
.map((rendering, index) => {
|
|
32
|
-
const { component, isEmpty, componentType, dynamic } = (0, placeholder_utils_1.getComponentForRendering)(rendering, props.name,
|
|
24
|
+
const { component: Component, isEmpty, componentType, dynamic, } = (0, placeholder_utils_1.getComponentForRendering)(rendering, props.name, componentMap, props.hiddenRenderingComponent, props.missingComponentComponent);
|
|
33
25
|
const isClient = componentType === 'client';
|
|
34
26
|
const key = rendering.uid || `component-${index}`;
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
|
|
27
|
+
const renderedProps = (0, placeholder_utils_1.getAppComponentProps)(props, rendering);
|
|
28
|
+
const finalRenderedProps = props.modifyComponentProps
|
|
29
|
+
? props.modifyComponentProps(renderedProps)
|
|
30
|
+
: renderedProps;
|
|
31
|
+
// Client wrapper is required only when component crosses boundary from server to client.
|
|
32
|
+
// It happens when component is marker as client and rendered in RSC context.
|
|
33
|
+
// Also, it is not required when component is hidden or empty, as it will be rendered whthout boundary crossing.
|
|
34
|
+
const useClientWrapper = isClient && (0, placeholder_utils_1.getRSC)() && !isEmpty;
|
|
35
|
+
let rendered = useClientWrapper ? (react_1.default.createElement(ClientComponentWrapper_1.ClientComponentWrapper, { rendering: rendering, componentProps: finalRenderedProps, placeholderName: props.name, key: key })) : (react_1.default.createElement(Component, Object.assign({ key: key }, finalRenderedProps, { rendering: rendering, page: page, componentMap: componentMap })));
|
|
38
36
|
if (!isEmpty) {
|
|
39
37
|
const errorBoundaryKey = rendered.type + '-' + index;
|
|
40
38
|
const disableSuspense = props.disableSuspense || false;
|
|
41
39
|
rendered = (react_1.default.createElement(ErrorBoundary_1.default, { "data-testid": "error-boundary", key: errorBoundaryKey, errorComponent: props.errorComponent, componentLoadingMessage: props.componentLoadingMessage, isDynamic: dynamic, disableSuspense: disableSuspense, rendering: rendered.props.rendering }, rendered));
|
|
42
40
|
}
|
|
43
41
|
// if in edit mode then emit shallow chromes for hydration in Pages
|
|
44
|
-
if (
|
|
42
|
+
if (page.mode.isEditing) {
|
|
45
43
|
const key = rendering.uid || `component-${index}`;
|
|
46
44
|
return (react_1.default.createElement(PlaceholderMetadata_1.PlaceholderMetadata, { key: key, rendering: rendering }, rendered));
|
|
47
45
|
}
|
|
48
46
|
return rendered;
|
|
49
47
|
})
|
|
50
48
|
.filter((element) => element);
|
|
51
|
-
const finalRendering =
|
|
49
|
+
const finalRendering = page.mode.isEditing
|
|
52
50
|
? [
|
|
53
|
-
react_1.default.createElement(PlaceholderMetadata_1.PlaceholderMetadata, { key:
|
|
51
|
+
react_1.default.createElement(PlaceholderMetadata_1.PlaceholderMetadata, { key: parentRendering.uid, placeholderName: props.name, rendering: parentRendering }, components),
|
|
54
52
|
]
|
|
55
53
|
: components;
|
|
56
54
|
const placeholderEmpty = !placeholderRenderings.length;
|
|
57
55
|
if (placeholderEmpty) {
|
|
58
56
|
const rendered = props.renderEmpty ? props.renderEmpty(finalRendering) : finalRendering;
|
|
59
|
-
return
|
|
57
|
+
return page.mode.isEditing ? (0, placeholder_utils_1.renderEmptyPlaceholder)(rendered) : rendered;
|
|
60
58
|
}
|
|
61
59
|
if (props.render) {
|
|
62
|
-
return props.render(components, placeholderRenderings,
|
|
60
|
+
return props.render(components, placeholderRenderings, props);
|
|
63
61
|
}
|
|
64
62
|
else if (props.renderEach) {
|
|
65
63
|
const renderEach = props.renderEach;
|
|
@@ -74,4 +72,4 @@ const ServerPlaceholder = (props) => {
|
|
|
74
72
|
return finalRendering;
|
|
75
73
|
}
|
|
76
74
|
};
|
|
77
|
-
exports.
|
|
75
|
+
exports.AppPlaceholder = AppPlaceholder;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ClientComponentWrapper = void 0;
|
|
8
|
+
const SitecoreProvider_1 = require("../SitecoreProvider");
|
|
9
|
+
const react_1 = require("react");
|
|
10
|
+
const react_2 = __importDefault(require("react"));
|
|
11
|
+
const withSitecore_1 = require("../../enhancers/withSitecore");
|
|
12
|
+
const placeholder_utils_1 = require("./placeholder-utils");
|
|
13
|
+
const ClientComponentWrapper = (props) => {
|
|
14
|
+
const { page } = (0, withSitecore_1.useSitecore)();
|
|
15
|
+
const componentMap = (0, react_1.useContext)(SitecoreProvider_1.ComponentMapReactContext);
|
|
16
|
+
const componentPropsWithContext = Object.assign(Object.assign({}, props.componentProps), { rendering: props.rendering, componentMap,
|
|
17
|
+
page });
|
|
18
|
+
const { component: Component } = (0, placeholder_utils_1.getComponentForRendering)(props.rendering, props.placeholderName, componentMap);
|
|
19
|
+
return react_2.default.createElement(Component, Object.assign({}, componentPropsWithContext));
|
|
20
|
+
};
|
|
21
|
+
exports.ClientComponentWrapper = ClientComponentWrapper;
|
|
@@ -14,12 +14,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.
|
|
18
|
-
var ServerPlaceholder_1 = require("./ServerPlaceholder");
|
|
19
|
-
Object.defineProperty(exports, "ServerPlaceholder", { enumerable: true, get: function () { return ServerPlaceholder_1.ServerPlaceholder; } });
|
|
17
|
+
exports.AppPlaceholder = exports.PlaceholderMetadata = exports.PlaceholderComponent = exports.Placeholder = void 0;
|
|
20
18
|
var Placeholder_1 = require("./Placeholder");
|
|
21
19
|
Object.defineProperty(exports, "Placeholder", { enumerable: true, get: function () { return Placeholder_1.Placeholder; } });
|
|
22
20
|
Object.defineProperty(exports, "PlaceholderComponent", { enumerable: true, get: function () { return Placeholder_1.PlaceholderComponent; } });
|
|
23
21
|
var PlaceholderMetadata_1 = require("./PlaceholderMetadata");
|
|
24
22
|
Object.defineProperty(exports, "PlaceholderMetadata", { enumerable: true, get: function () { return PlaceholderMetadata_1.PlaceholderMetadata; } });
|
|
23
|
+
var AppPlaceholder_1 = require("./AppPlaceholder");
|
|
24
|
+
Object.defineProperty(exports, "AppPlaceholder", { enumerable: true, get: function () { return AppPlaceholder_1.AppPlaceholder; } });
|
|
25
25
|
__exportStar(require("./placeholder-utils"), exports);
|
|
@@ -15,6 +15,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
exports.getComponentForRendering = exports.getRenderedComponentProps = exports.renderEmptyPlaceholder = exports.getSXAParams = exports.getPlaceholderRenderings = void 0;
|
|
18
|
+
exports.getAppComponentProps = getAppComponentProps;
|
|
19
|
+
exports.getRSC = getRSC;
|
|
18
20
|
const react_1 = __importDefault(require("react"));
|
|
19
21
|
const MissingComponent_1 = require("../MissingComponent");
|
|
20
22
|
const sharedTypes_1 = require("../sharedTypes");
|
|
@@ -22,6 +24,7 @@ const layout_1 = require("@sitecore-content-sdk/core/layout");
|
|
|
22
24
|
const core_1 = require("@sitecore-content-sdk/core");
|
|
23
25
|
const HiddenRendering_1 = require("../HiddenRendering");
|
|
24
26
|
const FEaaS_1 = require("../FEaaS");
|
|
27
|
+
const rsc_env_1 = require("rsc-env");
|
|
25
28
|
/**
|
|
26
29
|
* Get the renderings for the specified placeholder from the rendering data.
|
|
27
30
|
* @param {ComponentRendering | RouteData } rendering rendering data
|
|
@@ -97,15 +100,30 @@ exports.renderEmptyPlaceholder = renderEmptyPlaceholder;
|
|
|
97
100
|
* @returns {RenderedProps} props to be passed to the rendered component
|
|
98
101
|
*/
|
|
99
102
|
const getRenderedComponentProps = (placeholderProps, componentRendering, renderingKey) => {
|
|
100
|
-
|
|
103
|
+
// eslint-disable-next-line no-unused-vars
|
|
104
|
+
const { fields, params: placeholderParams } = placeholderProps, passThroughProps = __rest(placeholderProps, ["fields", "params"]);
|
|
101
105
|
delete passThroughProps.missingComponentComponent;
|
|
102
106
|
delete passThroughProps.hiddenRenderingComponent;
|
|
103
107
|
delete passThroughProps.name;
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
return Object.assign(Object.assign({ key: renderingKey }, passThroughProps), { fields, params: Object.assign(Object.assign({}, params), (0, exports.getSXAParams)(componentRendering)), rendering: componentRendering });
|
|
108
|
+
const mergedContentProps = getAppComponentProps(placeholderProps, componentRendering);
|
|
109
|
+
return Object.assign(Object.assign(Object.assign({ key: renderingKey }, passThroughProps), mergedContentProps), { rendering: componentRendering });
|
|
107
110
|
};
|
|
108
111
|
exports.getRenderedComponentProps = getRenderedComponentProps;
|
|
112
|
+
/**
|
|
113
|
+
* Merge placeholder and component field and params content props.
|
|
114
|
+
* @param {BasePlaceholderProps} placeholderProps placeholder props
|
|
115
|
+
* @param {ComponentRendering} componentRendering component rendering
|
|
116
|
+
* @returns {ComponentProps} merged props
|
|
117
|
+
*/
|
|
118
|
+
function getAppComponentProps(placeholderProps, componentRendering) {
|
|
119
|
+
const fields = Object.assign(Object.assign({}, (placeholderProps.fields || {})), (componentRendering.fields || {}));
|
|
120
|
+
const params = Object.assign(Object.assign({}, (placeholderProps.params || {})), (componentRendering.params || {}));
|
|
121
|
+
return {
|
|
122
|
+
fields,
|
|
123
|
+
params: Object.assign(Object.assign({}, params), (0, exports.getSXAParams)(componentRendering)),
|
|
124
|
+
rendering: componentRendering,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
109
127
|
/**
|
|
110
128
|
* Get component implemenation from the component map based on the rendering definition.
|
|
111
129
|
* @param {ComponentRendering} renderingDefinition rendering data
|
|
@@ -121,6 +139,7 @@ const getComponentForRendering = (renderingDefinition, placeholderName, componen
|
|
|
121
139
|
return {
|
|
122
140
|
component: hiddenRenderingComponent !== null && hiddenRenderingComponent !== void 0 ? hiddenRenderingComponent : HiddenRendering_1.HiddenRendering,
|
|
123
141
|
isEmpty: true,
|
|
142
|
+
componentType: 'universal',
|
|
124
143
|
};
|
|
125
144
|
}
|
|
126
145
|
else if (!renderingDefinition.componentName) {
|
|
@@ -128,6 +147,7 @@ const getComponentForRendering = (renderingDefinition, placeholderName, componen
|
|
|
128
147
|
return {
|
|
129
148
|
component: () => react_1.default.createElement(react_1.default.Fragment, null),
|
|
130
149
|
isEmpty: true,
|
|
150
|
+
componentType: 'universal',
|
|
131
151
|
};
|
|
132
152
|
}
|
|
133
153
|
let component = null;
|
|
@@ -142,16 +162,22 @@ const getComponentForRendering = (renderingDefinition, placeholderName, componen
|
|
|
142
162
|
if (renderingDefinition.componentName === FEaaS_1.FEAAS_COMPONENT_RENDERING_NAME) {
|
|
143
163
|
return {
|
|
144
164
|
component: FEaaS_1.FEaaSComponent,
|
|
165
|
+
isEmpty: false,
|
|
166
|
+
componentType: 'universal',
|
|
145
167
|
};
|
|
146
168
|
}
|
|
147
169
|
else if (renderingDefinition.componentName === FEaaS_1.FEAAS_WRAPPER_RENDERING_NAME) {
|
|
148
170
|
return {
|
|
149
171
|
component: FEaaS_1.FEaaSWrapper,
|
|
172
|
+
isEmpty: false,
|
|
173
|
+
componentType: 'universal',
|
|
150
174
|
};
|
|
151
175
|
}
|
|
152
176
|
else if (renderingDefinition.componentName === FEaaS_1.BYOC_COMPONENT_RENDERING_NAME) {
|
|
153
177
|
return {
|
|
154
178
|
component: FEaaS_1.BYOCComponent,
|
|
179
|
+
isEmpty: false,
|
|
180
|
+
componentType: 'universal',
|
|
155
181
|
};
|
|
156
182
|
}
|
|
157
183
|
else if (renderingDefinition.componentName === FEaaS_1.BYOC_WRAPPER_RENDERING_NAME) {
|
|
@@ -160,11 +186,14 @@ const getComponentForRendering = (renderingDefinition, placeholderName, componen
|
|
|
160
186
|
return {
|
|
161
187
|
component: FEaaS_1.BYOCWrapper,
|
|
162
188
|
dynamic: true,
|
|
189
|
+
componentType: 'universal',
|
|
190
|
+
isEmpty: false,
|
|
163
191
|
};
|
|
164
192
|
}
|
|
165
193
|
return {
|
|
166
194
|
component: missingComponentComponent !== null && missingComponentComponent !== void 0 ? missingComponentComponent : MissingComponent_1.MissingComponent,
|
|
167
195
|
isEmpty: true,
|
|
196
|
+
componentType: 'universal',
|
|
168
197
|
};
|
|
169
198
|
}
|
|
170
199
|
// Render SXA Rendering Variant if available
|
|
@@ -180,7 +209,16 @@ const getComponentForRendering = (renderingDefinition, placeholderName, componen
|
|
|
180
209
|
return {
|
|
181
210
|
component: renderedComponent,
|
|
182
211
|
dynamic,
|
|
183
|
-
componentType: component
|
|
212
|
+
componentType: component
|
|
213
|
+
.componentType,
|
|
214
|
+
isEmpty: false,
|
|
184
215
|
};
|
|
185
216
|
};
|
|
186
217
|
exports.getComponentForRendering = getComponentForRendering;
|
|
218
|
+
/**
|
|
219
|
+
* Get the RSC environment variable.
|
|
220
|
+
* @returns {boolean} true if RSC is enabled, false otherwise.
|
|
221
|
+
*/
|
|
222
|
+
function getRSC() {
|
|
223
|
+
return rsc_env_1.rsc;
|
|
224
|
+
}
|
|
@@ -3,19 +3,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.withAppPlaceholder = void 0;
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
|
-
const
|
|
9
|
-
const
|
|
8
|
+
const AppPlaceholder_1 = require("../components/Placeholder/AppPlaceholder");
|
|
9
|
+
const withAppPlaceholder = (Component) => {
|
|
10
10
|
return (props) => {
|
|
11
11
|
const placeholders = props.rendering.placeholders;
|
|
12
12
|
const phProps = {};
|
|
13
13
|
for (const placeholder of Object.keys(placeholders)) {
|
|
14
|
-
phProps[placeholder] = (react_1.default.createElement(
|
|
14
|
+
phProps[placeholder] = (react_1.default.createElement(AppPlaceholder_1.AppPlaceholder, { name: placeholder, rendering: props.rendering, componentMap: props.componentMap, page: props.page }));
|
|
15
15
|
}
|
|
16
16
|
const displayName = Component.displayName || Component.name || 'Component';
|
|
17
17
|
const propsCopy = Object.assign(Object.assign({}, props), { displayName });
|
|
18
18
|
return react_1.default.createElement(Component, Object.assign({}, propsCopy, { placeholders: phProps }));
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
|
-
exports.
|
|
21
|
+
exports.withAppPlaceholder = withAppPlaceholder;
|
|
@@ -45,13 +45,15 @@ function withPlaceholder(placeholders, options) {
|
|
|
45
45
|
if (typeof placeholder !== 'string' && placeholder.placeholder && placeholder.prop) {
|
|
46
46
|
placeholderData = (0, Placeholder_1.getPlaceholderRenderings)(renderingData, placeholder.placeholder, childProps.page.mode.isEditing);
|
|
47
47
|
if (placeholderData) {
|
|
48
|
-
childProps[placeholder.prop] =
|
|
48
|
+
childProps[placeholder.prop] =
|
|
49
|
+
Placeholder_1.PlaceholderComponent.getRenderedComponents(this.props, placeholderData);
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
else {
|
|
52
53
|
placeholderData = (0, Placeholder_1.getPlaceholderRenderings)(renderingData, placeholder, childProps.page.mode.isEditing);
|
|
53
54
|
if (placeholderData) {
|
|
54
|
-
childProps[placeholder] =
|
|
55
|
+
childProps[placeholder] =
|
|
56
|
+
Placeholder_1.PlaceholderComponent.getRenderedComponents(this.props, placeholderData);
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
});
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DefaultEmptyFieldEditingComponentText = exports.EditingScripts = exports.withEmptyFieldEditingComponent = exports.withFieldMetadata = exports.withDatasourceCheck = exports.withPlaceholder = exports.withEditorChromes = exports.useSitecore = exports.withSitecore = exports.SitecoreProviderReactContext = exports.SitecoreProvider = exports.File = exports.Link = exports.DesignLibrary = exports.BYOCServerWrapper = exports.FEaaSServerWrapper = exports.FEaaSClientWrapper = exports.FEaaSWrapper = exports.BYOCClientWrapper = exports.BYOCWrapper = exports.fetchBYOCComponentServerProps = exports.BYOCComponent = exports.fetchFEaaSComponentServerProps = exports.FEaaSComponent = exports.DateField = exports.Text = exports.RichText = exports.Image = exports.
|
|
3
|
+
exports.DefaultEmptyFieldEditingComponentText = exports.EditingScripts = exports.withEmptyFieldEditingComponent = exports.withFieldMetadata = exports.withDatasourceCheck = exports.withPlaceholder = exports.withEditorChromes = exports.useSitecore = exports.withSitecore = exports.SitecoreProviderReactContext = exports.SitecoreProvider = exports.File = exports.Link = exports.DesignLibrary = exports.BYOCServerWrapper = exports.FEaaSServerWrapper = exports.FEaaSClientWrapper = exports.FEaaSWrapper = exports.BYOCClientWrapper = exports.BYOCWrapper = exports.fetchBYOCComponentServerProps = exports.BYOCComponent = exports.fetchFEaaSComponentServerProps = exports.FEaaSComponent = exports.DateField = exports.Text = exports.RichText = exports.Image = exports.AppPlaceholder = exports.Placeholder = exports.Form = exports.mediaApi = exports.ErrorPage = exports.GraphQLRequestClient = exports.DefaultRetryStrategy = exports.DictionaryService = exports.EditMode = exports.getFieldValue = exports.getChildPlaceholder = exports.LayoutService = exports.LayoutServicePageState = exports.getDesignLibraryStylesheetLinks = exports.getContentStylesheetLink = exports.resetEditorChromes = exports.isEditorActive = exports.NativeDataFetcher = exports.MemoryCacheClient = exports.ClientError = exports.enableDebug = exports.constants = void 0;
|
|
4
4
|
exports.SitePathService = exports.ClientEditingChromesUpdate = exports.DefaultEmptyFieldEditingComponentImage = void 0;
|
|
5
5
|
var core_1 = require("@sitecore-content-sdk/core");
|
|
6
6
|
Object.defineProperty(exports, "constants", { enumerable: true, get: function () { return core_1.constants; } });
|
|
@@ -31,7 +31,7 @@ var Form_1 = require("./components/Form");
|
|
|
31
31
|
Object.defineProperty(exports, "Form", { enumerable: true, get: function () { return Form_1.Form; } });
|
|
32
32
|
var Placeholder_1 = require("./components/Placeholder");
|
|
33
33
|
Object.defineProperty(exports, "Placeholder", { enumerable: true, get: function () { return Placeholder_1.Placeholder; } });
|
|
34
|
-
Object.defineProperty(exports, "
|
|
34
|
+
Object.defineProperty(exports, "AppPlaceholder", { enumerable: true, get: function () { return Placeholder_1.AppPlaceholder; } });
|
|
35
35
|
var Image_1 = require("./components/Image");
|
|
36
36
|
Object.defineProperty(exports, "Image", { enumerable: true, get: function () { return Image_1.Image; } });
|
|
37
37
|
var RichText_1 = require("./components/RichText");
|
|
@@ -1,59 +1,57 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { getComponentForRendering, getPlaceholderRenderings, getRenderedComponentProps, renderEmptyPlaceholder, } from './placeholder-utils';
|
|
1
|
+
import { getAppComponentProps, getComponentForRendering, getPlaceholderRenderings, renderEmptyPlaceholder, getRSC, } from './placeholder-utils';
|
|
3
2
|
import React from 'react';
|
|
4
3
|
import { PlaceholderMetadata } from './PlaceholderMetadata';
|
|
5
4
|
import ErrorBoundary from '../ErrorBoundary';
|
|
5
|
+
import { ClientComponentWrapper } from './ClientComponentWrapper';
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* The implemention of placeholder compatible with React Server Components.
|
|
8
8
|
* Renders components from the layout data for the given placeholder name, with consideration for page edit mode.
|
|
9
9
|
* Pulls components from the provided component map.
|
|
10
|
-
* @param {
|
|
10
|
+
* @param {AppPlaceholderProps} props Placeholder props
|
|
11
11
|
* @returns {React.ReactNode | React.ReactElement[]} rendered component(s)
|
|
12
12
|
*/
|
|
13
|
-
export const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
throw new Error('Component map is required for ServerPlaceholder');
|
|
17
|
-
}
|
|
18
|
-
// get serializable props for client rendering
|
|
19
|
-
const serializableProps = nonSerializedPlaceholderProps.reduce((finalProps, prop) => {
|
|
20
|
-
delete finalProps[prop];
|
|
21
|
-
return finalProps;
|
|
22
|
-
}, Object.assign({}, props));
|
|
23
|
-
const placeholderRenderings = getPlaceholderRenderings(props.rendering, props.name, (_a = props.page) === null || _a === void 0 ? void 0 : _a.mode.isEditing);
|
|
13
|
+
export const AppPlaceholder = (props) => {
|
|
14
|
+
const { rendering: parentRendering, componentMap, page } = props;
|
|
15
|
+
const placeholderRenderings = getPlaceholderRenderings(parentRendering, props.name, page.mode.isEditing);
|
|
24
16
|
const components = placeholderRenderings
|
|
25
17
|
.map((rendering, index) => {
|
|
26
|
-
const { component, isEmpty, componentType, dynamic } = getComponentForRendering(rendering, props.name,
|
|
18
|
+
const { component: Component, isEmpty, componentType, dynamic, } = getComponentForRendering(rendering, props.name, componentMap, props.hiddenRenderingComponent, props.missingComponentComponent);
|
|
27
19
|
const isClient = componentType === 'client';
|
|
28
20
|
const key = rendering.uid || `component-${index}`;
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
21
|
+
const renderedProps = getAppComponentProps(props, rendering);
|
|
22
|
+
const finalRenderedProps = props.modifyComponentProps
|
|
23
|
+
? props.modifyComponentProps(renderedProps)
|
|
24
|
+
: renderedProps;
|
|
25
|
+
// Client wrapper is required only when component crosses boundary from server to client.
|
|
26
|
+
// It happens when component is marker as client and rendered in RSC context.
|
|
27
|
+
// Also, it is not required when component is hidden or empty, as it will be rendered whthout boundary crossing.
|
|
28
|
+
const useClientWrapper = isClient && getRSC() && !isEmpty;
|
|
29
|
+
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 })));
|
|
32
30
|
if (!isEmpty) {
|
|
33
31
|
const errorBoundaryKey = rendered.type + '-' + index;
|
|
34
32
|
const disableSuspense = props.disableSuspense || false;
|
|
35
33
|
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));
|
|
36
34
|
}
|
|
37
35
|
// if in edit mode then emit shallow chromes for hydration in Pages
|
|
38
|
-
if (
|
|
36
|
+
if (page.mode.isEditing) {
|
|
39
37
|
const key = rendering.uid || `component-${index}`;
|
|
40
38
|
return (React.createElement(PlaceholderMetadata, { key: key, rendering: rendering }, rendered));
|
|
41
39
|
}
|
|
42
40
|
return rendered;
|
|
43
41
|
})
|
|
44
42
|
.filter((element) => element);
|
|
45
|
-
const finalRendering =
|
|
43
|
+
const finalRendering = page.mode.isEditing
|
|
46
44
|
? [
|
|
47
|
-
React.createElement(PlaceholderMetadata, { key:
|
|
45
|
+
React.createElement(PlaceholderMetadata, { key: parentRendering.uid, placeholderName: props.name, rendering: parentRendering }, components),
|
|
48
46
|
]
|
|
49
47
|
: components;
|
|
50
48
|
const placeholderEmpty = !placeholderRenderings.length;
|
|
51
49
|
if (placeholderEmpty) {
|
|
52
50
|
const rendered = props.renderEmpty ? props.renderEmpty(finalRendering) : finalRendering;
|
|
53
|
-
return
|
|
51
|
+
return page.mode.isEditing ? renderEmptyPlaceholder(rendered) : rendered;
|
|
54
52
|
}
|
|
55
53
|
if (props.render) {
|
|
56
|
-
return props.render(components, placeholderRenderings,
|
|
54
|
+
return props.render(components, placeholderRenderings, props);
|
|
57
55
|
}
|
|
58
56
|
else if (props.renderEach) {
|
|
59
57
|
const renderEach = props.renderEach;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { ComponentMapReactContext } from '../SitecoreProvider';
|
|
3
|
+
import { useContext } from 'react';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { useSitecore } from '../../enhancers/withSitecore';
|
|
6
|
+
import { getComponentForRendering } from './placeholder-utils';
|
|
7
|
+
export const ClientComponentWrapper = (props) => {
|
|
8
|
+
const { page } = useSitecore();
|
|
9
|
+
const componentMap = useContext(ComponentMapReactContext);
|
|
10
|
+
const componentPropsWithContext = Object.assign(Object.assign({}, props.componentProps), { rendering: props.rendering, componentMap,
|
|
11
|
+
page });
|
|
12
|
+
const { component: Component } = getComponentForRendering(props.rendering, props.placeholderName, componentMap);
|
|
13
|
+
return React.createElement(Component, Object.assign({}, componentPropsWithContext));
|
|
14
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ServerPlaceholder } from './ServerPlaceholder';
|
|
2
1
|
export { Placeholder, PlaceholderComponent } from './Placeholder';
|
|
3
2
|
export { PlaceholderMetadata } from './PlaceholderMetadata';
|
|
3
|
+
export { AppPlaceholder } from './AppPlaceholder';
|
|
4
4
|
export * from './placeholder-utils';
|
|
@@ -16,6 +16,7 @@ import { isDynamicPlaceholder, getDynamicPlaceholderPattern, } from '@sitecore-c
|
|
|
16
16
|
import { constants } from '@sitecore-content-sdk/core';
|
|
17
17
|
import { HiddenRendering } from '../HiddenRendering';
|
|
18
18
|
import { FEaaSComponent, FEaaSWrapper, BYOCComponent, BYOCWrapper, BYOC_COMPONENT_RENDERING_NAME, BYOC_WRAPPER_RENDERING_NAME, FEAAS_COMPONENT_RENDERING_NAME, FEAAS_WRAPPER_RENDERING_NAME, } from '../FEaaS';
|
|
19
|
+
import { rsc } from 'rsc-env';
|
|
19
20
|
/**
|
|
20
21
|
* Get the renderings for the specified placeholder from the rendering data.
|
|
21
22
|
* @param {ComponentRendering | RouteData } rendering rendering data
|
|
@@ -88,14 +89,29 @@ export const renderEmptyPlaceholder = (node) => {
|
|
|
88
89
|
* @returns {RenderedProps} props to be passed to the rendered component
|
|
89
90
|
*/
|
|
90
91
|
export const getRenderedComponentProps = (placeholderProps, componentRendering, renderingKey) => {
|
|
91
|
-
|
|
92
|
+
// eslint-disable-next-line no-unused-vars
|
|
93
|
+
const { fields, params: placeholderParams } = placeholderProps, passThroughProps = __rest(placeholderProps, ["fields", "params"]);
|
|
92
94
|
delete passThroughProps.missingComponentComponent;
|
|
93
95
|
delete passThroughProps.hiddenRenderingComponent;
|
|
94
96
|
delete passThroughProps.name;
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
return Object.assign(Object.assign({ key: renderingKey }, passThroughProps), { fields, params: Object.assign(Object.assign({}, params), getSXAParams(componentRendering)), rendering: componentRendering });
|
|
97
|
+
const mergedContentProps = getAppComponentProps(placeholderProps, componentRendering);
|
|
98
|
+
return Object.assign(Object.assign(Object.assign({ key: renderingKey }, passThroughProps), mergedContentProps), { rendering: componentRendering });
|
|
98
99
|
};
|
|
100
|
+
/**
|
|
101
|
+
* Merge placeholder and component field and params content props.
|
|
102
|
+
* @param {BasePlaceholderProps} placeholderProps placeholder props
|
|
103
|
+
* @param {ComponentRendering} componentRendering component rendering
|
|
104
|
+
* @returns {ComponentProps} merged props
|
|
105
|
+
*/
|
|
106
|
+
export function getAppComponentProps(placeholderProps, componentRendering) {
|
|
107
|
+
const fields = Object.assign(Object.assign({}, (placeholderProps.fields || {})), (componentRendering.fields || {}));
|
|
108
|
+
const params = Object.assign(Object.assign({}, (placeholderProps.params || {})), (componentRendering.params || {}));
|
|
109
|
+
return {
|
|
110
|
+
fields,
|
|
111
|
+
params: Object.assign(Object.assign({}, params), getSXAParams(componentRendering)),
|
|
112
|
+
rendering: componentRendering,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
99
115
|
/**
|
|
100
116
|
* Get component implemenation from the component map based on the rendering definition.
|
|
101
117
|
* @param {ComponentRendering} renderingDefinition rendering data
|
|
@@ -111,6 +127,7 @@ export const getComponentForRendering = (renderingDefinition, placeholderName, c
|
|
|
111
127
|
return {
|
|
112
128
|
component: hiddenRenderingComponent !== null && hiddenRenderingComponent !== void 0 ? hiddenRenderingComponent : HiddenRendering,
|
|
113
129
|
isEmpty: true,
|
|
130
|
+
componentType: 'universal',
|
|
114
131
|
};
|
|
115
132
|
}
|
|
116
133
|
else if (!renderingDefinition.componentName) {
|
|
@@ -118,6 +135,7 @@ export const getComponentForRendering = (renderingDefinition, placeholderName, c
|
|
|
118
135
|
return {
|
|
119
136
|
component: () => React.createElement(React.Fragment, null),
|
|
120
137
|
isEmpty: true,
|
|
138
|
+
componentType: 'universal',
|
|
121
139
|
};
|
|
122
140
|
}
|
|
123
141
|
let component = null;
|
|
@@ -132,16 +150,22 @@ export const getComponentForRendering = (renderingDefinition, placeholderName, c
|
|
|
132
150
|
if (renderingDefinition.componentName === FEAAS_COMPONENT_RENDERING_NAME) {
|
|
133
151
|
return {
|
|
134
152
|
component: FEaaSComponent,
|
|
153
|
+
isEmpty: false,
|
|
154
|
+
componentType: 'universal',
|
|
135
155
|
};
|
|
136
156
|
}
|
|
137
157
|
else if (renderingDefinition.componentName === FEAAS_WRAPPER_RENDERING_NAME) {
|
|
138
158
|
return {
|
|
139
159
|
component: FEaaSWrapper,
|
|
160
|
+
isEmpty: false,
|
|
161
|
+
componentType: 'universal',
|
|
140
162
|
};
|
|
141
163
|
}
|
|
142
164
|
else if (renderingDefinition.componentName === BYOC_COMPONENT_RENDERING_NAME) {
|
|
143
165
|
return {
|
|
144
166
|
component: BYOCComponent,
|
|
167
|
+
isEmpty: false,
|
|
168
|
+
componentType: 'universal',
|
|
145
169
|
};
|
|
146
170
|
}
|
|
147
171
|
else if (renderingDefinition.componentName === BYOC_WRAPPER_RENDERING_NAME) {
|
|
@@ -150,11 +174,14 @@ export const getComponentForRendering = (renderingDefinition, placeholderName, c
|
|
|
150
174
|
return {
|
|
151
175
|
component: BYOCWrapper,
|
|
152
176
|
dynamic: true,
|
|
177
|
+
componentType: 'universal',
|
|
178
|
+
isEmpty: false,
|
|
153
179
|
};
|
|
154
180
|
}
|
|
155
181
|
return {
|
|
156
182
|
component: missingComponentComponent !== null && missingComponentComponent !== void 0 ? missingComponentComponent : MissingComponent,
|
|
157
183
|
isEmpty: true,
|
|
184
|
+
componentType: 'universal',
|
|
158
185
|
};
|
|
159
186
|
}
|
|
160
187
|
// Render SXA Rendering Variant if available
|
|
@@ -170,6 +197,15 @@ export const getComponentForRendering = (renderingDefinition, placeholderName, c
|
|
|
170
197
|
return {
|
|
171
198
|
component: renderedComponent,
|
|
172
199
|
dynamic,
|
|
173
|
-
componentType: component
|
|
200
|
+
componentType: component
|
|
201
|
+
.componentType,
|
|
202
|
+
isEmpty: false,
|
|
174
203
|
};
|
|
175
204
|
};
|
|
205
|
+
/**
|
|
206
|
+
* Get the RSC environment variable.
|
|
207
|
+
* @returns {boolean} true if RSC is enabled, false otherwise.
|
|
208
|
+
*/
|
|
209
|
+
export function getRSC() {
|
|
210
|
+
return rsc;
|
|
211
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
export const
|
|
2
|
+
import { AppPlaceholder } from '../components/Placeholder/AppPlaceholder';
|
|
3
|
+
export const withAppPlaceholder = (Component) => {
|
|
4
4
|
return (props) => {
|
|
5
5
|
const placeholders = props.rendering.placeholders;
|
|
6
6
|
const phProps = {};
|
|
7
7
|
for (const placeholder of Object.keys(placeholders)) {
|
|
8
|
-
phProps[placeholder] = (React.createElement(
|
|
8
|
+
phProps[placeholder] = (React.createElement(AppPlaceholder, { name: placeholder, rendering: props.rendering, componentMap: props.componentMap, page: props.page }));
|
|
9
9
|
}
|
|
10
10
|
const displayName = Component.displayName || Component.name || 'Component';
|
|
11
11
|
const propsCopy = Object.assign(Object.assign({}, props), { displayName });
|
|
@@ -39,13 +39,15 @@ export function withPlaceholder(placeholders, options) {
|
|
|
39
39
|
if (typeof placeholder !== 'string' && placeholder.placeholder && placeholder.prop) {
|
|
40
40
|
placeholderData = getPlaceholderRenderings(renderingData, placeholder.placeholder, childProps.page.mode.isEditing);
|
|
41
41
|
if (placeholderData) {
|
|
42
|
-
childProps[placeholder.prop] =
|
|
42
|
+
childProps[placeholder.prop] =
|
|
43
|
+
PlaceholderComponent.getRenderedComponents(this.props, placeholderData);
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
else {
|
|
46
47
|
placeholderData = getPlaceholderRenderings(renderingData, placeholder, childProps.page.mode.isEditing);
|
|
47
48
|
if (placeholderData) {
|
|
48
|
-
childProps[placeholder] =
|
|
49
|
+
childProps[placeholder] =
|
|
50
|
+
PlaceholderComponent.getRenderedComponents(this.props, placeholderData);
|
|
49
51
|
}
|
|
50
52
|
}
|
|
51
53
|
});
|
package/dist/esm/index.js
CHANGED
|
@@ -5,7 +5,7 @@ export { DictionaryService } from '@sitecore-content-sdk/core/i18n';
|
|
|
5
5
|
export { DefaultRetryStrategy, GraphQLRequestClient, ErrorPage, } from '@sitecore-content-sdk/core/client';
|
|
6
6
|
export { mediaApi } from '@sitecore-content-sdk/core/media';
|
|
7
7
|
export { Form } from './components/Form';
|
|
8
|
-
export { Placeholder,
|
|
8
|
+
export { Placeholder, AppPlaceholder, } from './components/Placeholder';
|
|
9
9
|
export { Image, } from './components/Image';
|
|
10
10
|
export { RichText } from './components/RichText';
|
|
11
11
|
export { Text } from './components/Text';
|
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.52",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -72,12 +72,13 @@
|
|
|
72
72
|
"react-dom": "^19.1.0"
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
|
-
"@sitecore-content-sdk/core": "1.2.0-canary.
|
|
76
|
-
"fast-deep-equal": "^3.1.3"
|
|
75
|
+
"@sitecore-content-sdk/core": "1.2.0-canary.52",
|
|
76
|
+
"fast-deep-equal": "^3.1.3",
|
|
77
|
+
"rsc-env": "^0.0.2"
|
|
77
78
|
},
|
|
78
79
|
"description": "",
|
|
79
80
|
"types": "types/index.d.ts",
|
|
80
|
-
"gitHead": "
|
|
81
|
+
"gitHead": "561443139cdafcc487d7f3faba2038a24771474c",
|
|
81
82
|
"files": [
|
|
82
83
|
"dist",
|
|
83
84
|
"types"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AppPlaceholderProps } from './models';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* The implemention of placeholder compatible with React Server Components.
|
|
5
5
|
* Renders components from the layout data for the given placeholder name, with consideration for page edit mode.
|
|
6
6
|
* Pulls components from the provided component map.
|
|
7
|
-
* @param {
|
|
7
|
+
* @param {AppPlaceholderProps} props Placeholder props
|
|
8
8
|
* @returns {React.ReactNode | React.ReactElement[]} rendered component(s)
|
|
9
9
|
*/
|
|
10
|
-
export declare const
|
|
10
|
+
export declare const AppPlaceholder: (props: AppPlaceholderProps) => string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode>> | React.JSX.Element | (string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode>> | React.JSX.Element)[];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ComponentRendering } from '@sitecore-content-sdk/core/layout';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { AppComponentProps } from './models';
|
|
4
|
+
export interface ClientComponentWrapperProps {
|
|
5
|
+
rendering: ComponentRendering;
|
|
6
|
+
componentProps: AppComponentProps;
|
|
7
|
+
placeholderName: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const ClientComponentWrapper: (props: ClientComponentWrapperProps) => React.JSX.Element;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { ServerPlaceholder } from './ServerPlaceholder';
|
|
2
1
|
export { Placeholder, PlaceholderComponent } from './Placeholder';
|
|
3
2
|
export { PlaceholderMetadata } from './PlaceholderMetadata';
|
|
4
|
-
export { PlaceholderProps } from './models';
|
|
3
|
+
export { PlaceholderProps, AppPlaceholderProps } from './models';
|
|
4
|
+
export { AppPlaceholder } from './AppPlaceholder';
|
|
5
5
|
export * from './placeholder-utils';
|
|
@@ -11,18 +11,20 @@ export type ComponentProps = {
|
|
|
11
11
|
[key: string]: unknown;
|
|
12
12
|
rendering: ComponentRendering;
|
|
13
13
|
};
|
|
14
|
-
export interface
|
|
15
|
-
|
|
14
|
+
export interface AppComponentProps {
|
|
15
|
+
fields: {
|
|
16
|
+
[name: string]: Field | Item | Item[];
|
|
17
|
+
};
|
|
18
|
+
params: {
|
|
19
|
+
[name: string]: string;
|
|
20
|
+
};
|
|
21
|
+
rendering: ComponentRendering;
|
|
22
|
+
}
|
|
23
|
+
export interface BasePlaceholderProps {
|
|
16
24
|
/** Name of the placeholder to render. */
|
|
17
25
|
name: string;
|
|
18
26
|
/** Rendering data to be used when rendering the placeholder. */
|
|
19
27
|
rendering: ComponentRendering | RouteData;
|
|
20
|
-
/**
|
|
21
|
-
* Component Map will be used to map Sitecore component names to app implementation
|
|
22
|
-
* When rendered within a <SitecoreProvider> component, defaults to the context componentMap.
|
|
23
|
-
* When rendered as a server placeholder, this prop must be provided.
|
|
24
|
-
*/
|
|
25
|
-
componentMap?: ComponentMap;
|
|
26
28
|
/**
|
|
27
29
|
* An object of field names/values that are aggregated and propagated through the component tree created by a placeholder.
|
|
28
30
|
* Any component or placeholder rendered by a placeholder will have access to this data via `props.fields`.
|
|
@@ -37,13 +39,6 @@ export interface PlaceholderProps {
|
|
|
37
39
|
params?: {
|
|
38
40
|
[name: string]: string;
|
|
39
41
|
};
|
|
40
|
-
/**
|
|
41
|
-
* Modify final props of component (before render) provided by rendering data.
|
|
42
|
-
* Can be used in case when you need to insert additional data into the component.
|
|
43
|
-
* @param {ComponentProps} componentProps component props to be modified
|
|
44
|
-
* @returns {ComponentProps} modified or initial props
|
|
45
|
-
*/
|
|
46
|
-
modifyComponentProps?: (componentProps: ComponentProps) => ComponentProps;
|
|
47
42
|
/**
|
|
48
43
|
* A component that is rendered in place of any components that are in this placeholder,
|
|
49
44
|
* but do not have a definition in the componentMap (i.e. don't have a React implementation)
|
|
@@ -76,18 +71,54 @@ export interface PlaceholderProps {
|
|
|
76
71
|
* Render props function that is called when the placeholder contains no content components.
|
|
77
72
|
*/
|
|
78
73
|
renderEmpty?: (components: React.ReactNode[]) => React.ReactNode;
|
|
74
|
+
/**
|
|
75
|
+
* Render props function that is called for each non-system component added to the placeholder.
|
|
76
|
+
* Mutually exclusive with `render`.
|
|
77
|
+
*/
|
|
78
|
+
renderEach?: (component: React.ReactNode, index: number) => React.ReactNode;
|
|
79
|
+
}
|
|
80
|
+
export interface PlaceholderProps extends BasePlaceholderProps {
|
|
81
|
+
[key: string]: unknown;
|
|
82
|
+
/**
|
|
83
|
+
* Component Map will be used to map Sitecore component names to app implementation
|
|
84
|
+
* When rendered within a <SitecoreProvider> component, defaults to the context componentMap.
|
|
85
|
+
* When rendered as a server placeholder, this prop must be provided. This prop is not used in AppPlaceholder.
|
|
86
|
+
*/
|
|
87
|
+
componentMap?: ComponentMap;
|
|
88
|
+
/**
|
|
89
|
+
* Modify final props of component (before render) provided by rendering data.
|
|
90
|
+
* Can be used in case when you need to insert additional data into the component.
|
|
91
|
+
* @param {ComponentProps} componentProps component props to be modified
|
|
92
|
+
* @returns {ComponentProps} modified or initial props
|
|
93
|
+
*/
|
|
94
|
+
modifyComponentProps?: (componentProps: ComponentProps) => ComponentProps;
|
|
79
95
|
/**
|
|
80
96
|
* Render props function that enables control over the rendering of the components in the placeholder.
|
|
81
97
|
* Useful for techniques like wrapping each child in a wrapper component.
|
|
82
98
|
*/
|
|
83
99
|
render?: (components: React.ReactNode[], data: ComponentRendering[], props: PlaceholderProps) => React.ReactNode;
|
|
100
|
+
}
|
|
101
|
+
export interface AppPlaceholderProps extends BasePlaceholderProps {
|
|
84
102
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
103
|
+
* Component Map will be used to map Sitecore component names to app implementation
|
|
104
|
+
* When rendered within a <SitecoreProvider> component, defaults to the context componentMap.
|
|
105
|
+
* When rendered as a server placeholder, this prop must be provided. This prop is not used in AppPlaceholder.
|
|
87
106
|
*/
|
|
88
|
-
|
|
107
|
+
componentMap: ComponentMap;
|
|
108
|
+
/**
|
|
109
|
+
* Modify final props of component (before render) provided by rendering data.
|
|
110
|
+
* Can be used in case when you need to insert additional data into the component.
|
|
111
|
+
* @param {AppComponentProps} componentProps component props to be modified
|
|
112
|
+
* @returns {AppComponentProps} modified or initial props
|
|
113
|
+
*/
|
|
114
|
+
modifyComponentProps?: (componentProps: AppComponentProps) => AppComponentProps;
|
|
115
|
+
/**
|
|
116
|
+
* Render props function that enables control over the rendering of the components in the placeholder.
|
|
117
|
+
* Useful for techniques like wrapping each child in a wrapper component.
|
|
118
|
+
*/
|
|
119
|
+
render?: (components: React.ReactNode[], data: ComponentRendering[], props: AppPlaceholderProps) => React.ReactNode;
|
|
89
120
|
}
|
|
90
|
-
export type RenderedProps = Omit<PlaceholderProps, 'fields | params'> & {
|
|
121
|
+
export type RenderedProps = Omit<PlaceholderProps, 'fields' | 'params'> & {
|
|
91
122
|
key: string;
|
|
92
123
|
fields: {
|
|
93
124
|
[field: string]: unknown;
|
|
@@ -97,6 +128,12 @@ export type RenderedProps = Omit<PlaceholderProps, 'fields | params'> & {
|
|
|
97
128
|
};
|
|
98
129
|
rendering: ComponentRendering;
|
|
99
130
|
};
|
|
131
|
+
export interface ComponentForRendering {
|
|
132
|
+
component: React.ComponentType<any>;
|
|
133
|
+
isEmpty: boolean;
|
|
134
|
+
dynamic?: boolean;
|
|
135
|
+
componentType?: ComponentType;
|
|
136
|
+
}
|
|
100
137
|
/**
|
|
101
138
|
* Prop names from placeholder that cannot be serialized and passed from server to client side components
|
|
102
139
|
*/
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ComponentMap } from '../sharedTypes';
|
|
3
3
|
import { ComponentRendering, RouteData } from '@sitecore-content-sdk/core/layout';
|
|
4
|
-
import {
|
|
5
|
-
import { PlaceholderProps, RenderedProps } from './models';
|
|
4
|
+
import { AppComponentProps, BasePlaceholderProps, ComponentForRendering, PlaceholderProps, RenderedProps } from './models';
|
|
6
5
|
/**
|
|
7
6
|
* Get the renderings for the specified placeholder from the rendering data.
|
|
8
7
|
* @param {ComponentRendering | RouteData } rendering rendering data
|
|
@@ -35,6 +34,13 @@ export declare const renderEmptyPlaceholder: (node: React.ReactNode | React.Reac
|
|
|
35
34
|
* @returns {RenderedProps} props to be passed to the rendered component
|
|
36
35
|
*/
|
|
37
36
|
export declare const getRenderedComponentProps: (placeholderProps: PlaceholderProps, componentRendering: ComponentRendering, renderingKey: string) => RenderedProps;
|
|
37
|
+
/**
|
|
38
|
+
* Merge placeholder and component field and params content props.
|
|
39
|
+
* @param {BasePlaceholderProps} placeholderProps placeholder props
|
|
40
|
+
* @param {ComponentRendering} componentRendering component rendering
|
|
41
|
+
* @returns {ComponentProps} merged props
|
|
42
|
+
*/
|
|
43
|
+
export declare function getAppComponentProps<T extends BasePlaceholderProps>(placeholderProps: T, componentRendering: ComponentRendering): AppComponentProps;
|
|
38
44
|
/**
|
|
39
45
|
* Get component implemenation from the component map based on the rendering definition.
|
|
40
46
|
* @param {ComponentRendering} renderingDefinition rendering data
|
|
@@ -44,34 +50,9 @@ export declare const getRenderedComponentProps: (placeholderProps: PlaceholderPr
|
|
|
44
50
|
* @param {React.ComponentClass} [missingComponentComponent] fallback implementation in case no component is found in the component map
|
|
45
51
|
* @returns {ContentSDKComponet | null} component implementation or null if no component map is provided
|
|
46
52
|
*/
|
|
47
|
-
export declare const getComponentForRendering: (renderingDefinition: ComponentRendering, placeholderName: string, componentMap?: ComponentMap, hiddenRenderingComponent?: React.ComponentClass | React.FC, missingComponentComponent?: React.ComponentClass | React.FC) =>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
component: (props: import("../FEaaS").FEaaSComponentProps) => React.JSX.Element;
|
|
54
|
-
isEmpty?: undefined;
|
|
55
|
-
dynamic?: undefined;
|
|
56
|
-
componentType?: undefined;
|
|
57
|
-
} | {
|
|
58
|
-
component: typeof BYOCComponent;
|
|
59
|
-
isEmpty?: undefined;
|
|
60
|
-
dynamic?: undefined;
|
|
61
|
-
componentType?: undefined;
|
|
62
|
-
} | {
|
|
63
|
-
component: (props: import("../FEaaS").BYOCComponentProps) => React.JSX.Element;
|
|
64
|
-
dynamic: boolean;
|
|
65
|
-
isEmpty?: undefined;
|
|
66
|
-
componentType?: undefined;
|
|
67
|
-
} | {
|
|
68
|
-
component: React.FC<import("../MissingComponent").MissingComponentProps> | React.ComponentClass<{}, any>;
|
|
69
|
-
isEmpty: boolean;
|
|
70
|
-
dynamic?: undefined;
|
|
71
|
-
componentType?: undefined;
|
|
72
|
-
} | {
|
|
73
|
-
component: React.ComponentType;
|
|
74
|
-
dynamic: boolean;
|
|
75
|
-
componentType: unknown;
|
|
76
|
-
isEmpty?: undefined;
|
|
77
|
-
};
|
|
53
|
+
export declare const getComponentForRendering: (renderingDefinition: ComponentRendering, placeholderName: string, componentMap?: ComponentMap, hiddenRenderingComponent?: React.ComponentClass | React.FC, missingComponentComponent?: React.ComponentClass | React.FC) => ComponentForRendering;
|
|
54
|
+
/**
|
|
55
|
+
* Get the RSC environment variable.
|
|
56
|
+
* @returns {boolean} true if RSC is enabled, false otherwise.
|
|
57
|
+
*/
|
|
58
|
+
export declare function getRSC(): boolean;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
3
|
import { ComponentRendering } from '@sitecore-content-sdk/core/layout';
|
|
4
|
-
import { ComponentMap } from '../components/sharedTypes';
|
|
5
4
|
import { Page } from '@sitecore-content-sdk/core/client';
|
|
5
|
+
import { ComponentMap } from '../components/sharedTypes';
|
|
6
6
|
export type ComponentProps = {
|
|
7
7
|
rendering: ComponentRendering;
|
|
8
8
|
placeholders: Record<string, React.ReactNode>;
|
|
9
9
|
};
|
|
10
10
|
export type WrapperProps = {
|
|
11
|
+
rendering: ComponentRendering;
|
|
11
12
|
page: Page;
|
|
12
13
|
componentMap: ComponentMap;
|
|
13
|
-
rendering: ComponentRendering;
|
|
14
14
|
};
|
|
15
|
-
export declare const
|
|
15
|
+
export declare const withAppPlaceholder: <T extends ComponentProps, W extends T & WrapperProps>(Component: ComponentType<T>) => (props: W) => React.JSX.Element;
|
package/types/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { GraphQLClientError, RetryStrategy, DefaultRetryStrategy, GraphQLRequest
|
|
|
7
7
|
export { mediaApi } from '@sitecore-content-sdk/core/media';
|
|
8
8
|
export { Form } from './components/Form';
|
|
9
9
|
export { ReactContentSdkComponent, ComponentMap, ReactModule } from './components/sharedTypes';
|
|
10
|
-
export { Placeholder, PlaceholderProps, PlaceholderProps as PlaceholderComponentProps,
|
|
10
|
+
export { Placeholder, PlaceholderProps, PlaceholderProps as PlaceholderComponentProps, AppPlaceholder, AppPlaceholderProps, } from './components/Placeholder';
|
|
11
11
|
export { Image, ImageProps, ImageField, ImageFieldValue, ImageSizeParameters, } from './components/Image';
|
|
12
12
|
export { RichText, RichTextProps, RichTextField } from './components/RichText';
|
|
13
13
|
export { Text, TextField } from './components/Text';
|