@shopgate/pwa-ui-material 7.30.0-alpha.7 → 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/Accordion/components/AccordionContent/index.js +51 -2
- package/Accordion/components/AccordionContent/spec.js +32 -1
- package/Accordion/components/AccordionContent/style.js +9 -1
- package/Accordion/index.js +90 -2
- package/Accordion/spec.js +39 -1
- package/Accordion/style.js +47 -1
- package/AppBar/components/Below/index.js +24 -2
- package/AppBar/components/Center/index.js +24 -2
- package/AppBar/components/Field/index.js +39 -3
- package/AppBar/components/Field/style.js +14 -1
- package/AppBar/components/Icon/index.js +43 -3
- package/AppBar/components/Icon/style.js +14 -1
- package/AppBar/components/Left/index.js +24 -2
- package/AppBar/components/Right/index.js +24 -2
- package/AppBar/components/Title/index.js +37 -3
- package/AppBar/components/Title/style.js +11 -1
- package/AppBar/index.js +87 -3
- package/AppBar/style.js +21 -1
- package/BaseDialog/components/Buttons/index.js +28 -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 +39 -2
- package/BaseDialog/spec.js +39 -1
- package/BaseDialog/style.js +64 -1
- package/FloatingActionButton/index.js +56 -3
- package/FloatingActionButton/style.js +33 -1
- package/NavDrawer/components/Divider/index.js +10 -2
- package/NavDrawer/components/Divider/spec.js +9 -1
- package/NavDrawer/components/Divider/style.js +12 -2
- package/NavDrawer/components/Item/index.js +72 -6
- package/NavDrawer/components/Item/style.js +49 -1
- package/NavDrawer/components/Section/index.js +29 -2
- package/NavDrawer/components/Title/index.js +23 -2
- package/NavDrawer/components/Title/style.js +8 -1
- package/NavDrawer/index.js +132 -10
- package/NavDrawer/spec.js +35 -1
- package/NavDrawer/style.js +26 -1
- package/NavDrawer/transition.js +20 -1
- package/SnackBar/index.js +158 -23
- package/SnackBar/style.js +64 -2
- package/colors.js +4 -1
- package/icons/ShareIcon.js +11 -2
- package/index.js +5 -1
- package/jest.config.js +1 -1
- package/package.json +2 -2
package/AppBar/index.js
CHANGED
|
@@ -1,8 +1,92 @@
|
|
|
1
|
-
import React,{useMemo,useRef,useLayoutEffect}from'react';
|
|
1
|
+
import React, { useMemo, useRef, useLayoutEffect } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { getAbsoluteHeight } from '@shopgate/pwa-common/helpers/dom';
|
|
4
|
+
import { themeShadows, themeColors } from '@shopgate/pwa-common/helpers/config';
|
|
5
|
+
import { setCSSCustomProp } from '@shopgate/engage/styles';
|
|
6
|
+
import { SurroundPortals } from '@shopgate/engage/components';
|
|
7
|
+
import { APP_BAR_CONTENT } from '@shopgate/engage/core/constants';
|
|
8
|
+
import Field from "./components/Field";
|
|
9
|
+
import Icon from "./components/Icon";
|
|
10
|
+
import Title from "./components/Title";
|
|
11
|
+
import Right from "./components/Right";
|
|
12
|
+
import Center from "./components/Center";
|
|
13
|
+
import Left from "./components/Left";
|
|
14
|
+
import Below from "./components/Below";
|
|
15
|
+
import styles from "./style";
|
|
16
|
+
|
|
17
|
+
/**
|
|
2
18
|
* Updates the --app-bar-height custom property
|
|
3
19
|
* @param {Object} ref The app bar ref.
|
|
4
|
-
*/
|
|
20
|
+
*/
|
|
21
|
+
const updateAppBarHeight = ref => {
|
|
22
|
+
if (!ref.current) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
setCSSCustomProp('--app-bar-height', `${getAbsoluteHeight(ref.current)}px`);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
5
29
|
* The AppBar component
|
|
6
30
|
* @param {Object} props The component props.
|
|
7
31
|
* @returns {JSX}
|
|
8
|
-
*/
|
|
32
|
+
*/
|
|
33
|
+
const AppBar = ({
|
|
34
|
+
below,
|
|
35
|
+
center,
|
|
36
|
+
left,
|
|
37
|
+
right,
|
|
38
|
+
backgroundColor,
|
|
39
|
+
textColor,
|
|
40
|
+
shadow
|
|
41
|
+
}) => {
|
|
42
|
+
const contentRef = useRef(null);
|
|
43
|
+
const style = useMemo(() => ({
|
|
44
|
+
background: backgroundColor,
|
|
45
|
+
color: textColor,
|
|
46
|
+
boxShadow: !shadow ? 'none' : themeShadows.material
|
|
47
|
+
}), [backgroundColor, shadow, textColor]);
|
|
48
|
+
const observer = useMemo(() => new MutationObserver(() => {
|
|
49
|
+
updateAppBarHeight(contentRef);
|
|
50
|
+
}), [contentRef]);
|
|
51
|
+
useLayoutEffect(() => {
|
|
52
|
+
updateAppBarHeight(contentRef);
|
|
53
|
+
observer.observe(contentRef.current, {
|
|
54
|
+
childList: true
|
|
55
|
+
});
|
|
56
|
+
return () => {
|
|
57
|
+
observer.disconnect();
|
|
58
|
+
};
|
|
59
|
+
}, [contentRef, observer]);
|
|
60
|
+
return /*#__PURE__*/React.createElement("header", {
|
|
61
|
+
ref: contentRef,
|
|
62
|
+
className: `${styles.outer} ui-material__app-bar`,
|
|
63
|
+
"data-test-id": "Navigator",
|
|
64
|
+
role: "banner",
|
|
65
|
+
style: style
|
|
66
|
+
}, /*#__PURE__*/React.createElement(SurroundPortals, {
|
|
67
|
+
portalName: APP_BAR_CONTENT
|
|
68
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
69
|
+
className: styles.inner
|
|
70
|
+
}, /*#__PURE__*/React.createElement(Left, {
|
|
71
|
+
elements: left
|
|
72
|
+
}), /*#__PURE__*/React.createElement(Center, {
|
|
73
|
+
elements: center
|
|
74
|
+
}), /*#__PURE__*/React.createElement(Right, {
|
|
75
|
+
elements: right
|
|
76
|
+
}))), /*#__PURE__*/React.createElement(Below, {
|
|
77
|
+
elements: below
|
|
78
|
+
}));
|
|
79
|
+
};
|
|
80
|
+
AppBar.defaultProps = {
|
|
81
|
+
backgroundColor: themeColors.light,
|
|
82
|
+
below: null,
|
|
83
|
+
center: null,
|
|
84
|
+
left: null,
|
|
85
|
+
right: null,
|
|
86
|
+
shadow: true,
|
|
87
|
+
textColor: themeColors.dark
|
|
88
|
+
};
|
|
89
|
+
AppBar.Field = Field;
|
|
90
|
+
AppBar.Icon = Icon;
|
|
91
|
+
AppBar.Title = Title;
|
|
92
|
+
export default AppBar;
|
package/AppBar/style.js
CHANGED
|
@@ -1 +1,21 @@
|
|
|
1
|
-
import{css}from'glamor';
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
const outer = css({
|
|
3
|
+
boxSizing: 'content-box',
|
|
4
|
+
left: 0,
|
|
5
|
+
paddingTop: 'var(--safe-area-inset-top)',
|
|
6
|
+
position: 'sticky',
|
|
7
|
+
top: 0,
|
|
8
|
+
width: '100%',
|
|
9
|
+
zIndex: 15
|
|
10
|
+
});
|
|
11
|
+
const inner = css({
|
|
12
|
+
background: 'inherit',
|
|
13
|
+
display: 'flex',
|
|
14
|
+
justifyContent: 'space-between',
|
|
15
|
+
position: 'relative',
|
|
16
|
+
zIndex: 14
|
|
17
|
+
});
|
|
18
|
+
export default {
|
|
19
|
+
outer,
|
|
20
|
+
inner
|
|
21
|
+
};
|
|
@@ -1,4 +1,30 @@
|
|
|
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
|
+
disabled = false
|
|
17
|
+
}) => /*#__PURE__*/React.createElement(Button, {
|
|
18
|
+
key: label,
|
|
19
|
+
className: styles.button,
|
|
20
|
+
flat: true,
|
|
21
|
+
type: "primary",
|
|
22
|
+
onClick: action,
|
|
23
|
+
disabled: disabled
|
|
24
|
+
}, /*#__PURE__*/React.createElement(I18n.Text, {
|
|
25
|
+
string: label
|
|
26
|
+
})));
|
|
27
|
+
Buttons.defaultProps = {
|
|
28
|
+
actions: []
|
|
29
|
+
};
|
|
30
|
+
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,33 @@ 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-material__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("div", {
|
|
37
|
+
className: styles.innerActions
|
|
38
|
+
}, /*#__PURE__*/React.createElement(Buttons, {
|
|
39
|
+
actions: actions
|
|
40
|
+
})))));
|
|
41
|
+
BasicDialog.defaultProps = {
|
|
42
|
+
children: null,
|
|
43
|
+
actions: [],
|
|
44
|
+
title: null
|
|
45
|
+
};
|
|
46
|
+
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 +1,64 @@
|
|
|
1
|
-
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
import { responsiveMediaQuery } from '@shopgate/engage/styles';
|
|
3
|
+
import { themeConfig } from '@shopgate/pwa-common/helpers/config';
|
|
4
|
+
const outerGap = 40;
|
|
5
|
+
const container = css({
|
|
6
|
+
position: 'relative',
|
|
7
|
+
display: 'flex',
|
|
8
|
+
flexDirection: 'column',
|
|
9
|
+
width: `calc(100vw - ${outerGap * 2}px)`,
|
|
10
|
+
maxHeight: `calc(100vh - ${outerGap * 2}px)`,
|
|
11
|
+
borderRadius: 2,
|
|
12
|
+
boxShadow: themeConfig.shadows.dialog,
|
|
13
|
+
background: themeConfig.colors.light,
|
|
14
|
+
[responsiveMediaQuery('>xs', {
|
|
15
|
+
webOnly: true
|
|
16
|
+
})]: {
|
|
17
|
+
width: `calc(80vh - ${outerGap * 2}px)`,
|
|
18
|
+
maxHeight: `calc(80vh - ${outerGap * 2}px)`
|
|
19
|
+
},
|
|
20
|
+
[responsiveMediaQuery('>md', {
|
|
21
|
+
webOnly: true
|
|
22
|
+
})]: {
|
|
23
|
+
width: `calc(var(--page-content-width) * 0.5 - ${outerGap * 2}px)`,
|
|
24
|
+
maxHeight: `calc(var(--page-content-width) * 0.5 - ${outerGap * 2}px)`
|
|
25
|
+
}
|
|
26
|
+
}).toString();
|
|
27
|
+
const content = css({
|
|
28
|
+
padding: themeConfig.variables.gap.small * 3,
|
|
29
|
+
overflowY: 'auto'
|
|
30
|
+
}).toString();
|
|
31
|
+
const title = css({
|
|
32
|
+
fontSize: '1.25em',
|
|
33
|
+
lineHeight: themeConfig.typography.lineHeight,
|
|
34
|
+
fontWeight: 500,
|
|
35
|
+
paddingBottom: themeConfig.variables.gap.small,
|
|
36
|
+
marginTop: '-.25em'
|
|
37
|
+
}).toString();
|
|
38
|
+
const body = css({
|
|
39
|
+
color: themeConfig.colors.shade6,
|
|
40
|
+
flexGrow: 1,
|
|
41
|
+
overflow: 'auto'
|
|
42
|
+
}).toString();
|
|
43
|
+
const actions = css({
|
|
44
|
+
alignSelf: 'flex-end',
|
|
45
|
+
padding: themeConfig.variables.gap.small
|
|
46
|
+
}).toString();
|
|
47
|
+
const innerActions = css({
|
|
48
|
+
display: 'flex',
|
|
49
|
+
flexWrap: 'wrap',
|
|
50
|
+
justifyContent: 'flex-end'
|
|
51
|
+
}).toString();
|
|
52
|
+
const button = css({
|
|
53
|
+
marginRight: `-${themeConfig.variables.gap.small / 2}px`,
|
|
54
|
+
textAlign: 'right'
|
|
55
|
+
}).toString();
|
|
56
|
+
export default {
|
|
57
|
+
container,
|
|
58
|
+
content,
|
|
59
|
+
title,
|
|
60
|
+
body,
|
|
61
|
+
actions,
|
|
62
|
+
innerActions,
|
|
63
|
+
button
|
|
64
|
+
};
|
|
@@ -1,6 +1,59 @@
|
|
|
1
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import classNames from 'classnames';
|
|
4
|
+
import colors from "../colors";
|
|
5
|
+
import styles from "./style";
|
|
6
|
+
const SIZE_BIG = 'big';
|
|
7
|
+
const SIZE_SMALL = 'small';
|
|
8
|
+
/**
|
|
2
9
|
* The FloatingActionButton component.
|
|
3
10
|
* @param {Object} props The component props.
|
|
4
11
|
* @return {JSX}
|
|
5
|
-
*/
|
|
6
|
-
|
|
12
|
+
*/
|
|
13
|
+
const FloatingActionButton = props => {
|
|
14
|
+
const {
|
|
15
|
+
background,
|
|
16
|
+
children,
|
|
17
|
+
className,
|
|
18
|
+
disabled,
|
|
19
|
+
onClick,
|
|
20
|
+
raised,
|
|
21
|
+
ref,
|
|
22
|
+
size,
|
|
23
|
+
type
|
|
24
|
+
} = props;
|
|
25
|
+
const classes = classNames('floating-action-button', 'ui-material__floating-action-button', styles.button, {
|
|
26
|
+
[className]: className,
|
|
27
|
+
[styles.buttonSmall]: size === SIZE_SMALL,
|
|
28
|
+
[styles.buttonSmall]: size === SIZE_SMALL,
|
|
29
|
+
[styles.buttonLarge]: size === SIZE_BIG,
|
|
30
|
+
[styles.buttonShadow]: raised
|
|
31
|
+
});
|
|
32
|
+
return (
|
|
33
|
+
/*#__PURE__*/
|
|
34
|
+
// eslint-disable-next-line react/button-has-type
|
|
35
|
+
React.createElement("button", {
|
|
36
|
+
className: classes,
|
|
37
|
+
disabled: disabled,
|
|
38
|
+
onClick: onClick,
|
|
39
|
+
ref: ref,
|
|
40
|
+
style: {
|
|
41
|
+
background
|
|
42
|
+
},
|
|
43
|
+
type: type,
|
|
44
|
+
"data-test-id": props.testId
|
|
45
|
+
}, children)
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
FloatingActionButton.defaultProps = {
|
|
49
|
+
background: `var(--color-primary, ${colors.primary})`,
|
|
50
|
+
className: null,
|
|
51
|
+
disabled: false,
|
|
52
|
+
onClick: () => {},
|
|
53
|
+
raised: true,
|
|
54
|
+
ref: null,
|
|
55
|
+
size: SIZE_BIG,
|
|
56
|
+
testId: null,
|
|
57
|
+
type: 'button'
|
|
58
|
+
};
|
|
59
|
+
export default FloatingActionButton;
|
|
@@ -1 +1,33 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
import { themeConfig } from '@shopgate/pwa-common/helpers/config';
|
|
3
|
+
const {
|
|
4
|
+
shadows
|
|
5
|
+
} = themeConfig;
|
|
6
|
+
const button = css({
|
|
7
|
+
borderRadius: '50%',
|
|
8
|
+
outline: 0,
|
|
9
|
+
overflow: 'hidden',
|
|
10
|
+
padding: 0,
|
|
11
|
+
position: 'relative',
|
|
12
|
+
zIndex: 1,
|
|
13
|
+
':disabled': {
|
|
14
|
+
cursor: 'not-allowed'
|
|
15
|
+
}
|
|
16
|
+
}).toString();
|
|
17
|
+
const buttonSmall = css({
|
|
18
|
+
height: 40,
|
|
19
|
+
width: 40
|
|
20
|
+
});
|
|
21
|
+
const buttonLarge = css({
|
|
22
|
+
height: 56,
|
|
23
|
+
width: 56
|
|
24
|
+
});
|
|
25
|
+
const buttonShadow = css({
|
|
26
|
+
boxShadow: shadows.buttons.elevated
|
|
27
|
+
});
|
|
28
|
+
export default {
|
|
29
|
+
button,
|
|
30
|
+
buttonSmall,
|
|
31
|
+
buttonLarge,
|
|
32
|
+
buttonShadow
|
|
33
|
+
};
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styles from "./style";
|
|
3
|
+
|
|
4
|
+
/**
|
|
2
5
|
* @returns {JSX}
|
|
3
|
-
*/
|
|
6
|
+
*/
|
|
7
|
+
const NavDrawerDivider = () => /*#__PURE__*/React.createElement("hr", {
|
|
8
|
+
"aria-hidden": true,
|
|
9
|
+
className: styles
|
|
10
|
+
});
|
|
11
|
+
export default NavDrawerDivider;
|
|
@@ -1 +1,9 @@
|
|
|
1
|
-
import React from'react';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { mount } from 'enzyme';
|
|
3
|
+
import Divider from "./index";
|
|
4
|
+
describe('<NavDrawerDivider />', () => {
|
|
5
|
+
it('should match the snapshot', () => {
|
|
6
|
+
const wrapper = mount(/*#__PURE__*/React.createElement(Divider, null));
|
|
7
|
+
expect(wrapper).toMatchSnapshot();
|
|
8
|
+
});
|
|
9
|
+
});
|
|
@@ -1,2 +1,12 @@
|
|
|
1
|
-
import{css}from'glamor';
|
|
2
|
-
|
|
1
|
+
import { css } from 'glamor';
|
|
2
|
+
import { themeColors } from '@shopgate/pwa-common/helpers/config';
|
|
3
|
+
export default css({
|
|
4
|
+
// prevent two consecutive dividers
|
|
5
|
+
' + hr': {
|
|
6
|
+
display: 'none'
|
|
7
|
+
},
|
|
8
|
+
background: themeColors.darkGray,
|
|
9
|
+
border: 0,
|
|
10
|
+
height: 1,
|
|
11
|
+
margin: '16px 0'
|
|
12
|
+
});
|