@shopgate/pwa-ui-shared 7.32.0-beta.8 → 7.32.0
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/DiscountBadge/index.js +1 -1
- package/FavoritesButton/FavoritesButton.d.ts +74 -0
- package/FavoritesButton/FavoritesButton.d.ts.map +1 -0
- package/FavoritesButton/FavoritesButton.js +87 -0
- package/FavoritesButton/connector.d.ts +3 -0
- package/FavoritesButton/connector.d.ts.map +1 -0
- package/FavoritesButton/index.d.ts +3 -0
- package/FavoritesButton/index.d.ts.map +1 -0
- package/FavoritesButton/index.js +1 -134
- package/Glow/index.js +4 -3
- package/NoResults/components/Icon/index.js +4 -1
- package/Price/index.js +11 -4
- package/PriceStriked/index.js +7 -1
- package/package.json +5 -5
- package/AccordionContainer/spec.js +0 -35
- package/ActionButton/spec.js +0 -66
- package/AddToCartButton/spec.js +0 -68
- package/Availability/spec.js +0 -42
- package/Button/spec.js +0 -38
- package/ButtonLink/spec.js +0 -29
- package/Chip/spec.js +0 -27
- package/ContextMenu/spec.js +0 -113
- package/Dialog/components/HtmlContentDialog/spec.js +0 -107
- package/Dialog/components/PipelineErrorDialog/spec.js +0 -105
- package/Dialog/components/TextMessageDialog/spec.js +0 -62
- package/Dialog/components/VariantSelectModal/spec.js +0 -55
- package/Dialog/spec.js +0 -84
- package/DiscountBadge/spec.js +0 -20
- package/FavoritesButton/spec.js +0 -131
- package/Form/Builder/classes/ActionListener/spec.js +0 -323
- package/Form/Builder/spec.js +0 -309
- package/Form/InfoField/spec.js +0 -12
- package/Form/Password/spec.js +0 -39
- package/Form/RadioGroup/spec.js +0 -97
- package/Form/Select/spec.js +0 -39
- package/Form/SelectContextChoices/spec.js +0 -36
- package/Form/TextField/spec.js +0 -124
- package/FormElement/spec.js +0 -68
- package/Glow/spec.js +0 -14
- package/IndicatorCircle/spec.js +0 -26
- package/PlaceholderLabel/spec.js +0 -26
- package/PlaceholderParagraph/spec.js +0 -26
- package/ProgressBar/spec.js +0 -14
- package/RadioButton/spec.js +0 -22
- package/RatingStars/spec.js +0 -94
- package/RippleButton/spec.js +0 -58
- package/Sheet/components/Header/components/SearchBar/spec.js +0 -22
- package/Sheet/components/Header/spec.js +0 -17
- package/Sheet/spec.js +0 -100
- package/TaxDisclaimer/spec.js +0 -44
- package/TextField/spec.js +0 -146
- package/ToggleIcon/spec.js +0 -39
- package/tsconfig.build.json +0 -16
- package/tsconfig.json +0 -3
package/DiscountBadge/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
7
7
|
const useStyles = makeStyles()(theme => {
|
|
8
8
|
const badgeBase = {
|
|
9
9
|
background: theme.components.discountBadge.background,
|
|
10
|
-
borderRadius:
|
|
10
|
+
borderRadius: theme.shape.borderRadius,
|
|
11
11
|
color: theme.contrastColor(theme.components.discountBadge.background),
|
|
12
12
|
padding: 5,
|
|
13
13
|
width: '100%',
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { IconButtonSize } from '@shopgate/engage/components/v2';
|
|
3
|
+
export interface FavoritesButtonOwnProps {
|
|
4
|
+
/**
|
|
5
|
+
* Whether the product is on a favorites list.
|
|
6
|
+
* @default false
|
|
7
|
+
*/
|
|
8
|
+
active?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Hides the button from assistive technology, for a surface that exposes the action elsewhere.
|
|
11
|
+
*/
|
|
12
|
+
'aria-hidden'?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Custom class name for the button.
|
|
15
|
+
*/
|
|
16
|
+
className?: string;
|
|
17
|
+
/**
|
|
18
|
+
* If `true`, the button reacts to the first click only.
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
once?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* The product the button toggles.
|
|
24
|
+
*/
|
|
25
|
+
productId?: string | null;
|
|
26
|
+
/**
|
|
27
|
+
* Milliseconds to wait before a product is removed again.
|
|
28
|
+
* @default 0
|
|
29
|
+
*/
|
|
30
|
+
removeThrottle?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Whether removing the product also removes the favorites of its variants.
|
|
33
|
+
* @default false
|
|
34
|
+
*/
|
|
35
|
+
removeWithRelatives?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* The size of the button.
|
|
38
|
+
* @default 'small'
|
|
39
|
+
*/
|
|
40
|
+
size?: IconButtonSize;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The props the connector provides. Optional, so that the defaults apply to a button that is
|
|
44
|
+
* rendered without it.
|
|
45
|
+
*/
|
|
46
|
+
interface FavoritesButtonConnectedProps {
|
|
47
|
+
addFavorites?: (productId: string) => void;
|
|
48
|
+
removeFavorites?: (productId: string, removeWithRelatives?: boolean) => void;
|
|
49
|
+
loadWishlistOnAppStartEnabled?: boolean;
|
|
50
|
+
wishlistItemQuantityEnabled?: boolean;
|
|
51
|
+
}
|
|
52
|
+
export type FavoritesButtonProps = FavoritesButtonOwnProps & FavoritesButtonConnectedProps;
|
|
53
|
+
/**
|
|
54
|
+
* The favorites button toggles whether a product is on a favorites list, and shows which of the
|
|
55
|
+
* two states it is in. It renders nothing at all in a shop without the favorites feature.
|
|
56
|
+
*/
|
|
57
|
+
declare const FavoritesButtonComponent: import("react-redux").ConnectedComponent<React.MemoExoticComponent<({ active, addFavorites, "aria-hidden": ariaHidden, className, loadWishlistOnAppStartEnabled, once, productId, removeFavorites, removeThrottle, removeWithRelatives, size, wishlistItemQuantityEnabled, }: FavoritesButtonProps) => React.JSX.Element | null>, {
|
|
58
|
+
className?: string | undefined;
|
|
59
|
+
size?: IconButtonSize | undefined;
|
|
60
|
+
active?: boolean | undefined;
|
|
61
|
+
addFavorites?: ((productId: string) => void) | undefined;
|
|
62
|
+
'aria-hidden'?: boolean | undefined;
|
|
63
|
+
loadWishlistOnAppStartEnabled?: boolean | undefined;
|
|
64
|
+
once?: boolean | undefined;
|
|
65
|
+
productId?: string | null | undefined;
|
|
66
|
+
removeFavorites?: ((productId: string, removeWithRelatives?: boolean) => void) | undefined;
|
|
67
|
+
removeThrottle?: number | undefined;
|
|
68
|
+
removeWithRelatives?: boolean | undefined;
|
|
69
|
+
wishlistItemQuantityEnabled?: boolean | undefined;
|
|
70
|
+
context?: import("react-redux/es/components/Context").ReactReduxContextInstance | undefined;
|
|
71
|
+
store?: import("redux").Store | undefined;
|
|
72
|
+
}>;
|
|
73
|
+
export default FavoritesButtonComponent;
|
|
74
|
+
//# sourceMappingURL=FavoritesButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FavoritesButton.d.ts","sourceRoot":"","sources":["../../FavoritesButton/FavoritesButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAEN,MAAM,OAAO,CAAC;AAKf,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAiGrE,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB;AAED;;;GAGG;AACH,UAAU,6BAA6B;IACrC,YAAY,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,mBAAmB,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7E,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED,MAAM,MAAM,oBAAoB,GAAG,uBAAuB,GAAG,6BAA6B,CAAC;AAE3F;;;GAGG;AACH,QAAA,MAAM,wBAAwB,gRAnI3B,oBAAoB;gBAuFT,MAAM;WAwBX,cAAc;aAhCZ,OAAO;oBAwCD,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI;oBApC1B,OAAO;oCAsCS,OAAO;WA7BhC,OAAO;gBAIF,MAAM,GAAG,IAAI;uBAwBP,CAAC,SAAS,EAAE,MAAM,EAAE,mBAAmB,CAAC,EAAE,OAAO,KAAK,IAAI;qBAnB3D,MAAM;0BAKD,OAAO;kCAgBC,OAAO;;;EASwB,CAAC;AAEhE,eAAe,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import React, { useCallback, useRef, useMemo, memo } from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import appConfig from '@shopgate/pwa-common/helpers/config';
|
|
4
|
+
import { i18n } from '@shopgate/engage/core/helpers';
|
|
5
|
+
import { IconButton } from '@shopgate/engage/components/v2';
|
|
6
|
+
import HeartIcon from "../icons/HeartIcon";
|
|
7
|
+
import HeartOutlineIcon from "../icons/HeartOutlineIcon";
|
|
8
|
+
import HeartPlusOutlineIcon from "../icons/HeartPlusOutlineIcon";
|
|
9
|
+
import HeartPlus from "../icons/HeartPlusIcon";
|
|
10
|
+
import connect from "./connector";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Renders the button. Exported through `FavoritesButtonComponent`, which carries the public docs.
|
|
14
|
+
*/
|
|
15
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
16
|
+
const FavoritesButton = ({
|
|
17
|
+
active = false,
|
|
18
|
+
addFavorites,
|
|
19
|
+
'aria-hidden': ariaHidden,
|
|
20
|
+
className = '',
|
|
21
|
+
loadWishlistOnAppStartEnabled = true,
|
|
22
|
+
once = false,
|
|
23
|
+
productId = null,
|
|
24
|
+
removeFavorites,
|
|
25
|
+
removeThrottle = 0,
|
|
26
|
+
removeWithRelatives = false,
|
|
27
|
+
size = 'small',
|
|
28
|
+
wishlistItemQuantityEnabled = false
|
|
29
|
+
}) => {
|
|
30
|
+
const clickedOnceRef = useRef(false);
|
|
31
|
+
const handleClick = useCallback(event => {
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
event.stopPropagation();
|
|
34
|
+
if (once && clickedOnceRef.current) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
clickedOnceRef.current = true;
|
|
38
|
+
if (!productId) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (!active || wishlistItemQuantityEnabled) {
|
|
42
|
+
addFavorites?.(productId);
|
|
43
|
+
} else {
|
|
44
|
+
setTimeout(() => {
|
|
45
|
+
removeFavorites?.(productId, removeWithRelatives);
|
|
46
|
+
}, removeThrottle);
|
|
47
|
+
}
|
|
48
|
+
}, [once, productId, active, wishlistItemQuantityEnabled, addFavorites, removeFavorites, removeWithRelatives, removeThrottle]);
|
|
49
|
+
const icon = useMemo(() => {
|
|
50
|
+
if (!loadWishlistOnAppStartEnabled || wishlistItemQuantityEnabled && !active) {
|
|
51
|
+
return /*#__PURE__*/_jsx(HeartPlusOutlineIcon, {});
|
|
52
|
+
}
|
|
53
|
+
if (wishlistItemQuantityEnabled && active) {
|
|
54
|
+
return /*#__PURE__*/_jsx(HeartPlus, {});
|
|
55
|
+
}
|
|
56
|
+
if (active) {
|
|
57
|
+
return /*#__PURE__*/_jsx(HeartIcon, {});
|
|
58
|
+
}
|
|
59
|
+
return /*#__PURE__*/_jsx(HeartOutlineIcon, {});
|
|
60
|
+
}, [loadWishlistOnAppStartEnabled, wishlistItemQuantityEnabled, active]);
|
|
61
|
+
if (!appConfig.hasFavorites) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
return /*#__PURE__*/_jsx(IconButton, {
|
|
65
|
+
"aria-label": i18n.text(active ? 'favorites.remove' : 'favorites.add'),
|
|
66
|
+
"aria-hidden": ariaHidden,
|
|
67
|
+
variant: "surface",
|
|
68
|
+
color: "secondary",
|
|
69
|
+
size: size,
|
|
70
|
+
className: classNames('ui-shared__favorites-button', className),
|
|
71
|
+
onClick: handleClick,
|
|
72
|
+
testId: "favoriteButton",
|
|
73
|
+
children: icon
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The props the connector provides. Optional, so that the defaults apply to a button that is
|
|
79
|
+
* rendered without it.
|
|
80
|
+
*/
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The favorites button toggles whether a product is on a favorites list, and shows which of the
|
|
84
|
+
* two states it is in. It renders nothing at all in a shop without the favorites feature.
|
|
85
|
+
*/
|
|
86
|
+
const FavoritesButtonComponent = connect(/*#__PURE__*/memo(FavoritesButton));
|
|
87
|
+
export default FavoritesButtonComponent;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../FavoritesButton/connector.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../FavoritesButton/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,YAAY,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/FavoritesButton/index.js
CHANGED
|
@@ -1,134 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
|
-
import appConfig from '@shopgate/pwa-common/helpers/config';
|
|
4
|
-
import { i18n } from '@shopgate/engage/core/helpers';
|
|
5
|
-
import { makeStyles } from '@shopgate/engage/styles';
|
|
6
|
-
import HeartIcon from "../icons/HeartIcon";
|
|
7
|
-
import HeartOutlineIcon from "../icons/HeartOutlineIcon";
|
|
8
|
-
import HeartPlusOutlineIcon from "../icons/HeartPlusOutlineIcon";
|
|
9
|
-
import HeartPlus from "../icons/HeartPlusIcon";
|
|
10
|
-
import Ripple from "../Ripple";
|
|
11
|
-
import connect from "./connector";
|
|
12
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
-
const useStyles = makeStyles()(theme => {
|
|
14
|
-
const buttonProto = {
|
|
15
|
-
display: 'flex',
|
|
16
|
-
alignItems: 'center',
|
|
17
|
-
justifyContent: 'center',
|
|
18
|
-
position: 'relative',
|
|
19
|
-
background: theme.palette.common.white,
|
|
20
|
-
borderRadius: '50%',
|
|
21
|
-
padding: 0,
|
|
22
|
-
fontSize: theme.components.icon.small,
|
|
23
|
-
color: theme.palette.secondary.main,
|
|
24
|
-
outline: 0
|
|
25
|
-
};
|
|
26
|
-
return {
|
|
27
|
-
buttonFlat: {
|
|
28
|
-
...buttonProto
|
|
29
|
-
},
|
|
30
|
-
button: {
|
|
31
|
-
...buttonProto,
|
|
32
|
-
boxShadow: '0 8px 13px rgba(0, 0, 0, 0.25)'
|
|
33
|
-
},
|
|
34
|
-
ripple: {
|
|
35
|
-
padding: 6
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* The favorites button component.
|
|
42
|
-
* @param {Object} props Props.
|
|
43
|
-
* @returns {JSX.Element|null}
|
|
44
|
-
*/
|
|
45
|
-
const FavoritesButton = ({
|
|
46
|
-
active,
|
|
47
|
-
addFavorites,
|
|
48
|
-
'aria-hidden': ariaHidden,
|
|
49
|
-
className,
|
|
50
|
-
loadWishlistOnAppStartEnabled,
|
|
51
|
-
noShadow,
|
|
52
|
-
once,
|
|
53
|
-
onRippleComplete,
|
|
54
|
-
productId,
|
|
55
|
-
removeFavorites,
|
|
56
|
-
removeThrottle,
|
|
57
|
-
removeWithRelatives,
|
|
58
|
-
rippleClassName,
|
|
59
|
-
wishlistItemQuantityEnabled
|
|
60
|
-
}) => {
|
|
61
|
-
const {
|
|
62
|
-
classes,
|
|
63
|
-
cx
|
|
64
|
-
} = useStyles();
|
|
65
|
-
const clickedOnceRef = useRef(false);
|
|
66
|
-
const handleRippleComplete = useCallback(() => {
|
|
67
|
-
onRippleComplete(active);
|
|
68
|
-
}, [onRippleComplete, active]);
|
|
69
|
-
const handleClick = useCallback(event => {
|
|
70
|
-
event.preventDefault();
|
|
71
|
-
event.stopPropagation();
|
|
72
|
-
if (once && clickedOnceRef.current) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
clickedOnceRef.current = true;
|
|
76
|
-
if (!productId) {
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
if (!active || wishlistItemQuantityEnabled) {
|
|
80
|
-
addFavorites(productId);
|
|
81
|
-
} else {
|
|
82
|
-
setTimeout(() => {
|
|
83
|
-
removeFavorites(productId, removeWithRelatives);
|
|
84
|
-
}, removeThrottle);
|
|
85
|
-
}
|
|
86
|
-
}, [once, productId, active, wishlistItemQuantityEnabled, addFavorites, removeFavorites, removeWithRelatives, removeThrottle]);
|
|
87
|
-
const icon = useMemo(() => {
|
|
88
|
-
if (!loadWishlistOnAppStartEnabled || wishlistItemQuantityEnabled && !active) {
|
|
89
|
-
return /*#__PURE__*/_jsx(HeartPlusOutlineIcon, {});
|
|
90
|
-
}
|
|
91
|
-
if (wishlistItemQuantityEnabled && active) {
|
|
92
|
-
return /*#__PURE__*/_jsx(HeartPlus, {});
|
|
93
|
-
}
|
|
94
|
-
if (active) {
|
|
95
|
-
return /*#__PURE__*/_jsx(HeartIcon, {});
|
|
96
|
-
}
|
|
97
|
-
return /*#__PURE__*/_jsx(HeartOutlineIcon, {});
|
|
98
|
-
}, [loadWishlistOnAppStartEnabled, wishlistItemQuantityEnabled, active]);
|
|
99
|
-
if (!appConfig.hasFavorites) {
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
|
-
const buttonClass = noShadow ? classes.buttonFlat : classes.button;
|
|
103
|
-
const ariaLabel = i18n.text(active ? 'favorites.remove' : 'favorites.add');
|
|
104
|
-
return /*#__PURE__*/_jsx("button", {
|
|
105
|
-
"aria-label": ariaLabel,
|
|
106
|
-
"aria-hidden": ariaHidden,
|
|
107
|
-
className: cx('ui-shared__favorites-button', buttonClass, className),
|
|
108
|
-
onClick: handleClick,
|
|
109
|
-
"data-test-id": "favoriteButton",
|
|
110
|
-
type: "button",
|
|
111
|
-
children: /*#__PURE__*/_jsx(Ripple, {
|
|
112
|
-
className: cx(classes.ripple, rippleClassName),
|
|
113
|
-
onComplete: handleRippleComplete,
|
|
114
|
-
children: icon
|
|
115
|
-
})
|
|
116
|
-
});
|
|
117
|
-
};
|
|
118
|
-
FavoritesButton.defaultProps = {
|
|
119
|
-
active: false,
|
|
120
|
-
addFavorites: () => {},
|
|
121
|
-
'aria-hidden': null,
|
|
122
|
-
className: '',
|
|
123
|
-
noShadow: false,
|
|
124
|
-
once: false,
|
|
125
|
-
onRippleComplete: () => {},
|
|
126
|
-
productId: null,
|
|
127
|
-
removeFavorites: () => {},
|
|
128
|
-
removeThrottle: 0,
|
|
129
|
-
removeWithRelatives: false,
|
|
130
|
-
rippleClassName: '',
|
|
131
|
-
wishlistItemQuantityEnabled: false,
|
|
132
|
-
loadWishlistOnAppStartEnabled: true
|
|
133
|
-
};
|
|
134
|
-
export default connect(/*#__PURE__*/memo(FavoritesButton));
|
|
1
|
+
export { default } from "./FavoritesButton";
|
package/Glow/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import { withForwardedRef } from '@shopgate/engage/core';
|
|
4
|
-
import { makeStyles } from '@shopgate/engage/styles';
|
|
4
|
+
import { makeStyles, useTheme } from '@shopgate/engage/styles';
|
|
5
5
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
6
6
|
const useStyles = makeStyles()({
|
|
7
7
|
container: {
|
|
@@ -41,6 +41,7 @@ const Glow = ({
|
|
|
41
41
|
classes,
|
|
42
42
|
cx
|
|
43
43
|
} = useStyles();
|
|
44
|
+
const theme = useTheme();
|
|
44
45
|
const [hover, setHover] = useState(false);
|
|
45
46
|
const timeoutRef = useRef(null);
|
|
46
47
|
useEffect(() => () => {
|
|
@@ -58,7 +59,7 @@ const Glow = ({
|
|
|
58
59
|
const innerInlineStyles = hover ? {
|
|
59
60
|
...propStyles.glow,
|
|
60
61
|
...propStyles.hover,
|
|
61
|
-
background: color
|
|
62
|
+
background: color || theme?.palette?.action?.pressed
|
|
62
63
|
} : {
|
|
63
64
|
...propStyles.glow
|
|
64
65
|
};
|
|
@@ -80,7 +81,7 @@ const Glow = ({
|
|
|
80
81
|
jsx-a11y/click-events-have-key-events */
|
|
81
82
|
};
|
|
82
83
|
Glow.defaultProps = {
|
|
83
|
-
color:
|
|
84
|
+
color: null,
|
|
84
85
|
className: null,
|
|
85
86
|
forwardedRef: null,
|
|
86
87
|
disabled: false,
|
|
@@ -8,7 +8,10 @@ const useStyles = makeStyles()(theme => ({
|
|
|
8
8
|
fill: 'currentColor'
|
|
9
9
|
},
|
|
10
10
|
background: {
|
|
11
|
-
fill: theme.palette.
|
|
11
|
+
fill: theme.palette.common.white,
|
|
12
|
+
...theme.applyStyles('dark', {
|
|
13
|
+
fill: theme.palette.grey[200]
|
|
14
|
+
})
|
|
12
15
|
},
|
|
13
16
|
circle: {
|
|
14
17
|
fill: 'currentColor',
|
package/Price/index.js
CHANGED
|
@@ -7,11 +7,18 @@ import { makeStyles } from '@shopgate/engage/styles';
|
|
|
7
7
|
import showTaxDisclaimer from '@shopgate/pwa-common-commerce/market/helpers/showTaxDisclaimer';
|
|
8
8
|
import { useWidgetSettings } from '@shopgate/engage/core/hooks/useWidgetSettings';
|
|
9
9
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
|
-
const useStyles = makeStyles()({
|
|
10
|
+
const useStyles = makeStyles()(theme => ({
|
|
11
11
|
container: {
|
|
12
12
|
display: 'flex',
|
|
13
13
|
position: 'relative',
|
|
14
|
-
whiteSpace: 'nowrap'
|
|
14
|
+
whiteSpace: 'nowrap',
|
|
15
|
+
color: theme.components.price.defaultColor,
|
|
16
|
+
'--font-size': theme.typography.price.fontSize,
|
|
17
|
+
'--font-family': theme.typography.price.fontFamily,
|
|
18
|
+
'--font-weight': theme.typography.price.fontWeight,
|
|
19
|
+
fontSize: 'var(--font-size)',
|
|
20
|
+
fontFamily: 'var(--font-family)',
|
|
21
|
+
fontWeight: 'var(--font-weight)'
|
|
15
22
|
},
|
|
16
23
|
disclaimer: {
|
|
17
24
|
color: 'initial',
|
|
@@ -20,9 +27,9 @@ const useStyles = makeStyles()({
|
|
|
20
27
|
top: 0
|
|
21
28
|
},
|
|
22
29
|
discounted: {
|
|
23
|
-
color:
|
|
30
|
+
color: theme.components.price.saleColor
|
|
24
31
|
}
|
|
25
|
-
});
|
|
32
|
+
}));
|
|
26
33
|
|
|
27
34
|
/**
|
|
28
35
|
* The Price component
|
package/PriceStriked/index.js
CHANGED
|
@@ -24,8 +24,14 @@ const calcAngle = element => {
|
|
|
24
24
|
};
|
|
25
25
|
const useStyles = makeStyles()(theme => ({
|
|
26
26
|
root: {
|
|
27
|
+
'--font-size': `calc(${theme.typography.price.fontSize} * 0.75)`,
|
|
28
|
+
'--font-family': theme.typography.price.fontFamily,
|
|
29
|
+
'--font-weight': theme.typography.price.fontWeight,
|
|
30
|
+
fontSize: 'var(--font-size)',
|
|
31
|
+
fontFamily: 'var(--font-family)',
|
|
32
|
+
fontWeight: 'var(--font-weight)',
|
|
27
33
|
whiteSpace: 'nowrap',
|
|
28
|
-
color: theme.
|
|
34
|
+
color: theme.components.price.strikedColor,
|
|
29
35
|
'& span': {
|
|
30
36
|
position: 'relative',
|
|
31
37
|
'&::before': {
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shopgate/pwa-ui-shared",
|
|
3
|
-
"version": "7.32.0
|
|
3
|
+
"version": "7.32.0",
|
|
4
4
|
"description": "Shopgate's shared UI components.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@shopgate/pwa-ui-ios": "7.32.0
|
|
9
|
-
"@shopgate/pwa-ui-material": "7.32.0
|
|
8
|
+
"@shopgate/pwa-ui-ios": "7.32.0",
|
|
9
|
+
"@shopgate/pwa-ui-material": "7.32.0"
|
|
10
10
|
},
|
|
11
11
|
"devDependencies": {
|
|
12
|
-
"@shopgate/pwa-common": "7.32.0
|
|
13
|
-
"@shopgate/pwa-common-commerce": "7.32.0
|
|
12
|
+
"@shopgate/pwa-common": "7.32.0",
|
|
13
|
+
"@shopgate/pwa-common-commerce": "7.32.0",
|
|
14
14
|
"classnames": "2.5.1",
|
|
15
15
|
"react": "^17.0.2"
|
|
16
16
|
},
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { shallow } from 'enzyme';
|
|
3
|
-
import AccordionContainer from "./index";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @returns {JSX}
|
|
7
|
-
*/
|
|
8
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
-
const Child = () => /*#__PURE__*/_jsx("div", {});
|
|
10
|
-
describe('<AccordionContainer />', () => {
|
|
11
|
-
it('should render children with props', () => {
|
|
12
|
-
const wrapper = shallow(/*#__PURE__*/_jsx(AccordionContainer, {
|
|
13
|
-
children: props => /*#__PURE__*/_jsx(Child, {
|
|
14
|
-
...props
|
|
15
|
-
})
|
|
16
|
-
}));
|
|
17
|
-
const props = wrapper.find('Child').props();
|
|
18
|
-
expect(wrapper).toMatchSnapshot();
|
|
19
|
-
expect(props.open).toEqual(false);
|
|
20
|
-
expect(typeof props.handleOpen).toEqual('function');
|
|
21
|
-
expect(typeof props.handleClose).toEqual('function');
|
|
22
|
-
});
|
|
23
|
-
it('should update children props when state changes', () => {
|
|
24
|
-
const wrapper = shallow(/*#__PURE__*/_jsx(AccordionContainer, {
|
|
25
|
-
children: props => /*#__PURE__*/_jsx(Child, {
|
|
26
|
-
...props
|
|
27
|
-
})
|
|
28
|
-
}));
|
|
29
|
-
wrapper.setState({
|
|
30
|
-
open: true
|
|
31
|
-
});
|
|
32
|
-
expect(wrapper).toMatchSnapshot();
|
|
33
|
-
expect(wrapper.find('Child').props().open).toEqual(true);
|
|
34
|
-
});
|
|
35
|
-
});
|
package/ActionButton/spec.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { fireEvent, render, screen } from '@testing-library/react';
|
|
3
|
-
import ActionButton from "./index";
|
|
4
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
-
describe('<ActionButton />', () => {
|
|
6
|
-
const renderComponent = (props = {}) => render(/*#__PURE__*/_jsx(ActionButton, {
|
|
7
|
-
...props,
|
|
8
|
-
children: "Action Button"
|
|
9
|
-
}));
|
|
10
|
-
describe('Given the component was mounted to the DOM', () => {
|
|
11
|
-
let renderedElement;
|
|
12
|
-
let mockOnClick;
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
jest.useFakeTimers();
|
|
15
|
-
mockOnClick = jest.fn();
|
|
16
|
-
renderedElement = renderComponent({
|
|
17
|
-
onClick: mockOnClick
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
afterEach(() => {
|
|
21
|
-
jest.clearAllTimers();
|
|
22
|
-
jest.useRealTimers();
|
|
23
|
-
});
|
|
24
|
-
it('should match snapshot', () => {
|
|
25
|
-
expect(renderedElement.container.firstChild).toMatchSnapshot();
|
|
26
|
-
});
|
|
27
|
-
it('should not show the loading indicator by default', () => {
|
|
28
|
-
const indicator = renderedElement.container.querySelector('[data-test-id="loadingIndicator"]');
|
|
29
|
-
expect(indicator).toBeNull();
|
|
30
|
-
});
|
|
31
|
-
describe('Given the loading prop is set to true', () => {
|
|
32
|
-
beforeEach(() => {
|
|
33
|
-
renderedElement.rerender(/*#__PURE__*/_jsx(ActionButton, {
|
|
34
|
-
onClick: mockOnClick,
|
|
35
|
-
loading: true,
|
|
36
|
-
children: "Action Button"
|
|
37
|
-
}));
|
|
38
|
-
});
|
|
39
|
-
it('should match snapshot', () => {
|
|
40
|
-
expect(renderedElement.container.firstChild).toMatchSnapshot();
|
|
41
|
-
});
|
|
42
|
-
it('should show the loading indicator', () => {
|
|
43
|
-
const indicator = renderedElement.container.querySelector('[data-test-id="loadingIndicator"]');
|
|
44
|
-
expect(indicator).toBeTruthy();
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
describe('Given the component gets clicked', () => {
|
|
48
|
-
let timeoutSpy;
|
|
49
|
-
beforeEach(() => {
|
|
50
|
-
timeoutSpy = jest.spyOn(global, 'setTimeout');
|
|
51
|
-
fireEvent.click(screen.getByRole('button'));
|
|
52
|
-
});
|
|
53
|
-
afterEach(() => {
|
|
54
|
-
timeoutSpy.mockRestore();
|
|
55
|
-
});
|
|
56
|
-
it('should use setTimeout for delaying the onClick handler', () => {
|
|
57
|
-
expect(timeoutSpy).toHaveBeenCalledTimes(1);
|
|
58
|
-
expect(timeoutSpy.mock.calls[0][1]).toBe(ActionButton.clickDelay);
|
|
59
|
-
});
|
|
60
|
-
it('should eventually call the onClick handler', () => {
|
|
61
|
-
jest.runOnlyPendingTimers();
|
|
62
|
-
expect(mockOnClick).toHaveBeenCalledTimes(1);
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
});
|
package/AddToCartButton/spec.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { mount } from 'enzyme';
|
|
3
|
-
import { act } from 'react-dom/test-utils';
|
|
4
|
-
import AddToCartButton from "./index";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Flushes the promise queue.
|
|
8
|
-
* @returns {Promise}
|
|
9
|
-
*/
|
|
10
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
-
const flushMicrotasks = () => Promise.resolve();
|
|
12
|
-
describe('<AddToCartButton />', () => {
|
|
13
|
-
it('should render in loading state and should not be clickable', () => {
|
|
14
|
-
const spy = jest.fn(() => Promise.resolve());
|
|
15
|
-
const wrapper = mount(/*#__PURE__*/_jsx(AddToCartButton, {
|
|
16
|
-
onClick: spy,
|
|
17
|
-
isLoading: true,
|
|
18
|
-
isOrderable: true,
|
|
19
|
-
isDisabled: false
|
|
20
|
-
}));
|
|
21
|
-
|
|
22
|
-
// Click shouldn’t fire when loading
|
|
23
|
-
wrapper.find('button').prop('onClick')();
|
|
24
|
-
expect(wrapper).toMatchSnapshot();
|
|
25
|
-
expect(spy).toHaveBeenCalledTimes(0);
|
|
26
|
-
});
|
|
27
|
-
it('should render with checkmark icon and should not be clickable the second time', async () => {
|
|
28
|
-
const spy = jest.fn(() => Promise.resolve());
|
|
29
|
-
const wrapper = mount(/*#__PURE__*/_jsx(AddToCartButton, {
|
|
30
|
-
onClick: spy,
|
|
31
|
-
isLoading: false,
|
|
32
|
-
isOrderable: true,
|
|
33
|
-
isDisabled: false
|
|
34
|
-
}));
|
|
35
|
-
|
|
36
|
-
// First click triggers async work
|
|
37
|
-
await act(async () => {
|
|
38
|
-
wrapper.find('button').prop('onClick')();
|
|
39
|
-
await flushMicrotasks();
|
|
40
|
-
});
|
|
41
|
-
wrapper.update();
|
|
42
|
-
|
|
43
|
-
// Second click should be ignored
|
|
44
|
-
await act(async () => {
|
|
45
|
-
wrapper.find('button').prop('onClick')();
|
|
46
|
-
await flushMicrotasks();
|
|
47
|
-
});
|
|
48
|
-
wrapper.update();
|
|
49
|
-
expect(wrapper).toMatchSnapshot();
|
|
50
|
-
expect(spy).toHaveBeenCalledTimes(1);
|
|
51
|
-
});
|
|
52
|
-
it('should render with cart icon and should be clickable', async () => {
|
|
53
|
-
const spy = jest.fn(() => Promise.resolve());
|
|
54
|
-
const wrapper = mount(/*#__PURE__*/_jsx(AddToCartButton, {
|
|
55
|
-
onClick: spy,
|
|
56
|
-
isLoading: false,
|
|
57
|
-
isOrderable: true,
|
|
58
|
-
isDisabled: false
|
|
59
|
-
}));
|
|
60
|
-
await act(async () => {
|
|
61
|
-
wrapper.find('button').prop('onClick')();
|
|
62
|
-
await flushMicrotasks();
|
|
63
|
-
});
|
|
64
|
-
wrapper.update();
|
|
65
|
-
expect(wrapper).toMatchSnapshot();
|
|
66
|
-
expect(spy).toHaveBeenCalledTimes(1);
|
|
67
|
-
});
|
|
68
|
-
});
|
package/Availability/spec.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { render } from '@testing-library/react';
|
|
3
|
-
import { AVAILABILITY_STATE_OK, AVAILABILITY_STATE_WARNING, AVAILABILITY_STATE_ALERT } from '@shopgate/pwa-common-commerce/product/constants';
|
|
4
|
-
import Availability from "./index";
|
|
5
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
-
describe('<Availability />', () => {
|
|
7
|
-
it('should not render when text is empty', () => {
|
|
8
|
-
const wrapper = render(/*#__PURE__*/_jsx(Availability, {
|
|
9
|
-
text: ""
|
|
10
|
-
}));
|
|
11
|
-
expect(wrapper.asFragment()).toMatchSnapshot();
|
|
12
|
-
});
|
|
13
|
-
it('should not render by default if state is "ok"', () => {
|
|
14
|
-
const wrapper = render(/*#__PURE__*/_jsx(Availability, {
|
|
15
|
-
state: AVAILABILITY_STATE_OK,
|
|
16
|
-
text: "Available"
|
|
17
|
-
}));
|
|
18
|
-
expect(wrapper.asFragment()).toMatchSnapshot();
|
|
19
|
-
});
|
|
20
|
-
it('should render if state is "ok" when "showWhenAvailable" is set', () => {
|
|
21
|
-
const wrapper = render(/*#__PURE__*/_jsx(Availability, {
|
|
22
|
-
state: AVAILABILITY_STATE_OK,
|
|
23
|
-
text: "Available",
|
|
24
|
-
showWhenAvailable: true
|
|
25
|
-
}));
|
|
26
|
-
expect(wrapper.asFragment()).toMatchSnapshot();
|
|
27
|
-
});
|
|
28
|
-
it('should render if state is "warning"', () => {
|
|
29
|
-
const wrapper = render(/*#__PURE__*/_jsx(Availability, {
|
|
30
|
-
state: AVAILABILITY_STATE_WARNING,
|
|
31
|
-
text: "Only 5 left"
|
|
32
|
-
}));
|
|
33
|
-
expect(wrapper.asFragment()).toMatchSnapshot();
|
|
34
|
-
});
|
|
35
|
-
it('should render if state is "warning"', () => {
|
|
36
|
-
const wrapper = render(/*#__PURE__*/_jsx(Availability, {
|
|
37
|
-
state: AVAILABILITY_STATE_ALERT,
|
|
38
|
-
text: "Out of stock"
|
|
39
|
-
}));
|
|
40
|
-
expect(wrapper.asFragment()).toMatchSnapshot();
|
|
41
|
-
});
|
|
42
|
-
});
|