@sitecore-content-sdk/react 1.2.0-canary.8 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/LICENSE.txt +202 -202
  2. package/README.md +11 -11
  3. package/dist/cjs/components/ClientEditingChromesUpdate.js +52 -0
  4. package/dist/cjs/components/DefaultEmptyFieldEditingComponents.js +4 -4
  5. package/dist/cjs/components/DesignLibrary.js +85 -103
  6. package/dist/cjs/components/EditingScripts.js +1 -0
  7. package/dist/cjs/components/ErrorBoundary.js +1 -0
  8. package/dist/cjs/components/FEaaS/BYOCServerWrapper.js +28 -0
  9. package/dist/cjs/components/{BYOCComponent.js → FEaaS/BYOCWrapper.js} +17 -28
  10. package/dist/cjs/components/FEaaS/FEaaSSeverWrapper.js +34 -0
  11. package/dist/cjs/components/FEaaS/FEaaSWrapper.js +78 -0
  12. package/dist/cjs/components/{FEaaSComponent.js → FEaaS/feaas-utils.js} +18 -35
  13. package/dist/cjs/components/FEaaS/index.js +21 -0
  14. package/dist/cjs/components/FEaaS/models.js +7 -0
  15. package/dist/cjs/components/Link.js +1 -1
  16. package/dist/cjs/components/Placeholder/AppPlaceholder.js +76 -0
  17. package/dist/cjs/components/Placeholder/ClientComponentWrapper.js +21 -0
  18. package/dist/cjs/components/Placeholder/Placeholder.js +110 -0
  19. package/dist/cjs/components/Placeholder/index.js +25 -0
  20. package/dist/cjs/components/Placeholder/models.js +18 -0
  21. package/dist/cjs/components/Placeholder/placeholder-utils.js +215 -0
  22. package/dist/cjs/components/RichText.js +1 -0
  23. package/dist/cjs/components/Text.js +1 -0
  24. package/dist/cjs/enhancers/withAppPlaceholder.js +21 -0
  25. package/dist/cjs/enhancers/withEmptyFieldEditingComponent.js +12 -5
  26. package/dist/cjs/enhancers/withPlaceholder.js +8 -6
  27. package/dist/cjs/index.js +17 -11
  28. package/dist/cjs/rsc-utils/no-rsc.js +5 -0
  29. package/dist/cjs/rsc-utils/rsc.js +5 -0
  30. package/dist/esm/components/ClientEditingChromesUpdate.js +15 -0
  31. package/dist/esm/components/DefaultEmptyFieldEditingComponents.js +4 -4
  32. package/dist/esm/components/DesignLibrary.js +85 -102
  33. package/dist/esm/components/EditingScripts.js +1 -0
  34. package/dist/esm/components/ErrorBoundary.js +1 -0
  35. package/dist/esm/components/FEaaS/BYOCServerWrapper.js +21 -0
  36. package/dist/esm/components/{BYOCComponent.js → FEaaS/BYOCWrapper.js} +15 -26
  37. package/dist/esm/components/FEaaS/FEaaSSeverWrapper.js +27 -0
  38. package/dist/esm/components/FEaaS/FEaaSWrapper.js +37 -0
  39. package/dist/esm/components/{FEaaSComponent.js → FEaaS/feaas-utils.js} +16 -30
  40. package/dist/esm/components/FEaaS/index.js +6 -0
  41. package/dist/esm/components/FEaaS/models.js +4 -0
  42. package/dist/esm/components/Link.js +1 -1
  43. package/dist/esm/components/Placeholder/AppPlaceholder.js +69 -0
  44. package/dist/esm/components/Placeholder/ClientComponentWrapper.js +14 -0
  45. package/dist/esm/components/Placeholder/Placeholder.js +103 -0
  46. package/dist/esm/components/Placeholder/index.js +4 -0
  47. package/dist/esm/components/Placeholder/models.js +15 -0
  48. package/dist/esm/components/Placeholder/placeholder-utils.js +203 -0
  49. package/dist/esm/components/RichText.js +1 -0
  50. package/dist/esm/components/Text.js +1 -0
  51. package/dist/esm/enhancers/withAppPlaceholder.js +14 -0
  52. package/dist/esm/enhancers/withEmptyFieldEditingComponent.js +12 -5
  53. package/dist/esm/enhancers/withPlaceholder.js +8 -6
  54. package/dist/esm/index.js +5 -5
  55. package/dist/esm/rsc-utils/no-rsc.js +2 -0
  56. package/dist/esm/rsc-utils/rsc.js +2 -0
  57. package/package.json +16 -4
  58. package/types/components/ClientEditingChromesUpdate.d.ts +6 -0
  59. package/types/components/Date.d.ts +1 -1
  60. package/types/components/DefaultEmptyFieldEditingComponents.d.ts +8 -2
  61. package/types/components/DesignLibrary.d.ts +13 -13
  62. package/types/components/ErrorBoundary.d.ts +0 -1
  63. package/types/components/FEaaS/BYOCServerWrapper.d.ts +3 -0
  64. package/types/components/FEaaS/BYOCWrapper.d.ts +25 -0
  65. package/types/components/FEaaS/FEaaSSeverWrapper.d.ts +8 -0
  66. package/types/components/FEaaS/FEaaSWrapper.d.ts +7 -0
  67. package/types/components/FEaaS/feaas-utils.d.ts +21 -0
  68. package/types/components/FEaaS/index.d.ts +6 -0
  69. package/types/components/FEaaS/models.d.ts +125 -0
  70. package/types/components/Image.d.ts +1 -1
  71. package/types/components/Link.d.ts +1 -1
  72. package/types/components/Placeholder/AppPlaceholder.d.ts +10 -0
  73. package/types/components/Placeholder/ClientComponentWrapper.d.ts +9 -0
  74. package/types/components/Placeholder/Placeholder.d.ts +28 -0
  75. package/types/components/Placeholder/index.d.ts +5 -0
  76. package/types/components/Placeholder/models.d.ts +140 -0
  77. package/types/components/Placeholder/placeholder-utils.d.ts +53 -0
  78. package/types/components/RichText.d.ts +1 -1
  79. package/types/components/Text.d.ts +1 -1
  80. package/types/components/sharedTypes/components.d.ts +6 -0
  81. package/types/components/sharedTypes/props.d.ts +2 -2
  82. package/types/enhancers/withAppPlaceholder.d.ts +15 -0
  83. package/types/enhancers/withEmptyFieldEditingComponent.d.ts +3 -3
  84. package/types/enhancers/withPlaceholder.d.ts +2 -1
  85. package/types/index.d.ts +4 -5
  86. package/types/rsc-utils/no-rsc.d.ts +1 -0
  87. package/types/rsc-utils/rsc.d.ts +1 -0
  88. package/dist/cjs/components/BYOCWrapper.js +0 -22
  89. package/dist/cjs/components/FEaaSWrapper.js +0 -19
  90. package/dist/cjs/components/Placeholder.js +0 -68
  91. package/dist/cjs/components/PlaceholderCommon.js +0 -176
  92. package/dist/esm/components/BYOCWrapper.js +0 -15
  93. package/dist/esm/components/FEaaSWrapper.js +0 -12
  94. package/dist/esm/components/Placeholder.js +0 -62
  95. package/dist/esm/components/PlaceholderCommon.js +0 -169
  96. package/types/components/BYOCComponent.d.ts +0 -93
  97. package/types/components/BYOCWrapper.d.ts +0 -7
  98. package/types/components/FEaaSComponent.d.ts +0 -72
  99. package/types/components/FEaaSWrapper.d.ts +0 -4
  100. package/types/components/Placeholder.d.ts +0 -20
  101. package/types/components/PlaceholderCommon.d.ts +0 -89
  102. /package/dist/cjs/components/{PlaceholderMetadata.js → Placeholder/PlaceholderMetadata.js} +0 -0
  103. /package/dist/esm/components/{PlaceholderMetadata.js → Placeholder/PlaceholderMetadata.js} +0 -0
  104. /package/types/components/{PlaceholderMetadata.d.ts → Placeholder/PlaceholderMetadata.d.ts} +0 -0
@@ -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
+ };
@@ -0,0 +1,103 @@
1
+ 'use client';
2
+ import React from 'react';
3
+ import { withComponentMap } from '../../enhancers/withComponentMap';
4
+ import { PagesEditor } from '@sitecore-content-sdk/core/editing';
5
+ import { withSitecore } from '../../enhancers/withSitecore';
6
+ import { getComponentForRendering, getPlaceholderRenderings, getRenderedComponentProps, renderEmptyPlaceholder, } from './placeholder-utils';
7
+ import { PlaceholderMetadata } from './PlaceholderMetadata';
8
+ import ErrorBoundary from '../ErrorBoundary';
9
+ export class PlaceholderComponent extends React.Component {
10
+ constructor(props) {
11
+ super(props);
12
+ this.isEmpty = false;
13
+ this.state = {};
14
+ }
15
+ componentDidMount() {
16
+ if (this.isEmpty && PagesEditor.isActive()) {
17
+ PagesEditor.resetChromes();
18
+ }
19
+ }
20
+ componentDidCatch(error) {
21
+ this.setState({ error });
22
+ }
23
+ /**
24
+ * Renders the placeholder when it is empty. The required CSS styles are applied to the placeholder in edit mode.
25
+ * @param {React.ReactNode | React.ReactElement[]} node react node
26
+ * @returns react node
27
+ * @deprecated use renderEmptyPlaceholder from react/nextjs import instead
28
+ */
29
+ renderEmptyPlaceholder(node) {
30
+ return renderEmptyPlaceholder(node);
31
+ }
32
+ render() {
33
+ const childProps = Object.assign({}, this.props);
34
+ delete childProps.componentMap;
35
+ if (this.state.error) {
36
+ if (childProps.errorComponent) {
37
+ return React.createElement(childProps.errorComponent, { error: this.state.error });
38
+ }
39
+ return (React.createElement("div", { className: "sc-content-sdk-placeholder-error" },
40
+ "A rendering error occurred: ",
41
+ this.state.error.message,
42
+ "."));
43
+ }
44
+ const renderingData = childProps.rendering;
45
+ const placeholderRenderings = getPlaceholderRenderings(renderingData, this.props.name, this.props.page.mode.isEditing);
46
+ this.isEmpty = !placeholderRenderings.length;
47
+ const components = PlaceholderComponent.getRenderedComponents(this.props, placeholderRenderings);
48
+ if (this.isEmpty) {
49
+ const rendered = this.props.renderEmpty ? this.props.renderEmpty(components) : components;
50
+ return this.props.page.mode.isEditing ? renderEmptyPlaceholder(rendered) : rendered;
51
+ }
52
+ else if (this.props.render) {
53
+ return this.props.render(components, placeholderRenderings, childProps);
54
+ }
55
+ else if (this.props.renderEach) {
56
+ const renderEach = this.props.renderEach;
57
+ return components.map((component, index) => {
58
+ if (component && component.props && component.props.type === 'text/sitecore') {
59
+ return component;
60
+ }
61
+ return renderEach(component, index);
62
+ });
63
+ }
64
+ else {
65
+ return components;
66
+ }
67
+ }
68
+ }
69
+ /**
70
+ * Renders the components for the placeholder based on the provided rendering data.
71
+ * @param {PlaceholderProps} props placeholder component props
72
+ * @param {ComponentRendering[]} placeholderRenderings renderings within placeholder
73
+ * @returns {React.ReactNode | React.ReactElement[]} rendered components
74
+ */
75
+ PlaceholderComponent.getRenderedComponents = (props, placeholderRenderings) => {
76
+ const { name, missingComponentComponent, hiddenRenderingComponent } = props;
77
+ const transformedComponents = placeholderRenderings
78
+ .map((componentRendering, index) => {
79
+ const key = componentRendering.uid || `component-${index}`;
80
+ const renderedProps = getRenderedComponentProps(props, componentRendering, key);
81
+ const component = getComponentForRendering(componentRendering, name, props.componentMap, hiddenRenderingComponent, missingComponentComponent);
82
+ let rendered = React.createElement(component.component, props.modifyComponentProps ? props.modifyComponentProps(renderedProps) : renderedProps);
83
+ if (!component.isEmpty) {
84
+ const errorBoundaryKey = rendered.type + '-' + index;
85
+ const disableSuspense = props.disableSuspense || false;
86
+ rendered = (React.createElement(ErrorBoundary, { "data-testid": "error-boundary", key: errorBoundaryKey, errorComponent: props.errorComponent, componentLoadingMessage: props.componentLoadingMessage, isDynamic: component.dynamic, disableSuspense: disableSuspense, rendering: rendered.props.rendering }, rendered));
87
+ }
88
+ // if in edit mode then emit shallow chromes for hydration in Pages
89
+ if (props.page.mode.isEditing) {
90
+ return (React.createElement(PlaceholderMetadata, { key: key, rendering: componentRendering }, rendered));
91
+ }
92
+ return rendered;
93
+ })
94
+ .filter((element) => element); // remove nulls
95
+ if (props.page.mode.isEditing) {
96
+ return [
97
+ React.createElement(PlaceholderMetadata, { key: props.rendering.uid, placeholderName: name, rendering: props.rendering }, transformedComponents),
98
+ ];
99
+ }
100
+ return transformedComponents;
101
+ };
102
+ const PlaceholderWithComponentMap = withComponentMap(PlaceholderComponent);
103
+ export const Placeholder = withSitecore()(PlaceholderWithComponentMap);
@@ -0,0 +1,4 @@
1
+ export { Placeholder, PlaceholderComponent } from './Placeholder';
2
+ export { PlaceholderMetadata } from './PlaceholderMetadata';
3
+ export { AppPlaceholder } from './AppPlaceholder';
4
+ export * from './placeholder-utils';
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Prop names from placeholder that cannot be serialized and passed from server to client side components
3
+ */
4
+ export const nonSerializedPlaceholderProps = [
5
+ 'renderEmpty',
6
+ 'render',
7
+ 'renderEach',
8
+ 'errorComponent',
9
+ 'componentLoadingMessage',
10
+ 'modifyComponentProps',
11
+ 'componentMap',
12
+ 'page',
13
+ 'missingComponentComponent',
14
+ 'hiddenRenderingComponent',
15
+ ];
@@ -0,0 +1,203 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import React from 'react';
13
+ import { MissingComponent } from '../MissingComponent';
14
+ import { DEFAULT_EXPORT_NAME } from '../sharedTypes';
15
+ import { isDynamicPlaceholder, getDynamicPlaceholderPattern, } from '@sitecore-content-sdk/core/layout';
16
+ import { constants } from '@sitecore-content-sdk/core';
17
+ import { HiddenRendering } from '../HiddenRendering';
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
+ /**
20
+ * Get the renderings for the specified placeholder from the rendering data.
21
+ * @param {ComponentRendering | RouteData } rendering rendering data
22
+ * @param {string} name placeholder name
23
+ * @param {boolean} isEditing whether components should be rendered in editing mode
24
+ * @returns {ComponentRendering[]} array of component renderings
25
+ */
26
+ export const getPlaceholderRenderings = (rendering, name, isEditing) => {
27
+ let result;
28
+ let phName = name.slice();
29
+ /**
30
+ * Process (SXA) dynamic placeholders
31
+ * Find and replace the matching dynamic placeholder e.g 'nameOfContainer-{*}' with the requested e.g. 'nameOfContainer-1'.
32
+ * For Metadata EditMode, we need to keep the raw placeholder name in place.
33
+ */
34
+ if (rendering === null || rendering === void 0 ? void 0 : rendering.placeholders) {
35
+ Object.keys(rendering.placeholders).forEach((placeholder) => {
36
+ const patternPlaceholder = isDynamicPlaceholder(placeholder)
37
+ ? getDynamicPlaceholderPattern(placeholder)
38
+ : null;
39
+ if (patternPlaceholder && patternPlaceholder.test(phName)) {
40
+ if (isEditing) {
41
+ phName = placeholder;
42
+ }
43
+ else {
44
+ rendering.placeholders[phName] = rendering.placeholders[placeholder];
45
+ delete rendering.placeholders[placeholder];
46
+ }
47
+ }
48
+ });
49
+ }
50
+ if (rendering && rendering.placeholders && Object.keys(rendering.placeholders).length > 0) {
51
+ result = rendering.placeholders[phName];
52
+ }
53
+ else {
54
+ result = null;
55
+ }
56
+ if (!result) {
57
+ console.warn(`Placeholder '${phName}' was not found in the current rendering data`, JSON.stringify(rendering, null, 2));
58
+ return [];
59
+ }
60
+ return result;
61
+ };
62
+ /**
63
+ * Get SXA specific params from Sitecore rendering params
64
+ * @param {ComponentRendering} rendering rendering object
65
+ * @returns {object} converted SXA params
66
+ */
67
+ export const getSXAParams = (rendering) => {
68
+ if (!rendering.params)
69
+ return {};
70
+ const { GridParameters, Styles } = rendering.params;
71
+ return ((GridParameters || Styles) && {
72
+ styles: `${GridParameters || ''} ${Styles || ''}`,
73
+ });
74
+ };
75
+ /**
76
+ * Renders the placeholder when it is empty. The required CSS styles are applied to the placeholder in edit mode.
77
+ * @param {React.ReactNode | React.ReactElement[]} node react node
78
+ * @returns react node
79
+ */
80
+ export const renderEmptyPlaceholder = (node) => {
81
+ return React.createElement("div", { className: "sc-jss-empty-placeholder" }, node);
82
+ };
83
+ /**
84
+ * Get component props to be passed to the rendered component.
85
+ * @param {PlaceholderProps} placeholderProps current placeholder props
86
+ * @param {ComponentRendering} componentRendering rendering to be rendered
87
+ * @param {string} renderingKey unique key to pass over to rendering props
88
+ * @returns {RenderedProps} props to be passed to the rendered component
89
+ */
90
+ export const getRenderedComponentProps = (placeholderProps, componentRendering, renderingKey) => {
91
+ // eslint-disable-next-line no-unused-vars
92
+ const { fields, params: placeholderParams } = placeholderProps, passThroughProps = __rest(placeholderProps, ["fields", "params"]);
93
+ delete passThroughProps.missingComponentComponent;
94
+ delete passThroughProps.hiddenRenderingComponent;
95
+ delete passThroughProps.name;
96
+ const mergedContentProps = getAppComponentProps(placeholderProps, componentRendering);
97
+ return Object.assign(Object.assign(Object.assign({ key: renderingKey }, passThroughProps), mergedContentProps), { rendering: componentRendering });
98
+ };
99
+ /**
100
+ * Merge placeholder and component field and params content props.
101
+ * @param {BasePlaceholderProps} placeholderProps placeholder props
102
+ * @param {ComponentRendering} componentRendering component rendering
103
+ * @returns {ComponentProps} merged props
104
+ */
105
+ export function getAppComponentProps(placeholderProps, componentRendering) {
106
+ const fields = Object.assign(Object.assign({}, (placeholderProps.fields || {})), (componentRendering.fields || {}));
107
+ const params = Object.assign(Object.assign({}, (placeholderProps.params || {})), (componentRendering.params || {}));
108
+ return {
109
+ fields,
110
+ params: Object.assign(Object.assign({}, params), getSXAParams(componentRendering)),
111
+ rendering: componentRendering,
112
+ };
113
+ }
114
+ /**
115
+ * Get component implemenation from the component map based on the rendering definition.
116
+ * @param {ComponentRendering} renderingDefinition rendering data
117
+ * @param {string} placeholderName name of current placeholder
118
+ * @param {ComponentMap} componentMap component map for the current app
119
+ * @param {React.ComponentClass} [hiddenRenderingComponent] fallback implementation in to be rendered if the rendering is hidden
120
+ * @param {React.ComponentClass} [missingComponentComponent] fallback implementation in case no component is found in the component map
121
+ * @returns {ContentSDKComponet | null} component implementation or null if no component map is provided
122
+ */
123
+ export const getComponentForRendering = (renderingDefinition, placeholderName, componentMap, hiddenRenderingComponent, missingComponentComponent) => {
124
+ var _a, _b;
125
+ if (renderingDefinition.componentName === constants.HIDDEN_RENDERING_NAME) {
126
+ return {
127
+ component: hiddenRenderingComponent !== null && hiddenRenderingComponent !== void 0 ? hiddenRenderingComponent : HiddenRendering,
128
+ isEmpty: true,
129
+ componentType: 'universal',
130
+ };
131
+ }
132
+ else if (!renderingDefinition.componentName) {
133
+ console.error(`Placeholder ${placeholderName} contains unknown component ${renderingDefinition.componentName}. Ensure that a React component exists for it, and that it is registered in your component-map file.`);
134
+ return {
135
+ component: () => React.createElement(React.Fragment, null),
136
+ isEmpty: true,
137
+ componentType: 'universal',
138
+ };
139
+ }
140
+ let component = null;
141
+ if (!componentMap || componentMap.size === 0) {
142
+ console.warn(`No components were available in component map to service request for component ${renderingDefinition}`);
143
+ }
144
+ else {
145
+ component = componentMap.get(renderingDefinition.componentName);
146
+ }
147
+ if (!component) {
148
+ // Fallback/defaults for Sitecore Component renderings (in case not defined in component map)
149
+ if (renderingDefinition.componentName === FEAAS_COMPONENT_RENDERING_NAME) {
150
+ return {
151
+ component: FEaaSComponent,
152
+ isEmpty: false,
153
+ componentType: 'universal',
154
+ };
155
+ }
156
+ else if (renderingDefinition.componentName === FEAAS_WRAPPER_RENDERING_NAME) {
157
+ return {
158
+ component: FEaaSWrapper,
159
+ isEmpty: false,
160
+ componentType: 'universal',
161
+ };
162
+ }
163
+ else if (renderingDefinition.componentName === BYOC_COMPONENT_RENDERING_NAME) {
164
+ return {
165
+ component: BYOCComponent,
166
+ isEmpty: false,
167
+ componentType: 'universal',
168
+ };
169
+ }
170
+ else if (renderingDefinition.componentName === BYOC_WRAPPER_RENDERING_NAME) {
171
+ // wrapping with error boundary could cause problems in case where parent component uses withPlaceholder HOC and tries to access its children props
172
+ // that's why we need to mark BYOC wrapper dynamic
173
+ return {
174
+ component: BYOCWrapper,
175
+ dynamic: true,
176
+ componentType: 'universal',
177
+ isEmpty: false,
178
+ };
179
+ }
180
+ return {
181
+ component: missingComponentComponent !== null && missingComponentComponent !== void 0 ? missingComponentComponent : MissingComponent,
182
+ isEmpty: true,
183
+ componentType: 'universal',
184
+ };
185
+ }
186
+ // Render SXA Rendering Variant if available
187
+ const exportName = (_a = renderingDefinition.params) === null || _a === void 0 ? void 0 : _a.FieldNames;
188
+ const renderedComponent = exportName && exportName !== DEFAULT_EXPORT_NAME
189
+ ? component[exportName]
190
+ : component.default ||
191
+ component.Default ||
192
+ component;
193
+ const dynamic = !!((_b = renderedComponent.render) === null || _b === void 0 ? void 0 : _b.preload) ||
194
+ renderingDefinition.componentName === BYOC_WRAPPER_RENDERING_NAME;
195
+ // all dynamic elements will have a separate render prop
196
+ return {
197
+ component: renderedComponent,
198
+ dynamic,
199
+ componentType: component
200
+ .componentType,
201
+ isEmpty: false,
202
+ };
203
+ };
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  var __rest = (this && this.__rest) || function (s, e) {
2
3
  var t = {};
3
4
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  var __rest = (this && this.__rest) || function (s, e) {
2
3
  var t = {};
3
4
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { AppPlaceholder } from '../components/Placeholder/AppPlaceholder';
3
+ export const withAppPlaceholder = (Component) => {
4
+ return (props) => {
5
+ const placeholders = props.rendering.placeholders;
6
+ const phProps = {};
7
+ for (const placeholder of Object.keys(placeholders)) {
8
+ phProps[placeholder] = (React.createElement(AppPlaceholder, { name: placeholder, rendering: props.rendering, componentMap: props.componentMap, page: props.page }));
9
+ }
10
+ const displayName = Component.displayName || Component.name || 'Component';
11
+ const propsCopy = Object.assign(Object.assign({}, props), { displayName });
12
+ return React.createElement(Component, Object.assign({}, propsCopy, { placeholders: phProps }));
13
+ };
14
+ };
@@ -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
- return props.emptyFieldEditingComponent || options.defaultEmptyFieldEditingComponent;
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 EmptyFieldEditingComponent = getEmptyFieldEditingComponent(props);
20
- return (React.createElement(React.Fragment, null, (EmptyFieldEditingComponent && React.createElement(EmptyFieldEditingComponent, null)) || (React.createElement(FieldComponent, Object.assign({}, props, { ref: ref })))));
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 EmptyFieldEditingComponent = getEmptyFieldEditingComponent(props);
25
- return (React.createElement(React.Fragment, null, (EmptyFieldEditingComponent && React.createElement(EmptyFieldEditingComponent, null)) || (React.createElement(FieldComponent, Object.assign({}, props)))));
31
+ const emptyFieldEditingComponent = getEmptyFieldEditingComponent(props);
32
+ return emptyFieldEditingComponent || React.createElement(FieldComponent, Object.assign({}, props));
26
33
  };
27
34
  }
@@ -1,14 +1,15 @@
1
1
  import React from 'react';
2
- import { PlaceholderCommon } from '../components/PlaceholderCommon';
3
2
  import { withComponentMap } from './withComponentMap';
4
3
  import { withSitecore } from './withSitecore';
4
+ import { PlaceholderComponent, getPlaceholderRenderings, } from '../components/Placeholder';
5
5
  /**
6
+ * HOC to provide client-side placeholder functionality to a component.
6
7
  * @param {WithPlaceholderSpec} placeholders
7
8
  * @param {WithPlaceholderOptions} [options]
8
9
  */
9
10
  export function withPlaceholder(placeholders, options) {
10
11
  return (WrappedComponent) => {
11
- class WithPlaceholder extends PlaceholderCommon {
12
+ class WithPlaceholder extends PlaceholderComponent {
12
13
  constructor(props) {
13
14
  super(props);
14
15
  }
@@ -36,16 +37,17 @@ export function withPlaceholder(placeholders, options) {
36
37
  definitelyArrayPlacholders.forEach((placeholder) => {
37
38
  let placeholderData;
38
39
  if (typeof placeholder !== 'string' && placeholder.placeholder && placeholder.prop) {
39
- placeholderData = PlaceholderCommon.getPlaceholderDataFromRenderingData(renderingData, placeholder.placeholder, childProps.page.mode.isEditing);
40
+ placeholderData = getPlaceholderRenderings(renderingData, placeholder.placeholder, childProps.page.mode.isEditing);
40
41
  if (placeholderData) {
41
- childProps[placeholder.prop] = this.getComponentsForRenderingData(placeholderData);
42
+ childProps[placeholder.prop] =
43
+ PlaceholderComponent.getRenderedComponents(this.props, placeholderData);
42
44
  }
43
45
  }
44
46
  else {
45
- placeholderData = PlaceholderCommon.getPlaceholderDataFromRenderingData(renderingData, placeholder, childProps.page.mode.isEditing);
47
+ placeholderData = getPlaceholderRenderings(renderingData, placeholder, childProps.page.mode.isEditing);
46
48
  if (placeholderData) {
47
49
  childProps[placeholder] =
48
- this.getComponentsForRenderingData(placeholderData);
50
+ PlaceholderComponent.getRenderedComponents(this.props, placeholderData);
49
51
  }
50
52
  }
51
53
  });
package/dist/esm/index.js CHANGED
@@ -5,16 +5,15 @@ 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 } from './components/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';
12
12
  export { DateField } from './components/Date';
13
- export { FEaaSComponent, fetchFEaaSComponentServerProps, } from './components/FEaaSComponent';
14
- export { FEaaSWrapper } from './components/FEaaSWrapper';
13
+ export { FEaaSComponent, fetchFEaaSComponentServerProps, BYOCComponent, fetchBYOCComponentServerProps,
14
+ // leaving original names for backward compatibility
15
+ BYOCWrapper, BYOCWrapper as BYOCClientWrapper, FEaaSWrapper, FEaaSWrapper as FEaaSClientWrapper, FEaaSServerWrapper, BYOCServerWrapper, } from './components/FEaaS';
15
16
  export { DesignLibrary } from './components/DesignLibrary';
16
- export { BYOCComponent, fetchBYOCComponentServerProps, } from './components/BYOCComponent';
17
- export { BYOCWrapper } from './components/BYOCWrapper';
18
17
  export { Link } from './components/Link';
19
18
  export { File } from './components/File';
20
19
  export { SitecoreProvider, SitecoreProviderReactContext, } from './components/SitecoreProvider';
@@ -26,4 +25,5 @@ export { withFieldMetadata } from './enhancers/withFieldMetadata';
26
25
  export { withEmptyFieldEditingComponent } from './enhancers/withEmptyFieldEditingComponent';
27
26
  export { EditingScripts } from './components/EditingScripts';
28
27
  export { DefaultEmptyFieldEditingComponentText, DefaultEmptyFieldEditingComponentImage, } from './components/DefaultEmptyFieldEditingComponents';
28
+ export { ClientEditingChromesUpdate } from './components/ClientEditingChromesUpdate';
29
29
  export { SitePathService } from '@sitecore-content-sdk/core/site';
@@ -0,0 +1,2 @@
1
+ // Always false constant to import in the non-RSC contexts using conditional imports
2
+ export const rsc = false;
@@ -0,0 +1,2 @@
1
+ // Always true constant to import in the RSC environment using conditional imports
2
+ export const rsc = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sitecore-content-sdk/react",
3
- "version": "1.2.0-canary.8",
3
+ "version": "1.2.0",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "sideEffects": false,
@@ -38,6 +38,7 @@
38
38
  "@types/chai-string": "^1.4.5",
39
39
  "@types/mocha": "^10.0.10",
40
40
  "@types/node": "22.15.14",
41
+ "@types/proxyquire": "^1.3.31",
41
42
  "@types/react": "^19.1.3",
42
43
  "@types/react-dom": "^19.1.3",
43
44
  "@types/sinon": "^17.0.4",
@@ -58,6 +59,7 @@
58
59
  "mocha": "^11.2.2",
59
60
  "nyc": "^17.1.0",
60
61
  "prettier": "^2.8.0",
62
+ "proxyquire": "^2.1.3",
61
63
  "react": "^19.1.0",
62
64
  "react-dom": "^19.1.0",
63
65
  "sinon": "^20.0.0",
@@ -72,14 +74,24 @@
72
74
  "react-dom": "^19.1.0"
73
75
  },
74
76
  "dependencies": {
75
- "@sitecore-content-sdk/core": "1.2.0-canary.8",
77
+ "@sitecore-content-sdk/core": "1.2.0",
76
78
  "fast-deep-equal": "^3.1.3"
77
79
  },
78
80
  "description": "",
79
81
  "types": "types/index.d.ts",
80
- "gitHead": "6c28d70735881667365f3e65a423a90314fe5256",
82
+ "gitHead": "7c079f6f1d968ad39ce5b927559734c96d6adc20",
81
83
  "files": [
82
84
  "dist",
83
85
  "types"
84
- ]
86
+ ],
87
+ "imports": {
88
+ "#rsc-env": {
89
+ "react-server": {
90
+ "import": "./dist/esm/rsc-utils/rsc.js",
91
+ "default": "./dist/cjs/rsc-utils/rsc.js"
92
+ },
93
+ "import": "./dist/esm/rsc-utils/no-rsc.js",
94
+ "default": "./dist/cjs/rsc-utils/no-rsc.js"
95
+ }
96
+ }
85
97
  }
@@ -0,0 +1,6 @@
1
+ import { JSX } from 'react';
2
+ /**
3
+ * Updates editing chromes in app router / RSC context.
4
+ * This ensures all the relevant Pages editing markup is applied once all client components are loaded.
5
+ */
6
+ export declare const ClientEditingChromesUpdate: () => JSX.Element;
@@ -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
- export declare const DefaultEmptyFieldEditingComponentImage: React.FC;
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 { JSX } from 'react';
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
- export declare const DesignLibrary: ({ loadImportMap }: DesignLibraryProps) => JSX.Element;
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 {};
@@ -7,7 +7,6 @@ type ErrorComponentProps = {
7
7
  export type ErrorBoundaryProps = {
8
8
  children: ReactNode;
9
9
  page: Page;
10
- type: string;
11
10
  isDynamic?: boolean;
12
11
  errorComponent?: React.ComponentClass<ErrorComponentProps> | React.FC<ErrorComponentProps>;
13
12
  rendering?: ComponentRendering;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { BYOCServerWrapperProps } from './models';
3
+ export declare const BYOCServerWrapper: (props: BYOCServerWrapperProps) => Promise<React.JSX.Element>;
@@ -0,0 +1,25 @@
1
+ import React, { JSX } from 'react';
2
+ import { BYOCComponentProps } from './models';
3
+ /**
4
+ * BYOCComponent facilitate the rendering of external components. It manages potential errors,
5
+ * missing components, and customization of error messages or alternative rendering components.
6
+ * @param {ByocComponentProps} props component props
7
+ * @returns dynamically rendered component or Missing Component error frame
8
+ */
9
+ export declare class BYOCComponent extends React.Component<BYOCComponentProps> {
10
+ state: Readonly<{
11
+ error?: Error;
12
+ }>;
13
+ constructor(props: BYOCComponentProps);
14
+ static getDerivedStateFromError(error: Error): {
15
+ error: Error;
16
+ };
17
+ componentDidCatch(error: Error): void;
18
+ render(): JSX.Element;
19
+ }
20
+ /**
21
+ * SXA wrapper for BYOC components
22
+ * @param {BYOCComponentProps} props component props
23
+ * @returns wrapped BYOC component
24
+ */
25
+ export declare const BYOCWrapper: (props: BYOCComponentProps) => JSX.Element;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { FEaaSServerWrapperProps } from './models';
3
+ /**
4
+ * Server component for FEaaS. Retrieves server props and renders client FEaaSWrapper.
5
+ * @param {FEaaSComponentProps} props incoming props
6
+ * @returns {Promise<JSX.Element>} rendered FEaaSWrapper component
7
+ */
8
+ export declare const FEaaSServerWrapper: (props: FEaaSServerWrapperProps) => Promise<React.JSX.Element>;