@shopgate/pwa-common 7.30.3 → 7.31.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/App.js +0 -2
- package/actions/app/handleLink.js +1 -0
- package/collections/AuthRoutes.js +1 -0
- package/collections/PersistedReducers.js +1 -0
- package/collections/media-providers/Vimeo.js +1 -1
- package/collections/media-providers/style.js +1 -1
- package/components/Backdrop/index.js +18 -3
- package/components/Button/index.js +40 -52
- package/components/Checkbox/index.js +1 -1
- package/components/Drawer/index.js +118 -132
- package/components/Drawer/spec.js +4 -2
- package/components/Dropdown/index.js +52 -68
- package/components/Grid/components/Item/index.js +37 -40
- package/components/Grid/index.js +36 -34
- package/components/HtmlSanitizer/index.js +60 -7
- package/components/I18n/components/FormatNumber/spec.js +1 -0
- package/components/Icon/index.d.ts +36 -0
- package/components/Icon/index.d.ts.map +1 -0
- package/components/Icon/index.js +39 -28
- package/components/Image/Image.js +27 -6
- package/components/Image/ImageInner.js +32 -25
- package/components/InfiniteContainer/index.js +5 -7
- package/components/InfiniteContainer/spec.js +13 -17
- package/components/Link/index.js +75 -84
- package/components/List/components/Item/index.js +19 -10
- package/components/List/spec.js +1 -3
- package/components/Loading/index.d.ts +6 -0
- package/components/Loading/index.d.ts.map +1 -0
- package/components/Modal/index.js +41 -7
- package/components/Picker/index.js +18 -194
- package/components/Portal/index.d.ts +50 -0
- package/components/Portal/index.d.ts.map +1 -0
- package/components/ProductCharacteristics/index.js +14 -276
- package/components/RangeSlider/index.js +15 -258
- package/components/Select/components/Item/index.js +18 -7
- package/components/Select/index.js +108 -144
- package/components/Select/spec.js +49 -16
- package/components/SelectBox/components/Item/index.js +49 -51
- package/components/SelectBox/index.js +140 -160
- package/components/SurroundPortals/index.d.ts +24 -0
- package/components/SurroundPortals/index.d.ts.map +1 -0
- package/components/SurroundPortals/index.js +3 -13
- package/components/Swiper/components/SwiperItem/index.js +13 -4
- package/components/Swiper/components/SwiperItem/spec.js +3 -2
- package/components/Swiper/index.js +80 -12
- package/components/Widgets/components/Widget/index.js +54 -56
- package/components/Widgets/components/Widget/spec.js +12 -8
- package/components/Widgets/components/WidgetGrid/index.js +39 -53
- package/components/Widgets/components/WidgetGrid/spec.js +12 -8
- package/constants/Configuration.js +2 -1
- package/constants/Portals.d.ts +101 -0
- package/constants/Portals.d.ts.map +1 -0
- package/helpers/config/index.d.ts +94 -0
- package/helpers/config/index.d.ts.map +1 -0
- package/helpers/config/mock.d.ts +23 -0
- package/helpers/config/mock.d.ts.map +1 -0
- package/helpers/config/theme.d.ts +7 -0
- package/helpers/config/theme.d.ts.map +1 -0
- package/helpers/data/index.d.ts +35 -0
- package/helpers/data/index.d.ts.map +1 -0
- package/helpers/data/index.js +1 -0
- package/helpers/html/handleDOM.js +1 -0
- package/helpers/portals/portalCollection.d.ts +30 -0
- package/helpers/portals/portalCollection.d.ts.map +1 -0
- package/helpers/style/index.js +1 -0
- package/helpers/validation/index.d.ts +10 -0
- package/helpers/validation/index.d.ts.map +1 -0
- package/package.json +4 -3
- package/selectors/client.js +1 -0
- package/styles/reset/form.js +46 -51
- package/styles/reset/media.js +21 -19
- package/styles/reset/root.js +28 -26
- package/styles/reset/table.js +9 -7
- package/styles/reset/typography.js +24 -22
- package/subscriptions/error.js +1 -0
- package/subscriptions/helpers/handleLinks.js +1 -0
- package/subscriptions/router.js +1 -0
- package/tsconfig.build.json +16 -0
- package/tsconfig.json +3 -0
- package/components/Backdrop/style.js +0 -11
- package/components/Button/style.js +0 -6
- package/components/Drawer/style.js +0 -37
- package/components/Dropdown/style.js +0 -4
- package/components/Grid/components/Item/style.js +0 -23
- package/components/Grid/style.js +0 -14
- package/components/Icon/style.js +0 -6
- package/components/Image/style.js +0 -32
- package/components/Link/style.js +0 -10
- package/components/List/components/Item/style.js +0 -16
- package/components/Modal/style.js +0 -36
- package/components/Picker/components/Button/index.js +0 -42
- package/components/Picker/components/Button/style.js +0 -19
- package/components/Picker/components/List/index.js +0 -38
- package/components/Picker/components/List/style.js +0 -17
- package/components/Picker/components/Modal/index.js +0 -76
- package/components/Picker/components/Modal/style.js +0 -78
- package/components/Picker/spec.js +0 -88
- package/components/ProductCharacteristics/connector.js +0 -41
- package/components/ProductCharacteristics/context.js +0 -2
- package/components/ProductCharacteristics/helpers/index.js +0 -162
- package/components/RangeSlider/components/Handle/index.js +0 -34
- package/components/RangeSlider/components/Handle/style.js +0 -14
- package/components/RangeSlider/helper.js +0 -85
- package/components/RangeSlider/style.js +0 -14
- package/components/Select/components/Item/style.js +0 -4
- package/components/Select/style.js +0 -17
- package/components/SelectBox/components/Item/style.js +0 -7
- package/components/SelectBox/style.js +0 -18
- package/components/Swiper/components/SwiperItem/styles.js +0 -5
- package/components/Swiper/styles.js +0 -76
- package/components/Widgets/components/Widget/style.js +0 -27
- package/components/Widgets/components/WidgetGrid/style.js +0 -8
|
@@ -1,48 +1,45 @@
|
|
|
1
|
-
import
|
|
2
|
-
import React, { Component } from 'react';
|
|
1
|
+
import React from 'react';
|
|
3
2
|
import PropTypes from 'prop-types';
|
|
4
|
-
import {
|
|
5
|
-
|
|
3
|
+
import { makeStyles } from '@shopgate/engage/styles';
|
|
4
|
+
const useStyles = makeStyles()((_theme, {
|
|
5
|
+
grow,
|
|
6
|
+
shrink
|
|
7
|
+
}) => ({
|
|
8
|
+
root: {
|
|
9
|
+
...(grow !== 0 ? {
|
|
10
|
+
flexGrow: grow
|
|
11
|
+
} : {}),
|
|
12
|
+
...(shrink !== 1 ? {
|
|
13
|
+
flexShrink: shrink
|
|
14
|
+
} : {})
|
|
15
|
+
}
|
|
16
|
+
}));
|
|
6
17
|
|
|
7
18
|
/**
|
|
8
19
|
* The grid item component.
|
|
20
|
+
* @param {Object} props Props.
|
|
21
|
+
* @returns {JSX.Element}
|
|
9
22
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const props = {
|
|
31
|
-
...this.props,
|
|
32
|
-
className
|
|
33
|
-
};
|
|
34
|
-
return objectWithoutProps(props, ['component', 'grow', 'shrink']);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Renders the component.
|
|
39
|
-
* @returns {JSX}
|
|
40
|
-
*/;
|
|
41
|
-
_proto.render = function render() {
|
|
42
|
-
return /*#__PURE__*/React.createElement(this.props.component, this.getProps());
|
|
43
|
-
};
|
|
44
|
-
return GridItem;
|
|
45
|
-
}(Component);
|
|
23
|
+
const GridItem = ({
|
|
24
|
+
className,
|
|
25
|
+
component,
|
|
26
|
+
grow,
|
|
27
|
+
shrink,
|
|
28
|
+
...rest
|
|
29
|
+
}) => {
|
|
30
|
+
const {
|
|
31
|
+
classes,
|
|
32
|
+
cx
|
|
33
|
+
} = useStyles({
|
|
34
|
+
grow,
|
|
35
|
+
shrink
|
|
36
|
+
});
|
|
37
|
+
const composedClassName = cx(classes.root, className);
|
|
38
|
+
return /*#__PURE__*/React.createElement(component, {
|
|
39
|
+
...rest,
|
|
40
|
+
className: composedClassName
|
|
41
|
+
});
|
|
42
|
+
};
|
|
46
43
|
GridItem.defaultProps = {
|
|
47
44
|
className: '',
|
|
48
45
|
component: 'li',
|
package/components/Grid/index.js
CHANGED
|
@@ -1,44 +1,46 @@
|
|
|
1
|
-
import
|
|
2
|
-
import React, { Component } from 'react';
|
|
1
|
+
import React from 'react';
|
|
3
2
|
import PropTypes from 'prop-types';
|
|
3
|
+
import { makeStyles } from '@shopgate/engage/styles';
|
|
4
4
|
import { objectWithoutProps } from "../../helpers/data";
|
|
5
5
|
import GridItem from "./components/Item";
|
|
6
|
-
|
|
6
|
+
const useStyles = makeStyles()(() => ({
|
|
7
|
+
root: {
|
|
8
|
+
display: 'flex',
|
|
9
|
+
minWidth: '100%'
|
|
10
|
+
},
|
|
11
|
+
wrap: {
|
|
12
|
+
flexWrap: 'wrap'
|
|
13
|
+
},
|
|
14
|
+
noWrap: {
|
|
15
|
+
flexWrap: 'nowrap'
|
|
16
|
+
}
|
|
17
|
+
}));
|
|
7
18
|
|
|
8
19
|
/**
|
|
9
20
|
* The grid component.
|
|
21
|
+
* @param {Object} props Props.
|
|
22
|
+
* @returns {JSX.Element}
|
|
10
23
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Renders the component.
|
|
35
|
-
* @returns {JSX}
|
|
36
|
-
*/;
|
|
37
|
-
_proto.render = function render() {
|
|
38
|
-
return /*#__PURE__*/React.createElement(this.props.component, this.getProps());
|
|
39
|
-
};
|
|
40
|
-
return Grid;
|
|
41
|
-
}(Component);
|
|
24
|
+
const Grid = ({
|
|
25
|
+
className,
|
|
26
|
+
component,
|
|
27
|
+
wrap,
|
|
28
|
+
...rest
|
|
29
|
+
}) => {
|
|
30
|
+
const {
|
|
31
|
+
classes,
|
|
32
|
+
cx
|
|
33
|
+
} = useStyles();
|
|
34
|
+
const composedClassName = cx(classes.root, 'common__grid', {
|
|
35
|
+
[classes.wrap]: wrap,
|
|
36
|
+
[classes.noWrap]: !wrap
|
|
37
|
+
}, className);
|
|
38
|
+
const props = objectWithoutProps({
|
|
39
|
+
...rest,
|
|
40
|
+
className: composedClassName
|
|
41
|
+
}, ['wrap', 'component']);
|
|
42
|
+
return /*#__PURE__*/React.createElement(component, props);
|
|
43
|
+
};
|
|
42
44
|
Grid.Item = GridItem;
|
|
43
45
|
Grid.defaultProps = {
|
|
44
46
|
className: '',
|
|
@@ -2,15 +2,23 @@ import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
|
|
|
2
2
|
import React, { Component } from 'react';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import classNames from 'classnames';
|
|
5
|
-
import { embeddedMedia } from '@shopgate/
|
|
5
|
+
import { embeddedMedia, configuration } from '@shopgate/engage/core/collections';
|
|
6
|
+
import { CONFIGURATION_COLLECTION_KEY_UNIVERSAL_LINK_HANDLER } from '@shopgate/engage/core/constants';
|
|
6
7
|
import EmbeddedMedia from "../EmbeddedMedia";
|
|
7
8
|
import parseHTML from "../../helpers/html/parseHTML";
|
|
8
9
|
import connect from "./connector";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
|
-
*
|
|
12
|
+
* Checks if a link is a universal link.
|
|
13
|
+
* @param {string} link The link to check.
|
|
14
|
+
* @returns {boolean} True if the link is a universal link, false otherwise.
|
|
12
15
|
*/
|
|
13
16
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
17
|
+
const isUniversalLink = link => link.startsWith('http://') || link.startsWith('https://');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* HtmlSanitizer component.
|
|
21
|
+
*/
|
|
14
22
|
let HtmlSanitizer = /*#__PURE__*/function (_Component) {
|
|
15
23
|
/**
|
|
16
24
|
* @param {Object} props The component props.
|
|
@@ -23,19 +31,64 @@ let HtmlSanitizer = /*#__PURE__*/function (_Component) {
|
|
|
23
31
|
* @param {Object} event The touchstart event.
|
|
24
32
|
*/
|
|
25
33
|
_this.handleClick = event => {
|
|
34
|
+
// Prevent multiple clicks on links while the first one is still being processed.
|
|
35
|
+
if (_this.state.openingLink) {
|
|
36
|
+
event.preventDefault();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
_this.setState({
|
|
40
|
+
openingLink: true
|
|
41
|
+
});
|
|
26
42
|
const linkTag = event.target.closest('a');
|
|
27
43
|
if (!linkTag) return;
|
|
28
44
|
const href = linkTag.getAttribute('href');
|
|
29
45
|
const target = linkTag.getAttribute('target') || '';
|
|
30
46
|
if (!href) return;
|
|
31
47
|
event.preventDefault();
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Runs async logic to open links to potentially resolve universal links.
|
|
51
|
+
*/
|
|
52
|
+
const openLink = async () => {
|
|
53
|
+
const universalLinkHandler = configuration.get(CONFIGURATION_COLLECTION_KEY_UNIVERSAL_LINK_HANDLER);
|
|
54
|
+
let link = href;
|
|
55
|
+
// If the universalLinkHandler is registered by an extension and the link looks like a
|
|
56
|
+
// qualified URL, we try to resolve it as a universal link.
|
|
57
|
+
if (typeof universalLinkHandler === 'function' && isUniversalLink(link)) {
|
|
58
|
+
const {
|
|
59
|
+
redirectLink = null,
|
|
60
|
+
handled = false
|
|
61
|
+
} = (await universalLinkHandler({
|
|
62
|
+
link
|
|
63
|
+
})) ?? {};
|
|
64
|
+
if (handled) {
|
|
65
|
+
_this.setState({
|
|
66
|
+
openingLink: false
|
|
67
|
+
});
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (redirectLink) {
|
|
71
|
+
link = redirectLink;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
_this.setState({
|
|
75
|
+
openingLink: false
|
|
76
|
+
});
|
|
77
|
+
if (!link) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (_this.props.settings.handleClick) {
|
|
81
|
+
_this.props.settings.handleClick(link, target);
|
|
82
|
+
} else {
|
|
83
|
+
_this.props.navigate(link, target);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
openLink();
|
|
37
87
|
};
|
|
38
88
|
_this.htmlContainer = /*#__PURE__*/React.createRef();
|
|
89
|
+
_this.state = {
|
|
90
|
+
openingLink: false
|
|
91
|
+
};
|
|
39
92
|
return _this;
|
|
40
93
|
}
|
|
41
94
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface IconProps {
|
|
2
|
+
/**
|
|
3
|
+
* Raw SVG markup string that will be injected into the <svg>.
|
|
4
|
+
*/
|
|
5
|
+
content: string;
|
|
6
|
+
/**
|
|
7
|
+
* Additional class name(s) applied to the root element.
|
|
8
|
+
*/
|
|
9
|
+
className?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Overrides the icon color (maps to CSS `fill`).
|
|
12
|
+
*/
|
|
13
|
+
color?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Controls the icon size via `font-size`.
|
|
16
|
+
* Accepts any valid CSS size value.
|
|
17
|
+
* @default 'inherit'
|
|
18
|
+
*/
|
|
19
|
+
size?: string | number;
|
|
20
|
+
/**
|
|
21
|
+
* The SVG viewBox attribute.
|
|
22
|
+
* @default '0 0 24 24'
|
|
23
|
+
*/
|
|
24
|
+
viewBox?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The Icon component.
|
|
28
|
+
*
|
|
29
|
+
* Renders an inline SVG icon using injected SVG markup.
|
|
30
|
+
*
|
|
31
|
+
* Provides basic styling via `currentColor` and supports size and color
|
|
32
|
+
* overrides through props while allowing external class-based overrides.
|
|
33
|
+
*/
|
|
34
|
+
declare const Icon: ({ content, className, color, viewBox, size, }: IconProps) => import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
export default Icon;
|
|
36
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../components/Icon/index.tsx"],"names":[],"mappings":"AAUA,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,QAAA,MAAM,IAAI,GAAI,+CAMX,SAAS,4CAgBX,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
package/components/Icon/index.js
CHANGED
|
@@ -1,33 +1,44 @@
|
|
|
1
|
-
import
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import styles from "./style";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* The Icon component.
|
|
7
|
-
* @param {Object} props The component props.
|
|
8
|
-
* @param {string} props.content The SVG content of the icon
|
|
9
|
-
* @param {string} [props.className] Additional CSS styles for this component
|
|
10
|
-
* @param {string} [props.viewBox] The viewBox attribute passed to the SVG
|
|
11
|
-
* @param {number} [props.size=24] The icon size
|
|
12
|
-
* @returns {JSX.Element}
|
|
13
|
-
*/
|
|
1
|
+
import { makeStyles } from '@shopgate/engage/styles';
|
|
14
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
__html: props.content
|
|
21
|
-
},
|
|
22
|
-
style: {
|
|
23
|
-
fontSize: props.size,
|
|
24
|
-
fill: props.color
|
|
3
|
+
const useStyles = makeStyles()({
|
|
4
|
+
root: {
|
|
5
|
+
fill: 'currentColor',
|
|
6
|
+
width: '1em',
|
|
7
|
+
height: '1em'
|
|
25
8
|
}
|
|
26
9
|
});
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
10
|
+
/**
|
|
11
|
+
* The Icon component.
|
|
12
|
+
*
|
|
13
|
+
* Renders an inline SVG icon using injected SVG markup.
|
|
14
|
+
*
|
|
15
|
+
* Provides basic styling via `currentColor` and supports size and color
|
|
16
|
+
* overrides through props while allowing external class-based overrides.
|
|
17
|
+
*/
|
|
18
|
+
const Icon = ({
|
|
19
|
+
content,
|
|
20
|
+
className,
|
|
21
|
+
color,
|
|
22
|
+
viewBox = '0 0 24 24',
|
|
23
|
+
size = 'inherit'
|
|
24
|
+
}) => {
|
|
25
|
+
const {
|
|
26
|
+
cx,
|
|
27
|
+
classes
|
|
28
|
+
} = useStyles();
|
|
29
|
+
return /*#__PURE__*/_jsx("svg", {
|
|
30
|
+
className: cx(classes.root, 'common__icon', className),
|
|
31
|
+
viewBox: viewBox,
|
|
32
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
33
|
+
// eslint-disable-next-line react/no-danger
|
|
34
|
+
,
|
|
35
|
+
dangerouslySetInnerHTML: {
|
|
36
|
+
__html: content
|
|
37
|
+
},
|
|
38
|
+
style: {
|
|
39
|
+
fontSize: size,
|
|
40
|
+
fill: color
|
|
41
|
+
}
|
|
42
|
+
});
|
|
32
43
|
};
|
|
33
44
|
export default Icon;
|
|
@@ -1,15 +1,30 @@
|
|
|
1
1
|
import React, { useMemo, useState, useEffect, useRef, useCallback, memo } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import classNames from 'classnames';
|
|
4
3
|
import noop from 'lodash/noop';
|
|
5
4
|
import { themeConfig } from '@shopgate/engage';
|
|
5
|
+
import { makeStyles } from '@shopgate/engage/styles';
|
|
6
6
|
import { getFullImageSource } from '@shopgate/engage/core/helpers';
|
|
7
|
-
import styles from "./style";
|
|
8
7
|
import ImageInner from "./ImageInner";
|
|
9
8
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
9
|
const {
|
|
11
10
|
colors: themeColors
|
|
12
11
|
} = themeConfig;
|
|
12
|
+
const useStyles = makeStyles()((_theme, {
|
|
13
|
+
background,
|
|
14
|
+
paddingTop
|
|
15
|
+
}) => ({
|
|
16
|
+
container: {
|
|
17
|
+
background,
|
|
18
|
+
position: 'relative',
|
|
19
|
+
zIndex: 0,
|
|
20
|
+
':before': {
|
|
21
|
+
display: 'block',
|
|
22
|
+
content: '""',
|
|
23
|
+
width: '100%',
|
|
24
|
+
paddingTop
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}));
|
|
13
28
|
|
|
14
29
|
/**
|
|
15
30
|
* Calculates the Greatest Common Divisor (GCD) of two numbers using the Euclidean algorithm.
|
|
@@ -133,12 +148,19 @@ const Image = ({
|
|
|
133
148
|
paddingHackRatio: `${(height / width * 100).toFixed(3)}%`
|
|
134
149
|
};
|
|
135
150
|
}, [ratio, resolutions]);
|
|
151
|
+
const {
|
|
152
|
+
classes,
|
|
153
|
+
cx
|
|
154
|
+
} = useStyles({
|
|
155
|
+
background: backgroundColor,
|
|
156
|
+
paddingTop: paddingHackRatio
|
|
157
|
+
});
|
|
136
158
|
if (unwrapped) {
|
|
137
159
|
if (!(src && !parentRendersPlaceholder)) return null;
|
|
138
160
|
return /*#__PURE__*/_jsx(ImageInner, {
|
|
139
161
|
ref: imgRef,
|
|
140
162
|
src: sources.main,
|
|
141
|
-
className:
|
|
163
|
+
className: cx(classNameImg),
|
|
142
164
|
style: {
|
|
143
165
|
aspectRatio,
|
|
144
166
|
...(isInView && sources.preview && {
|
|
@@ -154,13 +176,12 @@ const Image = ({
|
|
|
154
176
|
onError: handleOnError
|
|
155
177
|
});
|
|
156
178
|
}
|
|
157
|
-
const containerStyle = styles.container(backgroundColor, paddingHackRatio);
|
|
158
179
|
return /*#__PURE__*/_jsx("div", {
|
|
159
|
-
className:
|
|
180
|
+
className: cx(classes.container, className, 'common__image__container'),
|
|
160
181
|
children: src && !parentRendersPlaceholder && /*#__PURE__*/_jsx(ImageInner, {
|
|
161
182
|
ref: imgRef,
|
|
162
183
|
src: sources.main,
|
|
163
|
-
className:
|
|
184
|
+
className: cx(classNameImg),
|
|
164
185
|
style: {
|
|
165
186
|
aspectRatio,
|
|
166
187
|
...(isInView && sources.preview && {
|
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import classNames from 'classnames';
|
|
4
3
|
import noop from 'lodash/noop';
|
|
5
|
-
import
|
|
4
|
+
import { makeStyles } from '@shopgate/engage/styles';
|
|
5
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
+
const useStyles = makeStyles()({
|
|
7
|
+
image: {
|
|
8
|
+
position: 'absolute',
|
|
9
|
+
top: 0,
|
|
10
|
+
left: 0,
|
|
11
|
+
width: '100%',
|
|
12
|
+
maxHeight: '100%',
|
|
13
|
+
WebkitTouchCallout: 'none',
|
|
14
|
+
fontSize: 0
|
|
15
|
+
}
|
|
16
|
+
});
|
|
6
17
|
|
|
7
18
|
/**
|
|
8
19
|
* The ImageInner component renders tha actual image of the Image component.
|
|
@@ -10,7 +21,6 @@ import styles from "./style";
|
|
|
10
21
|
* @param {Function} ref The component reference
|
|
11
22
|
* @returns {JSX.Element}
|
|
12
23
|
*/
|
|
13
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
24
|
const ImageInner = /*#__PURE__*/forwardRef(({
|
|
15
25
|
src,
|
|
16
26
|
className,
|
|
@@ -19,28 +29,25 @@ const ImageInner = /*#__PURE__*/forwardRef(({
|
|
|
19
29
|
onLoad,
|
|
20
30
|
onError,
|
|
21
31
|
style
|
|
22
|
-
}, ref) =>
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
src: PropTypes.string,
|
|
42
|
-
style: PropTypes.shape()
|
|
43
|
-
};
|
|
32
|
+
}, ref) => {
|
|
33
|
+
const {
|
|
34
|
+
classes,
|
|
35
|
+
cx
|
|
36
|
+
} = useStyles();
|
|
37
|
+
return /*#__PURE__*/_jsx("img", {
|
|
38
|
+
ref: ref,
|
|
39
|
+
loading: lazy ? 'lazy' : 'eager',
|
|
40
|
+
src: src,
|
|
41
|
+
className: cx(classes.image, 'common__image', className),
|
|
42
|
+
alt: alt,
|
|
43
|
+
"aria-label": alt,
|
|
44
|
+
"aria-hidden": !alt,
|
|
45
|
+
"data-test-id": "image",
|
|
46
|
+
onLoad: onLoad,
|
|
47
|
+
onError: onError,
|
|
48
|
+
style: style
|
|
49
|
+
});
|
|
50
|
+
});
|
|
44
51
|
ImageInner.defaultProps = {
|
|
45
52
|
src: null,
|
|
46
53
|
alt: null,
|
|
@@ -405,7 +405,7 @@ let InfiniteContainer = /*#__PURE__*/function (_Component) {
|
|
|
405
405
|
const {
|
|
406
406
|
wrapper,
|
|
407
407
|
items,
|
|
408
|
-
iterator,
|
|
408
|
+
iterator: Iterator,
|
|
409
409
|
loadingIndicator,
|
|
410
410
|
columns
|
|
411
411
|
} = this.props;
|
|
@@ -414,13 +414,11 @@ let InfiniteContainer = /*#__PURE__*/function (_Component) {
|
|
|
414
414
|
} = this.state;
|
|
415
415
|
const [start, length] = this.state.offset;
|
|
416
416
|
// Only show items in offset range. uses iterator component as item factory
|
|
417
|
-
const children = items.slice(0, start + length).map(item =>
|
|
417
|
+
const children = items.slice(0, start + length).map((item, index) => /*#__PURE__*/_jsx(Iterator, {
|
|
418
418
|
...item,
|
|
419
|
-
columns
|
|
420
|
-
}));
|
|
421
|
-
const content =
|
|
422
|
-
children
|
|
423
|
-
}) : (/*#__PURE__*/React.createElement(wrapper, {}, children));
|
|
419
|
+
columns: columns
|
|
420
|
+
}, item.id ?? index));
|
|
421
|
+
const content = /*#__PURE__*/React.createElement(wrapper, {}, children);
|
|
424
422
|
return /*#__PURE__*/_jsxs("div", {
|
|
425
423
|
className: "common__infinite-container",
|
|
426
424
|
children: [/*#__PURE__*/_jsx("div", {
|
|
@@ -12,7 +12,7 @@ describe('<InfiniteContainer />', () => {
|
|
|
12
12
|
let renderedElement;
|
|
13
13
|
let renderedInstance;
|
|
14
14
|
let mockLoader;
|
|
15
|
-
let
|
|
15
|
+
let MockIterator;
|
|
16
16
|
let mockItems;
|
|
17
17
|
const mockData = range(100).map(id => ({
|
|
18
18
|
id,
|
|
@@ -47,16 +47,16 @@ describe('<InfiniteContainer />', () => {
|
|
|
47
47
|
};
|
|
48
48
|
beforeEach(() => {
|
|
49
49
|
mockLoader = jest.fn();
|
|
50
|
-
|
|
50
|
+
MockIterator = data => /*#__PURE__*/_jsx("li", {
|
|
51
51
|
children: data.title
|
|
52
|
-
}, data.id)
|
|
52
|
+
}, data.id);
|
|
53
53
|
});
|
|
54
54
|
describe('Given the component was mounted to the DOM', () => {
|
|
55
55
|
beforeEach(() => {
|
|
56
56
|
renderComponent({
|
|
57
57
|
items: [],
|
|
58
58
|
loader: mockLoader,
|
|
59
|
-
iterator:
|
|
59
|
+
iterator: MockIterator,
|
|
60
60
|
totalItems: null
|
|
61
61
|
});
|
|
62
62
|
renderedInstance.componentDidMount();
|
|
@@ -73,12 +73,8 @@ describe('<InfiniteContainer />', () => {
|
|
|
73
73
|
beforeEach(() => {
|
|
74
74
|
receiveItemsByProp(mockItemsLength);
|
|
75
75
|
});
|
|
76
|
-
it('should call the iterator function according to the number of loaded items', () => {
|
|
77
|
-
expect(mockIterator).toBeCalled();
|
|
78
|
-
expect(mockIterator.mock.calls.length).toBe(mockItemsLength);
|
|
79
|
-
});
|
|
80
76
|
it('should render the loaded items', () => {
|
|
81
|
-
expect(renderedElement.find(
|
|
77
|
+
expect(renderedElement.find(MockIterator)).toHaveLength(mockItemsLength);
|
|
82
78
|
});
|
|
83
79
|
});
|
|
84
80
|
describe('Given the component was mounted within a scroll container', () => {
|
|
@@ -121,7 +117,7 @@ describe('<InfiniteContainer />', () => {
|
|
|
121
117
|
it('should keep state.awaitingItems as true if not all items are rendered', () => {
|
|
122
118
|
expect(renderedInstance.allItemsAreRendered()).toBe(false);
|
|
123
119
|
expect(renderedInstance.state.awaitingItems).toBe(true);
|
|
124
|
-
expect(renderedElement.find(
|
|
120
|
+
expect(renderedElement.find(MockIterator).length).toBeLessThan(mockItemsLength);
|
|
125
121
|
});
|
|
126
122
|
it('should set state.awaitingItems to false if all items are rendered', () => {
|
|
127
123
|
renderedElement.setState({
|
|
@@ -130,7 +126,7 @@ describe('<InfiniteContainer />', () => {
|
|
|
130
126
|
renderedInstance.handleLoading();
|
|
131
127
|
expect(renderedInstance.allItemsAreRendered()).toBe(true);
|
|
132
128
|
expect(renderedInstance.state.awaitingItems).toBe(false);
|
|
133
|
-
expect(renderedElement.find(
|
|
129
|
+
expect(renderedElement.find(MockIterator).length).toBe(mockItemsLength);
|
|
134
130
|
});
|
|
135
131
|
});
|
|
136
132
|
});
|
|
@@ -140,12 +136,12 @@ describe('<InfiniteContainer />', () => {
|
|
|
140
136
|
renderComponent({
|
|
141
137
|
items: mockData,
|
|
142
138
|
loader: mockLoader,
|
|
143
|
-
iterator:
|
|
139
|
+
iterator: MockIterator,
|
|
144
140
|
totalItems: mockData.length
|
|
145
141
|
});
|
|
146
142
|
|
|
147
143
|
// Check if the iniLimit was used
|
|
148
|
-
expect(renderedElement.find(
|
|
144
|
+
expect(renderedElement.find(MockIterator).length).toBe(renderedInstance.props.initialLimit);
|
|
149
145
|
|
|
150
146
|
// Reset the limit from props.initialLimit back to props.limit
|
|
151
147
|
renderedInstance.componentDidMount();
|
|
@@ -156,7 +152,7 @@ describe('<InfiniteContainer />', () => {
|
|
|
156
152
|
|
|
157
153
|
// Check if the correct limit was used for the second render
|
|
158
154
|
const newLimit = renderedInstance.props.initialLimit + renderedInstance.props.limit;
|
|
159
|
-
expect(renderedElement.find(
|
|
155
|
+
expect(renderedElement.find(MockIterator).length).toBe(newLimit);
|
|
160
156
|
});
|
|
161
157
|
});
|
|
162
158
|
describe('Given that the initialLimit is NOT used', () => {
|
|
@@ -164,7 +160,7 @@ describe('<InfiniteContainer />', () => {
|
|
|
164
160
|
renderComponent({
|
|
165
161
|
items: [],
|
|
166
162
|
loader: mockLoader,
|
|
167
|
-
iterator:
|
|
163
|
+
iterator: MockIterator,
|
|
168
164
|
totalItems: null
|
|
169
165
|
});
|
|
170
166
|
renderedInstance.componentDidMount();
|
|
@@ -172,7 +168,7 @@ describe('<InfiniteContainer />', () => {
|
|
|
172
168
|
|
|
173
169
|
// Check if the iniLimit wasn't used
|
|
174
170
|
expect(renderedElement).toMatchSnapshot();
|
|
175
|
-
expect(renderedElement.find(
|
|
171
|
+
expect(renderedElement.find(MockIterator).length).toBe(renderedInstance.props.limit);
|
|
176
172
|
});
|
|
177
173
|
});
|
|
178
174
|
});
|
|
@@ -181,7 +177,7 @@ describe('<InfiniteContainer />', () => {
|
|
|
181
177
|
const props = {
|
|
182
178
|
items: mockData,
|
|
183
179
|
loader: mockLoader,
|
|
184
|
-
iterator:
|
|
180
|
+
iterator: MockIterator,
|
|
185
181
|
totalItems: mockData.length,
|
|
186
182
|
requestHash: 'default'
|
|
187
183
|
};
|