@shopgate/pwa-common 7.30.3 → 7.30.4-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
 
@@ -67,6 +67,7 @@ const Swiper = ({
67
67
  paginationType: paginationTypeProp,
68
68
  ...swiperProps
69
69
  }) => {
70
+ const isBulletsBelow = paginationTypeProp === 'bulletsBelow';
70
71
  const useFraction = maxIndicators && maxIndicators < children.length;
71
72
  const paginationType = useFraction ? 'fraction' : 'bullets';
72
73
  const showPagination = indicators && children.length > 1;
@@ -111,7 +112,7 @@ const Swiper = ({
111
112
  ...(showPagination && {
112
113
  pagination: {
113
114
  el: undefined,
114
- type: paginationTypeProp || paginationType,
115
+ type: isBulletsBelow ? 'bullets' : paginationTypeProp || paginationType,
115
116
  bulletClass: classNames.bulletClass || 'swiper-pagination-bullet',
116
117
  bulletActiveClass: classNames.bulletActiveClass || 'swiper-pagination-bullet-active',
117
118
  dynamicBullets: true,
@@ -122,7 +123,7 @@ const Swiper = ({
122
123
  allowSlidePrev: !disabled,
123
124
  allowSlideNext: !disabled,
124
125
  onSlideChange: handleSlideChange
125
- }), [additionalModules, classNames.container, classNames.bulletClass, classNames.bulletActiveClass, swiperProps, autoPlay, interval, navigation, showPagination, paginationTypeProp, paginationType, indicators, children.length, disabled, handleSlideChange]);
126
+ }), [additionalModules, classNames.container, classNames.bulletClass, classNames.bulletActiveClass, swiperProps, autoPlay, interval, navigation, showPagination, paginationTypeProp, paginationType, indicators, children.length, disabled, handleSlideChange, isBulletsBelow]);
126
127
  useEffect(() => {
127
128
  if (!internalProps.autoplay && !swiperProps.autoplay) {
128
129
  if (swiperRef.current?.swiper?.autoplay) {
@@ -187,7 +188,9 @@ const Swiper = ({
187
188
  }
188
189
  }, [delay, loopProp, onBreakpoint]);
189
190
  return /*#__PURE__*/_jsx("div", {
190
- className: cls(container, className, 'common__swiper'),
191
+ className: cls(container, className, 'common__swiper', {
192
+ 'pagination-below': isBulletsBelow
193
+ }),
191
194
  "aria-hidden": ariaHidden,
192
195
  children: /*#__PURE__*/_jsxs(OriginalSwiper, {
193
196
  "aria-live": "off",
@@ -2,10 +2,15 @@ import { css } from 'glamor';
2
2
  import { themeColors } from '@shopgate/pwa-common/helpers/config';
3
3
  export const container = css({
4
4
  position: 'relative',
5
- maxHeight: '100%'
6
- // This needs to be 100vw to compensate a chrome 80 bug - see related ticket / pr. (PWA-2509)
7
- // commented out for now since it causes issues in the responsive layout
8
- // width: '100vw',
5
+ maxHeight: '100%',
6
+ '&.pagination-below': {
7
+ '& .swiper-pagination.swiper-pagination-bullets': {
8
+ '--swiper-pagination-bottom': 0,
9
+ position: 'relative',
10
+ height: 32,
11
+ lineHeight: '40px'
12
+ }
13
+ }
9
14
  }).toString();
10
15
  export const innerContainer = css({
11
16
  overflow: 'hidden',
@@ -33,4 +33,5 @@ export const IS_CONNECT_EXTENSION_ATTACHED = 'IS_CONNECT_EXTENSION_ATTACHED';
33
33
  * );
34
34
  */
35
35
  export const CONFIGURATION_COLLECTION_CREATE_EXTERNAL_IMAGE_URL = 'CONFIGURATION_COLLECTION_CREATE_EXTERNAL_IMAGE_URL';
36
- export const CONFIGURATION_COLLECTION_KEY_THEME_TYPOGRAPHY = 'CONFIGURATION_COLLECTION_KEY_THEME_TYPOGRAPHY';
36
+ export const CONFIGURATION_COLLECTION_KEY_THEME_TYPOGRAPHY = 'CONFIGURATION_COLLECTION_KEY_THEME_TYPOGRAPHY';
37
+ export const CONFIGURATION_COLLECTION_KEY_UNIVERSAL_LINK_HANDLER = 'universalLinkHandler';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shopgate/pwa-common",
3
- "version": "7.30.3",
3
+ "version": "7.30.4-beta.2",
4
4
  "description": "Common library for the Shopgate Connect PWA.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Shopgate <support@shopgate.com>",
@@ -17,7 +17,7 @@
17
17
  "dependencies": {
18
18
  "@redux-devtools/extension": "^3.3.0",
19
19
  "@sentry/browser": "6.0.1",
20
- "@shopgate/pwa-benchmark": "7.30.3",
20
+ "@shopgate/pwa-benchmark": "7.30.4-beta.2",
21
21
  "@virtuous/conductor": "~2.5.0",
22
22
  "@virtuous/react-conductor": "~2.5.0",
23
23
  "@virtuous/redux-persister": "1.1.0-beta.7",
@@ -40,7 +40,7 @@
40
40
  "swiper": "12.1.0"
41
41
  },
42
42
  "devDependencies": {
43
- "@shopgate/pwa-core": "7.30.3",
43
+ "@shopgate/pwa-core": "7.30.4-beta.2",
44
44
  "@types/react-portal": "^3.0.9",
45
45
  "lodash": "^4.17.23",
46
46
  "prop-types": "~15.8.1",