UNPKG

7.92 kBJavaScriptView Raw
1import _extends from "@babel/runtime/helpers/esm/extends";
2import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3import * as React from 'react';
4import PropTypes from 'prop-types';
5import clsx from 'clsx';
6import Modal from '../Modal';
7import Backdrop from '../Backdrop';
8import withStyles from '../styles/withStyles';
9import Slide from '../Slide';
10import Paper from '../Paper';
11import capitalize from '../utils/capitalize';
12import { duration } from '../styles/transitions';
13import useTheme from '../styles/useTheme';
14export const styles = theme => ({
15 /* Styles applied to the root element. */
16 root: {},
17
18 /* Styles applied to the root element if `variant="permanent or persistent"`. */
19 docked: {
20 flex: '0 0 auto'
21 },
22
23 /* Styles applied to the `Paper` component. */
24 paper: {
25 overflowY: 'auto',
26 display: 'flex',
27 flexDirection: 'column',
28 height: '100%',
29 flex: '1 0 auto',
30 zIndex: theme.zIndex.drawer,
31 WebkitOverflowScrolling: 'touch',
32 // Add iOS momentum scrolling.
33 // temporary style
34 position: 'fixed',
35 top: 0,
36 // We disable the focus ring for mouse, touch and keyboard users.
37 // At some point, it would be better to keep it for keyboard users.
38 // :focus-ring CSS pseudo-class will help.
39 outline: 0
40 },
41
42 /* Styles applied to the `Paper` component if `anchor="left"`. */
43 paperAnchorLeft: {
44 left: 0,
45 right: 'auto'
46 },
47
48 /* Styles applied to the `Paper` component if `anchor="right"`. */
49 paperAnchorRight: {
50 left: 'auto',
51 right: 0
52 },
53
54 /* Styles applied to the `Paper` component if `anchor="top"`. */
55 paperAnchorTop: {
56 top: 0,
57 left: 0,
58 bottom: 'auto',
59 right: 0,
60 height: 'auto',
61 maxHeight: '100%'
62 },
63
64 /* Styles applied to the `Paper` component if `anchor="bottom"`. */
65 paperAnchorBottom: {
66 top: 'auto',
67 left: 0,
68 bottom: 0,
69 right: 0,
70 height: 'auto',
71 maxHeight: '100%'
72 },
73
74 /* Styles applied to the `Paper` component if `anchor="left"` and `variant` is not "temporary". */
75 paperAnchorDockedLeft: {
76 borderRight: `1px solid ${theme.palette.divider}`
77 },
78
79 /* Styles applied to the `Paper` component if `anchor="top"` and `variant` is not "temporary". */
80 paperAnchorDockedTop: {
81 borderBottom: `1px solid ${theme.palette.divider}`
82 },
83
84 /* Styles applied to the `Paper` component if `anchor="right"` and `variant` is not "temporary". */
85 paperAnchorDockedRight: {
86 borderLeft: `1px solid ${theme.palette.divider}`
87 },
88
89 /* Styles applied to the `Paper` component if `anchor="bottom"` and `variant` is not "temporary". */
90 paperAnchorDockedBottom: {
91 borderTop: `1px solid ${theme.palette.divider}`
92 },
93
94 /* Styles applied to the `Modal` component. */
95 modal: {}
96});
97const oppositeDirection = {
98 left: 'right',
99 right: 'left',
100 top: 'down',
101 bottom: 'up'
102};
103export function isHorizontal(anchor) {
104 return ['left', 'right'].indexOf(anchor) !== -1;
105}
106export function getAnchor(theme, anchor) {
107 return theme.direction === 'rtl' && isHorizontal(anchor) ? oppositeDirection[anchor] : anchor;
108}
109const defaultTransitionDuration = {
110 enter: duration.enteringScreen,
111 exit: duration.leavingScreen
112};
113/**
114 * The props of the [Modal](/api/modal/) component are available
115 * when `variant="temporary"` is set.
116 */
117
118const Drawer = /*#__PURE__*/React.forwardRef(function Drawer(props, ref) {
119 const {
120 anchor: anchorProp = 'left',
121 BackdropProps,
122 children,
123 classes,
124 className,
125 elevation = 16,
126 ModalProps: {
127 BackdropProps: BackdropPropsProp
128 } = {},
129 onClose,
130 open = false,
131 PaperProps = {},
132 SlideProps,
133 // eslint-disable-next-line react/prop-types
134 TransitionComponent = Slide,
135 transitionDuration = defaultTransitionDuration,
136 variant = 'temporary'
137 } = props,
138 ModalProps = _objectWithoutPropertiesLoose(props.ModalProps, ["BackdropProps"]),
139 other = _objectWithoutPropertiesLoose(props, ["anchor", "BackdropProps", "children", "classes", "className", "elevation", "ModalProps", "onClose", "open", "PaperProps", "SlideProps", "TransitionComponent", "transitionDuration", "variant"]);
140
141 const theme = useTheme(); // Let's assume that the Drawer will always be rendered on user space.
142 // We use this state is order to skip the appear transition during the
143 // initial mount of the component.
144
145 const mounted = React.useRef(false);
146 React.useEffect(() => {
147 mounted.current = true;
148 }, []);
149 const anchor = getAnchor(theme, anchorProp);
150 const drawer = /*#__PURE__*/React.createElement(Paper, _extends({
151 elevation: variant === 'temporary' ? elevation : 0,
152 square: true
153 }, PaperProps, {
154 className: clsx(classes.paper, classes[`paperAnchor${capitalize(anchor)}`], PaperProps.className, variant !== 'temporary' && classes[`paperAnchorDocked${capitalize(anchor)}`])
155 }), children);
156
157 if (variant === 'permanent') {
158 return /*#__PURE__*/React.createElement("div", _extends({
159 className: clsx(classes.root, classes.docked, className),
160 ref: ref
161 }, other), drawer);
162 }
163
164 const slidingDrawer = /*#__PURE__*/React.createElement(TransitionComponent, _extends({
165 in: open,
166 direction: oppositeDirection[anchor],
167 timeout: transitionDuration,
168 appear: mounted.current
169 }, SlideProps), drawer);
170
171 if (variant === 'persistent') {
172 return /*#__PURE__*/React.createElement("div", _extends({
173 className: clsx(classes.root, classes.docked, className),
174 ref: ref
175 }, other), slidingDrawer);
176 } // variant === temporary
177
178
179 return /*#__PURE__*/React.createElement(Modal, _extends({
180 BackdropProps: _extends({}, BackdropProps, BackdropPropsProp, {
181 transitionDuration
182 }),
183 BackdropComponent: Backdrop,
184 className: clsx(classes.root, classes.modal, className),
185 open: open,
186 onClose: onClose,
187 ref: ref
188 }, other, ModalProps), slidingDrawer);
189});
190process.env.NODE_ENV !== "production" ? Drawer.propTypes = {
191 // ----------------------------- Warning --------------------------------
192 // | These PropTypes are generated from the TypeScript type definitions |
193 // | To update them edit the d.ts file and run "yarn proptypes" |
194 // ----------------------------------------------------------------------
195
196 /**
197 * Side from which the drawer will appear.
198 */
199 anchor: PropTypes.oneOf(['bottom', 'left', 'right', 'top']),
200
201 /**
202 * @ignore
203 */
204 BackdropProps: PropTypes.object,
205
206 /**
207 * The contents of the drawer.
208 */
209 children: PropTypes.node,
210
211 /**
212 * Override or extend the styles applied to the component.
213 * See [CSS API](#css) below for more details.
214 */
215 classes: PropTypes.object,
216
217 /**
218 * @ignore
219 */
220 className: PropTypes.string,
221
222 /**
223 * The elevation of the drawer.
224 */
225 elevation: PropTypes.number,
226
227 /**
228 * Props applied to the [`Modal`](/api/modal/) element.
229 */
230 ModalProps: PropTypes.object,
231
232 /**
233 * Callback fired when the component requests to be closed.
234 *
235 * @param {object} event The event source of the callback.
236 */
237 onClose: PropTypes.func,
238
239 /**
240 * If `true`, the drawer is open.
241 */
242 open: PropTypes.bool,
243
244 /**
245 * Props applied to the [`Paper`](/api/paper/) element.
246 */
247 PaperProps: PropTypes.object,
248
249 /**
250 * Props applied to the [`Slide`](/api/slide/) element.
251 */
252 SlideProps: PropTypes.object,
253
254 /**
255 * The duration for the transition, in milliseconds.
256 * You may specify a single timeout for all transitions, or individually with an object.
257 */
258 transitionDuration: PropTypes.oneOfType([PropTypes.number, PropTypes.shape({
259 appear: PropTypes.number,
260 enter: PropTypes.number,
261 exit: PropTypes.number
262 })]),
263
264 /**
265 * The variant to use.
266 */
267 variant: PropTypes.oneOf(['permanent', 'persistent', 'temporary'])
268} : void 0;
269export default withStyles(styles, {
270 name: 'MuiDrawer',
271 flip: false
272})(Drawer);
\No newline at end of file