@blaze-cms/react-page-builder 0.147.0-rc-eagle.4 → 0.147.0-rc-eagle.6
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/lib/components/ContentGroup/ContentGroup.js +40 -8
- package/lib/components/ContentGroup/ContentGroup.js.map +1 -1
- package/lib/components/ContentGroup/ContentGroupDataFetcher.js +96 -0
- package/lib/components/ContentGroup/ContentGroupDataFetcher.js.map +1 -0
- package/lib/components/ContentGroup/helpers/build-data-sections.js +46 -0
- package/lib/components/ContentGroup/helpers/build-data-sections.js.map +1 -0
- package/lib/components/ContentGroup/helpers/index.js +7 -0
- package/lib/components/ContentGroup/helpers/index.js.map +1 -1
- package/lib/components/ContentGroupSection/ContentGroupSection.js +3 -2
- package/lib/components/ContentGroupSection/ContentGroupSection.js.map +1 -1
- package/lib/components/Iframe/Iframe.js +16 -6
- package/lib/components/Iframe/Iframe.js.map +1 -1
- package/lib/components/Layout/Layout.js +14 -3
- package/lib/components/Layout/Layout.js.map +1 -1
- package/lib/helpers/get-component-id.js +9 -3
- package/lib/helpers/get-component-id.js.map +1 -1
- package/lib-es/components/ContentGroup/ContentGroup.js +41 -9
- package/lib-es/components/ContentGroup/ContentGroup.js.map +1 -1
- package/lib-es/components/ContentGroup/ContentGroupDataFetcher.js +88 -0
- package/lib-es/components/ContentGroup/ContentGroupDataFetcher.js.map +1 -0
- package/lib-es/components/ContentGroup/helpers/build-data-sections.js +38 -0
- package/lib-es/components/ContentGroup/helpers/build-data-sections.js.map +1 -0
- package/lib-es/components/ContentGroup/helpers/index.js +2 -1
- package/lib-es/components/ContentGroup/helpers/index.js.map +1 -1
- package/lib-es/components/ContentGroupSection/ContentGroupSection.js +3 -2
- package/lib-es/components/ContentGroupSection/ContentGroupSection.js.map +1 -1
- package/lib-es/components/Iframe/Iframe.js +16 -6
- package/lib-es/components/Iframe/Iframe.js.map +1 -1
- package/lib-es/components/Layout/Layout.js +14 -3
- package/lib-es/components/Layout/Layout.js.map +1 -1
- package/lib-es/helpers/get-component-id.js +9 -3
- package/lib-es/helpers/get-component-id.js.map +1 -1
- package/package.json +6 -6
- package/src/components/ContentGroup/ContentGroup.js +54 -8
- package/src/components/ContentGroup/ContentGroupDataFetcher.js +74 -0
- package/src/components/ContentGroup/helpers/build-data-sections.js +35 -0
- package/src/components/ContentGroup/helpers/index.js +2 -1
- package/src/components/ContentGroupSection/ContentGroupSection.js +2 -2
- package/src/components/Iframe/Iframe.js +22 -6
- package/src/components/Layout/Layout.js +13 -2
- package/src/helpers/get-component-id.js +7 -4
|
@@ -3,14 +3,27 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import { CONTENT_GROUP_TYPES } from './constants';
|
|
4
4
|
import ContentGroupTabs from './ContentGroupTabs';
|
|
5
5
|
import ContentGroupAccordion from './ContentGroupAccordion';
|
|
6
|
-
import
|
|
6
|
+
import ContentGroupDataFetcher from './ContentGroupDataFetcher';
|
|
7
|
+
import { getSectionsData, buildDataSections } from './helpers';
|
|
7
8
|
import getStructuredDataProperties from './helpers/get-structured-data-properties';
|
|
8
9
|
import { getCustomHtmlProperties } from '../../helpers';
|
|
9
10
|
|
|
10
11
|
const VALID_TYPES = Object.values(CONTENT_GROUP_TYPES);
|
|
11
12
|
|
|
12
|
-
const ContentGroup = ({
|
|
13
|
-
|
|
13
|
+
const ContentGroup = ({
|
|
14
|
+
contentType,
|
|
15
|
+
isFaqContent,
|
|
16
|
+
children,
|
|
17
|
+
customHtmlProps,
|
|
18
|
+
simpleData,
|
|
19
|
+
dataProperty,
|
|
20
|
+
...props
|
|
21
|
+
}) => {
|
|
22
|
+
const hasSimpleData = Array.isArray(simpleData) && simpleData.length > 0;
|
|
23
|
+
const dataPropertyName = Array.isArray(dataProperty) ? dataProperty[0] : dataProperty;
|
|
24
|
+
const hasDataProperty = !!dataPropertyName;
|
|
25
|
+
|
|
26
|
+
const childGroupSections = children?.props?.children?.[1];
|
|
14
27
|
|
|
15
28
|
const GroupComponent = useMemo(
|
|
16
29
|
() =>
|
|
@@ -30,9 +43,32 @@ const ContentGroup = ({ contentType, isFaqContent, children, customHtmlProps, ..
|
|
|
30
43
|
};
|
|
31
44
|
}, [isFaqContent, customHtmlProps]);
|
|
32
45
|
|
|
33
|
-
if (!
|
|
46
|
+
if (!VALID_TYPES.includes(contentType)) return '';
|
|
47
|
+
|
|
48
|
+
if (!hasSimpleData && hasDataProperty) {
|
|
49
|
+
return (
|
|
50
|
+
<WrapperComponent {...topWrapperProps}>
|
|
51
|
+
<ContentGroupDataFetcher
|
|
52
|
+
dataProperty={dataPropertyName}
|
|
53
|
+
contentType={contentType}
|
|
54
|
+
{...props}
|
|
55
|
+
{...schemaProperties}
|
|
56
|
+
/>
|
|
57
|
+
</WrapperComponent>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let groupSections;
|
|
62
|
+
let sectionsData;
|
|
34
63
|
|
|
35
|
-
|
|
64
|
+
if (hasSimpleData) {
|
|
65
|
+
({ groupSections, sectionsData } = buildDataSections(simpleData));
|
|
66
|
+
} else {
|
|
67
|
+
groupSections = childGroupSections;
|
|
68
|
+
if (!groupSections || !groupSections.length) return '';
|
|
69
|
+
sectionsData = getSectionsData(groupSections);
|
|
70
|
+
}
|
|
71
|
+
if (!groupSections || !groupSections.length) return '';
|
|
36
72
|
|
|
37
73
|
return (
|
|
38
74
|
<WrapperComponent {...topWrapperProps}>
|
|
@@ -48,7 +84,7 @@ const ContentGroup = ({ contentType, isFaqContent, children, customHtmlProps, ..
|
|
|
48
84
|
};
|
|
49
85
|
|
|
50
86
|
ContentGroup.propTypes = {
|
|
51
|
-
children: PropTypes.object
|
|
87
|
+
children: PropTypes.object,
|
|
52
88
|
contentType: PropTypes.oneOf(VALID_TYPES).isRequired,
|
|
53
89
|
isFaqContent: PropTypes.bool,
|
|
54
90
|
customHtmlProps: PropTypes.arrayOf(
|
|
@@ -56,12 +92,22 @@ ContentGroup.propTypes = {
|
|
|
56
92
|
name: PropTypes.string,
|
|
57
93
|
value: PropTypes.string
|
|
58
94
|
})
|
|
59
|
-
)
|
|
95
|
+
),
|
|
96
|
+
simpleData: PropTypes.arrayOf(
|
|
97
|
+
PropTypes.shape({
|
|
98
|
+
label: PropTypes.string,
|
|
99
|
+
text: PropTypes.string
|
|
100
|
+
})
|
|
101
|
+
),
|
|
102
|
+
dataProperty: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)])
|
|
60
103
|
};
|
|
61
104
|
|
|
62
105
|
ContentGroup.defaultProps = {
|
|
106
|
+
children: null,
|
|
63
107
|
isFaqContent: false,
|
|
64
|
-
customHtmlProps: []
|
|
108
|
+
customHtmlProps: [],
|
|
109
|
+
simpleData: null,
|
|
110
|
+
dataProperty: null
|
|
65
111
|
};
|
|
66
112
|
|
|
67
113
|
export default ContentGroup;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React, { useContext, useMemo } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { useQuery, gql } from '@apollo/client';
|
|
4
|
+
import { MainContext } from '@blaze-cms/nextjs-components';
|
|
5
|
+
import { getSingleEntitySchema, generateSingleItemQuery } from '../../application/query';
|
|
6
|
+
import ContentGroupTabs from './ContentGroupTabs';
|
|
7
|
+
import ContentGroupAccordion from './ContentGroupAccordion';
|
|
8
|
+
import { buildDataSections } from './helpers';
|
|
9
|
+
import { CONTENT_GROUP_TYPES } from './constants';
|
|
10
|
+
|
|
11
|
+
const PLACEHOLDER_QUERY = gql`
|
|
12
|
+
query {
|
|
13
|
+
__typename
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
const ContentGroupDataFetcher = ({ dataProperty, parent, contentType, ...props }) => {
|
|
18
|
+
const { isPreview } = useContext(MainContext);
|
|
19
|
+
const dataPropertyName = Array.isArray(dataProperty) ? dataProperty[0] : dataProperty;
|
|
20
|
+
|
|
21
|
+
const { data: schemaData, loading: schemaLoading } = useQuery(getSingleEntitySchema, {
|
|
22
|
+
variables: { id: parent?.itemEntity },
|
|
23
|
+
skip: !parent?.itemEntity || !dataPropertyName
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const dataQuery = useMemo(() => {
|
|
27
|
+
if (!schemaData) return null;
|
|
28
|
+
const { getEntitySchema } = schemaData;
|
|
29
|
+
const { actions: { getPublished, get } = {} } = getEntitySchema;
|
|
30
|
+
const actionKey = isPreview ? get : getPublished || get;
|
|
31
|
+
if (!actionKey) return null;
|
|
32
|
+
return generateSingleItemQuery(actionKey, `${dataPropertyName} { label text }`);
|
|
33
|
+
}, [schemaData, isPreview, dataPropertyName]);
|
|
34
|
+
|
|
35
|
+
const { data: recordData, loading: recordLoading } = useQuery(dataQuery || PLACEHOLDER_QUERY, {
|
|
36
|
+
variables: { id: parent?.itemId },
|
|
37
|
+
skip: !dataQuery || !parent?.itemId
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (schemaLoading || recordLoading) return '';
|
|
41
|
+
if (!recordData?.entityData) return null;
|
|
42
|
+
|
|
43
|
+
const propertyData = recordData.entityData[dataPropertyName];
|
|
44
|
+
if (!propertyData || !propertyData.length) return null;
|
|
45
|
+
|
|
46
|
+
const { groupSections, sectionsData } = buildDataSections(propertyData);
|
|
47
|
+
|
|
48
|
+
if (!groupSections.length) return null;
|
|
49
|
+
|
|
50
|
+
const GroupComponent =
|
|
51
|
+
contentType === CONTENT_GROUP_TYPES.ACCORDION ? ContentGroupAccordion : ContentGroupTabs;
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<GroupComponent
|
|
55
|
+
contentType={contentType}
|
|
56
|
+
groupSections={groupSections}
|
|
57
|
+
sectionsData={sectionsData}
|
|
58
|
+
{...props}
|
|
59
|
+
/>
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
ContentGroupDataFetcher.propTypes = {
|
|
64
|
+
dataProperty: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
|
|
65
|
+
parent: PropTypes.object,
|
|
66
|
+
contentType: PropTypes.string.isRequired
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
ContentGroupDataFetcher.defaultProps = {
|
|
70
|
+
dataProperty: null,
|
|
71
|
+
parent: null
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export default ContentGroupDataFetcher;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import dynamic from 'next/dynamic';
|
|
3
|
+
import getComponentId from '../../../helpers/get-component-id';
|
|
4
|
+
|
|
5
|
+
const TextBlock = dynamic(() => import('../../TextBlock'));
|
|
6
|
+
const ContentGroupSection = dynamic(() => import('../../ContentGroupSection'));
|
|
7
|
+
|
|
8
|
+
const buildDataSections = (items = []) => {
|
|
9
|
+
const itemData = items.map((item, i) => {
|
|
10
|
+
if (!item || !item.text || !item.label) return null;
|
|
11
|
+
|
|
12
|
+
const sectionName = getComponentId(item.label || `section-${i}`, true, true);
|
|
13
|
+
return {
|
|
14
|
+
sectionName,
|
|
15
|
+
label: item.label,
|
|
16
|
+
sectionContent: (
|
|
17
|
+
<ContentGroupSection key={sectionName} name={sectionName} disableChildCheck>
|
|
18
|
+
<TextBlock html={item.text} name={`${sectionName}-text`} />
|
|
19
|
+
</ContentGroupSection>
|
|
20
|
+
)
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return itemData.filter(Boolean).reduce(
|
|
25
|
+
(acc, { sectionName, label, sectionContent }) => {
|
|
26
|
+
if (!sectionName || !sectionContent) return acc;
|
|
27
|
+
acc.groupSections.push(sectionContent);
|
|
28
|
+
acc.sectionsData.push([sectionName, label]);
|
|
29
|
+
return acc;
|
|
30
|
+
},
|
|
31
|
+
{ groupSections: [], sectionsData: [] }
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default buildDataSections;
|
|
@@ -2,8 +2,8 @@ import React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { hasChildren } from '../../helpers';
|
|
4
4
|
|
|
5
|
-
const ContentGroupSection = ({ children, name }) => {
|
|
6
|
-
if (!hasChildren(children)) return null;
|
|
5
|
+
const ContentGroupSection = ({ children, name, disableChildCheck }) => {
|
|
6
|
+
if (!disableChildCheck && !hasChildren(children)) return null;
|
|
7
7
|
|
|
8
8
|
return (
|
|
9
9
|
<div key={name} className="content-group-section">
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import IframeResizer from 'iframe-resizer-react';
|
|
4
|
+
import { useStringTemplate } from '@blaze-cms/utils-handlebars';
|
|
4
5
|
import { IFRAME_CLASS, DEFAULT_WIDTH } from './constants';
|
|
5
6
|
|
|
6
|
-
const
|
|
7
|
-
|
|
7
|
+
const UNSAFE_URL_PATTERN = /^(javascript|data):/i;
|
|
8
|
+
|
|
9
|
+
const isSafeUrl = url => !UNSAFE_URL_PATTERN.test(url.trim());
|
|
10
|
+
|
|
11
|
+
const Iframe = ({ src, modifier, width, height, enableScrolling, parent }) => {
|
|
12
|
+
const {
|
|
13
|
+
data: [resolvedSrc]
|
|
14
|
+
} = useStringTemplate(parent, [src || '']);
|
|
15
|
+
if (!resolvedSrc || !isSafeUrl(resolvedSrc)) return null;
|
|
8
16
|
const modifierString = modifier ? ` ${modifier}` : '';
|
|
9
17
|
const iframeClassName = `${IFRAME_CLASS}${modifierString}`;
|
|
10
18
|
const defaultWidth = !width ? DEFAULT_WIDTH : {};
|
|
@@ -13,7 +21,7 @@ const Iframe = ({ src, modifier, width, height, enableScrolling }) => {
|
|
|
13
21
|
<IframeResizer
|
|
14
22
|
scrolling={enableScrolling}
|
|
15
23
|
autoResize
|
|
16
|
-
src={
|
|
24
|
+
src={resolvedSrc}
|
|
17
25
|
sizeHeight={!height}
|
|
18
26
|
height={height}
|
|
19
27
|
width={width}
|
|
@@ -24,13 +32,21 @@ const Iframe = ({ src, modifier, width, height, enableScrolling }) => {
|
|
|
24
32
|
};
|
|
25
33
|
|
|
26
34
|
Iframe.propTypes = {
|
|
27
|
-
src: PropTypes.string
|
|
35
|
+
src: PropTypes.string,
|
|
28
36
|
enableScrolling: PropTypes.bool,
|
|
29
37
|
modifier: PropTypes.string,
|
|
30
38
|
width: PropTypes.string,
|
|
31
|
-
height: PropTypes.string
|
|
39
|
+
height: PropTypes.string,
|
|
40
|
+
parent: PropTypes.object
|
|
32
41
|
};
|
|
33
42
|
|
|
34
|
-
Iframe.defaultProps = {
|
|
43
|
+
Iframe.defaultProps = {
|
|
44
|
+
src: '',
|
|
45
|
+
enableScrolling: false,
|
|
46
|
+
modifier: '',
|
|
47
|
+
width: '',
|
|
48
|
+
height: '',
|
|
49
|
+
parent: {}
|
|
50
|
+
};
|
|
35
51
|
|
|
36
52
|
export default Iframe;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
+
import { useStringTemplate } from '@blaze-cms/utils-handlebars';
|
|
3
4
|
import Wrapper from '../Wrapper';
|
|
4
5
|
import { getClassModifiers } from '../../utils';
|
|
5
6
|
import { useGetImages } from '../../hooks';
|
|
@@ -15,6 +16,8 @@ const Layout = React.forwardRef(
|
|
|
15
16
|
settings,
|
|
16
17
|
modifier,
|
|
17
18
|
backgroundImage,
|
|
19
|
+
backgroundImageUrl,
|
|
20
|
+
parent,
|
|
18
21
|
tagType,
|
|
19
22
|
dataNoSnippet,
|
|
20
23
|
sticky,
|
|
@@ -24,10 +27,14 @@ const Layout = React.forwardRef(
|
|
|
24
27
|
},
|
|
25
28
|
ref
|
|
26
29
|
) => {
|
|
30
|
+
const {
|
|
31
|
+
data: [resolvedBackgroundImageUrl]
|
|
32
|
+
} = useStringTemplate(parent, [backgroundImageUrl || '']);
|
|
27
33
|
const {
|
|
28
34
|
data: { getFile: { url = null } = {} }
|
|
29
|
-
} = useGetImages(backgroundImage);
|
|
30
|
-
const
|
|
35
|
+
} = useGetImages(backgroundImage, false, !!resolvedBackgroundImageUrl);
|
|
36
|
+
const backgroundUrl = resolvedBackgroundImageUrl || url;
|
|
37
|
+
const style = getStylesToUpdate({ backgroundImage: backgroundUrl });
|
|
31
38
|
const { title } = settings;
|
|
32
39
|
const classModifiers = getClassModifiers(type, { modifier, sticky, ...otherProps });
|
|
33
40
|
const additionalRowModifier = checkIfRowHasColumns(type, children) ? ' display-row' : '';
|
|
@@ -65,6 +72,8 @@ Layout.propTypes = {
|
|
|
65
72
|
}),
|
|
66
73
|
modifier: PropTypes.string,
|
|
67
74
|
backgroundImage: PropTypes.string,
|
|
75
|
+
backgroundImageUrl: PropTypes.string,
|
|
76
|
+
parent: PropTypes.object,
|
|
68
77
|
tagType: PropTypes.string,
|
|
69
78
|
dataNoSnippet: PropTypes.bool,
|
|
70
79
|
VariantComponent: PropTypes.func,
|
|
@@ -82,6 +91,8 @@ Layout.defaultProps = {
|
|
|
82
91
|
title: ''
|
|
83
92
|
},
|
|
84
93
|
backgroundImage: '',
|
|
94
|
+
backgroundImageUrl: '',
|
|
95
|
+
parent: {},
|
|
85
96
|
modifier: '',
|
|
86
97
|
tagType: '',
|
|
87
98
|
dataNoSnippet: false,
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import cssesc from 'cssesc';
|
|
2
2
|
import { COMPONENT_ID_PREFIX } from '../constants';
|
|
3
3
|
|
|
4
|
-
const getComponentId = componentName =>
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
const getComponentId = (componentName, noPrefix = false, toLowerCase = false) => {
|
|
5
|
+
let id = `${noPrefix ? '' : COMPONENT_ID_PREFIX}${componentName.replace(/\s+/g, '-')}`;
|
|
6
|
+
if (toLowerCase) {
|
|
7
|
+
id = id.toLowerCase();
|
|
8
|
+
}
|
|
9
|
+
return cssesc(id, { isIdentifier: true });
|
|
10
|
+
};
|
|
8
11
|
|
|
9
12
|
export default getComponentId;
|