@magento/pagebuilder 7.1.0 → 7.2.0-alpha.1
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/ContentTypes/Banner/__tests__/__snapshots__/banner.shimmer.spec.js.snap +0 -1
- package/lib/ContentTypes/Banner/__tests__/__snapshots__/banner.spec.js.snap +0 -1
- package/lib/ContentTypes/Banner/banner.js +23 -4
- package/lib/ContentTypes/Banner/banner.shimmer.js +13 -2
- package/lib/ContentTypes/Banner/configAggregator.js +4 -2
- package/lib/ContentTypes/Column/column.js +13 -2
- package/lib/ContentTypes/Column/configAggregator.js +3 -1
- package/lib/ContentTypes/DynamicBlock/__tests__/__snapshots__/dynamicBlock.ce.spec.js.snap +3 -0
- package/lib/ContentTypes/DynamicBlock/__tests__/__snapshots__/dynamicBlock.ee.spec.js.snap +93 -0
- package/lib/ContentTypes/DynamicBlock/__tests__/__snapshots__/dynamicBlock.shimmer.spec.js.snap +39 -0
- package/lib/ContentTypes/DynamicBlock/__tests__/configAggregator.spec.js +49 -0
- package/lib/ContentTypes/DynamicBlock/__tests__/dynamicBlock.ce.spec.js +17 -0
- package/lib/ContentTypes/DynamicBlock/__tests__/dynamicBlock.ee.spec.js +70 -0
- package/lib/ContentTypes/DynamicBlock/__tests__/dynamicBlock.shimmer.spec.js +20 -0
- package/lib/ContentTypes/DynamicBlock/configAggregator.js +25 -0
- package/lib/ContentTypes/DynamicBlock/dynamicBlock.ce.js +5 -0
- package/lib/ContentTypes/DynamicBlock/dynamicBlock.ee.js +134 -0
- package/lib/ContentTypes/DynamicBlock/dynamicBlock.module.css +8 -0
- package/lib/ContentTypes/DynamicBlock/dynamicBlock.shimmer.js +134 -0
- package/lib/ContentTypes/DynamicBlock/dynamicBlock.shimmer.module.css +26 -0
- package/lib/ContentTypes/DynamicBlock/index.js +2 -0
- package/lib/ContentTypes/Image/__tests__/__snapshots__/image.shimmer.spec.js.snap +139 -0
- package/lib/ContentTypes/Image/__tests__/configAggregator.spec.js +28 -10
- package/lib/ContentTypes/Image/__tests__/image.shimmer.spec.js +122 -0
- package/lib/ContentTypes/Image/__tests__/image.spec.js +5 -5
- package/lib/ContentTypes/Image/configAggregator.js +51 -18
- package/lib/ContentTypes/Image/image.js +25 -9
- package/lib/ContentTypes/Image/image.module.css +2 -0
- package/lib/ContentTypes/Image/image.shimmer.js +191 -0
- package/lib/ContentTypes/Image/image.shimmer.module.css +5 -0
- package/lib/ContentTypes/Image/index.js +1 -0
- package/lib/ContentTypes/Row/__tests__/configAggregator.spec.js +18 -0
- package/lib/ContentTypes/Row/__tests__/row.spec.js +2 -1
- package/lib/ContentTypes/Row/configAggregator.js +13 -3
- package/lib/ContentTypes/Row/row.js +26 -3
- package/lib/ContentTypes/Slider/configAggregator.js +3 -2
- package/lib/ContentTypes/Slider/slider.js +21 -2
- package/lib/ContentTypes/Slider/slider.shimmer.js +13 -2
- package/lib/ContentTypes/TabItem/configAggregator.js +4 -2
- package/lib/ContentTypes/TabItem/tabItem.js +13 -2
- package/lib/ContentTypes/Tabs/configAggregator.js +4 -2
- package/lib/ContentTypes/Tabs/tabs.js +19 -2
- package/lib/__tests__/parseStorageHtml.spec.js +35 -0
- package/lib/__tests__/utils.spec.js +21 -1
- package/lib/config.js +10 -2
- package/lib/parseStorageHtml.js +32 -0
- package/lib/utils.js +46 -0
- package/package.json +7 -7
|
@@ -14,7 +14,7 @@ test('renders an empty Image component', () => {
|
|
|
14
14
|
|
|
15
15
|
test('renders a Image component', () => {
|
|
16
16
|
const imageProps = {
|
|
17
|
-
desktopImage: 'test-image.png'
|
|
17
|
+
desktopImage: { src: 'test-image.png' }
|
|
18
18
|
};
|
|
19
19
|
const component = createTestInstance(<Image {...imageProps} />);
|
|
20
20
|
|
|
@@ -23,8 +23,8 @@ test('renders a Image component', () => {
|
|
|
23
23
|
|
|
24
24
|
test('renders a Image component with all props configured', () => {
|
|
25
25
|
const imageProps = {
|
|
26
|
-
desktopImage: 'desktop-image.png',
|
|
27
|
-
mobileImage: 'mobile-image.png',
|
|
26
|
+
desktopImage: { src: 'desktop-image.png' },
|
|
27
|
+
mobileImage: { src: 'mobile-image.png' },
|
|
28
28
|
altText: 'Alt Text',
|
|
29
29
|
title: 'Title Text',
|
|
30
30
|
link: 'http://www.adobe.com/',
|
|
@@ -53,7 +53,7 @@ test('renders a Image component with all props configured', () => {
|
|
|
53
53
|
|
|
54
54
|
test('renders a Image component with openInNewTab set to false', () => {
|
|
55
55
|
const imageProps = {
|
|
56
|
-
desktopImage: 'desktop-image.png',
|
|
56
|
+
desktopImage: { src: 'desktop-image.png' },
|
|
57
57
|
link: 'http://www.adobe.com/',
|
|
58
58
|
linkType: 'default',
|
|
59
59
|
openInNewTab: false
|
|
@@ -65,7 +65,7 @@ test('renders a Image component with openInNewTab set to false', () => {
|
|
|
65
65
|
|
|
66
66
|
test('renders a Image component with only mobile image', () => {
|
|
67
67
|
const imageProps = {
|
|
68
|
-
mobileImage: 'mobile-image.png'
|
|
68
|
+
mobileImage: { src: 'mobile-image.png' }
|
|
69
69
|
};
|
|
70
70
|
const component = createTestInstance(<Image {...imageProps} />);
|
|
71
71
|
|
|
@@ -4,7 +4,8 @@ import {
|
|
|
4
4
|
getIsHidden,
|
|
5
5
|
getMargin,
|
|
6
6
|
getPadding,
|
|
7
|
-
getTextAlign
|
|
7
|
+
getTextAlign,
|
|
8
|
+
getMediaQueries
|
|
8
9
|
} from '../../utils';
|
|
9
10
|
|
|
10
11
|
export default node => {
|
|
@@ -17,35 +18,67 @@ export default node => {
|
|
|
17
18
|
? node.childNodes[0].childNodes
|
|
18
19
|
: node.childNodes;
|
|
19
20
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
const getImageData = imageNode => {
|
|
22
|
+
let imageDimension = null;
|
|
23
|
+
try {
|
|
24
|
+
imageDimension = JSON.parse(
|
|
25
|
+
imageNode.getAttribute('data-image-dimensions')
|
|
26
|
+
);
|
|
27
|
+
} catch (e) {
|
|
28
|
+
// Do nothing
|
|
23
29
|
}
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
return {
|
|
31
|
+
src: imageNode.getAttribute('src'),
|
|
32
|
+
dimensions: imageDimension
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const getImageProps = () => {
|
|
37
|
+
const image = imageNode[0];
|
|
38
|
+
let imageProps = {
|
|
39
|
+
desktopImage: null,
|
|
40
|
+
mobileImage: null,
|
|
41
|
+
altText: null,
|
|
42
|
+
title: null
|
|
43
|
+
};
|
|
44
|
+
if (image) {
|
|
45
|
+
const imageData = getImageData(image);
|
|
46
|
+
if (image.getAttribute('data-element') === 'desktop_image') {
|
|
47
|
+
imageProps.desktopImage = imageData;
|
|
48
|
+
const image2 = imageNode[1];
|
|
49
|
+
if (
|
|
50
|
+
image2.getAttribute('data-element') === 'mobile_image' &&
|
|
51
|
+
image2.getAttribute('src') !== imageData.src
|
|
52
|
+
) {
|
|
53
|
+
imageProps.mobileImage = getImageData(image2);
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
// If there is no desktop image
|
|
57
|
+
imageProps.mobileImage = imageData;
|
|
58
|
+
}
|
|
59
|
+
imageProps.altText = image.getAttribute('alt');
|
|
60
|
+
imageProps.title = image.getAttribute('title');
|
|
61
|
+
imageProps = {
|
|
62
|
+
...imageProps,
|
|
63
|
+
...getBorder(image)
|
|
64
|
+
};
|
|
26
65
|
}
|
|
27
|
-
|
|
66
|
+
|
|
67
|
+
return imageProps;
|
|
28
68
|
};
|
|
29
69
|
|
|
30
70
|
const props = {
|
|
31
|
-
|
|
32
|
-
imageNode[0] && imageNode[1]
|
|
33
|
-
? imageNode[0].getAttribute('src')
|
|
34
|
-
: null,
|
|
35
|
-
mobileImage: mobileImageSrc(),
|
|
36
|
-
altText: imageNode[0] ? imageNode[0].getAttribute('alt') : null,
|
|
37
|
-
title: imageNode[0] ? imageNode[0].getAttribute('title') : null,
|
|
71
|
+
...getImageProps(),
|
|
38
72
|
openInNewTab: node.childNodes[0].getAttribute('target') === '_blank',
|
|
39
73
|
...getPadding(node),
|
|
40
74
|
...getMargin(node),
|
|
41
75
|
...(imageNode[0] ? getBorder(imageNode[0]) : []),
|
|
42
76
|
...getCssClasses(node),
|
|
43
77
|
...getTextAlign(node),
|
|
44
|
-
...getIsHidden(node)
|
|
78
|
+
...getIsHidden(node),
|
|
79
|
+
...getMediaQueries(node)
|
|
45
80
|
};
|
|
46
|
-
|
|
47
|
-
props.mobileImage = null;
|
|
48
|
-
}
|
|
81
|
+
|
|
49
82
|
if (node.childNodes[0].nodeName === 'A') {
|
|
50
83
|
props.link = node.childNodes[0].getAttribute('href');
|
|
51
84
|
props.linkType = node.childNodes[0].getAttribute('data-link-type');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import defaultClasses from './image.module.css';
|
|
3
|
-
import { arrayOf, bool, oneOf, shape, string } from 'prop-types';
|
|
3
|
+
import { arrayOf, bool, oneOf, shape, string, number } from 'prop-types';
|
|
4
4
|
import { Link } from 'react-router-dom';
|
|
5
5
|
import resolveLinkProps from '../../resolveLinkProps';
|
|
6
6
|
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
@@ -67,10 +67,10 @@ const Image = props => {
|
|
|
67
67
|
return null;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
const
|
|
70
|
+
const MobileSourceFragment = mobileImage ? (
|
|
71
71
|
<source
|
|
72
72
|
media="(max-width: 48rem)"
|
|
73
|
-
srcSet={resourceUrl(mobileImage, {
|
|
73
|
+
srcSet={resourceUrl(mobileImage.src, {
|
|
74
74
|
type: 'image-wysiwyg',
|
|
75
75
|
quality: 85
|
|
76
76
|
})}
|
|
@@ -80,7 +80,7 @@ const Image = props => {
|
|
|
80
80
|
);
|
|
81
81
|
|
|
82
82
|
const imgSrc = desktopImage
|
|
83
|
-
? resourceUrl(desktopImage, {
|
|
83
|
+
? resourceUrl(desktopImage.src, {
|
|
84
84
|
type: 'image-wysiwyg',
|
|
85
85
|
quality: 85
|
|
86
86
|
})
|
|
@@ -94,7 +94,7 @@ const Image = props => {
|
|
|
94
94
|
const PictureFragment = (
|
|
95
95
|
<>
|
|
96
96
|
<picture>
|
|
97
|
-
{
|
|
97
|
+
{MobileSourceFragment}
|
|
98
98
|
<img
|
|
99
99
|
className={imgClassName}
|
|
100
100
|
srcSet={`${imgSrc} 1x`}
|
|
@@ -115,6 +115,7 @@ const Image = props => {
|
|
|
115
115
|
|
|
116
116
|
return (
|
|
117
117
|
<figure
|
|
118
|
+
data-cy="PageBuilder-Image-root"
|
|
118
119
|
style={figureStyles}
|
|
119
120
|
className={[classes.root, ...cssClasses].join(' ')}
|
|
120
121
|
>
|
|
@@ -129,6 +130,7 @@ const Image = props => {
|
|
|
129
130
|
} else {
|
|
130
131
|
return (
|
|
131
132
|
<figure
|
|
133
|
+
data-cy="PageBuilder-Image-root"
|
|
132
134
|
style={figureStyles}
|
|
133
135
|
className={[classes.root, ...cssClasses].join(' ')}
|
|
134
136
|
>
|
|
@@ -145,8 +147,8 @@ const Image = props => {
|
|
|
145
147
|
*
|
|
146
148
|
* @property {Object} classes An object containing the class names for the Image
|
|
147
149
|
* @property {String} classes.img CSS classes for the img element
|
|
148
|
-
* @property {
|
|
149
|
-
* @property {
|
|
150
|
+
* @property {Object} desktopImage desktop image URL src and dimensions
|
|
151
|
+
* @property {Object} mobileImage mobile image URL src and dimensions
|
|
150
152
|
* @property {String} altText Alternate text
|
|
151
153
|
* @property {String} title Title of the image
|
|
152
154
|
* @property {String} link URL to redirect to
|
|
@@ -174,8 +176,22 @@ Image.propTypes = {
|
|
|
174
176
|
img: string,
|
|
175
177
|
mobileOnly: string
|
|
176
178
|
}),
|
|
177
|
-
desktopImage:
|
|
178
|
-
|
|
179
|
+
desktopImage: shape({
|
|
180
|
+
src: string,
|
|
181
|
+
dimensions: shape({
|
|
182
|
+
height: number,
|
|
183
|
+
ratio: number,
|
|
184
|
+
width: number
|
|
185
|
+
})
|
|
186
|
+
}),
|
|
187
|
+
mobileImage: shape({
|
|
188
|
+
src: string,
|
|
189
|
+
dimensions: shape({
|
|
190
|
+
height: number,
|
|
191
|
+
ratio: number,
|
|
192
|
+
width: number
|
|
193
|
+
})
|
|
194
|
+
}),
|
|
179
195
|
altText: string,
|
|
180
196
|
title: string,
|
|
181
197
|
link: string,
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import React, { useMemo, useRef, useEffect } from 'react';
|
|
2
|
+
import { arrayOf, shape, string, number } from 'prop-types';
|
|
3
|
+
import defaultClasses from './image.shimmer.module.css';
|
|
4
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
5
|
+
import Shimmer from '@magento/venia-ui/lib/components/Shimmer';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Page Builder Image Shimmer component.
|
|
9
|
+
*
|
|
10
|
+
* @typedef ImageShimmer
|
|
11
|
+
* @kind functional component
|
|
12
|
+
*
|
|
13
|
+
* @param {props} props React component props
|
|
14
|
+
*
|
|
15
|
+
* @returns {React.Element|null} A React component that displays an Image Shimmer.
|
|
16
|
+
*/
|
|
17
|
+
const ImageShimmer = props => {
|
|
18
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
19
|
+
const {
|
|
20
|
+
desktopImage,
|
|
21
|
+
mobileImage,
|
|
22
|
+
textAlign,
|
|
23
|
+
border,
|
|
24
|
+
borderColor,
|
|
25
|
+
borderWidth,
|
|
26
|
+
borderRadius,
|
|
27
|
+
marginTop,
|
|
28
|
+
marginRight,
|
|
29
|
+
marginBottom,
|
|
30
|
+
marginLeft,
|
|
31
|
+
paddingTop,
|
|
32
|
+
paddingRight,
|
|
33
|
+
paddingBottom,
|
|
34
|
+
paddingLeft,
|
|
35
|
+
cssClasses = []
|
|
36
|
+
} = props;
|
|
37
|
+
|
|
38
|
+
const figureStyles = {
|
|
39
|
+
textAlign,
|
|
40
|
+
marginTop,
|
|
41
|
+
marginRight,
|
|
42
|
+
marginBottom,
|
|
43
|
+
marginLeft,
|
|
44
|
+
paddingTop,
|
|
45
|
+
paddingRight,
|
|
46
|
+
paddingBottom,
|
|
47
|
+
paddingLeft
|
|
48
|
+
};
|
|
49
|
+
const imageStyles = {
|
|
50
|
+
border,
|
|
51
|
+
borderColor,
|
|
52
|
+
borderWidth,
|
|
53
|
+
borderRadius
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const figureRef = useRef();
|
|
57
|
+
|
|
58
|
+
const dimensions = useMemo(() => {
|
|
59
|
+
const value = {
|
|
60
|
+
height: 0,
|
|
61
|
+
width: 0
|
|
62
|
+
};
|
|
63
|
+
if (
|
|
64
|
+
window.matchMedia('(max-width: 48rem)').matches &&
|
|
65
|
+
mobileImage &&
|
|
66
|
+
mobileImage.dimensions
|
|
67
|
+
) {
|
|
68
|
+
value.width = mobileImage.dimensions.width;
|
|
69
|
+
value.height = mobileImage.dimensions.height;
|
|
70
|
+
} else if (desktopImage && desktopImage.dimensions) {
|
|
71
|
+
value.width = desktopImage.dimensions.width;
|
|
72
|
+
value.height = desktopImage.dimensions.height;
|
|
73
|
+
} else {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
return value;
|
|
77
|
+
}, [desktopImage, mobileImage]);
|
|
78
|
+
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (figureRef.current) {
|
|
81
|
+
const width = figureRef.current.offsetWidth;
|
|
82
|
+
if (dimensions.width > width) {
|
|
83
|
+
if (
|
|
84
|
+
window.matchMedia('(max-width: 48rem)').matches &&
|
|
85
|
+
mobileImage &&
|
|
86
|
+
mobileImage.dimensions
|
|
87
|
+
) {
|
|
88
|
+
dimensions.width = width;
|
|
89
|
+
dimensions.height =
|
|
90
|
+
dimensions.width * mobileImage.dimensions.ratio;
|
|
91
|
+
} else if (desktopImage && desktopImage.dimensions) {
|
|
92
|
+
dimensions.width = width;
|
|
93
|
+
dimensions.height =
|
|
94
|
+
dimensions.width * desktopImage.dimensions.ratio;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}, [desktopImage, dimensions, mobileImage]);
|
|
99
|
+
|
|
100
|
+
if (!dimensions) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<figure style={figureStyles} ref={figureRef}>
|
|
106
|
+
<Shimmer
|
|
107
|
+
aria-live="polite"
|
|
108
|
+
aria-busy="true"
|
|
109
|
+
classes={{
|
|
110
|
+
root_rectangle: [
|
|
111
|
+
classes.root,
|
|
112
|
+
classes.shimmerRoot,
|
|
113
|
+
...cssClasses
|
|
114
|
+
].join(' ')
|
|
115
|
+
}}
|
|
116
|
+
style={imageStyles}
|
|
117
|
+
height={dimensions.height + 'px'}
|
|
118
|
+
width={dimensions.width + 'px'}
|
|
119
|
+
/>
|
|
120
|
+
</figure>
|
|
121
|
+
);
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Props for {@link ImageShimmer}
|
|
126
|
+
*
|
|
127
|
+
* * @typedef props
|
|
128
|
+
* *
|
|
129
|
+
* * @property {Object} classes An object containing the class names for the Image
|
|
130
|
+
* * @property {String} classes.img CSS classes for the img element
|
|
131
|
+
* * @property {Object} desktopImage desktop image URL src and dimensions
|
|
132
|
+
* * @property {Object} mobileImage mobile image URL src and dimensions
|
|
133
|
+
* * @property {String} altText Alternate text
|
|
134
|
+
* * @property {String} textAlign Alignment of the divider within the parent container
|
|
135
|
+
* * @property {String} border CSS border property
|
|
136
|
+
* * @property {String} borderColor CSS border color property
|
|
137
|
+
* * @property {String} borderWidth CSS border width property
|
|
138
|
+
* * @property {String} borderRadius CSS border radius property
|
|
139
|
+
* * @property {String} marginTop CSS margin top property
|
|
140
|
+
* * @property {String} marginRight CSS margin right property
|
|
141
|
+
* * @property {String} marginBottom CSS margin bottom property
|
|
142
|
+
* * @property {String} marginLeft CSS margin left property
|
|
143
|
+
* * @property {String} paddingTop CSS padding top property
|
|
144
|
+
* * @property {String} paddingRight CSS padding right property
|
|
145
|
+
* * @property {String} paddingBottom CSS padding bottom property
|
|
146
|
+
* * @property {String} paddingLeft CSS padding left property
|
|
147
|
+
* * @property {Array} cssClasses List of CSS classes to be applied to the component
|
|
148
|
+
* */
|
|
149
|
+
ImageShimmer.propTypes = {
|
|
150
|
+
classes: shape({
|
|
151
|
+
root: string,
|
|
152
|
+
shimmerRoot: string,
|
|
153
|
+
overlay: string,
|
|
154
|
+
content: string,
|
|
155
|
+
wrapper: string,
|
|
156
|
+
img: string,
|
|
157
|
+
mobileOnly: string
|
|
158
|
+
}),
|
|
159
|
+
desktopImage: shape({
|
|
160
|
+
src: string,
|
|
161
|
+
dimensions: shape({
|
|
162
|
+
height: number,
|
|
163
|
+
ratio: number,
|
|
164
|
+
width: number
|
|
165
|
+
})
|
|
166
|
+
}),
|
|
167
|
+
mobileImage: shape({
|
|
168
|
+
src: string,
|
|
169
|
+
dimensions: shape({
|
|
170
|
+
height: number,
|
|
171
|
+
ratio: number,
|
|
172
|
+
width: number
|
|
173
|
+
})
|
|
174
|
+
}),
|
|
175
|
+
altText: string,
|
|
176
|
+
textAlign: string,
|
|
177
|
+
border: string,
|
|
178
|
+
borderColor: string,
|
|
179
|
+
borderWidth: string,
|
|
180
|
+
borderRadius: string,
|
|
181
|
+
marginTop: string,
|
|
182
|
+
marginRight: string,
|
|
183
|
+
marginBottom: string,
|
|
184
|
+
marginLeft: string,
|
|
185
|
+
paddingTop: string,
|
|
186
|
+
paddingRight: string,
|
|
187
|
+
paddingBottom: string,
|
|
188
|
+
cssClasses: arrayOf(string)
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
export default ImageShimmer;
|
|
@@ -93,3 +93,21 @@ test('config is aggregated correctly for row appearance == full-width with video
|
|
|
93
93
|
})
|
|
94
94
|
);
|
|
95
95
|
});
|
|
96
|
+
|
|
97
|
+
test('config is aggregated correctly for row containing dynamic block', () => {
|
|
98
|
+
const node = document.createElement('div');
|
|
99
|
+
node.innerHTML = `<div data-content-type="row" data-appearance="contained" data-element="main"><div class="class1 class2" data-enable-parallax="0" data-parallax-speed="0.5" data-background-images="{}" data-element="inner" style="justify-content: flex-start; display: flex; flex-direction: column; background-position: left top; background-size: cover; background-repeat: no-repeat; background-attachment: scroll; text-align: right; border-style: dashed; border-color: rgb(252, 0, 9); border-width: 20px; border-radius: 30px; margin: 5px; padding: 10px; min-height: 40px;"><div data-content-type="dynamic_block" data-appearance="default" data-element="main">{{widget type="Magento\\Banner\\Block\\Widget\\Banner" display_mode="fixed" rotate="" template="widget/block.phtml" banner_ids="2" unique_id="2" type_name="Dynamic Blocks Rotator"}}</div></div></div>`;
|
|
100
|
+
const config = configAggregator(node.childNodes[0], {
|
|
101
|
+
appearance: 'contained'
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// minHeight should be null, minHeight is managed by dynamicBlock
|
|
105
|
+
expect(config).toEqual(
|
|
106
|
+
expect.objectContaining({
|
|
107
|
+
minHeight: null,
|
|
108
|
+
backgroundColor: null,
|
|
109
|
+
enableParallax: false,
|
|
110
|
+
parallaxSpeed: 0.5
|
|
111
|
+
})
|
|
112
|
+
);
|
|
113
|
+
});
|
|
@@ -2,7 +2,8 @@ import {
|
|
|
2
2
|
getAdvanced,
|
|
3
3
|
getBackgroundImages,
|
|
4
4
|
getVerticalAlignment,
|
|
5
|
-
getIsHidden
|
|
5
|
+
getIsHidden,
|
|
6
|
+
getMediaQueries
|
|
6
7
|
} from '../../utils';
|
|
7
8
|
|
|
8
9
|
export default (node, props) => {
|
|
@@ -16,8 +17,16 @@ export default (node, props) => {
|
|
|
16
17
|
: dataNode.childNodes[0] &&
|
|
17
18
|
dataNode.childNodes[0].getAttribute('data-video-overlay-color');
|
|
18
19
|
|
|
20
|
+
const minHeight = dataNode.style.minHeight
|
|
21
|
+
? dataNode.style.minHeight
|
|
22
|
+
: null;
|
|
23
|
+
|
|
24
|
+
const containsDynamicBlock = [...dataNode.childNodes].some(e => {
|
|
25
|
+
return e.getAttribute('data-content-type') === 'dynamic_block';
|
|
26
|
+
});
|
|
27
|
+
|
|
19
28
|
return {
|
|
20
|
-
minHeight:
|
|
29
|
+
minHeight: containsDynamicBlock ? null : minHeight,
|
|
21
30
|
...getVerticalAlignment(dataNode),
|
|
22
31
|
backgroundColor: dataNode.style.backgroundColor
|
|
23
32
|
? dataNode.style.backgroundColor
|
|
@@ -35,6 +44,7 @@ export default (node, props) => {
|
|
|
35
44
|
dataNode.getAttribute('data-video-lazy-load') === 'true',
|
|
36
45
|
videoOverlayColor: videoOverlayColor || null,
|
|
37
46
|
...getAdvanced(dataNode),
|
|
38
|
-
...getIsHidden(node)
|
|
47
|
+
...getIsHidden(node),
|
|
48
|
+
...getMediaQueries(dataNode)
|
|
39
49
|
};
|
|
40
50
|
};
|
|
@@ -2,9 +2,18 @@ import React, { useEffect, useRef, useState } from 'react';
|
|
|
2
2
|
import defaultClasses from './row.module.css';
|
|
3
3
|
import { verticalAlignmentToFlex } from '../../utils';
|
|
4
4
|
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
arrayOf,
|
|
7
|
+
oneOf,
|
|
8
|
+
shape,
|
|
9
|
+
bool,
|
|
10
|
+
string,
|
|
11
|
+
number,
|
|
12
|
+
object
|
|
13
|
+
} from 'prop-types';
|
|
6
14
|
import resourceUrl from '@magento/peregrine/lib/util/makeUrl';
|
|
7
15
|
import { useDetectScrollWidth } from '@magento/peregrine/lib/hooks/useDetectScrollWidth';
|
|
16
|
+
import { useMediaQuery } from '@magento/peregrine/lib/hooks/useMediaQuery';
|
|
8
17
|
|
|
9
18
|
const { matchMedia } = globalThis;
|
|
10
19
|
|
|
@@ -24,6 +33,7 @@ const Row = props => {
|
|
|
24
33
|
const backgroundElement = useRef(null);
|
|
25
34
|
const [bgImageStyle, setBgImageStyle] = useState(null);
|
|
26
35
|
const classes = useStyle(defaultClasses, props.classes);
|
|
36
|
+
|
|
27
37
|
const {
|
|
28
38
|
appearance,
|
|
29
39
|
verticalAlignment,
|
|
@@ -46,6 +56,7 @@ const Row = props => {
|
|
|
46
56
|
marginRight,
|
|
47
57
|
marginBottom,
|
|
48
58
|
marginLeft,
|
|
59
|
+
mediaQueries,
|
|
49
60
|
paddingTop,
|
|
50
61
|
paddingRight,
|
|
51
62
|
paddingBottom,
|
|
@@ -61,6 +72,8 @@ const Row = props => {
|
|
|
61
72
|
videoOverlayColor
|
|
62
73
|
} = props;
|
|
63
74
|
|
|
75
|
+
const { styles: mediaQueryStyles } = useMediaQuery({ mediaQueries });
|
|
76
|
+
|
|
64
77
|
let image = desktopImage;
|
|
65
78
|
if (mobileImage && matchMedia && matchMedia('(max-width: 768px)').matches) {
|
|
66
79
|
image = mobileImage;
|
|
@@ -171,7 +184,8 @@ const Row = props => {
|
|
|
171
184
|
videoSrc,
|
|
172
185
|
videoLoop,
|
|
173
186
|
videoPlayOnlyVisible,
|
|
174
|
-
videoLazyLoading
|
|
187
|
+
videoLazyLoading,
|
|
188
|
+
zIndex: 'auto'
|
|
175
189
|
});
|
|
176
190
|
|
|
177
191
|
parallaxElement.jarallax.video &&
|
|
@@ -218,6 +232,7 @@ const Row = props => {
|
|
|
218
232
|
ref={backgroundElement}
|
|
219
233
|
style={{
|
|
220
234
|
...dynamicStyles,
|
|
235
|
+
...mediaQueryStyles,
|
|
221
236
|
marginLeft: null,
|
|
222
237
|
marginRight: null,
|
|
223
238
|
'--pbRowMarginLeft': marginLeft,
|
|
@@ -241,6 +256,7 @@ const Row = props => {
|
|
|
241
256
|
ref={backgroundElement}
|
|
242
257
|
style={{
|
|
243
258
|
...dynamicStyles,
|
|
259
|
+
...mediaQueryStyles,
|
|
244
260
|
marginLeft: null,
|
|
245
261
|
marginRight: null,
|
|
246
262
|
'--pbRowMarginLeft': marginLeft,
|
|
@@ -263,7 +279,7 @@ const Row = props => {
|
|
|
263
279
|
<div
|
|
264
280
|
ref={backgroundElement}
|
|
265
281
|
className={classes.inner}
|
|
266
|
-
style={dynamicStyles}
|
|
282
|
+
style={{ ...dynamicStyles, ...mediaQueryStyles }}
|
|
267
283
|
>
|
|
268
284
|
{videoOverlay}
|
|
269
285
|
{children}
|
|
@@ -301,6 +317,7 @@ const Row = props => {
|
|
|
301
317
|
* @property {String} marginRight CSS margin right property
|
|
302
318
|
* @property {String} marginBottom CSS margin bottom property
|
|
303
319
|
* @property {String} marginLeft CSS margin left property
|
|
320
|
+
* @property {Array} mediaQueries List of media query rules to be applied to the component
|
|
304
321
|
* @property {String} paddingTop CSS padding top property
|
|
305
322
|
* @property {String} paddingRight CSS padding right property
|
|
306
323
|
* @property {String} paddingBottom CSS padding bottom property
|
|
@@ -343,6 +360,12 @@ Row.propTypes = {
|
|
|
343
360
|
marginRight: string,
|
|
344
361
|
marginBottom: string,
|
|
345
362
|
marginLeft: string,
|
|
363
|
+
mediaQueries: arrayOf(
|
|
364
|
+
shape({
|
|
365
|
+
media: string,
|
|
366
|
+
style: object
|
|
367
|
+
})
|
|
368
|
+
),
|
|
346
369
|
paddingTop: string,
|
|
347
370
|
paddingRight: string,
|
|
348
371
|
paddingBottom: string,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getAdvanced } from '../../utils';
|
|
1
|
+
import { getAdvanced, getMediaQueries } from '../../utils';
|
|
2
2
|
|
|
3
3
|
export default node => {
|
|
4
4
|
const autoplaySpeed = parseInt(node.getAttribute('data-autoplay-speed'));
|
|
@@ -11,6 +11,7 @@ export default node => {
|
|
|
11
11
|
showArrows: node.getAttribute('data-show-arrows') === 'true',
|
|
12
12
|
showDots: node.getAttribute('data-show-dots') === 'true',
|
|
13
13
|
...(!isNaN(autoplaySpeed) && { autoplaySpeed }),
|
|
14
|
-
...getAdvanced(node)
|
|
14
|
+
...getAdvanced(node),
|
|
15
|
+
...getMediaQueries(node)
|
|
15
16
|
};
|
|
16
17
|
};
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import React, { Children } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
arrayOf,
|
|
4
|
+
bool,
|
|
5
|
+
number,
|
|
6
|
+
oneOf,
|
|
7
|
+
shape,
|
|
8
|
+
string,
|
|
9
|
+
object
|
|
10
|
+
} from 'prop-types';
|
|
3
11
|
import SlickSlider from 'react-slick';
|
|
4
12
|
import defaultClasses from './slider.module.css';
|
|
5
13
|
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
14
|
+
import { useMediaQuery } from '@magento/peregrine/lib/hooks/useMediaQuery';
|
|
6
15
|
import { jarallax } from 'jarallax';
|
|
7
16
|
|
|
8
17
|
/**
|
|
@@ -37,6 +46,7 @@ const Slider = props => {
|
|
|
37
46
|
marginRight,
|
|
38
47
|
marginBottom,
|
|
39
48
|
marginLeft,
|
|
49
|
+
mediaQueries,
|
|
40
50
|
paddingTop,
|
|
41
51
|
paddingRight,
|
|
42
52
|
paddingBottom,
|
|
@@ -45,6 +55,8 @@ const Slider = props => {
|
|
|
45
55
|
children
|
|
46
56
|
} = props;
|
|
47
57
|
|
|
58
|
+
const { styles: mediaQueryStyles } = useMediaQuery({ mediaQueries });
|
|
59
|
+
|
|
48
60
|
const dynamicStyles = {
|
|
49
61
|
minHeight,
|
|
50
62
|
textAlign,
|
|
@@ -101,7 +113,7 @@ const Slider = props => {
|
|
|
101
113
|
aria-live="polite"
|
|
102
114
|
aria-busy="false"
|
|
103
115
|
className={[classes.root, ...cssClasses].join(' ')}
|
|
104
|
-
style={dynamicStyles}
|
|
116
|
+
style={{ ...dynamicStyles, ...mediaQueryStyles }}
|
|
105
117
|
>
|
|
106
118
|
<SlickSlider {...sliderSettings}>{children}</SlickSlider>
|
|
107
119
|
</div>
|
|
@@ -135,6 +147,7 @@ const Slider = props => {
|
|
|
135
147
|
* @property {String} marginRight CSS margin right property
|
|
136
148
|
* @property {String} marginBottom CSS margin bottom property
|
|
137
149
|
* @property {String} marginLeft CSS margin left property
|
|
150
|
+
* @property {Array} mediaQueries List of media query rules to be applied to the component
|
|
138
151
|
* @property {String} paddingTop CSS padding top property
|
|
139
152
|
* @property {String} paddingRight CSS padding right property
|
|
140
153
|
* @property {String} paddingBottom CSS padding bottom property
|
|
@@ -166,6 +179,12 @@ Slider.propTypes = {
|
|
|
166
179
|
marginRight: string,
|
|
167
180
|
marginBottom: string,
|
|
168
181
|
marginLeft: string,
|
|
182
|
+
mediaQueries: arrayOf(
|
|
183
|
+
shape({
|
|
184
|
+
media: string,
|
|
185
|
+
style: object
|
|
186
|
+
})
|
|
187
|
+
),
|
|
169
188
|
paddingTop: string,
|
|
170
189
|
paddingRight: string,
|
|
171
190
|
paddingBottom: string,
|