Drawer в библиотеке MUI представляет собой боковую
панель, которая может выезжать слева, справа, сверху или снизу экрана.
Основная цель Drawer — предоставить пользователю навигационное меню или
дополнительные элементы управления, которые не занимают постоянное место
на экране. В MUI Drawer реализован как контролируемый компонент: его
открытие и закрытие управляется через проп open и событие
onClose.
Пример базового использования:
import React, { useState } from 'react';
import Drawer from '@mui/material/Drawer';
import Button from '@mui/material/Button';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemText from '@mui/material/ListItemText';
function BasicDrawer() {
const [open, setOpen] = useState(false);
return (
<>
<Button onCl ick={() => setOpen(true)}>Открыть меню</Button>
<Drawer anchor="left" open={open} onCl ose={() => setOpen(false)}>
<List>
<ListItem button>
<ListItemText primary="Главная" />
</ListItem>
<ListItem button>
<ListItemText primary="Профиль" />
</ListItem>
</List>
</Drawer>
</>
);
}
Здесь anchor=“left” определяет сторону, с которой Drawer выезжает.
Для организации навигации внутри приложения Drawer часто комбинируют с React Router. Каждое меню в Drawer становится ссылкой на отдельный маршрут, что позволяет менять содержимое основного экрана без перезагрузки страницы.
Использование Link из react-router-dom в
списке Drawer:
import { Link } from 'react-router-dom';
<List>
<ListItem button component={Link} to="/">
<ListItemText primary="Главная" />
</ListItem>
<ListItem button component={Link} to="/profile">
<ListItemText primary="Профиль" />
</ListItem>
<ListItem button component={Link} to="/settings">
<ListItemText primary="Настройки" />
</ListItem>
</List>
Проп component={Link} позволяет элементу MUI ListItem
вести себя как React Router Link, сохраняя стили Material UI и
обеспечивая корректную маршрутизацию.
В приложениях с Drawer важно закрывать панель после выбора пункта меню на мобильных устройствах. Это можно реализовать через колбэк, который вызывается при клике на элемент списка:
function handleDrawerClose() {
setOpen(false);
}
<List>
<ListItem button component={Link} to="/" onCl ick={handleDrawerClose}>
<ListItemText primary="Главная" />
</ListItem>
<ListItem button component={Link} to="/profile" onCl ick={handleDrawerClose}>
<ListItemText primary="Профиль" />
</ListItem>
</List>
Такой подход обеспечивает плавный пользовательский опыт, особенно на маленьких экранах.
MUI позволяет кастомизировать внешний вид Drawer через
sx или стилизованные компоненты. Пример с фиксированной
шириной и тёмным фоном:
<Drawer
anchor="left"
open={open}
onCl ose={() => setOpen(false)}
sx={{
'& .MuiDrawer-paper': {
width: 240,
backgroundColor: '#1e1e1e',
color: '#fff',
},
}}
>
<List>
<ListItem button component={Link} to="/">
<ListItemText primary="Главная" />
</ListItem>
<ListItem button component={Link} to="/profile">
<ListItemText primary="Профиль" />
</ListItem>
</List>
</Drawer>
С помощью & .MuiDrawer-paper можно напрямую влиять
на внутренний контейнер Drawer.
Для приложений с большим количеством маршрутов удобно хранить конфигурацию в массиве и рендерить меню через map:
const menuItems = [
{ text: 'Главная', path: '/' },
{ text: 'Профиль', path: '/profile' },
{ text: 'Настройки', path: '/settings' },
];
<List>
{menuItems.map(item => (
<ListItem
button
key={item.text}
component={Link}
to={item.path}
onCl ick={() => setOpen(false)}
>
<ListItemText primary={item.text} />
</ListItem>
))}
</List>
Такой подход упрощает поддержку и добавление новых пунктов меню без дублирования кода.
MUI предоставляет варианты Drawer:
Пример Persistent Drawer:
<Drawer
variant="persistent"
anchor="left"
open={open}
sx={{
width: 240,
flexShrink: 0,
'& .MuiDrawer-paper': { width: 240 },
}}
>
<List>
{menuItems.map(item => (
<ListItem
button
key={item.text}
component={Link}
to={item.path}
>
<ListItemText primary={item.text} />
</ListItem>
))}
</List>
</Drawer>
Для визуальной подсветки текущего маршрута используют хук
useLocation из React Router:
import { useLocation } from 'react-router-dom';
const location = useLocation();
<List>
{menuItems.map(item => (
<ListItem
button
key={item.text}
component={Link}
to={item.path}
selected={location.pathname === item.path}
onCl ick={() => setOpen(false)}
>
<ListItemText primary={item.text} />
</ListItem>
))}
</List>
Проп selected автоматически применяет MUI стили для
активного элемента, улучшая UX.
Для меню с подкатегориями используют компонент Collapse
вместе с List:
import Collapse from '@mui/material/Collapse';
import ExpandLess from '@mui/icons-material/ExpandLess';
import ExpandMore from '@mui/icons-material/ExpandMore';
const [openSubMenu, setOpenSubMenu] = useState(false);
<ListItem button onCl ick={() => setOpenSubMenu(!openSubMenu)}>
<ListItemText primary="Настройки" />
{openSubMenu ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={openSubMenu} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItem button component={Link} to="/settings/profile">
<ListItemText primary="Профиль" />
</ListItem>
<ListItem button component={Link} to="/settings/account">
<ListItemText primary="Аккаунт" />
</ListItem>
</List>
</Collapse>
Использование Collapse позволяет создавать
многоуровневое меню с анимацией и сохранением стиля MUI.
Такое сочетание обеспечивает современный, отзывчивый и гибкий интерфейс навигации для любых React-приложений на MUI.