@shopgate/pwa-ui-ios 7.30.0-alpha.6 → 7.30.0-alpha.8
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/AppBar/components/Below/index.js +24 -2
- package/AppBar/components/Center/index.js +24 -2
- package/AppBar/components/Field/index.js +38 -3
- package/AppBar/components/Field/style.js +14 -1
- package/AppBar/components/Icon/index.js +51 -3
- package/AppBar/components/Icon/style.js +15 -1
- package/AppBar/components/Left/index.js +24 -2
- package/AppBar/components/Right/index.js +24 -2
- package/AppBar/components/Title/index.js +29 -3
- package/AppBar/components/Title/style.js +15 -1
- package/AppBar/index.js +93 -3
- package/AppBar/style.js +16 -1
- package/BaseDialog/components/Buttons/index.js +30 -2
- package/BaseDialog/components/Buttons/spec.js +28 -1
- package/BaseDialog/components/Content/index.js +21 -2
- package/BaseDialog/components/Content/spec.js +17 -1
- package/BaseDialog/components/Title/index.js +29 -2
- package/BaseDialog/components/Title/spec.js +17 -1
- package/BaseDialog/index.js +37 -2
- package/BaseDialog/spec.js +39 -1
- package/BaseDialog/style.js +78 -3
- package/icons/CartIcon.js +11 -2
- package/icons/FilterIcon.js +11 -2
- package/icons/HomeIcon.js +11 -2
- package/icons/ShareIcon.js +11 -2
- package/index.js +2 -1
- package/package.json +2 -2
|
@@ -1,4 +1,26 @@
|
|
|
1
|
-
import React,{Fragment}from'react';
|
|
1
|
+
import React, { Fragment } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Portal } from '@shopgate/pwa-common/components';
|
|
4
|
+
import { APP_BAR_BELOW, APP_BAR_BELOW_BEFORE, APP_BAR_BELOW_AFTER } from '@shopgate/pwa-common/constants/Portals';
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* @param {Object} props The component props.
|
|
3
8
|
* @returns {JSX}
|
|
4
|
-
*/
|
|
9
|
+
*/
|
|
10
|
+
function Below({
|
|
11
|
+
elements
|
|
12
|
+
}) {
|
|
13
|
+
return /*#__PURE__*/React.createElement(Fragment, {
|
|
14
|
+
key: "below"
|
|
15
|
+
}, /*#__PURE__*/React.createElement(Portal, {
|
|
16
|
+
name: APP_BAR_BELOW_BEFORE
|
|
17
|
+
}), /*#__PURE__*/React.createElement(Portal, {
|
|
18
|
+
name: APP_BAR_BELOW
|
|
19
|
+
}, elements), /*#__PURE__*/React.createElement(Portal, {
|
|
20
|
+
name: APP_BAR_BELOW_AFTER
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
Below.defaultProps = {
|
|
24
|
+
elements: null
|
|
25
|
+
};
|
|
26
|
+
export default Below;
|
|
@@ -1,4 +1,26 @@
|
|
|
1
|
-
import React,{Fragment}from'react';
|
|
1
|
+
import React, { Fragment } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Portal } from '@shopgate/pwa-common/components';
|
|
4
|
+
import { APP_BAR_CENTER, APP_BAR_CENTER_BEFORE, APP_BAR_CENTER_AFTER } from '@shopgate/pwa-common/constants/Portals';
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* @param {Object} props The component props.
|
|
3
8
|
* @returns {JSX}
|
|
4
|
-
*/
|
|
9
|
+
*/
|
|
10
|
+
function Center({
|
|
11
|
+
elements
|
|
12
|
+
}) {
|
|
13
|
+
return /*#__PURE__*/React.createElement(Fragment, {
|
|
14
|
+
key: "center"
|
|
15
|
+
}, /*#__PURE__*/React.createElement(Portal, {
|
|
16
|
+
name: APP_BAR_CENTER_BEFORE
|
|
17
|
+
}), /*#__PURE__*/React.createElement(Portal, {
|
|
18
|
+
name: APP_BAR_CENTER
|
|
19
|
+
}, elements), /*#__PURE__*/React.createElement(Portal, {
|
|
20
|
+
name: APP_BAR_CENTER_AFTER
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
Center.defaultProps = {
|
|
24
|
+
elements: null
|
|
25
|
+
};
|
|
26
|
+
export default Center;
|
|
@@ -1,5 +1,40 @@
|
|
|
1
|
-
|
|
1
|
+
import React, { PureComponent } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styles from "./style";
|
|
4
|
+
|
|
5
|
+
/**
|
|
2
6
|
* The AppBarField component.
|
|
3
|
-
*/
|
|
7
|
+
*/
|
|
8
|
+
class AppBarField extends PureComponent {
|
|
9
|
+
/**
|
|
4
10
|
* @returns {JSX}
|
|
5
|
-
*/
|
|
11
|
+
*/
|
|
12
|
+
render() {
|
|
13
|
+
const {
|
|
14
|
+
fieldRef,
|
|
15
|
+
onChange,
|
|
16
|
+
onSubmit
|
|
17
|
+
} = this.props;
|
|
18
|
+
const {
|
|
19
|
+
__
|
|
20
|
+
} = this.context.i18n();
|
|
21
|
+
return /*#__PURE__*/React.createElement("form", {
|
|
22
|
+
className: styles.form,
|
|
23
|
+
onSubmit: onSubmit
|
|
24
|
+
}, /*#__PURE__*/React.createElement("input", {
|
|
25
|
+
className: styles.field,
|
|
26
|
+
onChange: onChange,
|
|
27
|
+
placeholder: __('search.placeholder'),
|
|
28
|
+
ref: fieldRef
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
AppBarField.defaultProps = {
|
|
33
|
+
fieldRef: null,
|
|
34
|
+
onChange: null,
|
|
35
|
+
onSubmit: null
|
|
36
|
+
};
|
|
37
|
+
AppBarField.contextTypes = {
|
|
38
|
+
i18n: PropTypes.func
|
|
39
|
+
};
|
|
40
|
+
export default AppBarField;
|
|
@@ -1 +1,14 @@
|
|
|
1
|
-
import{css
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
const form = css({
|
|
3
|
+
display: 'flex',
|
|
4
|
+
flexGrow: 1
|
|
5
|
+
});
|
|
6
|
+
const field = css({
|
|
7
|
+
outline: 0,
|
|
8
|
+
padding: '0 16px',
|
|
9
|
+
width: '100%'
|
|
10
|
+
});
|
|
11
|
+
export default {
|
|
12
|
+
form,
|
|
13
|
+
field
|
|
14
|
+
};
|
|
@@ -1,5 +1,53 @@
|
|
|
1
|
-
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React, { PureComponent } from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import styles from "./style";
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* The AppBarIcon component.
|
|
3
|
-
*/
|
|
8
|
+
*/
|
|
9
|
+
class AppBarIcon extends PureComponent {
|
|
10
|
+
/**
|
|
4
11
|
* @returns {JSX}
|
|
5
|
-
*/
|
|
12
|
+
*/
|
|
13
|
+
render() {
|
|
14
|
+
const {
|
|
15
|
+
background,
|
|
16
|
+
badge: Badge,
|
|
17
|
+
color,
|
|
18
|
+
icon: Icon,
|
|
19
|
+
onClick,
|
|
20
|
+
testId,
|
|
21
|
+
'aria-hidden': ariaHidden,
|
|
22
|
+
'aria-label': ariaLabel,
|
|
23
|
+
...iconProps
|
|
24
|
+
} = this.props;
|
|
25
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
26
|
+
onKeyDown: onClick,
|
|
27
|
+
tabIndex: 0,
|
|
28
|
+
role: "button",
|
|
29
|
+
"aria-hidden": ariaHidden,
|
|
30
|
+
"aria-label": ariaLabel,
|
|
31
|
+
className: styles,
|
|
32
|
+
onClick: onClick,
|
|
33
|
+
style: {
|
|
34
|
+
background,
|
|
35
|
+
color
|
|
36
|
+
},
|
|
37
|
+
"data-test-id": testId
|
|
38
|
+
}, /*#__PURE__*/React.createElement(Icon, _extends({
|
|
39
|
+
key: "icon"
|
|
40
|
+
}, iconProps)), Badge && /*#__PURE__*/React.createElement(Badge, {
|
|
41
|
+
key: "badge"
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
AppBarIcon.defaultProps = {
|
|
46
|
+
'aria-hidden': false,
|
|
47
|
+
'aria-label': null,
|
|
48
|
+
background: 'inherit',
|
|
49
|
+
badge: null,
|
|
50
|
+
color: 'inherit',
|
|
51
|
+
testId: null
|
|
52
|
+
};
|
|
53
|
+
export default AppBarIcon;
|
|
@@ -1 +1,15 @@
|
|
|
1
|
-
import{css}from'glamor';
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
export default css({
|
|
3
|
+
alignItems: 'center',
|
|
4
|
+
color: 'inherit',
|
|
5
|
+
display: 'flex',
|
|
6
|
+
flexShrink: 0,
|
|
7
|
+
fontSize: 24,
|
|
8
|
+
height: 44,
|
|
9
|
+
justifyContent: 'center',
|
|
10
|
+
outline: 0,
|
|
11
|
+
padding: 0,
|
|
12
|
+
position: 'relative',
|
|
13
|
+
width: 44,
|
|
14
|
+
zIndex: 1
|
|
15
|
+
});
|
|
@@ -1,4 +1,26 @@
|
|
|
1
|
-
import React,{Fragment}from'react';
|
|
1
|
+
import React, { Fragment } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Portal } from '@shopgate/pwa-common/components';
|
|
4
|
+
import { APP_BAR_LEFT, APP_BAR_LEFT_BEFORE, APP_BAR_LEFT_AFTER } from '@shopgate/pwa-common/constants/Portals';
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* @param {Object} props The component props.
|
|
3
8
|
* @returns {JSX}
|
|
4
|
-
*/
|
|
9
|
+
*/
|
|
10
|
+
function Left({
|
|
11
|
+
elements
|
|
12
|
+
}) {
|
|
13
|
+
return /*#__PURE__*/React.createElement(Fragment, {
|
|
14
|
+
key: "left"
|
|
15
|
+
}, /*#__PURE__*/React.createElement(Portal, {
|
|
16
|
+
name: APP_BAR_LEFT_BEFORE
|
|
17
|
+
}), /*#__PURE__*/React.createElement(Portal, {
|
|
18
|
+
name: APP_BAR_LEFT
|
|
19
|
+
}, elements), /*#__PURE__*/React.createElement(Portal, {
|
|
20
|
+
name: APP_BAR_LEFT_AFTER
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
Left.defaultProps = {
|
|
24
|
+
elements: null
|
|
25
|
+
};
|
|
26
|
+
export default Left;
|
|
@@ -1,4 +1,26 @@
|
|
|
1
|
-
import React,{Fragment}from'react';
|
|
1
|
+
import React, { Fragment } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { Portal } from '@shopgate/pwa-common/components';
|
|
4
|
+
import { APP_BAR_RIGHT, APP_BAR_RIGHT_BEFORE, APP_BAR_RIGHT_AFTER } from '@shopgate/pwa-common/constants/Portals';
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* @param {Object} props The component props.
|
|
3
8
|
* @returns {JSX}
|
|
4
|
-
*/
|
|
9
|
+
*/
|
|
10
|
+
function Right({
|
|
11
|
+
elements
|
|
12
|
+
}) {
|
|
13
|
+
return /*#__PURE__*/React.createElement(Fragment, {
|
|
14
|
+
key: "right"
|
|
15
|
+
}, /*#__PURE__*/React.createElement(Portal, {
|
|
16
|
+
name: APP_BAR_RIGHT_BEFORE
|
|
17
|
+
}), /*#__PURE__*/React.createElement(Portal, {
|
|
18
|
+
name: APP_BAR_RIGHT
|
|
19
|
+
}, elements), /*#__PURE__*/React.createElement(Portal, {
|
|
20
|
+
name: APP_BAR_RIGHT_AFTER
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
Right.defaultProps = {
|
|
24
|
+
elements: null
|
|
25
|
+
};
|
|
26
|
+
export default Right;
|
|
@@ -1,5 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
import React, { PureComponent } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import styles from "./style";
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* The AppBarTitle component.
|
|
3
|
-
*/
|
|
8
|
+
*/
|
|
9
|
+
class AppBarTitle extends PureComponent {
|
|
10
|
+
/**
|
|
4
11
|
* @returns {JSX.Element}
|
|
5
|
-
*/
|
|
12
|
+
*/
|
|
13
|
+
render() {
|
|
14
|
+
const {
|
|
15
|
+
title
|
|
16
|
+
} = this.props;
|
|
17
|
+
if (!title) return null;
|
|
18
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
19
|
+
className: classNames(styles, 'theme__app-bar__title'),
|
|
20
|
+
role: "heading",
|
|
21
|
+
"aria-level": "1",
|
|
22
|
+
"aria-live": "polite",
|
|
23
|
+
tabIndex: -1,
|
|
24
|
+
"data-test-id": `title: ${title}`,
|
|
25
|
+
dangerouslySetInnerHTML: {
|
|
26
|
+
__html: title
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export default AppBarTitle;
|
|
@@ -1 +1,15 @@
|
|
|
1
|
-
import{css}from'glamor';
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
export default css({
|
|
3
|
+
fontSize: 17,
|
|
4
|
+
fontWeight: 600,
|
|
5
|
+
flexGrow: 1,
|
|
6
|
+
lineHeight: '44px',
|
|
7
|
+
left: 90,
|
|
8
|
+
overflow: 'hidden',
|
|
9
|
+
position: 'absolute',
|
|
10
|
+
right: 90,
|
|
11
|
+
textAlign: 'center',
|
|
12
|
+
textOverflow: 'ellipsis',
|
|
13
|
+
top: 0,
|
|
14
|
+
whiteSpace: 'nowrap'
|
|
15
|
+
});
|
package/AppBar/index.js
CHANGED
|
@@ -1,8 +1,98 @@
|
|
|
1
|
-
import React,{useMemo,useRef,useLayoutEffect}
|
|
1
|
+
import React, { useMemo, useRef, useLayoutEffect } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import classnames from 'classnames';
|
|
4
|
+
import { getAbsoluteHeight } from '@shopgate/pwa-common/helpers/dom';
|
|
5
|
+
import { themeColors } from '@shopgate/pwa-common/helpers/config';
|
|
6
|
+
import { setCSSCustomProp } from '@shopgate/engage/styles';
|
|
7
|
+
import { SurroundPortals } from '@shopgate/engage/components';
|
|
8
|
+
import { APP_BAR_CONTENT } from '@shopgate/engage/core/constants';
|
|
9
|
+
import Field from "./components/Field";
|
|
10
|
+
import Icon from "./components/Icon";
|
|
11
|
+
import Title from "./components/Title";
|
|
12
|
+
import Right from "./components/Right";
|
|
13
|
+
import Center from "./components/Center";
|
|
14
|
+
import Left from "./components/Left";
|
|
15
|
+
import Below from "./components/Below";
|
|
16
|
+
import styles from "./style";
|
|
17
|
+
|
|
18
|
+
/**
|
|
2
19
|
* Updates the --app-bar-height custom property
|
|
3
20
|
* @param {Object} ref The app bar ref.
|
|
4
|
-
*/
|
|
21
|
+
*/
|
|
22
|
+
const updateAppBarHeight = ref => {
|
|
23
|
+
if (!ref.current) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
setCSSCustomProp('--app-bar-height', `${getAbsoluteHeight(ref.current)}px`);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
5
30
|
* The AppBar component.
|
|
6
31
|
* @param {Object} props The component props.
|
|
7
32
|
* @returns {JSX}
|
|
8
|
-
*/
|
|
33
|
+
*/
|
|
34
|
+
const AppBar = ({
|
|
35
|
+
below,
|
|
36
|
+
center,
|
|
37
|
+
left,
|
|
38
|
+
right,
|
|
39
|
+
classes,
|
|
40
|
+
'aria-hidden': ariaHidden,
|
|
41
|
+
backgroundColor,
|
|
42
|
+
textColor
|
|
43
|
+
}) => {
|
|
44
|
+
const contentRef = useRef(null);
|
|
45
|
+
const style = useMemo(() => ({
|
|
46
|
+
background: backgroundColor,
|
|
47
|
+
color: textColor
|
|
48
|
+
}), [backgroundColor, textColor]);
|
|
49
|
+
const observer = useMemo(() => new MutationObserver(() => {
|
|
50
|
+
updateAppBarHeight(contentRef);
|
|
51
|
+
}), [contentRef]);
|
|
52
|
+
useLayoutEffect(() => {
|
|
53
|
+
updateAppBarHeight(contentRef);
|
|
54
|
+
observer.observe(contentRef.current, {
|
|
55
|
+
childList: true
|
|
56
|
+
});
|
|
57
|
+
return () => {
|
|
58
|
+
observer.disconnect();
|
|
59
|
+
};
|
|
60
|
+
}, [contentRef, observer]);
|
|
61
|
+
const sectionClasses = classnames(styles.outer, classes.outer, 'ui-ios__app-bar');
|
|
62
|
+
return /*#__PURE__*/React.createElement("section", {
|
|
63
|
+
className: sectionClasses,
|
|
64
|
+
"data-test-id": "Navigator",
|
|
65
|
+
style: style,
|
|
66
|
+
"aria-hidden": ariaHidden,
|
|
67
|
+
ref: contentRef
|
|
68
|
+
}, /*#__PURE__*/React.createElement(SurroundPortals, {
|
|
69
|
+
portalName: APP_BAR_CONTENT
|
|
70
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
71
|
+
className: classnames(styles.inner, classes.inner)
|
|
72
|
+
}, /*#__PURE__*/React.createElement(Left, {
|
|
73
|
+
elements: left
|
|
74
|
+
}), /*#__PURE__*/React.createElement(Center, {
|
|
75
|
+
elements: center
|
|
76
|
+
}), /*#__PURE__*/React.createElement(Right, {
|
|
77
|
+
elements: right
|
|
78
|
+
}))), /*#__PURE__*/React.createElement(Below, {
|
|
79
|
+
elements: below
|
|
80
|
+
}));
|
|
81
|
+
};
|
|
82
|
+
AppBar.defaultProps = {
|
|
83
|
+
'aria-hidden': null,
|
|
84
|
+
backgroundColor: themeColors.light,
|
|
85
|
+
below: null,
|
|
86
|
+
center: null,
|
|
87
|
+
classes: {
|
|
88
|
+
inner: '',
|
|
89
|
+
outer: ''
|
|
90
|
+
},
|
|
91
|
+
left: null,
|
|
92
|
+
right: null,
|
|
93
|
+
textColor: themeColors.dark
|
|
94
|
+
};
|
|
95
|
+
AppBar.Field = Field;
|
|
96
|
+
AppBar.Icon = Icon;
|
|
97
|
+
AppBar.Title = Title;
|
|
98
|
+
export default AppBar;
|
package/AppBar/style.js
CHANGED
|
@@ -1 +1,16 @@
|
|
|
1
|
-
import{css}from'glamor';
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
const outer = css({
|
|
3
|
+
boxSizing: 'content-box',
|
|
4
|
+
minHeight: 44,
|
|
5
|
+
paddingTop: 'var(--safe-area-inset-top)'
|
|
6
|
+
}).toString();
|
|
7
|
+
const inner = css({
|
|
8
|
+
display: 'flex',
|
|
9
|
+
justifyContent: 'space-between',
|
|
10
|
+
position: 'relative',
|
|
11
|
+
zIndex: 1
|
|
12
|
+
}).toString();
|
|
13
|
+
export default {
|
|
14
|
+
outer,
|
|
15
|
+
inner
|
|
16
|
+
};
|
|
@@ -1,4 +1,32 @@
|
|
|
1
|
-
import React,{memo}
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import I18n from '@shopgate/pwa-common/components/I18n';
|
|
4
|
+
import Button from '@shopgate/pwa-ui-shared/Button';
|
|
5
|
+
import styles from "../../style";
|
|
6
|
+
|
|
7
|
+
/**
|
|
2
8
|
* @param {Object} props The component props.
|
|
3
9
|
* @returns {JSX}
|
|
4
|
-
*/
|
|
10
|
+
*/
|
|
11
|
+
const Buttons = ({
|
|
12
|
+
actions
|
|
13
|
+
}) => actions.map(({
|
|
14
|
+
label,
|
|
15
|
+
action,
|
|
16
|
+
type = 'normal',
|
|
17
|
+
disabled = false
|
|
18
|
+
}) => /*#__PURE__*/React.createElement(Button, {
|
|
19
|
+
key: label,
|
|
20
|
+
className: `${styles.button} ${type === 'primary' ? styles.buttonPrimary : ''}`,
|
|
21
|
+
type: "primary",
|
|
22
|
+
onClick: action,
|
|
23
|
+
disabled: disabled,
|
|
24
|
+
flat: true
|
|
25
|
+
}, /*#__PURE__*/React.createElement(I18n.Text, {
|
|
26
|
+
className: styles.buttonText,
|
|
27
|
+
string: label
|
|
28
|
+
})));
|
|
29
|
+
Buttons.defaultProps = {
|
|
30
|
+
actions: []
|
|
31
|
+
};
|
|
32
|
+
export default /*#__PURE__*/memo(Buttons);
|
|
@@ -1 +1,28 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { shallow } from 'enzyme';
|
|
3
|
+
import Button from '@shopgate/pwa-ui-shared/Button';
|
|
4
|
+
import Buttons from "./index";
|
|
5
|
+
const actions = [{
|
|
6
|
+
label: 'action0',
|
|
7
|
+
action: jest.fn()
|
|
8
|
+
}, {
|
|
9
|
+
label: 'action1',
|
|
10
|
+
action: jest.fn()
|
|
11
|
+
}, {
|
|
12
|
+
label: 'action2',
|
|
13
|
+
action: jest.fn()
|
|
14
|
+
}];
|
|
15
|
+
describe('<Buttons />', () => {
|
|
16
|
+
it('should not render if no actions are passed', () => {
|
|
17
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(Buttons, null));
|
|
18
|
+
expect(wrapper).toMatchSnapshot();
|
|
19
|
+
expect(wrapper.instance()).toEqual(null);
|
|
20
|
+
});
|
|
21
|
+
it('should render buttons', () => {
|
|
22
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(Buttons, {
|
|
23
|
+
actions: actions
|
|
24
|
+
}));
|
|
25
|
+
expect(wrapper).toMatchSnapshot();
|
|
26
|
+
expect(wrapper.find(Button).length).toBe(actions.length);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -1,4 +1,23 @@
|
|
|
1
|
-
import React,{memo}from'react';
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styles from "../../style";
|
|
4
|
+
|
|
5
|
+
/**
|
|
2
6
|
* @param {Object} props The component props.
|
|
3
7
|
* @returns {JSX}
|
|
4
|
-
*/
|
|
8
|
+
*/
|
|
9
|
+
const Content = ({
|
|
10
|
+
content
|
|
11
|
+
}) => {
|
|
12
|
+
if (!content) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
16
|
+
className: styles.body,
|
|
17
|
+
id: "basicDialogDesc"
|
|
18
|
+
}, content);
|
|
19
|
+
};
|
|
20
|
+
Content.defaultProps = {
|
|
21
|
+
content: null
|
|
22
|
+
};
|
|
23
|
+
export default /*#__PURE__*/memo(Content);
|
|
@@ -1 +1,17 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { shallow } from 'enzyme';
|
|
3
|
+
import Content from "./index";
|
|
4
|
+
describe('<Content />', () => {
|
|
5
|
+
it('should not render if no content is passed', () => {
|
|
6
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(Content, null));
|
|
7
|
+
expect(wrapper).toMatchSnapshot();
|
|
8
|
+
expect(wrapper.instance()).toEqual(null);
|
|
9
|
+
});
|
|
10
|
+
it('should render content components', () => {
|
|
11
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(Content, {
|
|
12
|
+
content: "Hello World"
|
|
13
|
+
}));
|
|
14
|
+
expect(wrapper).toMatchSnapshot();
|
|
15
|
+
expect(wrapper.find('[id="basicDialogDesc"]').length).toBe(1);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
@@ -1,4 +1,31 @@
|
|
|
1
|
-
import React,{memo}
|
|
1
|
+
import React, { memo } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import Ellipsis from '@shopgate/pwa-common/components/Ellipsis';
|
|
4
|
+
import I18n from '@shopgate/pwa-common/components/I18n';
|
|
5
|
+
import styles from "../../style";
|
|
6
|
+
|
|
7
|
+
/**
|
|
2
8
|
* @param {Object} props The component props.
|
|
3
9
|
* @returns {JSX}
|
|
4
|
-
*/
|
|
10
|
+
*/
|
|
11
|
+
const Title = ({
|
|
12
|
+
title
|
|
13
|
+
}) => {
|
|
14
|
+
if (!title) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
18
|
+
className: styles.title,
|
|
19
|
+
id: "basicDialogTitle",
|
|
20
|
+
role: "heading",
|
|
21
|
+
"aria-level": "2"
|
|
22
|
+
}, /*#__PURE__*/React.createElement(Ellipsis, {
|
|
23
|
+
rows: 3
|
|
24
|
+
}, typeof title === 'string' ? /*#__PURE__*/React.createElement(I18n.Text, {
|
|
25
|
+
string: title
|
|
26
|
+
}) : title));
|
|
27
|
+
};
|
|
28
|
+
Title.defaultProps = {
|
|
29
|
+
title: null
|
|
30
|
+
};
|
|
31
|
+
export default /*#__PURE__*/memo(Title);
|
|
@@ -1 +1,17 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { shallow } from 'enzyme';
|
|
3
|
+
import Title from "./index";
|
|
4
|
+
describe('<Title />', () => {
|
|
5
|
+
it('should not render without a title', () => {
|
|
6
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(Title, null));
|
|
7
|
+
expect(wrapper).toMatchSnapshot();
|
|
8
|
+
expect(wrapper.instance()).toEqual(null);
|
|
9
|
+
});
|
|
10
|
+
it('should render with a title', () => {
|
|
11
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(Title, {
|
|
12
|
+
title: "Some test title"
|
|
13
|
+
}));
|
|
14
|
+
expect(wrapper).toMatchSnapshot();
|
|
15
|
+
expect(wrapper.find('[id="basicDialogTitle"]').length).toBe(1);
|
|
16
|
+
});
|
|
17
|
+
});
|
package/BaseDialog/index.js
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { FocusTrap } from '@shopgate/engage/a11y/components';
|
|
4
|
+
import Title from "./components/Title";
|
|
5
|
+
import Content from "./components/Content";
|
|
6
|
+
import Buttons from "./components/Buttons";
|
|
7
|
+
import styles from "./style";
|
|
8
|
+
|
|
9
|
+
/**
|
|
2
10
|
* This component renders a basic dialog in Google Material Design.
|
|
3
11
|
* @param {Object} props The component props.
|
|
4
12
|
* @param {ReactNode} props.children The component children to render in the dialog.
|
|
@@ -6,4 +14,31 @@ import React from'react';import PropTypes from'prop-types';import{FocusTrap}from
|
|
|
6
14
|
* the label and the callback to invoke when the action is triggered
|
|
7
15
|
* @param {string | ReactNode} props.title The title of the dialog.
|
|
8
16
|
* @return {JSX.Element} The rendered dialog.
|
|
9
|
-
*/
|
|
17
|
+
*/
|
|
18
|
+
const BasicDialog = ({
|
|
19
|
+
children,
|
|
20
|
+
actions,
|
|
21
|
+
title
|
|
22
|
+
}) => /*#__PURE__*/React.createElement(FocusTrap, null, /*#__PURE__*/React.createElement("div", {
|
|
23
|
+
className: `${styles.container} ui-ios__base-dialog`,
|
|
24
|
+
"data-test-id": "basicDialog",
|
|
25
|
+
role: "alertdialog",
|
|
26
|
+
"aria-modal": true,
|
|
27
|
+
"aria-labelledby": "basicDialogTitle basicDialogDesc"
|
|
28
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
29
|
+
className: styles.content
|
|
30
|
+
}, /*#__PURE__*/React.createElement(Title, {
|
|
31
|
+
title: title
|
|
32
|
+
}), /*#__PURE__*/React.createElement(Content, {
|
|
33
|
+
content: children
|
|
34
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
35
|
+
className: styles.actions
|
|
36
|
+
}, /*#__PURE__*/React.createElement(Buttons, {
|
|
37
|
+
actions: actions
|
|
38
|
+
}))));
|
|
39
|
+
BasicDialog.defaultProps = {
|
|
40
|
+
children: null,
|
|
41
|
+
actions: [],
|
|
42
|
+
title: null
|
|
43
|
+
};
|
|
44
|
+
export default BasicDialog;
|
package/BaseDialog/spec.js
CHANGED
|
@@ -1 +1,39 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { shallow } from 'enzyme';
|
|
3
|
+
import Title from "./components/Title";
|
|
4
|
+
import Content from "./components/Content";
|
|
5
|
+
import Buttons from "./components/Buttons";
|
|
6
|
+
import BasicDialog from "./index";
|
|
7
|
+
const props = {
|
|
8
|
+
title: 'Hello World',
|
|
9
|
+
children: /*#__PURE__*/React.createElement("div", null, "Hello World"),
|
|
10
|
+
actions: [{
|
|
11
|
+
label: 'action0',
|
|
12
|
+
action: jest.fn()
|
|
13
|
+
}, {
|
|
14
|
+
label: 'action1',
|
|
15
|
+
action: jest.fn()
|
|
16
|
+
}, {
|
|
17
|
+
label: 'action2',
|
|
18
|
+
action: jest.fn()
|
|
19
|
+
}]
|
|
20
|
+
};
|
|
21
|
+
jest.mock('@shopgate/engage/a11y/components');
|
|
22
|
+
describe('<BasicDialog />', () => {
|
|
23
|
+
it('should render with minimal props', () => {
|
|
24
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(BasicDialog, {
|
|
25
|
+
actions: []
|
|
26
|
+
}));
|
|
27
|
+
expect(wrapper).toMatchSnapshot();
|
|
28
|
+
});
|
|
29
|
+
it('should render as expected', () => {
|
|
30
|
+
const wrapper = shallow(/*#__PURE__*/React.createElement(BasicDialog, props));
|
|
31
|
+
expect(wrapper).toMatchSnapshot();
|
|
32
|
+
expect(wrapper.find(Title).length).toBe(1);
|
|
33
|
+
expect(wrapper.find(Title).props().title).toEqual(props.title);
|
|
34
|
+
expect(wrapper.find(Content).length).toBe(1);
|
|
35
|
+
expect(wrapper.find(Content).props().content).toEqual(props.children);
|
|
36
|
+
expect(wrapper.find(Buttons).length).toBe(1);
|
|
37
|
+
expect(wrapper.find(Buttons).props().actions).toEqual(props.actions);
|
|
38
|
+
});
|
|
39
|
+
});
|
package/BaseDialog/style.js
CHANGED
|
@@ -1,5 +1,80 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
import { themeColors, themeVariables } from '@shopgate/pwa-common/helpers/config';
|
|
3
|
+
const outerGap = 40;
|
|
4
|
+
const borderColor = 'rgba(0,0,0,0.2)';
|
|
5
|
+
const container = css({
|
|
6
|
+
position: 'relative',
|
|
7
|
+
overflow: 'hidden',
|
|
8
|
+
display: 'flex',
|
|
9
|
+
flexDirection: 'column',
|
|
10
|
+
width: 270,
|
|
11
|
+
maxHeight: `calc(100vh - ${outerGap * 2}px)`,
|
|
12
|
+
borderRadius: 14,
|
|
13
|
+
background: themeColors.lightTransparent,
|
|
14
|
+
backdropFilter: 'blur(20px)'
|
|
15
|
+
}).toString();
|
|
16
|
+
const content = css({
|
|
17
|
+
padding: '16px',
|
|
18
|
+
display: 'flex',
|
|
19
|
+
flexDirection: 'column'
|
|
20
|
+
}).toString();
|
|
21
|
+
const title = css({
|
|
22
|
+
textAlign: 'center',
|
|
23
|
+
fontWeight: 600
|
|
24
|
+
}).toString();
|
|
25
|
+
const body = css({
|
|
26
|
+
color: themeColors.dark,
|
|
27
|
+
flexGrow: 1,
|
|
28
|
+
fontSize: '13px',
|
|
29
|
+
textAlign: 'center',
|
|
30
|
+
overflow: 'auto'
|
|
31
|
+
}).toString();
|
|
32
|
+
const actions = css({
|
|
33
|
+
borderTop: `0.5px solid ${borderColor}`,
|
|
34
|
+
display: 'flex',
|
|
35
|
+
flexWrap: 'wrap'
|
|
36
|
+
}).toString();
|
|
37
|
+
const button = css({
|
|
38
|
+
'&& > *': {
|
|
39
|
+
color: 'var(--color-button-dialog-ios, #1a73e8)'
|
|
40
|
+
},
|
|
41
|
+
// Increases specificity to allow button customization.
|
|
42
|
+
'&&': {
|
|
43
|
+
fontWeight: 400,
|
|
44
|
+
minWidth: '50%',
|
|
45
|
+
flexGrow: 1,
|
|
46
|
+
paddingTop: 10,
|
|
47
|
+
paddingBottom: 10
|
|
48
|
+
},
|
|
49
|
+
/*
|
|
3
50
|
* Due to overflow hidden this will cause the bottom border to be
|
|
4
51
|
* not visible in vertical button mode.
|
|
5
|
-
*/
|
|
52
|
+
*/
|
|
53
|
+
marginBottom: -1,
|
|
54
|
+
marginRight: `-${themeVariables.gap.small / 2}px`,
|
|
55
|
+
'&:not(:last-child)': {
|
|
56
|
+
borderRadius: '0 !important',
|
|
57
|
+
borderRight: `0.5px solid ${borderColor}`,
|
|
58
|
+
borderBottom: `0.5px solid ${borderColor}`
|
|
59
|
+
}
|
|
60
|
+
}).toString();
|
|
61
|
+
const buttonPrimary = css({
|
|
62
|
+
'&&': {
|
|
63
|
+
fontWeight: 400
|
|
64
|
+
}
|
|
65
|
+
}).toString();
|
|
66
|
+
const buttonText = css({
|
|
67
|
+
overflow: 'hidden',
|
|
68
|
+
textOverflow: 'ellipsis',
|
|
69
|
+
display: 'block'
|
|
70
|
+
}).toString();
|
|
71
|
+
export default {
|
|
72
|
+
container,
|
|
73
|
+
content,
|
|
74
|
+
title,
|
|
75
|
+
body,
|
|
76
|
+
actions,
|
|
77
|
+
button,
|
|
78
|
+
buttonPrimary,
|
|
79
|
+
buttonText
|
|
80
|
+
};
|
package/icons/CartIcon.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import Icon from '@shopgate/pwa-common/components/Icon';
|
|
4
|
+
import { themeConfig } from '@shopgate/pwa-common/helpers/config';
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* The cart icon component.
|
|
3
8
|
* @param {Object} props The icon component properties.
|
|
4
9
|
* @returns {JSX}
|
|
5
|
-
*/
|
|
10
|
+
*/
|
|
11
|
+
const CartIcon = props => /*#__PURE__*/React.createElement(Icon, _extends({
|
|
12
|
+
content: themeConfig.icons.cart
|
|
13
|
+
}, props));
|
|
14
|
+
export default CartIcon;
|
package/icons/FilterIcon.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import Icon from '@shopgate/pwa-common/components/Icon';
|
|
4
|
+
import { themeConfig } from '@shopgate/pwa-common/helpers/config';
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* The filter icon component.
|
|
3
8
|
* @param {Object} props The icon component properties.
|
|
4
9
|
* @returns {JSX}
|
|
5
|
-
*/
|
|
10
|
+
*/
|
|
11
|
+
const Filter = props => /*#__PURE__*/React.createElement(Icon, _extends({
|
|
12
|
+
content: themeConfig.icons.filter
|
|
13
|
+
}, props));
|
|
14
|
+
export default Filter;
|
package/icons/HomeIcon.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import Icon from '@shopgate/pwa-common/components/Icon';
|
|
4
|
+
import { themeConfig } from '@shopgate/pwa-common/helpers/config';
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* The home icon component.
|
|
3
8
|
* @param {Object} props The icon component properties.
|
|
4
9
|
* @returns {JSX}
|
|
5
|
-
*/
|
|
10
|
+
*/
|
|
11
|
+
const Home = props => /*#__PURE__*/React.createElement(Icon, _extends({
|
|
12
|
+
content: themeConfig.icons.home
|
|
13
|
+
}, props));
|
|
14
|
+
export default Home;
|
package/icons/ShareIcon.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import Icon from '@shopgate/pwa-common/components/Icon';
|
|
4
|
+
import { themeConfig } from '@shopgate/pwa-common/helpers/config';
|
|
5
|
+
|
|
6
|
+
/**
|
|
2
7
|
* The Share icon component.
|
|
3
8
|
* @param {Object} props The icon component properties.
|
|
4
9
|
* @returns {JSX}
|
|
5
|
-
*/
|
|
10
|
+
*/
|
|
11
|
+
const ShareIcon = props => /*#__PURE__*/React.createElement(Icon, _extends({
|
|
12
|
+
content: themeConfig.icons.share
|
|
13
|
+
}, props));
|
|
14
|
+
export default ShareIcon;
|
package/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export{default as AppBar}from"./AppBar";
|
|
1
|
+
export { default as AppBar } from "./AppBar";
|
|
2
|
+
export { default as CartIcon } from "./icons/CartIcon";
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shopgate/pwa-ui-ios",
|
|
3
|
-
"version": "7.30.0-alpha.
|
|
3
|
+
"version": "7.30.0-alpha.8",
|
|
4
4
|
"description": "Shopgate's iOS UI components.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"devDependencies": {
|
|
8
|
-
"@shopgate/pwa-common": "7.30.0-alpha.
|
|
8
|
+
"@shopgate/pwa-common": "7.30.0-alpha.8",
|
|
9
9
|
"react": "~16.14.0"
|
|
10
10
|
},
|
|
11
11
|
"peerDependencies": {
|