@shopgate/pwa-ui-material 7.30.3 → 7.31.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Accordion/components/AccordionContent/index.js +23 -10
- package/Accordion/index.js +62 -12
- package/AppBar/components/Field/index.js +37 -39
- package/AppBar/components/Icon/index.js +47 -39
- package/AppBar/components/Title/index.js +44 -38
- package/AppBar/index.js +26 -5
- package/BaseDialog/components/Buttons/index.js +29 -18
- package/BaseDialog/components/Content/index.js +14 -3
- package/BaseDialog/components/Title/index.js +17 -5
- package/BaseDialog/index.js +71 -26
- package/FloatingActionButton/index.js +40 -12
- package/NavDrawer/components/Divider/index.js +24 -6
- package/NavDrawer/components/Item/index.js +91 -65
- package/NavDrawer/components/Title/index.js +16 -4
- package/NavDrawer/index.js +129 -120
- package/NavDrawer/spec.js +112 -14
- package/SnackBar/index.js +176 -166
- package/icons/ShareIcon.d.ts +7 -0
- package/icons/ShareIcon.d.ts.map +1 -0
- package/icons/ShareIcon.js +0 -2
- package/package.json +6 -4
- package/tsconfig.build.json +16 -0
- package/tsconfig.json +3 -0
- package/Accordion/components/AccordionContent/style.js +0 -9
- package/Accordion/style.js +0 -47
- package/AppBar/components/Field/style.js +0 -14
- package/AppBar/components/Icon/style.js +0 -14
- package/AppBar/components/Title/style.js +0 -11
- package/AppBar/style.js +0 -21
- package/BaseDialog/style.js +0 -64
- package/FloatingActionButton/style.js +0 -33
- package/NavDrawer/components/Divider/style.js +0 -12
- package/NavDrawer/components/Item/style.js +0 -49
- package/NavDrawer/components/Title/style.js +0 -8
- package/NavDrawer/style.js +0 -26
- package/SnackBar/style.js +0 -64
package/NavDrawer/index.js
CHANGED
|
@@ -1,151 +1,160 @@
|
|
|
1
|
-
import
|
|
2
|
-
import React, { Component, Fragment } from 'react';
|
|
1
|
+
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
3
2
|
import PropTypes from 'prop-types';
|
|
4
3
|
import noop from 'lodash/noop';
|
|
5
4
|
import Transition from 'react-transition-group/Transition';
|
|
6
5
|
import { Backdrop } from '@shopgate/engage/components';
|
|
7
6
|
import { ModalStateTracker } from '@shopgate/engage/a11y/components';
|
|
8
7
|
import { UIEvents } from '@shopgate/pwa-core';
|
|
8
|
+
import { themeShadows, themeColors } from '@shopgate/pwa-common/helpers/config';
|
|
9
|
+
import { makeStyles } from '@shopgate/engage/styles';
|
|
9
10
|
import Divider from "./components/Divider";
|
|
10
11
|
import Item from "./components/Item";
|
|
11
12
|
import Section from "./components/Section";
|
|
12
13
|
import Title from "./components/Title";
|
|
13
|
-
import { contentStyle, drawerStyle } from "./style";
|
|
14
14
|
import transition from "./transition";
|
|
15
15
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
16
16
|
const OPEN = 'navdrawer_open';
|
|
17
17
|
const CLOSE = 'navdrawer_close';
|
|
18
|
+
const useStyles = makeStyles()({
|
|
19
|
+
content: {
|
|
20
|
+
fontSize: 14,
|
|
21
|
+
height: '100%',
|
|
22
|
+
overflowY: 'scroll',
|
|
23
|
+
paddingBottom: 'var(--safe-area-inset-bottom)',
|
|
24
|
+
WebkitOverflowScrolling: 'touch'
|
|
25
|
+
},
|
|
26
|
+
drawer: {
|
|
27
|
+
background: themeColors.light,
|
|
28
|
+
boxShadow: themeShadows.navDrawer,
|
|
29
|
+
color: themeColors.dark,
|
|
30
|
+
height: '100vh',
|
|
31
|
+
left: 0,
|
|
32
|
+
maxWidth: '300px',
|
|
33
|
+
position: 'fixed',
|
|
34
|
+
top: 0,
|
|
35
|
+
transition: 'transform 300ms cubic-bezier(0.25, 0.1, 0.25, 1)',
|
|
36
|
+
width: '100%',
|
|
37
|
+
willChange: 'transform',
|
|
38
|
+
zIndex: 50,
|
|
39
|
+
'@media(max-width: 480px)': {
|
|
40
|
+
maxWidth: '67vw'
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
18
44
|
|
|
19
45
|
/**
|
|
20
|
-
*
|
|
46
|
+
* Material navigation drawer; opens/closes via `NavDrawer.open()` / `NavDrawer.close()` (UIEvents).
|
|
47
|
+
* @param {Object} props Props.
|
|
48
|
+
* @returns {JSX.Element}
|
|
21
49
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
_this.onExiting = () => {
|
|
45
|
-
_this.props.onClose();
|
|
50
|
+
const NavDrawer = ({
|
|
51
|
+
children,
|
|
52
|
+
'aria-hidden': ariaHiddenProp,
|
|
53
|
+
onClose,
|
|
54
|
+
onOpen
|
|
55
|
+
}) => {
|
|
56
|
+
const {
|
|
57
|
+
classes,
|
|
58
|
+
cx
|
|
59
|
+
} = useStyles();
|
|
60
|
+
const [open, setOpen] = useState(false);
|
|
61
|
+
const contentRef = useRef(null);
|
|
62
|
+
const a11yCloseRef = useRef(null);
|
|
63
|
+
const triggerElementRef = useRef(null);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
/**
|
|
66
|
+
* Opens the drawer and stores the active element for focus restore.
|
|
67
|
+
* @returns {void}
|
|
68
|
+
*/
|
|
69
|
+
const handleOpenEvent = () => {
|
|
70
|
+
triggerElementRef.current = document.activeElement;
|
|
71
|
+
setOpen(true);
|
|
46
72
|
};
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Closes the drawer (event listener).
|
|
75
|
+
* @returns {void}
|
|
76
|
+
*/
|
|
77
|
+
const handleCloseEvent = () => {
|
|
78
|
+
setOpen(false);
|
|
53
79
|
};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
80
|
+
UIEvents.addListener(OPEN, handleOpenEvent);
|
|
81
|
+
UIEvents.addListener(CLOSE, handleCloseEvent);
|
|
82
|
+
return () => {
|
|
83
|
+
UIEvents.removeListener(OPEN, handleOpenEvent);
|
|
84
|
+
UIEvents.removeListener(CLOSE, handleCloseEvent);
|
|
58
85
|
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
})
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
}), /*#__PURE__*/_jsx(Backdrop, {
|
|
125
|
-
isVisible: this.state.open,
|
|
126
|
-
level: 4,
|
|
127
|
-
onClick: this.close,
|
|
128
|
-
opacity: 20
|
|
129
|
-
})]
|
|
130
|
-
});
|
|
131
|
-
};
|
|
132
|
-
return NavDrawer;
|
|
133
|
-
}(Component);
|
|
86
|
+
}, []);
|
|
87
|
+
const closeDrawer = useCallback(() => {
|
|
88
|
+
setOpen(false);
|
|
89
|
+
}, []);
|
|
90
|
+
const handleEntering = useCallback(() => {
|
|
91
|
+
onOpen();
|
|
92
|
+
}, [onOpen]);
|
|
93
|
+
const handleEntered = useCallback(() => {
|
|
94
|
+
a11yCloseRef.current?.focus();
|
|
95
|
+
}, []);
|
|
96
|
+
const handleExiting = useCallback(() => {
|
|
97
|
+
onClose();
|
|
98
|
+
}, [onClose]);
|
|
99
|
+
const handleExited = useCallback(() => {
|
|
100
|
+
if (contentRef.current) {
|
|
101
|
+
contentRef.current.scrollTop = 0;
|
|
102
|
+
}
|
|
103
|
+
const trigger = triggerElementRef.current;
|
|
104
|
+
if (trigger && typeof trigger.focus === 'function') {
|
|
105
|
+
trigger.focus();
|
|
106
|
+
}
|
|
107
|
+
}, []);
|
|
108
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
109
|
+
children: [/*#__PURE__*/_jsx(Transition, {
|
|
110
|
+
onEntering: handleEntering,
|
|
111
|
+
onEntered: handleEntered,
|
|
112
|
+
onExited: handleExited,
|
|
113
|
+
onExiting: handleExiting,
|
|
114
|
+
in: open,
|
|
115
|
+
timeout: 300,
|
|
116
|
+
children: state => /*#__PURE__*/_jsx(ModalStateTracker, {
|
|
117
|
+
isVisible: open,
|
|
118
|
+
children: /*#__PURE__*/_jsxs("section", {
|
|
119
|
+
className: cx(classes.drawer, 'ui-material__nav-drawer'),
|
|
120
|
+
"data-test-id": "NavDrawer",
|
|
121
|
+
style: transition[state],
|
|
122
|
+
"aria-hidden": ariaHiddenProp || state === 'exited',
|
|
123
|
+
tabIndex: "-1",
|
|
124
|
+
children: [/*#__PURE__*/_jsx(Item, {
|
|
125
|
+
label: "common.close",
|
|
126
|
+
ref: a11yCloseRef,
|
|
127
|
+
srOnly: true
|
|
128
|
+
}), /*#__PURE__*/_jsx("nav", {
|
|
129
|
+
className: classes.content,
|
|
130
|
+
ref: contentRef,
|
|
131
|
+
children: children
|
|
132
|
+
})]
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
}), /*#__PURE__*/_jsx(Backdrop, {
|
|
136
|
+
isVisible: open,
|
|
137
|
+
level: 4,
|
|
138
|
+
onClick: closeDrawer,
|
|
139
|
+
opacity: 20
|
|
140
|
+
})]
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
NavDrawer.defaultProps = {
|
|
144
|
+
'aria-hidden': false,
|
|
145
|
+
onClose: noop,
|
|
146
|
+
onOpen: noop
|
|
147
|
+
};
|
|
134
148
|
NavDrawer.EVENT_OPEN = OPEN;
|
|
135
149
|
NavDrawer.EVENT_CLOSE = CLOSE;
|
|
136
150
|
NavDrawer.Divider = Divider;
|
|
137
151
|
NavDrawer.Item = Item;
|
|
138
152
|
NavDrawer.Section = Section;
|
|
139
153
|
NavDrawer.Title = Title;
|
|
140
|
-
NavDrawer.close = () => {
|
|
141
|
-
UIEvents.emit(CLOSE);
|
|
142
|
-
};
|
|
143
154
|
NavDrawer.open = () => {
|
|
144
155
|
UIEvents.emit(OPEN);
|
|
145
156
|
};
|
|
146
|
-
NavDrawer.
|
|
147
|
-
|
|
148
|
-
onClose: noop,
|
|
149
|
-
onOpen: noop
|
|
157
|
+
NavDrawer.close = () => {
|
|
158
|
+
UIEvents.emit(CLOSE);
|
|
150
159
|
};
|
|
151
160
|
export default NavDrawer;
|
package/NavDrawer/spec.js
CHANGED
|
@@ -1,10 +1,95 @@
|
|
|
1
|
+
import "core-js/modules/es.array.reduce.js";
|
|
2
|
+
/* eslint-disable global-require, extra-rules/no-single-line-objects */
|
|
1
3
|
import React from 'react';
|
|
2
4
|
import { shallow, mount } from 'enzyme';
|
|
5
|
+
import { act } from 'react-dom/test-utils';
|
|
6
|
+
import Transition from 'react-transition-group/Transition';
|
|
7
|
+
jest.unmock('@shopgate/pwa-core');
|
|
8
|
+
jest.mock('@shopgate/engage/styles', () => ({
|
|
9
|
+
makeStyles: () => function mockUseStylesFactory(defs) {
|
|
10
|
+
return function useStylesMock() {
|
|
11
|
+
const keys = Object.keys(defs);
|
|
12
|
+
const classes = keys.reduce((acc, key) => {
|
|
13
|
+
acc[key] = `mock-class-${key}`;
|
|
14
|
+
return acc;
|
|
15
|
+
}, {});
|
|
16
|
+
const cx = (...parts) => parts.filter(Boolean).join(' ');
|
|
17
|
+
return {
|
|
18
|
+
classes,
|
|
19
|
+
cx
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}));
|
|
24
|
+
jest.mock('@shopgate/engage/components', () => {
|
|
25
|
+
const mockReact = require('react');
|
|
26
|
+
const mockPropTypes = require('prop-types');
|
|
27
|
+
function Backdrop(props) {
|
|
28
|
+
const {
|
|
29
|
+
isVisible,
|
|
30
|
+
onClick
|
|
31
|
+
} = props;
|
|
32
|
+
if (!isVisible) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return mockReact.createElement('button', {
|
|
36
|
+
type: 'button',
|
|
37
|
+
'aria-label': 'Close',
|
|
38
|
+
'data-test-id': 'NavDrawerBackdrop',
|
|
39
|
+
onClick
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
Backdrop.propTypes = {
|
|
43
|
+
isVisible: mockPropTypes.bool,
|
|
44
|
+
onClick: mockPropTypes.func
|
|
45
|
+
};
|
|
46
|
+
Backdrop.defaultProps = {
|
|
47
|
+
isVisible: false,
|
|
48
|
+
onClick: undefined
|
|
49
|
+
};
|
|
50
|
+
Backdrop.displayName = 'Backdrop';
|
|
51
|
+
return {
|
|
52
|
+
Backdrop
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
jest.mock('@shopgate/engage/a11y/components', () => {
|
|
56
|
+
const mockPropTypes = require('prop-types');
|
|
57
|
+
function ModalStateTracker(props) {
|
|
58
|
+
return props.children;
|
|
59
|
+
}
|
|
60
|
+
ModalStateTracker.propTypes = {
|
|
61
|
+
children: mockPropTypes.node
|
|
62
|
+
};
|
|
63
|
+
ModalStateTracker.defaultProps = {
|
|
64
|
+
children: null
|
|
65
|
+
};
|
|
66
|
+
return {
|
|
67
|
+
ModalStateTracker
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
jest.mock("./components/Item", () => {
|
|
71
|
+
const mockReact = require('react');
|
|
72
|
+
const mockPropTypes = require('prop-types');
|
|
73
|
+
const ItemWithRef = mockReact.forwardRef((props, ref) => mockReact.createElement('button', {
|
|
74
|
+
type: 'button',
|
|
75
|
+
ref,
|
|
76
|
+
'data-test-id': 'nav-drawer-item'
|
|
77
|
+
}, props.label));
|
|
78
|
+
ItemWithRef.propTypes = {
|
|
79
|
+
label: mockPropTypes.string
|
|
80
|
+
};
|
|
81
|
+
ItemWithRef.defaultProps = {
|
|
82
|
+
label: ''
|
|
83
|
+
};
|
|
84
|
+
return {
|
|
85
|
+
__esModule: true,
|
|
86
|
+
default: ItemWithRef
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// eslint-disable-next-line import/first
|
|
3
91
|
import NavDrawer from "./index";
|
|
4
92
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
-
jest.unmock('@shopgate/pwa-core');
|
|
6
|
-
jest.mock('@shopgate/engage/components');
|
|
7
|
-
jest.mock('@shopgate/engage/a11y/components');
|
|
8
93
|
describe('NavDrawer', () => {
|
|
9
94
|
it('should match the snapshot', () => {
|
|
10
95
|
const wrapper = shallow(/*#__PURE__*/_jsx(NavDrawer, {
|
|
@@ -20,22 +105,35 @@ describe('NavDrawer', () => {
|
|
|
20
105
|
onClose: onClose,
|
|
21
106
|
children: "Content"
|
|
22
107
|
}));
|
|
23
|
-
|
|
24
|
-
|
|
108
|
+
act(() => {
|
|
109
|
+
NavDrawer.open();
|
|
110
|
+
});
|
|
111
|
+
wrapper.update();
|
|
112
|
+
expect(wrapper.find(Transition).prop('in')).toEqual(true);
|
|
25
113
|
expect(onOpen).toHaveBeenCalled();
|
|
26
114
|
expect(onClose).not.toHaveBeenCalled();
|
|
27
|
-
|
|
28
|
-
|
|
115
|
+
act(() => {
|
|
116
|
+
NavDrawer.close();
|
|
117
|
+
});
|
|
118
|
+
wrapper.update();
|
|
119
|
+
expect(wrapper.find(Transition).prop('in')).toEqual(false);
|
|
29
120
|
expect(onClose).toHaveBeenCalled();
|
|
30
121
|
});
|
|
31
122
|
it('should close when Backdrop is clicked', () => {
|
|
32
|
-
const wrapper =
|
|
123
|
+
const wrapper = mount(/*#__PURE__*/_jsx(NavDrawer, {
|
|
33
124
|
children: "Content"
|
|
34
125
|
}));
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
expect(wrapper.
|
|
126
|
+
act(() => {
|
|
127
|
+
NavDrawer.open();
|
|
128
|
+
});
|
|
129
|
+
wrapper.update();
|
|
130
|
+
expect(wrapper.find(Transition).prop('in')).toEqual(true);
|
|
131
|
+
const backdrop = wrapper.find('[data-test-id="NavDrawerBackdrop"]');
|
|
132
|
+
act(() => {
|
|
133
|
+
backdrop.simulate('click');
|
|
134
|
+
});
|
|
135
|
+
wrapper.update();
|
|
136
|
+
expect(wrapper.find(Transition).prop('in')).toEqual(false);
|
|
40
137
|
});
|
|
41
|
-
});
|
|
138
|
+
});
|
|
139
|
+
/* eslint-enable global-require, extra-rules/no-single-line-objects */
|