@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.
Files changed (112) hide show
  1. package/App.js +0 -2
  2. package/actions/app/handleLink.js +1 -0
  3. package/collections/AuthRoutes.js +1 -0
  4. package/collections/PersistedReducers.js +1 -0
  5. package/collections/media-providers/Vimeo.js +1 -1
  6. package/collections/media-providers/style.js +1 -1
  7. package/components/Backdrop/index.js +18 -3
  8. package/components/Button/index.js +40 -52
  9. package/components/Checkbox/index.js +1 -1
  10. package/components/Drawer/index.js +118 -132
  11. package/components/Drawer/spec.js +4 -2
  12. package/components/Dropdown/index.js +52 -68
  13. package/components/Grid/components/Item/index.js +37 -40
  14. package/components/Grid/index.js +36 -34
  15. package/components/HtmlSanitizer/index.js +60 -7
  16. package/components/I18n/components/FormatNumber/spec.js +1 -0
  17. package/components/Icon/index.d.ts +36 -0
  18. package/components/Icon/index.d.ts.map +1 -0
  19. package/components/Icon/index.js +39 -28
  20. package/components/Image/Image.js +27 -6
  21. package/components/Image/ImageInner.js +32 -25
  22. package/components/InfiniteContainer/index.js +5 -7
  23. package/components/InfiniteContainer/spec.js +13 -17
  24. package/components/Link/index.js +75 -84
  25. package/components/List/components/Item/index.js +19 -10
  26. package/components/List/spec.js +1 -3
  27. package/components/Loading/index.d.ts +6 -0
  28. package/components/Loading/index.d.ts.map +1 -0
  29. package/components/Modal/index.js +41 -7
  30. package/components/Picker/index.js +18 -194
  31. package/components/Portal/index.d.ts +50 -0
  32. package/components/Portal/index.d.ts.map +1 -0
  33. package/components/ProductCharacteristics/index.js +14 -276
  34. package/components/RangeSlider/index.js +15 -258
  35. package/components/Select/components/Item/index.js +18 -7
  36. package/components/Select/index.js +108 -144
  37. package/components/Select/spec.js +49 -16
  38. package/components/SelectBox/components/Item/index.js +49 -51
  39. package/components/SelectBox/index.js +140 -160
  40. package/components/SurroundPortals/index.d.ts +24 -0
  41. package/components/SurroundPortals/index.d.ts.map +1 -0
  42. package/components/SurroundPortals/index.js +3 -13
  43. package/components/Swiper/components/SwiperItem/index.js +13 -4
  44. package/components/Swiper/components/SwiperItem/spec.js +3 -2
  45. package/components/Swiper/index.js +80 -12
  46. package/components/Widgets/components/Widget/index.js +54 -56
  47. package/components/Widgets/components/Widget/spec.js +12 -8
  48. package/components/Widgets/components/WidgetGrid/index.js +39 -53
  49. package/components/Widgets/components/WidgetGrid/spec.js +12 -8
  50. package/constants/Configuration.js +2 -1
  51. package/constants/Portals.d.ts +101 -0
  52. package/constants/Portals.d.ts.map +1 -0
  53. package/helpers/config/index.d.ts +94 -0
  54. package/helpers/config/index.d.ts.map +1 -0
  55. package/helpers/config/mock.d.ts +23 -0
  56. package/helpers/config/mock.d.ts.map +1 -0
  57. package/helpers/config/theme.d.ts +7 -0
  58. package/helpers/config/theme.d.ts.map +1 -0
  59. package/helpers/data/index.d.ts +35 -0
  60. package/helpers/data/index.d.ts.map +1 -0
  61. package/helpers/data/index.js +1 -0
  62. package/helpers/html/handleDOM.js +1 -0
  63. package/helpers/portals/portalCollection.d.ts +30 -0
  64. package/helpers/portals/portalCollection.d.ts.map +1 -0
  65. package/helpers/style/index.js +1 -0
  66. package/helpers/validation/index.d.ts +10 -0
  67. package/helpers/validation/index.d.ts.map +1 -0
  68. package/package.json +4 -3
  69. package/selectors/client.js +1 -0
  70. package/styles/reset/form.js +46 -51
  71. package/styles/reset/media.js +21 -19
  72. package/styles/reset/root.js +28 -26
  73. package/styles/reset/table.js +9 -7
  74. package/styles/reset/typography.js +24 -22
  75. package/subscriptions/error.js +1 -0
  76. package/subscriptions/helpers/handleLinks.js +1 -0
  77. package/subscriptions/router.js +1 -0
  78. package/tsconfig.build.json +16 -0
  79. package/tsconfig.json +3 -0
  80. package/components/Backdrop/style.js +0 -11
  81. package/components/Button/style.js +0 -6
  82. package/components/Drawer/style.js +0 -37
  83. package/components/Dropdown/style.js +0 -4
  84. package/components/Grid/components/Item/style.js +0 -23
  85. package/components/Grid/style.js +0 -14
  86. package/components/Icon/style.js +0 -6
  87. package/components/Image/style.js +0 -32
  88. package/components/Link/style.js +0 -10
  89. package/components/List/components/Item/style.js +0 -16
  90. package/components/Modal/style.js +0 -36
  91. package/components/Picker/components/Button/index.js +0 -42
  92. package/components/Picker/components/Button/style.js +0 -19
  93. package/components/Picker/components/List/index.js +0 -38
  94. package/components/Picker/components/List/style.js +0 -17
  95. package/components/Picker/components/Modal/index.js +0 -76
  96. package/components/Picker/components/Modal/style.js +0 -78
  97. package/components/Picker/spec.js +0 -88
  98. package/components/ProductCharacteristics/connector.js +0 -41
  99. package/components/ProductCharacteristics/context.js +0 -2
  100. package/components/ProductCharacteristics/helpers/index.js +0 -162
  101. package/components/RangeSlider/components/Handle/index.js +0 -34
  102. package/components/RangeSlider/components/Handle/style.js +0 -14
  103. package/components/RangeSlider/helper.js +0 -85
  104. package/components/RangeSlider/style.js +0 -14
  105. package/components/Select/components/Item/style.js +0 -4
  106. package/components/Select/style.js +0 -17
  107. package/components/SelectBox/components/Item/style.js +0 -7
  108. package/components/SelectBox/style.js +0 -18
  109. package/components/Swiper/components/SwiperItem/styles.js +0 -5
  110. package/components/Swiper/styles.js +0 -76
  111. package/components/Widgets/components/Widget/style.js +0 -27
  112. package/components/Widgets/components/WidgetGrid/style.js +0 -8
@@ -1,48 +1,45 @@
1
- import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
2
- import React, { Component } from 'react';
1
+ import React from 'react';
3
2
  import PropTypes from 'prop-types';
4
- import { objectWithoutProps } from "../../../../helpers/data";
5
- import styles from "./style";
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
- let GridItem = /*#__PURE__*/function (_Component) {
11
- function GridItem() {
12
- return _Component.apply(this, arguments) || this;
13
- }
14
- _inheritsLoose(GridItem, _Component);
15
- var _proto = GridItem.prototype;
16
- /**
17
- * Composes the props.
18
- * @returns {Object} The composed props.
19
- */
20
- _proto.getProps = function getProps() {
21
- let {
22
- className
23
- } = this.props;
24
- if (this.props.grow !== 0) {
25
- className += ` ${styles.grow(this.props.grow)}`;
26
- }
27
- if (this.props.shrink !== 1) {
28
- className += ` ${styles.shrink(this.props.shrink)}`;
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',
@@ -1,44 +1,46 @@
1
- import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
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
- import styles, { wrap } from "./style";
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
- let Grid = /*#__PURE__*/function (_Component) {
12
- function Grid() {
13
- return _Component.apply(this, arguments) || this;
14
- }
15
- _inheritsLoose(Grid, _Component);
16
- var _proto = Grid.prototype;
17
- /**
18
- * Composes the props.
19
- * @returns {Object} The composed props.
20
- */
21
- _proto.getProps = function getProps() {
22
- let className = `${this.props.className} ${styles} common__grid`;
23
- if (this.props.wrap) {
24
- className += ` ${wrap(this.props.wrap)}`;
25
- }
26
- const props = {
27
- ...this.props,
28
- className
29
- };
30
- return objectWithoutProps(props, ['wrap', 'component']);
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/pwa-common/collections';
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
- * HtmlSanitizer component.
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
- if (_this.props.settings.handleClick) {
33
- _this.props.settings.handleClick(href, target);
34
- } else {
35
- _this.props.navigate(href, target);
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
 
@@ -1,3 +1,4 @@
1
+ import "core-js/modules/es.array.includes.js";
1
2
  import React from 'react';
2
3
  import { mount } from 'enzyme';
3
4
  import { i18n } from '@shopgate/engage/core';
@@ -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"}
@@ -1,33 +1,44 @@
1
- import React from 'react';
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 Icon = props => /*#__PURE__*/_jsx("svg", {
16
- className: `${styles} ${props.className} common__icon`,
17
- viewBox: props.viewBox,
18
- xmlns: "http://www.w3.org/2000/svg",
19
- dangerouslySetInnerHTML: {
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
- Icon.defaultProps = {
28
- className: '',
29
- color: null,
30
- viewBox: '0 0 24 24',
31
- size: 'inherit'
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: classNames(classNameImg),
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: classNames(containerStyle, className, 'common__image__container'),
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: classNames(classNameImg),
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 styles from "./style";
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) => /*#__PURE__*/_jsx("img", {
23
- ref: ref,
24
- loading: lazy ? 'lazy' : 'eager',
25
- src: src,
26
- className: classNames(className, styles.image, 'common__image'),
27
- alt: alt,
28
- "aria-label": alt,
29
- "aria-hidden": !alt,
30
- "data-test-id": "image",
31
- onLoad: onLoad,
32
- onError: onError,
33
- style: style
34
- }));
35
- ImageInner.propTypes = {
36
- alt: PropTypes.string,
37
- className: PropTypes.string,
38
- lazy: PropTypes.bool,
39
- onError: PropTypes.func,
40
- onLoad: PropTypes.func,
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 => iterator({
417
+ const children = items.slice(0, start + length).map((item, index) => /*#__PURE__*/_jsx(Iterator, {
418
418
  ...item,
419
- columns
420
- }));
421
- const content = typeof wrapper === 'function' ? wrapper({
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 mockIterator;
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
- mockIterator = jest.fn(data => /*#__PURE__*/_jsx("li", {
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: mockIterator,
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('li').length).toBe(mockItemsLength);
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('li').length).toBeLessThan(mockItemsLength);
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('li').length).toBe(mockItemsLength);
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: mockIterator,
139
+ iterator: MockIterator,
144
140
  totalItems: mockData.length
145
141
  });
146
142
 
147
143
  // Check if the iniLimit was used
148
- expect(renderedElement.find('li').length).toBe(renderedInstance.props.initialLimit);
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('li').length).toBe(newLimit);
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: mockIterator,
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('li').length).toBe(renderedInstance.props.limit);
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: mockIterator,
180
+ iterator: MockIterator,
185
181
  totalItems: mockData.length,
186
182
  requestHash: 'default'
187
183
  };