@sitecore-jss/sitecore-jss-react 21.3.0-canary.4 → 21.3.0-canary.41
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/README.md +3 -3
- package/dist/cjs/components/BYOCRenderer.js +77 -0
- package/dist/cjs/components/FEaaSComponent.js +66 -32
- package/dist/cjs/components/Image.js +2 -2
- package/dist/cjs/components/MissingComponent.js +6 -2
- package/dist/cjs/components/Placeholder.js +1 -29
- package/dist/cjs/index.js +5 -1
- package/dist/cjs/utils.js +50 -2
- package/dist/esm/components/BYOCRenderer.js +70 -0
- package/dist/esm/components/FEaaSComponent.js +66 -32
- package/dist/esm/components/Image.js +2 -2
- package/dist/esm/components/MissingComponent.js +6 -2
- package/dist/esm/components/Placeholder.js +2 -30
- package/dist/esm/index.js +2 -0
- package/dist/esm/utils.js +47 -1
- package/package.json +3 -3
- package/types/components/BYOCRenderer.d.ts +75 -0
- package/types/components/FEaaSComponent.d.ts +5 -4
- package/types/components/MissingComponent.d.ts +1 -0
- package/types/index.d.ts +2 -0
- package/types/utils.d.ts +18 -1
package/README.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
This module is provided as a part of Sitecore JavaScript Rendering SDK (JSS). It contains React components and integration for JSS.
|
|
4
4
|
|
|
5
5
|
<!---
|
|
6
|
-
@TODO: Update to version
|
|
6
|
+
@TODO: Update to next version docs before release
|
|
7
7
|
-->
|
|
8
|
-
[Documentation](https://doc.sitecore.com/xp/en/developers/hd/
|
|
8
|
+
[Documentation (Experience Platform)](https://doc.sitecore.com/xp/en/developers/hd/21/sitecore-headless-development/sitecore-javascript-rendering-sdk--jss--for-react.html)
|
|
9
9
|
|
|
10
|
-
[API reference documentation](/ref-docs/sitecore-jss-react/)
|
|
10
|
+
[API reference documentation](/ref-docs/sitecore-jss-react/)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.BYOCRenderer = void 0;
|
|
7
|
+
const react_1 = __importDefault(require("react"));
|
|
8
|
+
const utils_1 = require("../utils");
|
|
9
|
+
const MissingComponent_1 = require("./MissingComponent");
|
|
10
|
+
const DefaultErrorComponent = (props) => {
|
|
11
|
+
var _a;
|
|
12
|
+
return (react_1.default.createElement("div", null,
|
|
13
|
+
"A rendering error occurred: ", (_a = props.error) === null || _a === void 0 ? void 0 :
|
|
14
|
+
_a.message,
|
|
15
|
+
"."));
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* BYOCRenderer helps rendering BYOC components - that can be taken from anywhere
|
|
19
|
+
* and registered without being deployed as Sitecore renderings
|
|
20
|
+
* @param {ByocRendererProps} props component props
|
|
21
|
+
* @returns dynamicly rendered component or Missing Component error frame
|
|
22
|
+
*/
|
|
23
|
+
class BYOCRenderer extends react_1.default.Component {
|
|
24
|
+
constructor(props) {
|
|
25
|
+
super(props);
|
|
26
|
+
this.state = {};
|
|
27
|
+
}
|
|
28
|
+
static getDerivedStateFromError(error) {
|
|
29
|
+
// Update state so the next render will show the fallback UI.
|
|
30
|
+
return { error: error };
|
|
31
|
+
}
|
|
32
|
+
componentDidCatch(error) {
|
|
33
|
+
this.setState({ error });
|
|
34
|
+
}
|
|
35
|
+
render() {
|
|
36
|
+
var _a, _b, _c;
|
|
37
|
+
const props = this.props;
|
|
38
|
+
if (this.state.error) {
|
|
39
|
+
return this.props.errorComponent ? (react_1.default.createElement(this.props.errorComponent, { error: this.state.error })) : (react_1.default.createElement(DefaultErrorComponent, { error: this.state.error }));
|
|
40
|
+
}
|
|
41
|
+
const { ComponentName: componentName } = props.params || {};
|
|
42
|
+
if (!componentName) {
|
|
43
|
+
const noNameProps = {
|
|
44
|
+
errorOverride: 'BYOC: The ComponentName for this rendering is missing',
|
|
45
|
+
};
|
|
46
|
+
return props.missingComponentComponent ? (react_1.default.createElement(this.props.missingComponentComponent, Object.assign({}, noNameProps))) : (react_1.default.createElement(MissingComponent_1.MissingComponent, Object.assign({}, noNameProps)));
|
|
47
|
+
}
|
|
48
|
+
// props.components would contain component from internal FEAAS regsitered component collection (registered in app)
|
|
49
|
+
// we can't access this collection here directly, as the collection from packages's dependency would be different from the one in app
|
|
50
|
+
const Component = (_a = props.components[componentName]) === null || _a === void 0 ? void 0 : _a.component;
|
|
51
|
+
if (!Component) {
|
|
52
|
+
console.warn(`Component "${componentName}" was not registered, please ensure the FEEAS.External.registerComponent call is made.`);
|
|
53
|
+
const missingProps = {
|
|
54
|
+
rendering: {
|
|
55
|
+
componentName: componentName,
|
|
56
|
+
},
|
|
57
|
+
errorOverride: 'BYOC: This component was not registered.',
|
|
58
|
+
};
|
|
59
|
+
return props.missingComponentComponent ? (react_1.default.createElement(this.props.missingComponentComponent, Object.assign({}, missingProps))) : (react_1.default.createElement(MissingComponent_1.MissingComponent, Object.assign({}, missingProps)));
|
|
60
|
+
}
|
|
61
|
+
let componentProps = undefined;
|
|
62
|
+
if ((_b = props.params) === null || _b === void 0 ? void 0 : _b.ComponentProps) {
|
|
63
|
+
try {
|
|
64
|
+
componentProps = (_c = JSON.parse(props.params.ComponentProps)) !== null && _c !== void 0 ? _c : {};
|
|
65
|
+
}
|
|
66
|
+
catch (e) {
|
|
67
|
+
console.warn(`Parsing props for ${componentName} component from rendering params failed. Error: ${e}`);
|
|
68
|
+
return this.props.errorComponent ? (react_1.default.createElement(this.props.errorComponent, { error: e })) : (react_1.default.createElement(DefaultErrorComponent, { error: e }));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (!componentProps) {
|
|
72
|
+
componentProps = props.fields ? (0, utils_1.getDataFromFields)(props.fields) : {};
|
|
73
|
+
}
|
|
74
|
+
return react_1.default.createElement(Component, Object.assign({}, componentProps));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.BYOCRenderer = BYOCRenderer;
|
|
@@ -39,6 +39,7 @@ exports.composeComponentEndpoint = exports.fetchFEaaSComponentServerProps = expo
|
|
|
39
39
|
const react_1 = __importDefault(require("react"));
|
|
40
40
|
const FEAAS = __importStar(require("@sitecore-feaas/clientside/react"));
|
|
41
41
|
const layout_1 = require("@sitecore-jss/sitecore-jss/layout");
|
|
42
|
+
const utils_1 = require("../utils");
|
|
42
43
|
exports.FEAAS_COMPONENT_RENDERING_NAME = 'FEaaSComponent';
|
|
43
44
|
/**
|
|
44
45
|
* @param {FEaaSComponentProps} props component props
|
|
@@ -46,7 +47,7 @@ exports.FEAAS_COMPONENT_RENDERING_NAME = 'FEaaSComponent';
|
|
|
46
47
|
const FEaaSComponent = (props) => {
|
|
47
48
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
48
49
|
const computedRevision = ((_a = props.params) === null || _a === void 0 ? void 0 : _a.ComponentRevision) || props.revisionFallback;
|
|
49
|
-
if (
|
|
50
|
+
if (!props.template &&
|
|
50
51
|
(!props.params ||
|
|
51
52
|
!props.params.LibraryId ||
|
|
52
53
|
!props.params.ComponentId ||
|
|
@@ -57,23 +58,25 @@ const FEaaSComponent = (props) => {
|
|
|
57
58
|
return null;
|
|
58
59
|
}
|
|
59
60
|
let data = null;
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
if (props.fetchedData === null || props.fetchedData === undefined) {
|
|
62
|
+
if ((_b = props.params) === null || _b === void 0 ? void 0 : _b.ComponentDataOverride) {
|
|
63
|
+
// Use override data if provided
|
|
64
|
+
try {
|
|
65
|
+
data = JSON.parse(props.params.ComponentDataOverride);
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
data = null;
|
|
69
|
+
}
|
|
64
70
|
}
|
|
65
|
-
|
|
66
|
-
data
|
|
71
|
+
else if (props.fields) {
|
|
72
|
+
// Otherwise use datasource data (provided in fields)
|
|
73
|
+
data = (0, utils_1.getDataFromFields)(props.fields);
|
|
67
74
|
}
|
|
68
75
|
}
|
|
69
|
-
else if (props.fields) {
|
|
70
|
-
// Otherwise use datasource data (provided in fields)
|
|
71
|
-
data = getDataFromFields(props.fields);
|
|
72
|
-
}
|
|
73
76
|
// FEaaS control would still be hydrated by client
|
|
74
77
|
// we pass all the props as a workaround to avoid hydration error, until we convert all JSS components to server side
|
|
75
78
|
// this also allows component to fall back to full client-side rendering when template or src is empty
|
|
76
|
-
return (react_1.default.createElement(FEAAS.Component, { data:
|
|
79
|
+
return (react_1.default.createElement(FEAAS.Component, { data: props.fetchedData || data, template: props.template, cdn: (_c = props.params) === null || _c === void 0 ? void 0 : _c.ComponentHostName, library: (_d = props.params) === null || _d === void 0 ? void 0 : _d.LibraryId, version: (_e = props.params) === null || _e === void 0 ? void 0 : _e.ComponentVersion, component: (_f = props.params) === null || _f === void 0 ? void 0 : _f.ComponentId, instance: (_g = props.params) === null || _g === void 0 ? void 0 : _g.ComponentInstanceId, revision: computedRevision }));
|
|
77
80
|
};
|
|
78
81
|
exports.FEaaSComponent = FEaaSComponent;
|
|
79
82
|
/**
|
|
@@ -87,34 +90,65 @@ function fetchFEaaSComponentServerProps(params, pageState, endpointOverride) {
|
|
|
87
90
|
return __awaiter(this, void 0, void 0, function* () {
|
|
88
91
|
const revisionFallback = pageState && pageState !== layout_1.LayoutServicePageState.Normal ? 'staged' : 'published';
|
|
89
92
|
const src = endpointOverride || (0, exports.composeComponentEndpoint)(params, revisionFallback);
|
|
93
|
+
let template = '';
|
|
94
|
+
let fetchedData = null;
|
|
95
|
+
const fetchDataOptions = params.ComponentDataOverride
|
|
96
|
+
? JSON.parse(params.ComponentDataOverride)
|
|
97
|
+
: {};
|
|
90
98
|
try {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
revisionFallback,
|
|
94
|
-
template,
|
|
95
|
-
lastModified,
|
|
96
|
-
};
|
|
99
|
+
template = yield fetchComponentTemplate(src, params, revisionFallback);
|
|
100
|
+
fetchedData = yield fetchData(fetchDataOptions);
|
|
97
101
|
}
|
|
98
102
|
catch (e) {
|
|
99
|
-
console.error(`Fetch FEAAS component from ${src} failed. Ensure the component revision "${params.ComponentRevision ||
|
|
100
|
-
revisionFallback}" is present`);
|
|
101
103
|
console.error(e);
|
|
102
|
-
// leave revision fallback in so we can re-try with client-side rendering
|
|
103
|
-
return {
|
|
104
|
-
revisionFallback,
|
|
105
|
-
};
|
|
106
104
|
}
|
|
105
|
+
return {
|
|
106
|
+
fetchedData,
|
|
107
|
+
revisionFallback,
|
|
108
|
+
template,
|
|
109
|
+
};
|
|
107
110
|
});
|
|
108
111
|
}
|
|
109
112
|
exports.fetchFEaaSComponentServerProps = fetchFEaaSComponentServerProps;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return
|
|
117
|
-
|
|
113
|
+
/**
|
|
114
|
+
* @param {string} src component endpoint
|
|
115
|
+
* @param {FEaaSComponentParams} params rendering parameters for FEAAS component
|
|
116
|
+
* @param {RevisionType} revisionFallback fallback revision to fetch if revision is absent in params
|
|
117
|
+
*/
|
|
118
|
+
function fetchComponentTemplate(src, params, revisionFallback) {
|
|
119
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
120
|
+
try {
|
|
121
|
+
const { template } = yield FEAAS.fetchComponent(src);
|
|
122
|
+
return template;
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
console.error(`Fetch FEAAS component from ${src} failed. Ensure the component revision "${params.ComponentRevision ||
|
|
126
|
+
revisionFallback}" is present`);
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Fetches component data based on the provided data options.
|
|
133
|
+
* This function asynchronously fetches data using the FEAAS.DataSettings.fetch method.
|
|
134
|
+
*
|
|
135
|
+
* @param {FEAAS.DataOptions} dataOptions - Options to customize data fetching.
|
|
136
|
+
* @returns {Promise<FEAAS.DataScopes>} A promise that resolves with the fetched data,
|
|
137
|
+
* or rejects with an error if data fetching encounters an issue.
|
|
138
|
+
* @throws {Error} If an error occurs during data fetching, it is propagated as an error.
|
|
139
|
+
*/
|
|
140
|
+
function fetchData(dataOptions) {
|
|
141
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
142
|
+
try {
|
|
143
|
+
const fetchedData = yield FEAAS.DataSettings.fetch(dataOptions || {});
|
|
144
|
+
return fetchedData;
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
console.error('Fetch FEAAS component data settings failed');
|
|
148
|
+
throw error;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
118
152
|
/**
|
|
119
153
|
* Build component endpoint URL from component's params
|
|
120
154
|
* @param {FEaaSComponentParams} params rendering parameters for FEAAS component
|
|
@@ -18,8 +18,8 @@ exports.Image = exports.getEEMarkup = void 0;
|
|
|
18
18
|
const media_1 = require("@sitecore-jss/sitecore-jss/media");
|
|
19
19
|
const prop_types_1 = __importDefault(require("prop-types"));
|
|
20
20
|
const react_1 = __importDefault(require("react"));
|
|
21
|
-
const server_1 = __importDefault(require("react-dom/server"));
|
|
22
21
|
const utils_1 = require("../utils");
|
|
22
|
+
const utils_2 = require("../utils");
|
|
23
23
|
const getEditableWrapper = (editableMarkup, ...otherProps) => (
|
|
24
24
|
// create an inline wrapper and use dangerouslySetInnerHTML.
|
|
25
25
|
// if we try to parse the EE value, the parser will strip invalid or disallowed attributes from html elements - and EE uses several
|
|
@@ -61,7 +61,7 @@ const getEEMarkup = (imageField, imageParams, mediaUrlPrefix, otherProps) => {
|
|
|
61
61
|
if (!imgAttrs) {
|
|
62
62
|
return getEditableWrapper(imageField.editable);
|
|
63
63
|
}
|
|
64
|
-
const imgHtml =
|
|
64
|
+
const imgHtml = `<img ${(0, utils_2.getAttributesString)(imgAttrs)} />`;
|
|
65
65
|
const editableMarkup = imageField.editable.replace(foundImg.imgTag, imgHtml);
|
|
66
66
|
return getEditableWrapper(editableMarkup);
|
|
67
67
|
};
|
|
@@ -10,7 +10,11 @@ const MissingComponent = (props) => {
|
|
|
10
10
|
const componentName = props.rendering && props.rendering.componentName
|
|
11
11
|
? props.rendering.componentName
|
|
12
12
|
: 'Unnamed Component';
|
|
13
|
-
|
|
13
|
+
// error override would mean component is not unimplemented
|
|
14
|
+
!props.errorOverride &&
|
|
15
|
+
console.log(`Component props for unimplemented '${componentName}' component`, props);
|
|
16
|
+
const errorMessage = props.errorOverride ||
|
|
17
|
+
'JSS component is missing React implementation. See the developer console for more information.';
|
|
14
18
|
return (react_1.default.createElement("div", { style: {
|
|
15
19
|
background: 'darkorange',
|
|
16
20
|
outline: '5px solid orange',
|
|
@@ -19,7 +23,7 @@ const MissingComponent = (props) => {
|
|
|
19
23
|
maxWidth: '500px',
|
|
20
24
|
} },
|
|
21
25
|
react_1.default.createElement("h2", null, componentName),
|
|
22
|
-
react_1.default.createElement("p", null,
|
|
26
|
+
react_1.default.createElement("p", null, errorMessage)));
|
|
23
27
|
};
|
|
24
28
|
exports.MissingComponent = MissingComponent;
|
|
25
29
|
exports.MissingComponent.propTypes = {
|
|
@@ -50,36 +50,8 @@ class PlaceholderComponent extends PlaceholderCommon_1.PlaceholderCommon {
|
|
|
50
50
|
}
|
|
51
51
|
const renderingData = childProps.rendering;
|
|
52
52
|
const placeholderData = PlaceholderCommon_1.PlaceholderCommon.getPlaceholderDataFromRenderingData(renderingData, this.props.name);
|
|
53
|
-
this.isEmpty = placeholderData.every((rendering) => isRawRendering(rendering));
|
|
54
|
-
// This is a workaround to insert Experience Editor-specific markup on the page for empty placeholders.
|
|
55
|
-
// It makes sure the markup is inserted by react and thus avoiding hydration errors when in editing mode
|
|
56
|
-
if (this.isEmpty && utils_1.ExperienceEditor.isActive()) {
|
|
57
|
-
const codePos = placeholderData.findIndex((component) => component.name === 'code' &&
|
|
58
|
-
component.attributes.kind === 'open');
|
|
59
|
-
const plhId = placeholderData[codePos].attributes.id;
|
|
60
|
-
const emptyPlaceholderMarkup = [
|
|
61
|
-
{
|
|
62
|
-
name: 'span',
|
|
63
|
-
contents: null,
|
|
64
|
-
attributes: {
|
|
65
|
-
type: 'text/sitecore',
|
|
66
|
-
'sc-part-of': 'placeholder rendering',
|
|
67
|
-
style: 'display: none;',
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
name: 'div',
|
|
72
|
-
contents: null,
|
|
73
|
-
attributes: {
|
|
74
|
-
class: 'scEnabledChrome scEmptyPlaceholder',
|
|
75
|
-
'sc-part-of': 'placeholder',
|
|
76
|
-
'sc-placeholder-id': plhId,
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
];
|
|
80
|
-
placeholderData.splice(codePos + 1, 0, ...emptyPlaceholderMarkup);
|
|
81
|
-
}
|
|
82
53
|
const components = this.getComponentsForRenderingData(placeholderData);
|
|
54
|
+
this.isEmpty = placeholderData.every((rendering) => isRawRendering(rendering));
|
|
83
55
|
if (this.props.renderEmpty && this.isEmpty) {
|
|
84
56
|
const rendered = this.props.renderEmpty(components);
|
|
85
57
|
return components.length ? this.renderEmptyPlaceholder(rendered) : rendered;
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ComponentBuilder = exports.EditFrame = exports.withDatasourceCheck = exports.withPlaceholder = exports.withEditorChromes = exports.useSitecoreContext = exports.withSitecoreContext = exports.SitecoreContextReactContext = exports.SitecoreContext = exports.VisitorIdentification = exports.File = exports.LinkPropTypes = exports.Link = exports.fetchFEaaSComponentServerProps = exports.FEaaSComponent = exports.DateField = exports.Text = exports.RichTextPropTypes = exports.RichText = exports.getEEMarkup = exports.Image = exports.Placeholder = exports.mediaApi = exports.RestDictionaryService = exports.GraphQLDictionaryService = exports.trackingApi = exports.getFieldValue = exports.getChildPlaceholder = exports.RestLayoutService = exports.GraphQLLayoutService = exports.LayoutServicePageState = exports.DefaultEditFrameButtons = exports.DefaultEditFrameButton = exports.resetEditorChromes = exports.isEditorActive = exports.enableDebug = exports.constants = void 0;
|
|
3
|
+
exports.ComponentBuilder = exports.EditFrame = exports.withDatasourceCheck = exports.withPlaceholder = exports.withEditorChromes = exports.useSitecoreContext = exports.withSitecoreContext = exports.SitecoreContextReactContext = exports.SitecoreContext = exports.VisitorIdentification = exports.File = exports.LinkPropTypes = exports.Link = exports.BYOCRenderer = exports.fetchFEaaSComponentServerProps = exports.FEaaSComponent = exports.DateField = exports.Text = exports.RichTextPropTypes = exports.RichText = exports.getEEMarkup = exports.Image = exports.Placeholder = exports.getFEAASLibraryStylesheetLinks = exports.mediaApi = exports.RestDictionaryService = exports.GraphQLDictionaryService = exports.trackingApi = exports.getFieldValue = exports.getChildPlaceholder = exports.RestLayoutService = exports.GraphQLLayoutService = exports.LayoutServicePageState = exports.DefaultEditFrameButtons = exports.DefaultEditFrameButton = exports.resetEditorChromes = exports.isEditorActive = exports.enableDebug = exports.constants = void 0;
|
|
4
4
|
var sitecore_jss_1 = require("@sitecore-jss/sitecore-jss");
|
|
5
5
|
Object.defineProperty(exports, "constants", { enumerable: true, get: function () { return sitecore_jss_1.constants; } });
|
|
6
6
|
Object.defineProperty(exports, "enableDebug", { enumerable: true, get: function () { return sitecore_jss_1.enableDebug; } });
|
|
@@ -22,6 +22,8 @@ Object.defineProperty(exports, "GraphQLDictionaryService", { enumerable: true, g
|
|
|
22
22
|
Object.defineProperty(exports, "RestDictionaryService", { enumerable: true, get: function () { return i18n_1.RestDictionaryService; } });
|
|
23
23
|
var media_1 = require("@sitecore-jss/sitecore-jss/media");
|
|
24
24
|
Object.defineProperty(exports, "mediaApi", { enumerable: true, get: function () { return media_1.mediaApi; } });
|
|
25
|
+
var feaas_1 = require("@sitecore-jss/sitecore-jss/feaas");
|
|
26
|
+
Object.defineProperty(exports, "getFEAASLibraryStylesheetLinks", { enumerable: true, get: function () { return feaas_1.getFEAASLibraryStylesheetLinks; } });
|
|
25
27
|
var Placeholder_1 = require("./components/Placeholder");
|
|
26
28
|
Object.defineProperty(exports, "Placeholder", { enumerable: true, get: function () { return Placeholder_1.Placeholder; } });
|
|
27
29
|
var Image_1 = require("./components/Image");
|
|
@@ -37,6 +39,8 @@ Object.defineProperty(exports, "DateField", { enumerable: true, get: function ()
|
|
|
37
39
|
var FEaaSComponent_1 = require("./components/FEaaSComponent");
|
|
38
40
|
Object.defineProperty(exports, "FEaaSComponent", { enumerable: true, get: function () { return FEaaSComponent_1.FEaaSComponent; } });
|
|
39
41
|
Object.defineProperty(exports, "fetchFEaaSComponentServerProps", { enumerable: true, get: function () { return FEaaSComponent_1.fetchFEaaSComponentServerProps; } });
|
|
42
|
+
var BYOCRenderer_1 = require("./components/BYOCRenderer");
|
|
43
|
+
Object.defineProperty(exports, "BYOCRenderer", { enumerable: true, get: function () { return BYOCRenderer_1.BYOCRenderer; } });
|
|
40
44
|
var Link_1 = require("./components/Link");
|
|
41
45
|
Object.defineProperty(exports, "Link", { enumerable: true, get: function () { return Link_1.Link; } });
|
|
42
46
|
Object.defineProperty(exports, "LinkPropTypes", { enumerable: true, get: function () { return Link_1.LinkPropTypes; } });
|
package/dist/cjs/utils.js
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
2
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.addClassName = exports.convertAttributesToReactProps = exports.convertStyleAttribute = exports.convertKebabCasetoCamelCase = void 0;
|
|
14
|
+
exports.getDataFromFields = exports.getAttributesString = exports.addClassName = exports.convertAttributesToReactProps = exports.convertStyleAttribute = exports.convertKebabCasetoCamelCase = void 0;
|
|
15
|
+
const layout_1 = require("@sitecore-jss/sitecore-jss/layout");
|
|
4
16
|
const style_attr_1 = require("style-attr");
|
|
5
17
|
// https://stackoverflow.com/a/10426674/9324
|
|
6
18
|
const convertKebabCasetoCamelCase = (str) => str.replace(/^.|-./g, (letter, index) => index === 0 ? letter.toLowerCase() : letter.substr(1).toUpperCase());
|
|
@@ -51,7 +63,7 @@ exports.convertAttributesToReactProps = convertAttributesToReactProps;
|
|
|
51
63
|
/**
|
|
52
64
|
* "class" property will be transformed into or appended to "className" instead.
|
|
53
65
|
* @param {string} otherAttrs all other props included on the image component
|
|
54
|
-
*
|
|
66
|
+
* @returns {void}
|
|
55
67
|
*/
|
|
56
68
|
const addClassName = (otherAttrs) => {
|
|
57
69
|
if (otherAttrs.class) {
|
|
@@ -68,3 +80,39 @@ const addClassName = (otherAttrs) => {
|
|
|
68
80
|
}
|
|
69
81
|
};
|
|
70
82
|
exports.addClassName = addClassName;
|
|
83
|
+
/**
|
|
84
|
+
* Converts the given tag attributes object to a string
|
|
85
|
+
* @param {Object.<string, unknown>} attributes the attributes object
|
|
86
|
+
* @returns {string} string representation of the attributes
|
|
87
|
+
*/
|
|
88
|
+
const getAttributesString = (attributes) => {
|
|
89
|
+
const { className } = attributes, restAttributes = __rest(attributes, ["className"]);
|
|
90
|
+
const attributesEntries = Object.entries(restAttributes).map(([key, value]) => {
|
|
91
|
+
if (typeof value === 'object') {
|
|
92
|
+
const valueString = JSON.stringify(value)
|
|
93
|
+
.replace(/"|{|}/g, '')
|
|
94
|
+
.replace(/,/g, ';');
|
|
95
|
+
return `${key}="${valueString}"`;
|
|
96
|
+
}
|
|
97
|
+
return `${key}="${value}"`;
|
|
98
|
+
});
|
|
99
|
+
if (className) {
|
|
100
|
+
attributesEntries.push(`class="${className}"`);
|
|
101
|
+
}
|
|
102
|
+
return attributesEntries.join(' ');
|
|
103
|
+
};
|
|
104
|
+
exports.getAttributesString = getAttributesString;
|
|
105
|
+
/**
|
|
106
|
+
* Used in FEAAS and BYOC implementations to convert datasource item field values into component props
|
|
107
|
+
* @param {ComponentFields} fields field collection from Sitecore
|
|
108
|
+
* @returns JSON object that can be used as props
|
|
109
|
+
*/
|
|
110
|
+
const getDataFromFields = (fields) => {
|
|
111
|
+
let data = {};
|
|
112
|
+
data = Object.entries(fields).reduce((acc, [key]) => {
|
|
113
|
+
acc[key] = (0, layout_1.getFieldValue)(fields, key);
|
|
114
|
+
return acc;
|
|
115
|
+
}, data);
|
|
116
|
+
return data;
|
|
117
|
+
};
|
|
118
|
+
exports.getDataFromFields = getDataFromFields;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { getDataFromFields } from '../utils';
|
|
3
|
+
import { MissingComponent } from './MissingComponent';
|
|
4
|
+
const DefaultErrorComponent = (props) => {
|
|
5
|
+
var _a;
|
|
6
|
+
return (React.createElement("div", null,
|
|
7
|
+
"A rendering error occurred: ", (_a = props.error) === null || _a === void 0 ? void 0 :
|
|
8
|
+
_a.message,
|
|
9
|
+
"."));
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* BYOCRenderer helps rendering BYOC components - that can be taken from anywhere
|
|
13
|
+
* and registered without being deployed as Sitecore renderings
|
|
14
|
+
* @param {ByocRendererProps} props component props
|
|
15
|
+
* @returns dynamicly rendered component or Missing Component error frame
|
|
16
|
+
*/
|
|
17
|
+
export class BYOCRenderer extends React.Component {
|
|
18
|
+
constructor(props) {
|
|
19
|
+
super(props);
|
|
20
|
+
this.state = {};
|
|
21
|
+
}
|
|
22
|
+
static getDerivedStateFromError(error) {
|
|
23
|
+
// Update state so the next render will show the fallback UI.
|
|
24
|
+
return { error: error };
|
|
25
|
+
}
|
|
26
|
+
componentDidCatch(error) {
|
|
27
|
+
this.setState({ error });
|
|
28
|
+
}
|
|
29
|
+
render() {
|
|
30
|
+
var _a, _b, _c;
|
|
31
|
+
const props = this.props;
|
|
32
|
+
if (this.state.error) {
|
|
33
|
+
return this.props.errorComponent ? (React.createElement(this.props.errorComponent, { error: this.state.error })) : (React.createElement(DefaultErrorComponent, { error: this.state.error }));
|
|
34
|
+
}
|
|
35
|
+
const { ComponentName: componentName } = props.params || {};
|
|
36
|
+
if (!componentName) {
|
|
37
|
+
const noNameProps = {
|
|
38
|
+
errorOverride: 'BYOC: The ComponentName for this rendering is missing',
|
|
39
|
+
};
|
|
40
|
+
return props.missingComponentComponent ? (React.createElement(this.props.missingComponentComponent, Object.assign({}, noNameProps))) : (React.createElement(MissingComponent, Object.assign({}, noNameProps)));
|
|
41
|
+
}
|
|
42
|
+
// props.components would contain component from internal FEAAS regsitered component collection (registered in app)
|
|
43
|
+
// we can't access this collection here directly, as the collection from packages's dependency would be different from the one in app
|
|
44
|
+
const Component = (_a = props.components[componentName]) === null || _a === void 0 ? void 0 : _a.component;
|
|
45
|
+
if (!Component) {
|
|
46
|
+
console.warn(`Component "${componentName}" was not registered, please ensure the FEEAS.External.registerComponent call is made.`);
|
|
47
|
+
const missingProps = {
|
|
48
|
+
rendering: {
|
|
49
|
+
componentName: componentName,
|
|
50
|
+
},
|
|
51
|
+
errorOverride: 'BYOC: This component was not registered.',
|
|
52
|
+
};
|
|
53
|
+
return props.missingComponentComponent ? (React.createElement(this.props.missingComponentComponent, Object.assign({}, missingProps))) : (React.createElement(MissingComponent, Object.assign({}, missingProps)));
|
|
54
|
+
}
|
|
55
|
+
let componentProps = undefined;
|
|
56
|
+
if ((_b = props.params) === null || _b === void 0 ? void 0 : _b.ComponentProps) {
|
|
57
|
+
try {
|
|
58
|
+
componentProps = (_c = JSON.parse(props.params.ComponentProps)) !== null && _c !== void 0 ? _c : {};
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
console.warn(`Parsing props for ${componentName} component from rendering params failed. Error: ${e}`);
|
|
62
|
+
return this.props.errorComponent ? (React.createElement(this.props.errorComponent, { error: e })) : (React.createElement(DefaultErrorComponent, { error: e }));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (!componentProps) {
|
|
66
|
+
componentProps = props.fields ? getDataFromFields(props.fields) : {};
|
|
67
|
+
}
|
|
68
|
+
return React.createElement(Component, Object.assign({}, componentProps));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -9,7 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import React from 'react';
|
|
11
11
|
import * as FEAAS from '@sitecore-feaas/clientside/react';
|
|
12
|
-
import { LayoutServicePageState
|
|
12
|
+
import { LayoutServicePageState } from '@sitecore-jss/sitecore-jss/layout';
|
|
13
|
+
import { getDataFromFields } from '../utils';
|
|
13
14
|
export const FEAAS_COMPONENT_RENDERING_NAME = 'FEaaSComponent';
|
|
14
15
|
/**
|
|
15
16
|
* @param {FEaaSComponentProps} props component props
|
|
@@ -17,7 +18,7 @@ export const FEAAS_COMPONENT_RENDERING_NAME = 'FEaaSComponent';
|
|
|
17
18
|
export const FEaaSComponent = (props) => {
|
|
18
19
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
19
20
|
const computedRevision = ((_a = props.params) === null || _a === void 0 ? void 0 : _a.ComponentRevision) || props.revisionFallback;
|
|
20
|
-
if (
|
|
21
|
+
if (!props.template &&
|
|
21
22
|
(!props.params ||
|
|
22
23
|
!props.params.LibraryId ||
|
|
23
24
|
!props.params.ComponentId ||
|
|
@@ -28,23 +29,25 @@ export const FEaaSComponent = (props) => {
|
|
|
28
29
|
return null;
|
|
29
30
|
}
|
|
30
31
|
let data = null;
|
|
31
|
-
if (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
if (props.fetchedData === null || props.fetchedData === undefined) {
|
|
33
|
+
if ((_b = props.params) === null || _b === void 0 ? void 0 : _b.ComponentDataOverride) {
|
|
34
|
+
// Use override data if provided
|
|
35
|
+
try {
|
|
36
|
+
data = JSON.parse(props.params.ComponentDataOverride);
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
data = null;
|
|
40
|
+
}
|
|
35
41
|
}
|
|
36
|
-
|
|
37
|
-
data
|
|
42
|
+
else if (props.fields) {
|
|
43
|
+
// Otherwise use datasource data (provided in fields)
|
|
44
|
+
data = getDataFromFields(props.fields);
|
|
38
45
|
}
|
|
39
46
|
}
|
|
40
|
-
else if (props.fields) {
|
|
41
|
-
// Otherwise use datasource data (provided in fields)
|
|
42
|
-
data = getDataFromFields(props.fields);
|
|
43
|
-
}
|
|
44
47
|
// FEaaS control would still be hydrated by client
|
|
45
48
|
// we pass all the props as a workaround to avoid hydration error, until we convert all JSS components to server side
|
|
46
49
|
// this also allows component to fall back to full client-side rendering when template or src is empty
|
|
47
|
-
return (React.createElement(FEAAS.Component, { data:
|
|
50
|
+
return (React.createElement(FEAAS.Component, { data: props.fetchedData || data, template: props.template, cdn: (_c = props.params) === null || _c === void 0 ? void 0 : _c.ComponentHostName, library: (_d = props.params) === null || _d === void 0 ? void 0 : _d.LibraryId, version: (_e = props.params) === null || _e === void 0 ? void 0 : _e.ComponentVersion, component: (_f = props.params) === null || _f === void 0 ? void 0 : _f.ComponentId, instance: (_g = props.params) === null || _g === void 0 ? void 0 : _g.ComponentInstanceId, revision: computedRevision }));
|
|
48
51
|
};
|
|
49
52
|
/**
|
|
50
53
|
* Fetches server component props required for server rendering, based on rendering params.
|
|
@@ -57,33 +60,64 @@ export function fetchFEaaSComponentServerProps(params, pageState, endpointOverri
|
|
|
57
60
|
return __awaiter(this, void 0, void 0, function* () {
|
|
58
61
|
const revisionFallback = pageState && pageState !== LayoutServicePageState.Normal ? 'staged' : 'published';
|
|
59
62
|
const src = endpointOverride || composeComponentEndpoint(params, revisionFallback);
|
|
63
|
+
let template = '';
|
|
64
|
+
let fetchedData = null;
|
|
65
|
+
const fetchDataOptions = params.ComponentDataOverride
|
|
66
|
+
? JSON.parse(params.ComponentDataOverride)
|
|
67
|
+
: {};
|
|
60
68
|
try {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
revisionFallback,
|
|
64
|
-
template,
|
|
65
|
-
lastModified,
|
|
66
|
-
};
|
|
69
|
+
template = yield fetchComponentTemplate(src, params, revisionFallback);
|
|
70
|
+
fetchedData = yield fetchData(fetchDataOptions);
|
|
67
71
|
}
|
|
68
72
|
catch (e) {
|
|
73
|
+
console.error(e);
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
fetchedData,
|
|
77
|
+
revisionFallback,
|
|
78
|
+
template,
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* @param {string} src component endpoint
|
|
84
|
+
* @param {FEaaSComponentParams} params rendering parameters for FEAAS component
|
|
85
|
+
* @param {RevisionType} revisionFallback fallback revision to fetch if revision is absent in params
|
|
86
|
+
*/
|
|
87
|
+
function fetchComponentTemplate(src, params, revisionFallback) {
|
|
88
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
+
try {
|
|
90
|
+
const { template } = yield FEAAS.fetchComponent(src);
|
|
91
|
+
return template;
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
69
94
|
console.error(`Fetch FEAAS component from ${src} failed. Ensure the component revision "${params.ComponentRevision ||
|
|
70
95
|
revisionFallback}" is present`);
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Fetches component data based on the provided data options.
|
|
102
|
+
* This function asynchronously fetches data using the FEAAS.DataSettings.fetch method.
|
|
103
|
+
*
|
|
104
|
+
* @param {FEAAS.DataOptions} dataOptions - Options to customize data fetching.
|
|
105
|
+
* @returns {Promise<FEAAS.DataScopes>} A promise that resolves with the fetched data,
|
|
106
|
+
* or rejects with an error if data fetching encounters an issue.
|
|
107
|
+
* @throws {Error} If an error occurs during data fetching, it is propagated as an error.
|
|
108
|
+
*/
|
|
109
|
+
function fetchData(dataOptions) {
|
|
110
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
try {
|
|
112
|
+
const fetchedData = yield FEAAS.DataSettings.fetch(dataOptions || {});
|
|
113
|
+
return fetchedData;
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
console.error('Fetch FEAAS component data settings failed');
|
|
117
|
+
throw error;
|
|
76
118
|
}
|
|
77
119
|
});
|
|
78
120
|
}
|
|
79
|
-
const getDataFromFields = (fields) => {
|
|
80
|
-
let data = {};
|
|
81
|
-
data = Object.entries(fields).reduce((acc, [key]) => {
|
|
82
|
-
acc[key] = getFieldValue(fields, key);
|
|
83
|
-
return acc;
|
|
84
|
-
}, data);
|
|
85
|
-
return data;
|
|
86
|
-
};
|
|
87
121
|
/**
|
|
88
122
|
* Build component endpoint URL from component's params
|
|
89
123
|
* @param {FEaaSComponentParams} params rendering parameters for FEAAS component
|
|
@@ -12,8 +12,8 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
12
12
|
import { mediaApi } from '@sitecore-jss/sitecore-jss/media';
|
|
13
13
|
import PropTypes from 'prop-types';
|
|
14
14
|
import React from 'react';
|
|
15
|
-
import ReactDOMServer from 'react-dom/server';
|
|
16
15
|
import { addClassName, convertAttributesToReactProps } from '../utils';
|
|
16
|
+
import { getAttributesString } from '../utils';
|
|
17
17
|
const getEditableWrapper = (editableMarkup, ...otherProps) => (
|
|
18
18
|
// create an inline wrapper and use dangerouslySetInnerHTML.
|
|
19
19
|
// if we try to parse the EE value, the parser will strip invalid or disallowed attributes from html elements - and EE uses several
|
|
@@ -55,7 +55,7 @@ export const getEEMarkup = (imageField, imageParams, mediaUrlPrefix, otherProps)
|
|
|
55
55
|
if (!imgAttrs) {
|
|
56
56
|
return getEditableWrapper(imageField.editable);
|
|
57
57
|
}
|
|
58
|
-
const imgHtml =
|
|
58
|
+
const imgHtml = `<img ${getAttributesString(imgAttrs)} />`;
|
|
59
59
|
const editableMarkup = imageField.editable.replace(foundImg.imgTag, imgHtml);
|
|
60
60
|
return getEditableWrapper(editableMarkup);
|
|
61
61
|
};
|
|
@@ -4,7 +4,11 @@ export const MissingComponent = (props) => {
|
|
|
4
4
|
const componentName = props.rendering && props.rendering.componentName
|
|
5
5
|
? props.rendering.componentName
|
|
6
6
|
: 'Unnamed Component';
|
|
7
|
-
|
|
7
|
+
// error override would mean component is not unimplemented
|
|
8
|
+
!props.errorOverride &&
|
|
9
|
+
console.log(`Component props for unimplemented '${componentName}' component`, props);
|
|
10
|
+
const errorMessage = props.errorOverride ||
|
|
11
|
+
'JSS component is missing React implementation. See the developer console for more information.';
|
|
8
12
|
return (React.createElement("div", { style: {
|
|
9
13
|
background: 'darkorange',
|
|
10
14
|
outline: '5px solid orange',
|
|
@@ -13,7 +17,7 @@ export const MissingComponent = (props) => {
|
|
|
13
17
|
maxWidth: '500px',
|
|
14
18
|
} },
|
|
15
19
|
React.createElement("h2", null, componentName),
|
|
16
|
-
React.createElement("p", null,
|
|
20
|
+
React.createElement("p", null, errorMessage)));
|
|
17
21
|
};
|
|
18
22
|
MissingComponent.propTypes = {
|
|
19
23
|
rendering: PropTypes.shape({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { PlaceholderCommon } from './PlaceholderCommon';
|
|
3
3
|
import { withComponentFactory } from '../enhancers/withComponentFactory';
|
|
4
|
-
import { HorizonEditor
|
|
4
|
+
import { HorizonEditor } from '@sitecore-jss/sitecore-jss/utils';
|
|
5
5
|
/**
|
|
6
6
|
* @param {HtmlElementRendering | ComponentRendering} rendering
|
|
7
7
|
*/
|
|
@@ -44,36 +44,8 @@ class PlaceholderComponent extends PlaceholderCommon {
|
|
|
44
44
|
}
|
|
45
45
|
const renderingData = childProps.rendering;
|
|
46
46
|
const placeholderData = PlaceholderCommon.getPlaceholderDataFromRenderingData(renderingData, this.props.name);
|
|
47
|
-
this.isEmpty = placeholderData.every((rendering) => isRawRendering(rendering));
|
|
48
|
-
// This is a workaround to insert Experience Editor-specific markup on the page for empty placeholders.
|
|
49
|
-
// It makes sure the markup is inserted by react and thus avoiding hydration errors when in editing mode
|
|
50
|
-
if (this.isEmpty && ExperienceEditor.isActive()) {
|
|
51
|
-
const codePos = placeholderData.findIndex((component) => component.name === 'code' &&
|
|
52
|
-
component.attributes.kind === 'open');
|
|
53
|
-
const plhId = placeholderData[codePos].attributes.id;
|
|
54
|
-
const emptyPlaceholderMarkup = [
|
|
55
|
-
{
|
|
56
|
-
name: 'span',
|
|
57
|
-
contents: null,
|
|
58
|
-
attributes: {
|
|
59
|
-
type: 'text/sitecore',
|
|
60
|
-
'sc-part-of': 'placeholder rendering',
|
|
61
|
-
style: 'display: none;',
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
name: 'div',
|
|
66
|
-
contents: null,
|
|
67
|
-
attributes: {
|
|
68
|
-
class: 'scEnabledChrome scEmptyPlaceholder',
|
|
69
|
-
'sc-part-of': 'placeholder',
|
|
70
|
-
'sc-placeholder-id': plhId,
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
];
|
|
74
|
-
placeholderData.splice(codePos + 1, 0, ...emptyPlaceholderMarkup);
|
|
75
|
-
}
|
|
76
47
|
const components = this.getComponentsForRenderingData(placeholderData);
|
|
48
|
+
this.isEmpty = placeholderData.every((rendering) => isRawRendering(rendering));
|
|
77
49
|
if (this.props.renderEmpty && this.isEmpty) {
|
|
78
50
|
const rendered = this.props.renderEmpty(components);
|
|
79
51
|
return components.length ? this.renderEmptyPlaceholder(rendered) : rendered;
|
package/dist/esm/index.js
CHANGED
|
@@ -4,12 +4,14 @@ export { LayoutServicePageState, GraphQLLayoutService, RestLayoutService, getChi
|
|
|
4
4
|
export { trackingApi, } from '@sitecore-jss/sitecore-jss/tracking';
|
|
5
5
|
export { GraphQLDictionaryService, RestDictionaryService, } from '@sitecore-jss/sitecore-jss/i18n';
|
|
6
6
|
export { mediaApi } from '@sitecore-jss/sitecore-jss/media';
|
|
7
|
+
export { getFEAASLibraryStylesheetLinks } from '@sitecore-jss/sitecore-jss/feaas';
|
|
7
8
|
export { Placeholder } from './components/Placeholder';
|
|
8
9
|
export { Image, getEEMarkup, } from './components/Image';
|
|
9
10
|
export { RichText, RichTextPropTypes } from './components/RichText';
|
|
10
11
|
export { Text } from './components/Text';
|
|
11
12
|
export { DateField } from './components/Date';
|
|
12
13
|
export { FEaaSComponent, fetchFEaaSComponentServerProps, } from './components/FEaaSComponent';
|
|
14
|
+
export { BYOCRenderer, } from './components/BYOCRenderer';
|
|
13
15
|
export { Link, LinkPropTypes } from './components/Link';
|
|
14
16
|
export { File } from './components/File';
|
|
15
17
|
export { VisitorIdentification } from './components/VisitorIdentification';
|
package/dist/esm/utils.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
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 { getFieldValue } from '@sitecore-jss/sitecore-jss/layout';
|
|
1
13
|
import { parse as styleParse } from 'style-attr';
|
|
2
14
|
// https://stackoverflow.com/a/10426674/9324
|
|
3
15
|
export const convertKebabCasetoCamelCase = (str) => str.replace(/^.|-./g, (letter, index) => index === 0 ? letter.toLowerCase() : letter.substr(1).toUpperCase());
|
|
@@ -45,7 +57,7 @@ export const convertAttributesToReactProps = (attributes) => {
|
|
|
45
57
|
/**
|
|
46
58
|
* "class" property will be transformed into or appended to "className" instead.
|
|
47
59
|
* @param {string} otherAttrs all other props included on the image component
|
|
48
|
-
*
|
|
60
|
+
* @returns {void}
|
|
49
61
|
*/
|
|
50
62
|
export const addClassName = (otherAttrs) => {
|
|
51
63
|
if (otherAttrs.class) {
|
|
@@ -61,3 +73,37 @@ export const addClassName = (otherAttrs) => {
|
|
|
61
73
|
delete otherAttrs.class;
|
|
62
74
|
}
|
|
63
75
|
};
|
|
76
|
+
/**
|
|
77
|
+
* Converts the given tag attributes object to a string
|
|
78
|
+
* @param {Object.<string, unknown>} attributes the attributes object
|
|
79
|
+
* @returns {string} string representation of the attributes
|
|
80
|
+
*/
|
|
81
|
+
export const getAttributesString = (attributes) => {
|
|
82
|
+
const { className } = attributes, restAttributes = __rest(attributes, ["className"]);
|
|
83
|
+
const attributesEntries = Object.entries(restAttributes).map(([key, value]) => {
|
|
84
|
+
if (typeof value === 'object') {
|
|
85
|
+
const valueString = JSON.stringify(value)
|
|
86
|
+
.replace(/"|{|}/g, '')
|
|
87
|
+
.replace(/,/g, ';');
|
|
88
|
+
return `${key}="${valueString}"`;
|
|
89
|
+
}
|
|
90
|
+
return `${key}="${value}"`;
|
|
91
|
+
});
|
|
92
|
+
if (className) {
|
|
93
|
+
attributesEntries.push(`class="${className}"`);
|
|
94
|
+
}
|
|
95
|
+
return attributesEntries.join(' ');
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Used in FEAAS and BYOC implementations to convert datasource item field values into component props
|
|
99
|
+
* @param {ComponentFields} fields field collection from Sitecore
|
|
100
|
+
* @returns JSON object that can be used as props
|
|
101
|
+
*/
|
|
102
|
+
export const getDataFromFields = (fields) => {
|
|
103
|
+
let data = {};
|
|
104
|
+
data = Object.entries(fields).reduce((acc, [key]) => {
|
|
105
|
+
acc[key] = getFieldValue(fields, key);
|
|
106
|
+
return acc;
|
|
107
|
+
}, data);
|
|
108
|
+
return data;
|
|
109
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sitecore-jss/sitecore-jss-react",
|
|
3
|
-
"version": "21.3.0-canary.
|
|
3
|
+
"version": "21.3.0-canary.41",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -62,14 +62,14 @@
|
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@sitecore-feaas/clientside": "^0.3.0",
|
|
65
|
-
"@sitecore-jss/sitecore-jss": "^21.3.0-canary.
|
|
65
|
+
"@sitecore-jss/sitecore-jss": "^21.3.0-canary.41",
|
|
66
66
|
"deep-equal": "^2.1.0",
|
|
67
67
|
"prop-types": "^15.8.1",
|
|
68
68
|
"style-attr": "^1.3.0"
|
|
69
69
|
},
|
|
70
70
|
"description": "",
|
|
71
71
|
"types": "types/index.d.ts",
|
|
72
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "99f1b478d91b9a562ad721b8ca75a64eadc6d73d",
|
|
73
73
|
"files": [
|
|
74
74
|
"dist",
|
|
75
75
|
"types"
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ComponentFields } from '@sitecore-jss/sitecore-jss/layout';
|
|
3
|
+
import { MissingComponentProps } from './MissingComponent';
|
|
4
|
+
import { RegisteredComponents } from '@sitecore-feaas/clientside/types/ui/FEAASExternal';
|
|
5
|
+
/**
|
|
6
|
+
* Data from rendering params on Sitecore's BYOC rendering
|
|
7
|
+
*/
|
|
8
|
+
export type BYOCRenderingParams = {
|
|
9
|
+
/**
|
|
10
|
+
* Name of the component to render
|
|
11
|
+
*/
|
|
12
|
+
ComponentName: string;
|
|
13
|
+
/**
|
|
14
|
+
* JSON props to pass into rendered component
|
|
15
|
+
*/
|
|
16
|
+
ComponentProps?: string;
|
|
17
|
+
/**
|
|
18
|
+
* A string with classes that can be used to apply themes, via SXA functionality
|
|
19
|
+
*/
|
|
20
|
+
styles?: string;
|
|
21
|
+
RenderingIdentifier?: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Props for BYOC wrapper component
|
|
25
|
+
*/
|
|
26
|
+
export type BYOCProps = {
|
|
27
|
+
/**
|
|
28
|
+
* rendering params
|
|
29
|
+
*/
|
|
30
|
+
params?: BYOCRenderingParams;
|
|
31
|
+
/**
|
|
32
|
+
* fields from datasource items to be passed as rendered child component props
|
|
33
|
+
*/
|
|
34
|
+
fields?: ComponentFields;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Props for BYOCRenderer component. Includes components list to load external components from.
|
|
38
|
+
*/
|
|
39
|
+
export type BYOCRendererProps = BYOCProps & {
|
|
40
|
+
/**
|
|
41
|
+
* Registered component collection. Would be taken from FEAAS.External.registered
|
|
42
|
+
*/
|
|
43
|
+
components: RegisteredComponents;
|
|
44
|
+
/**
|
|
45
|
+
* Error component override. To be shown when Renderer or underlying component throws
|
|
46
|
+
*/
|
|
47
|
+
errorComponent?: React.ComponentClass<ErrorComponentProps> | React.FC<ErrorComponentProps>;
|
|
48
|
+
/**
|
|
49
|
+
* Override to indicate missing component situations. Would be shown when BYOC component is not registered
|
|
50
|
+
* or ComponentName is missing
|
|
51
|
+
*/
|
|
52
|
+
missingComponentComponent?: React.ComponentClass<MissingComponentProps> | React.FC<MissingComponentProps>;
|
|
53
|
+
};
|
|
54
|
+
type ErrorComponentProps = {
|
|
55
|
+
[prop: string]: unknown;
|
|
56
|
+
error?: Error;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* BYOCRenderer helps rendering BYOC components - that can be taken from anywhere
|
|
60
|
+
* and registered without being deployed as Sitecore renderings
|
|
61
|
+
* @param {ByocRendererProps} props component props
|
|
62
|
+
* @returns dynamicly rendered component or Missing Component error frame
|
|
63
|
+
*/
|
|
64
|
+
export declare class BYOCRenderer extends React.Component<BYOCRendererProps> {
|
|
65
|
+
state: Readonly<{
|
|
66
|
+
error?: Error;
|
|
67
|
+
}>;
|
|
68
|
+
constructor(props: BYOCRendererProps);
|
|
69
|
+
static getDerivedStateFromError(error: Error): {
|
|
70
|
+
error: Error;
|
|
71
|
+
};
|
|
72
|
+
componentDidCatch(error: Error): void;
|
|
73
|
+
render(): JSX.Element;
|
|
74
|
+
}
|
|
75
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as FEAAS from '@sitecore-feaas/clientside/react';
|
|
1
2
|
import { ComponentFields, LayoutServicePageState } from '@sitecore-jss/sitecore-jss/layout';
|
|
2
3
|
export declare const FEAAS_COMPONENT_RENDERING_NAME = "FEaaSComponent";
|
|
3
4
|
/**
|
|
@@ -24,14 +25,14 @@ type FEaaSComponentServerProps = {
|
|
|
24
25
|
* HTML template for presentation rendered inside the component
|
|
25
26
|
*/
|
|
26
27
|
template?: string;
|
|
27
|
-
/**
|
|
28
|
-
* the date component data was last modified
|
|
29
|
-
*/
|
|
30
|
-
lastModified?: string;
|
|
31
28
|
/**
|
|
32
29
|
* Default revision to be fetched. Should be 'staged' for editing/preview. Can be overriden by params.ComponentRevision
|
|
33
30
|
*/
|
|
34
31
|
revisionFallback?: RevisionType;
|
|
32
|
+
/**
|
|
33
|
+
* Fetched data from server component props for server rendering, based on rendering params.
|
|
34
|
+
*/
|
|
35
|
+
fetchedData?: FEAAS.DataScopes;
|
|
35
36
|
};
|
|
36
37
|
/**
|
|
37
38
|
* FEaaS props for client side component. Should be used as fallback when server props are not provided.
|
package/types/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export { LayoutService, LayoutServiceData, LayoutServicePageState, LayoutService
|
|
|
4
4
|
export { trackingApi, TrackingRequestOptions, CampaignInstance, GoalInstance, OutcomeInstance, EventInstance, PageViewInstance, } from '@sitecore-jss/sitecore-jss/tracking';
|
|
5
5
|
export { DictionaryPhrases, DictionaryService, GraphQLDictionaryService, RestDictionaryService, } from '@sitecore-jss/sitecore-jss/i18n';
|
|
6
6
|
export { mediaApi } from '@sitecore-jss/sitecore-jss/media';
|
|
7
|
+
export { getFEAASLibraryStylesheetLinks } from '@sitecore-jss/sitecore-jss/feaas';
|
|
7
8
|
export { ComponentFactory } from './components/sharedTypes';
|
|
8
9
|
export { Placeholder, PlaceholderComponentProps } from './components/Placeholder';
|
|
9
10
|
export { Image, ImageProps, ImageField, getEEMarkup, ImageFieldValue, ImageSizeParameters, } from './components/Image';
|
|
@@ -11,6 +12,7 @@ export { RichText, RichTextProps, RichTextPropTypes, RichTextField } from './com
|
|
|
11
12
|
export { Text, TextField } from './components/Text';
|
|
12
13
|
export { DateField, DateFieldProps } from './components/Date';
|
|
13
14
|
export { FEaaSComponent, FEaaSComponentProps, FEaaSComponentParams, fetchFEaaSComponentServerProps, } from './components/FEaaSComponent';
|
|
15
|
+
export { BYOCProps, BYOCRenderer, BYOCRenderingParams, BYOCRendererProps, } from './components/BYOCRenderer';
|
|
14
16
|
export { Link, LinkField, LinkFieldValue, LinkProps, LinkPropTypes } from './components/Link';
|
|
15
17
|
export { File, FileField } from './components/File';
|
|
16
18
|
export { VisitorIdentification } from './components/VisitorIdentification';
|
package/types/utils.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ComponentFields } from '@sitecore-jss/sitecore-jss/layout';
|
|
1
2
|
export declare const convertKebabCasetoCamelCase: (str: string) => string;
|
|
2
3
|
/**
|
|
3
4
|
* https://facebook.github.io/react/docs/dom-elements.html
|
|
@@ -18,8 +19,24 @@ export declare const convertAttributesToReactProps: (attributes: {
|
|
|
18
19
|
/**
|
|
19
20
|
* "class" property will be transformed into or appended to "className" instead.
|
|
20
21
|
* @param {string} otherAttrs all other props included on the image component
|
|
21
|
-
*
|
|
22
|
+
* @returns {void}
|
|
22
23
|
*/
|
|
23
24
|
export declare const addClassName: (otherAttrs: {
|
|
24
25
|
[key: string]: unknown;
|
|
25
26
|
}) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Converts the given tag attributes object to a string
|
|
29
|
+
* @param {Object.<string, unknown>} attributes the attributes object
|
|
30
|
+
* @returns {string} string representation of the attributes
|
|
31
|
+
*/
|
|
32
|
+
export declare const getAttributesString: (attributes: {
|
|
33
|
+
[key: string]: unknown;
|
|
34
|
+
}) => string;
|
|
35
|
+
/**
|
|
36
|
+
* Used in FEAAS and BYOC implementations to convert datasource item field values into component props
|
|
37
|
+
* @param {ComponentFields} fields field collection from Sitecore
|
|
38
|
+
* @returns JSON object that can be used as props
|
|
39
|
+
*/
|
|
40
|
+
export declare const getDataFromFields: (fields: ComponentFields) => {
|
|
41
|
+
[key: string]: unknown;
|
|
42
|
+
};
|