UNPKG

10.4 kBJavaScriptView Raw
1'use client';
2
3import * as React from 'react';
4import PropTypes from 'prop-types';
5import clsx from 'clsx';
6import integerPropType from '@mui/utils/integerPropType';
7import composeClasses from '@mui/utils/composeClasses';
8import { useRtl } from '@mui/system/RtlProvider';
9import Modal from "../Modal/index.js";
10import Slide from "../Slide/index.js";
11import Paper from "../Paper/index.js";
12import capitalize from "../utils/capitalize.js";
13import rootShouldForwardProp from "../styles/rootShouldForwardProp.js";
14import { styled, useTheme } from "../zero-styled/index.js";
15import memoTheme from "../utils/memoTheme.js";
16import { useDefaultProps } from "../DefaultPropsProvider/index.js";
17import { getDrawerUtilityClass } from "./drawerClasses.js";
18import { jsx as _jsx } from "react/jsx-runtime";
19const overridesResolver = (props, styles) => {
20 const {
21 ownerState
22 } = props;
23 return [styles.root, (ownerState.variant === 'permanent' || ownerState.variant === 'persistent') && styles.docked, styles.modal];
24};
25const useUtilityClasses = ownerState => {
26 const {
27 classes,
28 anchor,
29 variant
30 } = ownerState;
31 const slots = {
32 root: ['root'],
33 docked: [(variant === 'permanent' || variant === 'persistent') && 'docked'],
34 modal: ['modal'],
35 paper: ['paper', `paperAnchor${capitalize(anchor)}`, variant !== 'temporary' && `paperAnchorDocked${capitalize(anchor)}`]
36 };
37 return composeClasses(slots, getDrawerUtilityClass, classes);
38};
39const DrawerRoot = styled(Modal, {
40 name: 'MuiDrawer',
41 slot: 'Root',
42 overridesResolver
43})(memoTheme(({
44 theme
45}) => ({
46 zIndex: (theme.vars || theme).zIndex.drawer
47})));
48const DrawerDockedRoot = styled('div', {
49 shouldForwardProp: rootShouldForwardProp,
50 name: 'MuiDrawer',
51 slot: 'Docked',
52 skipVariantsResolver: false,
53 overridesResolver
54})({
55 flex: '0 0 auto'
56});
57const DrawerPaper = styled(Paper, {
58 name: 'MuiDrawer',
59 slot: 'Paper',
60 overridesResolver: (props, styles) => {
61 const {
62 ownerState
63 } = props;
64 return [styles.paper, styles[`paperAnchor${capitalize(ownerState.anchor)}`], ownerState.variant !== 'temporary' && styles[`paperAnchorDocked${capitalize(ownerState.anchor)}`]];
65 }
66})(memoTheme(({
67 theme
68}) => ({
69 overflowY: 'auto',
70 display: 'flex',
71 flexDirection: 'column',
72 height: '100%',
73 flex: '1 0 auto',
74 zIndex: (theme.vars || theme).zIndex.drawer,
75 // Add iOS momentum scrolling for iOS < 13.0
76 WebkitOverflowScrolling: 'touch',
77 // temporary style
78 position: 'fixed',
79 top: 0,
80 // We disable the focus ring for mouse, touch and keyboard users.
81 // At some point, it would be better to keep it for keyboard users.
82 // :focus-ring CSS pseudo-class will help.
83 outline: 0,
84 variants: [{
85 props: {
86 anchor: 'left'
87 },
88 style: {
89 left: 0
90 }
91 }, {
92 props: {
93 anchor: 'top'
94 },
95 style: {
96 top: 0,
97 left: 0,
98 right: 0,
99 height: 'auto',
100 maxHeight: '100%'
101 }
102 }, {
103 props: {
104 anchor: 'right'
105 },
106 style: {
107 right: 0
108 }
109 }, {
110 props: {
111 anchor: 'bottom'
112 },
113 style: {
114 top: 'auto',
115 left: 0,
116 bottom: 0,
117 right: 0,
118 height: 'auto',
119 maxHeight: '100%'
120 }
121 }, {
122 props: ({
123 ownerState
124 }) => ownerState.anchor === 'left' && ownerState.variant !== 'temporary',
125 style: {
126 borderRight: `1px solid ${(theme.vars || theme).palette.divider}`
127 }
128 }, {
129 props: ({
130 ownerState
131 }) => ownerState.anchor === 'top' && ownerState.variant !== 'temporary',
132 style: {
133 borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`
134 }
135 }, {
136 props: ({
137 ownerState
138 }) => ownerState.anchor === 'right' && ownerState.variant !== 'temporary',
139 style: {
140 borderLeft: `1px solid ${(theme.vars || theme).palette.divider}`
141 }
142 }, {
143 props: ({
144 ownerState
145 }) => ownerState.anchor === 'bottom' && ownerState.variant !== 'temporary',
146 style: {
147 borderTop: `1px solid ${(theme.vars || theme).palette.divider}`
148 }
149 }]
150})));
151const oppositeDirection = {
152 left: 'right',
153 right: 'left',
154 top: 'down',
155 bottom: 'up'
156};
157export function isHorizontal(anchor) {
158 return ['left', 'right'].includes(anchor);
159}
160export function getAnchor({
161 direction
162}, anchor) {
163 return direction === 'rtl' && isHorizontal(anchor) ? oppositeDirection[anchor] : anchor;
164}
165
166/**
167 * The props of the [Modal](/material-ui/api/modal/) component are available
168 * when `variant="temporary"` is set.
169 */
170const Drawer = /*#__PURE__*/React.forwardRef(function Drawer(inProps, ref) {
171 const props = useDefaultProps({
172 props: inProps,
173 name: 'MuiDrawer'
174 });
175 const theme = useTheme();
176 const isRtl = useRtl();
177 const defaultTransitionDuration = {
178 enter: theme.transitions.duration.enteringScreen,
179 exit: theme.transitions.duration.leavingScreen
180 };
181 const {
182 anchor: anchorProp = 'left',
183 BackdropProps,
184 children,
185 className,
186 elevation = 16,
187 hideBackdrop = false,
188 ModalProps: {
189 BackdropProps: BackdropPropsProp,
190 ...ModalProps
191 } = {},
192 onClose,
193 open = false,
194 PaperProps = {},
195 SlideProps,
196 // eslint-disable-next-line react/prop-types
197 TransitionComponent = Slide,
198 transitionDuration = defaultTransitionDuration,
199 variant = 'temporary',
200 ...other
201 } = props;
202
203 // Let's assume that the Drawer will always be rendered on user space.
204 // We use this state is order to skip the appear transition during the
205 // initial mount of the component.
206 const mounted = React.useRef(false);
207 React.useEffect(() => {
208 mounted.current = true;
209 }, []);
210 const anchorInvariant = getAnchor({
211 direction: isRtl ? 'rtl' : 'ltr'
212 }, anchorProp);
213 const anchor = anchorProp;
214 const ownerState = {
215 ...props,
216 anchor,
217 elevation,
218 open,
219 variant,
220 ...other
221 };
222 const classes = useUtilityClasses(ownerState);
223 const drawer = /*#__PURE__*/_jsx(DrawerPaper, {
224 elevation: variant === 'temporary' ? elevation : 0,
225 square: true,
226 ...PaperProps,
227 className: clsx(classes.paper, PaperProps.className),
228 ownerState: ownerState,
229 children: children
230 });
231 if (variant === 'permanent') {
232 return /*#__PURE__*/_jsx(DrawerDockedRoot, {
233 className: clsx(classes.root, classes.docked, className),
234 ownerState: ownerState,
235 ref: ref,
236 ...other,
237 children: drawer
238 });
239 }
240 const slidingDrawer = /*#__PURE__*/_jsx(TransitionComponent, {
241 in: open,
242 direction: oppositeDirection[anchorInvariant],
243 timeout: transitionDuration,
244 appear: mounted.current,
245 ...SlideProps,
246 children: drawer
247 });
248 if (variant === 'persistent') {
249 return /*#__PURE__*/_jsx(DrawerDockedRoot, {
250 className: clsx(classes.root, classes.docked, className),
251 ownerState: ownerState,
252 ref: ref,
253 ...other,
254 children: slidingDrawer
255 });
256 }
257
258 // variant === temporary
259 return /*#__PURE__*/_jsx(DrawerRoot, {
260 BackdropProps: {
261 ...BackdropProps,
262 ...BackdropPropsProp,
263 transitionDuration
264 },
265 className: clsx(classes.root, classes.modal, className),
266 open: open,
267 ownerState: ownerState,
268 onClose: onClose,
269 hideBackdrop: hideBackdrop,
270 ref: ref,
271 ...other,
272 ...ModalProps,
273 children: slidingDrawer
274 });
275});
276process.env.NODE_ENV !== "production" ? Drawer.propTypes /* remove-proptypes */ = {
277 // ┌────────────────────────────── Warning ──────────────────────────────┐
278 // │ These PropTypes are generated from the TypeScript type definitions. │
279 // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
280 // └─────────────────────────────────────────────────────────────────────┘
281 /**
282 * Side from which the drawer will appear.
283 * @default 'left'
284 */
285 anchor: PropTypes.oneOf(['bottom', 'left', 'right', 'top']),
286 /**
287 * @ignore
288 */
289 BackdropProps: PropTypes.object,
290 /**
291 * The content of the component.
292 */
293 children: PropTypes.node,
294 /**
295 * Override or extend the styles applied to the component.
296 */
297 classes: PropTypes.object,
298 /**
299 * @ignore
300 */
301 className: PropTypes.string,
302 /**
303 * The elevation of the drawer.
304 * @default 16
305 */
306 elevation: integerPropType,
307 /**
308 * If `true`, the backdrop is not rendered.
309 * @default false
310 */
311 hideBackdrop: PropTypes.bool,
312 /**
313 * Props applied to the [`Modal`](https://mui.com/material-ui/api/modal/) element.
314 * @default {}
315 */
316 ModalProps: PropTypes.object,
317 /**
318 * Callback fired when the component requests to be closed.
319 * The `reason` parameter can optionally be used to control the response to `onClose`.
320 *
321 * @param {object} event The event source of the callback.
322 * @param {string} reason Can be: `"escapeKeyDown"`, `"backdropClick"`.
323 */
324 onClose: PropTypes.func,
325 /**
326 * If `true`, the component is shown.
327 * @default false
328 */
329 open: PropTypes.bool,
330 /**
331 * Props applied to the [`Paper`](https://mui.com/material-ui/api/paper/) element.
332 * @default {}
333 */
334 PaperProps: PropTypes.object,
335 /**
336 * Props applied to the [`Slide`](https://mui.com/material-ui/api/slide/) element.
337 */
338 SlideProps: PropTypes.object,
339 /**
340 * The system prop that allows defining system overrides as well as additional CSS styles.
341 */
342 sx: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.bool])), PropTypes.func, PropTypes.object]),
343 /**
344 * The duration for the transition, in milliseconds.
345 * You may specify a single timeout for all transitions, or individually with an object.
346 * @default {
347 * enter: theme.transitions.duration.enteringScreen,
348 * exit: theme.transitions.duration.leavingScreen,
349 * }
350 */
351 transitionDuration: PropTypes.oneOfType([PropTypes.number, PropTypes.shape({
352 appear: PropTypes.number,
353 enter: PropTypes.number,
354 exit: PropTypes.number
355 })]),
356 /**
357 * The variant to use.
358 * @default 'temporary'
359 */
360 variant: PropTypes.oneOf(['permanent', 'persistent', 'temporary'])
361} : void 0;
362export default Drawer;
\No newline at end of file