@sitecore-jss/sitecore-jss-react 0.1.0-beta.2

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 (78) hide show
  1. package/LICENSE.txt +202 -0
  2. package/README.md +8 -0
  3. package/dist/cjs/ComponentBuilder.js +25 -0
  4. package/dist/cjs/components/BYOCComponent.js +122 -0
  5. package/dist/cjs/components/BYOCWrapper.js +18 -0
  6. package/dist/cjs/components/Date.js +58 -0
  7. package/dist/cjs/components/EditFrame.js +39 -0
  8. package/dist/cjs/components/FEaaSComponent.js +152 -0
  9. package/dist/cjs/components/FEaaSWrapper.js +18 -0
  10. package/dist/cjs/components/File.js +53 -0
  11. package/dist/cjs/components/HiddenRendering.js +15 -0
  12. package/dist/cjs/components/Image.js +120 -0
  13. package/dist/cjs/components/Link.js +115 -0
  14. package/dist/cjs/components/MissingComponent.js +34 -0
  15. package/dist/cjs/components/Placeholder.js +80 -0
  16. package/dist/cjs/components/PlaceholderCommon.js +212 -0
  17. package/dist/cjs/components/RichText.js +66 -0
  18. package/dist/cjs/components/SitecoreContext.js +67 -0
  19. package/dist/cjs/components/Text.js +83 -0
  20. package/dist/cjs/components/sharedTypes.js +2 -0
  21. package/dist/cjs/enhancers/withComponentFactory.js +27 -0
  22. package/dist/cjs/enhancers/withDatasourceCheck.js +28 -0
  23. package/dist/cjs/enhancers/withEditorChromes.js +24 -0
  24. package/dist/cjs/enhancers/withPlaceholder.js +63 -0
  25. package/dist/cjs/enhancers/withSitecoreContext.js +53 -0
  26. package/dist/cjs/index.js +66 -0
  27. package/dist/cjs/utils.js +118 -0
  28. package/dist/esm/ComponentBuilder.js +21 -0
  29. package/dist/esm/components/BYOCComponent.js +91 -0
  30. package/dist/esm/components/BYOCWrapper.js +11 -0
  31. package/dist/esm/components/Date.js +51 -0
  32. package/dist/esm/components/EditFrame.js +32 -0
  33. package/dist/esm/components/FEaaSComponent.js +120 -0
  34. package/dist/esm/components/FEaaSWrapper.js +11 -0
  35. package/dist/esm/components/File.js +46 -0
  36. package/dist/esm/components/HiddenRendering.js +8 -0
  37. package/dist/esm/components/Image.js +112 -0
  38. package/dist/esm/components/Link.js +86 -0
  39. package/dist/esm/components/MissingComponent.js +27 -0
  40. package/dist/esm/components/Placeholder.js +74 -0
  41. package/dist/esm/components/PlaceholderCommon.js +205 -0
  42. package/dist/esm/components/RichText.js +37 -0
  43. package/dist/esm/components/SitecoreContext.js +60 -0
  44. package/dist/esm/components/Text.js +76 -0
  45. package/dist/esm/components/sharedTypes.js +1 -0
  46. package/dist/esm/enhancers/withComponentFactory.js +20 -0
  47. package/dist/esm/enhancers/withDatasourceCheck.js +20 -0
  48. package/dist/esm/enhancers/withEditorChromes.js +17 -0
  49. package/dist/esm/enhancers/withPlaceholder.js +56 -0
  50. package/dist/esm/enhancers/withSitecoreContext.js +45 -0
  51. package/dist/esm/index.js +23 -0
  52. package/dist/esm/utils.js +109 -0
  53. package/package.json +76 -0
  54. package/types/ComponentBuilder.d.ts +28 -0
  55. package/types/components/BYOCComponent.d.ts +87 -0
  56. package/types/components/BYOCWrapper.d.ts +3 -0
  57. package/types/components/Date.d.ts +22 -0
  58. package/types/components/EditFrame.d.ts +12 -0
  59. package/types/components/FEaaSComponent.d.ts +71 -0
  60. package/types/components/FEaaSWrapper.d.ts +3 -0
  61. package/types/components/File.d.ts +19 -0
  62. package/types/components/HiddenRendering.d.ts +4 -0
  63. package/types/components/Image.d.ts +62 -0
  64. package/types/components/Link.d.ts +47 -0
  65. package/types/components/MissingComponent.d.ts +9 -0
  66. package/types/components/Placeholder.d.ts +25 -0
  67. package/types/components/PlaceholderCommon.d.ts +105 -0
  68. package/types/components/RichText.d.ts +32 -0
  69. package/types/components/SitecoreContext.d.ts +43 -0
  70. package/types/components/Text.d.ts +26 -0
  71. package/types/components/sharedTypes.d.ts +7 -0
  72. package/types/enhancers/withComponentFactory.d.ts +13 -0
  73. package/types/enhancers/withDatasourceCheck.d.ts +22 -0
  74. package/types/enhancers/withEditorChromes.d.ts +3 -0
  75. package/types/enhancers/withPlaceholder.d.ts +37 -0
  76. package/types/enhancers/withSitecoreContext.d.ts +47 -0
  77. package/types/index.d.ts +24 -0
  78. package/types/utils.d.ts +42 -0
@@ -0,0 +1,53 @@
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
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.File = void 0;
18
+ const prop_types_1 = __importDefault(require("prop-types"));
19
+ const react_1 = __importDefault(require("react"));
20
+ const File = (_a) => {
21
+ /*
22
+ File fields cannot be managed via the EE. We never output "editable."
23
+ */
24
+ var { field, children } = _a, otherProps = __rest(_a, ["field", "children"]);
25
+ const dynamicField = field;
26
+ if (!field || (!dynamicField.value && !dynamicField.src)) {
27
+ return null;
28
+ }
29
+ // handle link directly on field for forgetful devs
30
+ const file = (dynamicField.src
31
+ ? field
32
+ : dynamicField.value);
33
+ if (!file) {
34
+ return null;
35
+ }
36
+ const linkText = !children ? file.title || file.displayName : null;
37
+ const anchorAttrs = {
38
+ href: file.src,
39
+ };
40
+ return react_1.default.createElement('a', Object.assign(Object.assign({}, anchorAttrs), otherProps), linkText, children);
41
+ };
42
+ exports.File = File;
43
+ exports.File.propTypes = {
44
+ field: prop_types_1.default.oneOfType([
45
+ prop_types_1.default.shape({
46
+ src: prop_types_1.default.string,
47
+ }),
48
+ prop_types_1.default.shape({
49
+ value: prop_types_1.default.object,
50
+ }),
51
+ ]).isRequired,
52
+ };
53
+ exports.File.displayName = 'File';
@@ -0,0 +1,15 @@
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.HIDDEN_RENDERING_NAME = exports.HiddenRendering = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const styles = {
9
+ height: '100px',
10
+ backgroundImage: 'linear-gradient(45deg, #ffffff 25%, #dcdcdc 25%, #dcdcdc 50%, #ffffff 50%, #ffffff 75%, #dcdcdc 75%, #dcdcdc 100%)',
11
+ backgroundSize: '3px 3px',
12
+ };
13
+ const HiddenRendering = () => react_1.default.createElement("div", { style: styles });
14
+ exports.HiddenRendering = HiddenRendering;
15
+ exports.HIDDEN_RENDERING_NAME = 'Hidden Rendering';
@@ -0,0 +1,120 @@
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
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.Image = exports.getEEMarkup = void 0;
18
+ const media_1 = require("@sitecore-jss/sitecore-jss/media");
19
+ const prop_types_1 = __importDefault(require("prop-types"));
20
+ const react_1 = __importDefault(require("react"));
21
+ const utils_1 = require("../utils");
22
+ const utils_2 = require("../utils");
23
+ const getEditableWrapper = (editableMarkup, ...otherProps) => (
24
+ // create an inline wrapper and use dangerouslySetInnerHTML.
25
+ // if we try to parse the EE value, the parser will strip invalid or disallowed attributes from html elements - and EE uses several
26
+ react_1.default.createElement("span", Object.assign({ className: "sc-image-wrapper" }, otherProps, { dangerouslySetInnerHTML: { __html: editableMarkup } })));
27
+ const getImageAttrs = (_a, imageParams, mediaUrlPrefix) => {
28
+ var { src, srcSet } = _a, otherAttrs = __rest(_a, ["src", "srcSet"]);
29
+ if (!src) {
30
+ return null;
31
+ }
32
+ (0, utils_1.addClassName)(otherAttrs);
33
+ const newAttrs = Object.assign({}, otherAttrs);
34
+ // update image URL for jss handler and image rendering params
35
+ const resolvedSrc = media_1.mediaApi.updateImageUrl(src, imageParams, mediaUrlPrefix);
36
+ if (srcSet) {
37
+ // replace with HTML-formatted srcset, including updated image URLs
38
+ newAttrs.srcSet = media_1.mediaApi.getSrcSet(resolvedSrc, srcSet, imageParams, mediaUrlPrefix);
39
+ }
40
+ // always output original src as fallback for older browsers
41
+ newAttrs.src = resolvedSrc;
42
+ return newAttrs;
43
+ };
44
+ /**
45
+ * @param {ImageField} imageField {ImageField} provides the dynamicMedia which is used to render the image
46
+ * @param {ImageProps.imageParams} imageParams {ImageProp['imageParams']}} provides the image parameters that will be attached to the image URL
47
+ * @param {RegExp} mediaUrlPrefix {RegExp} the url prefix regex used in the mediaApi
48
+ * @param {ImageProps} otherProps {ImageProps} all other props included on the image component
49
+ * @returns Experience Editor Markup
50
+ */
51
+ const getEEMarkup = (imageField, imageParams, mediaUrlPrefix, otherProps) => {
52
+ // we likely have an experience editor value, should be a string
53
+ const foundImg = media_1.mediaApi.findEditorImageTag(imageField.editable);
54
+ if (!foundImg) {
55
+ return getEditableWrapper(imageField.editable);
56
+ }
57
+ const foundImgProps = (0, utils_1.convertAttributesToReactProps)(foundImg.attrs);
58
+ // Note: otherProps may override values from foundImgProps, e.g. `style`, `className` prop
59
+ // We do not attempt to merge.
60
+ const imgAttrs = getImageAttrs(Object.assign(Object.assign({}, foundImgProps), otherProps), imageParams, mediaUrlPrefix);
61
+ if (!imgAttrs) {
62
+ return getEditableWrapper(imageField.editable);
63
+ }
64
+ const imgHtml = `<img ${(0, utils_2.getAttributesString)(imgAttrs)} />`;
65
+ const editableMarkup = imageField.editable.replace(foundImg.imgTag, imgHtml);
66
+ return getEditableWrapper(editableMarkup);
67
+ };
68
+ exports.getEEMarkup = getEEMarkup;
69
+ const Image = (_a) => {
70
+ var { editable, imageParams, field, mediaUrlPrefix } = _a, otherProps = __rest(_a, ["editable", "imageParams", "field", "mediaUrlPrefix"]);
71
+ const dynamicMedia = field;
72
+ if (!field ||
73
+ (!dynamicMedia.editable && !dynamicMedia.value && !dynamicMedia.src)) {
74
+ return null;
75
+ }
76
+ const imageField = dynamicMedia;
77
+ if (editable && imageField.editable) {
78
+ return (0, exports.getEEMarkup)(imageField, imageParams, mediaUrlPrefix, otherProps);
79
+ }
80
+ // some wise-guy/gal is passing in a 'raw' image object value
81
+ const img = dynamicMedia.src
82
+ ? field
83
+ : dynamicMedia.value;
84
+ if (!img) {
85
+ return null;
86
+ }
87
+ const attrs = getImageAttrs(Object.assign(Object.assign({}, img), otherProps), imageParams, mediaUrlPrefix);
88
+ if (attrs) {
89
+ return react_1.default.createElement("img", Object.assign({}, attrs));
90
+ }
91
+ return null; // we can't handle the truth
92
+ };
93
+ exports.Image = Image;
94
+ exports.Image.propTypes = {
95
+ media: prop_types_1.default.oneOfType([
96
+ prop_types_1.default.shape({
97
+ src: prop_types_1.default.string,
98
+ }),
99
+ prop_types_1.default.shape({
100
+ value: prop_types_1.default.object,
101
+ editable: prop_types_1.default.string,
102
+ }),
103
+ ]),
104
+ field: prop_types_1.default.oneOfType([
105
+ prop_types_1.default.shape({
106
+ src: prop_types_1.default.string,
107
+ }),
108
+ prop_types_1.default.shape({
109
+ value: prop_types_1.default.object,
110
+ editable: prop_types_1.default.string,
111
+ }),
112
+ ]),
113
+ editable: prop_types_1.default.bool,
114
+ mediaUrlPrefix: prop_types_1.default.instanceOf(RegExp),
115
+ imageParams: prop_types_1.default.objectOf(prop_types_1.default.oneOfType([prop_types_1.default.number.isRequired, prop_types_1.default.string.isRequired]).isRequired),
116
+ };
117
+ exports.Image.defaultProps = {
118
+ editable: true,
119
+ };
120
+ exports.Image.displayName = 'Image';
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __rest = (this && this.__rest) || function (s, e) {
26
+ var t = {};
27
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
28
+ t[p] = s[p];
29
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
30
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
31
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
32
+ t[p[i]] = s[p[i]];
33
+ }
34
+ return t;
35
+ };
36
+ var __importDefault = (this && this.__importDefault) || function (mod) {
37
+ return (mod && mod.__esModule) ? mod : { "default": mod };
38
+ };
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.LinkPropTypes = exports.Link = void 0;
41
+ const react_1 = __importStar(require("react"));
42
+ const prop_types_1 = __importDefault(require("prop-types"));
43
+ exports.Link = (0, react_1.forwardRef)((_a, ref) => {
44
+ var { field, editable, showLinkTextWithChildrenPresent } = _a, otherProps = __rest(_a, ["field", "editable", "showLinkTextWithChildrenPresent"]);
45
+ const children = otherProps.children;
46
+ const dynamicField = field;
47
+ if (!field ||
48
+ (!dynamicField.editableFirstPart &&
49
+ !dynamicField.value &&
50
+ !dynamicField.href)) {
51
+ return null;
52
+ }
53
+ const resultTags = [];
54
+ // EXPERIENCE EDITOR RENDERING
55
+ if (editable && dynamicField.editableFirstPart) {
56
+ const markup = dynamicField.editableFirstPart + dynamicField.editableLastPart;
57
+ // in an ideal world, we'd pre-render React children here and inject them between editableFirstPart and editableLastPart.
58
+ // However, we cannot combine arbitrary unparsed HTML (innerHTML) based components with actual vDOM components (the children)
59
+ // because the innerHTML is not parsed - it'd make a discontinuous vDOM. So, we'll go for the next best compromise of rendering the link field and children separately
60
+ // as siblings. Should be "good enough" for most cases - and write your own helper if it isn't. Or bring xEditor out of 2006.
61
+ const htmlProps = Object.assign(Object.assign({ className: 'sc-link-wrapper', dangerouslySetInnerHTML: {
62
+ __html: markup,
63
+ } }, otherProps), { key: 'editable' });
64
+ // Exclude children, since 'dangerouslySetInnerHTML' and 'children' can't be set together
65
+ // and children will be added as a sibling
66
+ delete htmlProps.children;
67
+ resultTags.push(react_1.default.createElement("span", Object.assign({}, htmlProps)));
68
+ // don't render normal link tag when editing, if no children exist
69
+ // this preserves normal-ish behavior if not using a link body (no hacks required)
70
+ if (!children) {
71
+ return resultTags[0];
72
+ }
73
+ }
74
+ // handle link directly on field for forgetful devs
75
+ const link = dynamicField.href
76
+ ? field
77
+ : dynamicField.value;
78
+ if (!link) {
79
+ return null;
80
+ }
81
+ const anchor = link.linktype !== 'anchor' && link.anchor ? `#${link.anchor}` : '';
82
+ const querystring = link.querystring ? `?${link.querystring}` : '';
83
+ const anchorAttrs = {
84
+ href: `${link.href}${querystring}${anchor}`,
85
+ className: link.class,
86
+ title: link.title,
87
+ target: link.target,
88
+ };
89
+ if (anchorAttrs.target === '_blank' && !anchorAttrs.rel) {
90
+ // information disclosure attack prevention keeps target blank site from getting ref to window.opener
91
+ anchorAttrs.rel = 'noopener noreferrer';
92
+ }
93
+ const linkText = showLinkTextWithChildrenPresent || !children ? link.text || link.href : null;
94
+ resultTags.push(react_1.default.createElement('a', Object.assign(Object.assign(Object.assign({}, anchorAttrs), otherProps), { key: 'link', ref }), linkText, children));
95
+ return react_1.default.createElement(react_1.default.Fragment, null, resultTags);
96
+ });
97
+ exports.LinkPropTypes = {
98
+ field: prop_types_1.default.oneOfType([
99
+ prop_types_1.default.shape({
100
+ href: prop_types_1.default.oneOfType([prop_types_1.default.string.isRequired, prop_types_1.default.oneOf([null]).isRequired]),
101
+ }),
102
+ prop_types_1.default.shape({
103
+ value: prop_types_1.default.object,
104
+ editableFirstPart: prop_types_1.default.string,
105
+ editableLastPart: prop_types_1.default.string,
106
+ }),
107
+ ]).isRequired,
108
+ editable: prop_types_1.default.bool,
109
+ showLinkTextWithChildrenPresent: prop_types_1.default.bool,
110
+ };
111
+ exports.Link.propTypes = exports.LinkPropTypes;
112
+ exports.Link.defaultProps = {
113
+ editable: true,
114
+ };
115
+ exports.Link.displayName = 'Link';
@@ -0,0 +1,34 @@
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.MissingComponent = void 0;
7
+ const prop_types_1 = __importDefault(require("prop-types"));
8
+ const react_1 = __importDefault(require("react"));
9
+ const MissingComponent = (props) => {
10
+ const componentName = props.rendering && props.rendering.componentName
11
+ ? props.rendering.componentName
12
+ : 'Unnamed Component';
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.';
18
+ return (react_1.default.createElement("div", { style: {
19
+ background: 'darkorange',
20
+ outline: '5px solid orange',
21
+ padding: '10px',
22
+ color: 'white',
23
+ maxWidth: '500px',
24
+ } },
25
+ react_1.default.createElement("h2", null, componentName),
26
+ react_1.default.createElement("p", null, errorMessage)));
27
+ };
28
+ exports.MissingComponent = MissingComponent;
29
+ exports.MissingComponent.propTypes = {
30
+ rendering: prop_types_1.default.shape({
31
+ componentName: prop_types_1.default.string,
32
+ }),
33
+ };
34
+ exports.MissingComponent.displayName = 'MissingComponent';
@@ -0,0 +1,80 @@
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.Placeholder = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const PlaceholderCommon_1 = require("./PlaceholderCommon");
9
+ const withComponentFactory_1 = require("../enhancers/withComponentFactory");
10
+ const utils_1 = require("@sitecore-jss/sitecore-jss/utils");
11
+ /**
12
+ * @param {HtmlElementRendering | ComponentRendering} rendering
13
+ */
14
+ function isRawRendering(rendering) {
15
+ return (!rendering.componentName &&
16
+ rendering.name !== undefined);
17
+ }
18
+ class PlaceholderComponent extends PlaceholderCommon_1.PlaceholderCommon {
19
+ constructor(props) {
20
+ super(props);
21
+ this.isEmpty = false;
22
+ }
23
+ componentDidMount() {
24
+ super.componentDidMount();
25
+ if (this.isEmpty && utils_1.HorizonEditor.isActive()) {
26
+ utils_1.HorizonEditor.resetChromes();
27
+ }
28
+ }
29
+ /**
30
+ * In case we need to render an empty placeholder, some part of the markup will be inserted by the EE,
31
+ * so we need to separate the empty placeholder's markup and allow React reconciliation to be executed correctly
32
+ * and retain sibling tags
33
+ * @param {React.ReactNode | React.ReactElement[]} node react node
34
+ * @returns react node
35
+ */
36
+ renderEmptyPlaceholder(node) {
37
+ return react_1.default.createElement("div", { className: "sc-jss-empty-placeholder" }, node);
38
+ }
39
+ render() {
40
+ const childProps = Object.assign({}, this.props);
41
+ delete childProps.componentFactory;
42
+ if (this.state.error) {
43
+ if (childProps.errorComponent) {
44
+ return react_1.default.createElement(childProps.errorComponent, { error: this.state.error });
45
+ }
46
+ return (react_1.default.createElement("div", { className: "sc-jss-placeholder-error" },
47
+ "A rendering error occurred: ",
48
+ this.state.error.message,
49
+ "."));
50
+ }
51
+ const renderingData = childProps.rendering;
52
+ const placeholderData = PlaceholderCommon_1.PlaceholderCommon.getPlaceholderDataFromRenderingData(renderingData, this.props.name);
53
+ const components = this.getComponentsForRenderingData(placeholderData);
54
+ this.isEmpty = placeholderData.every((rendering) => isRawRendering(rendering));
55
+ if (this.props.renderEmpty && this.isEmpty) {
56
+ const rendered = this.props.renderEmpty(components);
57
+ return components.length ? this.renderEmptyPlaceholder(rendered) : rendered;
58
+ }
59
+ else if (components.length && this.isEmpty) {
60
+ return this.renderEmptyPlaceholder(components);
61
+ }
62
+ else if (this.props.render) {
63
+ return this.props.render(components, placeholderData, childProps);
64
+ }
65
+ else if (this.props.renderEach) {
66
+ const renderEach = this.props.renderEach;
67
+ return components.map((component, index) => {
68
+ if (component && component.props && component.props.type === 'text/sitecore') {
69
+ return component;
70
+ }
71
+ return renderEach(component, index);
72
+ });
73
+ }
74
+ else {
75
+ return components;
76
+ }
77
+ }
78
+ }
79
+ PlaceholderComponent.propTypes = PlaceholderCommon_1.PlaceholderCommon.propTypes;
80
+ exports.Placeholder = (0, withComponentFactory_1.withComponentFactory)(PlaceholderComponent);
@@ -0,0 +1,212 @@
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
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.PlaceholderCommon = void 0;
18
+ const react_1 = __importDefault(require("react"));
19
+ const prop_types_1 = __importDefault(require("prop-types"));
20
+ const MissingComponent_1 = require("./MissingComponent");
21
+ const utils_1 = require("../utils");
22
+ const HiddenRendering_1 = require("./HiddenRendering");
23
+ const FEaaSComponent_1 = require("./FEaaSComponent");
24
+ const FEaaSWrapper_1 = require("./FEaaSWrapper");
25
+ const BYOCComponent_1 = require("./BYOCComponent");
26
+ const BYOCWrapper_1 = require("./BYOCWrapper");
27
+ /**
28
+ * These patterns need for right rendering Dynamic placeholders.
29
+ * Must be distinguished Splitter components and another placeholders(containers)
30
+ */
31
+ const EXCLUDE_PLACEHOLDERS_RENDER = [
32
+ new RegExp(/column-(\d{1})-\{\*\}/i),
33
+ new RegExp(/row-(\d{1})-\{\*\}/i),
34
+ ];
35
+ class PlaceholderCommon extends react_1.default.Component {
36
+ constructor(props) {
37
+ super(props);
38
+ this.nodeRefs = [];
39
+ this.state = {};
40
+ this.addRef = this.addRef.bind(this);
41
+ this.updateKeyAttributes = this.updateKeyAttributes.bind(this);
42
+ this.createRawElement = this.createRawElement.bind(this);
43
+ }
44
+ static getPlaceholderDataFromRenderingData(rendering, name) {
45
+ let result;
46
+ /** [SXA] it needs for deleting dynamics placeholder when we set him number(props.name) of container.
47
+ from backend side we get common name of placeholder is called 'nameOfContainer-{*}' where '{*}' marker for replacing **/
48
+ if (rendering === null || rendering === void 0 ? void 0 : rendering.placeholders) {
49
+ Object.keys(rendering.placeholders).forEach((placeholder) => {
50
+ if (placeholder.indexOf('{*}') !== -1 &&
51
+ !EXCLUDE_PLACEHOLDERS_RENDER.some((pattern) => name.search(pattern) !== -1) &&
52
+ name.replace(/[^a-zA-Z]*/gi, '') === placeholder.replace(/[^a-zA-Z]*/gi, '')) {
53
+ rendering.placeholders[name] = rendering.placeholders[placeholder];
54
+ delete rendering.placeholders[placeholder];
55
+ }
56
+ });
57
+ }
58
+ if (rendering && rendering.placeholders && Object.keys(rendering.placeholders).length > 0) {
59
+ result = rendering.placeholders[name];
60
+ }
61
+ else {
62
+ result = null;
63
+ }
64
+ if (!result) {
65
+ console.warn(`Placeholder '${name}' was not found in the current rendering data`, JSON.stringify(rendering, null, 2));
66
+ return [];
67
+ }
68
+ return result;
69
+ }
70
+ componentDidMount() {
71
+ this.updateKeyAttributes();
72
+ }
73
+ componentDidUpdate() {
74
+ this.updateKeyAttributes();
75
+ }
76
+ componentDidCatch(error) {
77
+ this.setState({ error });
78
+ }
79
+ getSXAParams(rendering) {
80
+ if (!rendering.params)
81
+ return {};
82
+ return (rendering.params.FieldNames && {
83
+ styles: `${rendering.params.GridParameters || ''} ${rendering.params.Styles || ''}`,
84
+ });
85
+ }
86
+ getComponentsForRenderingData(placeholderData) {
87
+ const _a = this.props, { name, fields: placeholderFields, params: placeholderParams, missingComponentComponent, hiddenRenderingComponent } = _a, placeholderProps = __rest(_a, ["name", "fields", "params", "missingComponentComponent", "hiddenRenderingComponent"]);
88
+ return placeholderData
89
+ .map((rendering, index) => {
90
+ const key = rendering.uid
91
+ ? rendering.uid
92
+ : `component-${index}`;
93
+ const commonProps = { key };
94
+ // if the element is not a 'component rendering', render it 'raw'
95
+ if (!rendering.componentName &&
96
+ rendering.name) {
97
+ return this.createRawElement(rendering, commonProps);
98
+ }
99
+ const componentRendering = rendering;
100
+ let component;
101
+ if (componentRendering.componentName === HiddenRendering_1.HIDDEN_RENDERING_NAME) {
102
+ component = hiddenRenderingComponent !== null && hiddenRenderingComponent !== void 0 ? hiddenRenderingComponent : HiddenRendering_1.HiddenRendering;
103
+ }
104
+ else if (!componentRendering.componentName) {
105
+ component = () => react_1.default.createElement(react_1.default.Fragment, null);
106
+ }
107
+ else {
108
+ component = this.getComponentForRendering(componentRendering);
109
+ }
110
+ // Fallback/defaults for Sitecore Component renderings (in case not defined in component factory)
111
+ if (!component) {
112
+ if (componentRendering.componentName === FEaaSComponent_1.FEAAS_COMPONENT_RENDERING_NAME) {
113
+ component = FEaaSComponent_1.FEaaSComponent;
114
+ }
115
+ else if (componentRendering.componentName === FEaaSWrapper_1.FEAAS_WRAPPER_RENDERING_NAME) {
116
+ component = FEaaSWrapper_1.FEaaSWrapper;
117
+ }
118
+ else if (componentRendering.componentName === BYOCComponent_1.BYOC_COMPONENT_RENDERING_NAME) {
119
+ component = BYOCComponent_1.BYOCComponent;
120
+ }
121
+ else if (componentRendering.componentName === BYOCWrapper_1.BYOC_WRAPPER_RENDERING_NAME) {
122
+ component = BYOCWrapper_1.BYOCWrapper;
123
+ }
124
+ }
125
+ if (!component) {
126
+ console.error(`Placeholder ${name} contains unknown component ${componentRendering.componentName}. Ensure that a React component exists for it, and that it is registered in your componentFactory.js.`);
127
+ component = missingComponentComponent !== null && missingComponentComponent !== void 0 ? missingComponentComponent : MissingComponent_1.MissingComponent;
128
+ }
129
+ const finalProps = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, commonProps), placeholderProps), ((placeholderFields || componentRendering.fields) && {
130
+ fields: Object.assign(Object.assign({}, placeholderFields), componentRendering.fields),
131
+ })), ((placeholderParams || componentRendering.params) && {
132
+ params: Object.assign(Object.assign(Object.assign({}, placeholderParams), componentRendering.params), this.getSXAParams(componentRendering)),
133
+ })), { rendering: componentRendering });
134
+ return react_1.default.createElement(component, this.props.modifyComponentProps ? this.props.modifyComponentProps(finalProps) : finalProps);
135
+ })
136
+ .filter((element) => element); // remove nulls
137
+ }
138
+ getComponentForRendering(renderingDefinition) {
139
+ var _a;
140
+ const componentFactory = this.props.componentFactory;
141
+ if (!componentFactory || typeof componentFactory !== 'function') {
142
+ console.warn(`No componentFactory was available to service request for component ${renderingDefinition}`);
143
+ return null;
144
+ }
145
+ // Render SXA Rendering Variant
146
+ if ((_a = renderingDefinition.params) === null || _a === void 0 ? void 0 : _a.FieldNames) {
147
+ return componentFactory(renderingDefinition.componentName, renderingDefinition.params.FieldNames);
148
+ }
149
+ return componentFactory(renderingDefinition.componentName);
150
+ }
151
+ addRef(nodeRef) {
152
+ this.nodeRefs.push(nodeRef);
153
+ }
154
+ createRawElement(elem, baseProps) {
155
+ if (!elem.name) {
156
+ console.error('"elem.name" is undefined in "createRawElement". Something is likely wrong with your component data. Ensure that your components have a name.');
157
+ return null;
158
+ }
159
+ const attributes = (0, utils_1.convertAttributesToReactProps)(elem.attributes);
160
+ const props = Object.assign(Object.assign(Object.assign({}, baseProps), attributes), { dangerouslySetInnerHTML: elem.contents ? { __html: elem.contents } : undefined });
161
+ /* Since we can't set the "key" attribute via React, stash it
162
+ * so we can set in the DOM after render.
163
+ */
164
+ if (!Array.isArray(attributes) && attributes && attributes.chrometype === 'placeholder') {
165
+ props.phkey = elem.attributes.key; // props that get rendered as dom attribute names need to be lowercase, otherwise React complains.
166
+ props.ref = this.addRef; // only need ref for placeholder containers, trying to add it to other components (e.g. stateless components) may result in a warning.
167
+ }
168
+ return react_1.default.createElement(elem.name, props);
169
+ }
170
+ updateKeyAttributes() {
171
+ if (!this.nodeRefs) {
172
+ return;
173
+ }
174
+ this.nodeRefs.forEach((ref) => {
175
+ if (ref && ref.getAttribute) {
176
+ // ref might be a wrapped component, so check for existence of getAttribute method
177
+ const key = ref.getAttribute('phkey');
178
+ if (key) {
179
+ // need to manually set the 'key' attribute after component mount because
180
+ // 'key' is a reserved attribute/prop in React. so it will never be rendered
181
+ // as an html attribute.
182
+ ref.setAttribute('key', key);
183
+ }
184
+ }
185
+ });
186
+ }
187
+ }
188
+ exports.PlaceholderCommon = PlaceholderCommon;
189
+ PlaceholderCommon.propTypes = {
190
+ rendering: prop_types_1.default.oneOfType([
191
+ prop_types_1.default.object,
192
+ prop_types_1.default.object,
193
+ ]).isRequired,
194
+ fields: prop_types_1.default.objectOf(prop_types_1.default.oneOfType([
195
+ prop_types_1.default.object,
196
+ prop_types_1.default.object,
197
+ ]).isRequired),
198
+ params: prop_types_1.default.objectOf(prop_types_1.default.string.isRequired),
199
+ missingComponentComponent: prop_types_1.default.oneOfType([
200
+ prop_types_1.default.object,
201
+ prop_types_1.default.func,
202
+ ]),
203
+ hiddenRenderingComponent: prop_types_1.default.oneOfType([
204
+ prop_types_1.default.object,
205
+ prop_types_1.default.func,
206
+ ]),
207
+ errorComponent: prop_types_1.default.oneOfType([
208
+ prop_types_1.default.object,
209
+ prop_types_1.default.func,
210
+ ]),
211
+ modifyComponentProps: prop_types_1.default.func,
212
+ };