В библиотеке MUI для работы со списками используется компонент
List, который позволяет создавать
упорядоченные и неупорядоченные элементы интерфейса с удобной структурой
и стилизацией. Вложенные списки реализуются с помощью сочетания
компонентов ListItem,
ListItemText,
Collapse и
List внутри других
ListItem.
List Корневой компонент, содержащий
элементы списка. Поддерживает вертикальную и горизонтальную ориентацию,
а также возможность применения стилей через пропсы sx или
className.
ListItem Элемент списка. Может быть
интерактивным (с button={true}) или статическим. Позволяет
добавлять иконки, чекбоксы и вторичные тексты.
ListItemText Компонент для
отображения текста в элементе списка. Поддерживает primary
и secondary тексты, что удобно для вложенных
структур.
Collapse Используется для скрытия и
отображения вложенных списков с анимацией. Часто применяется вместе с
состоянием компонента (useState) для контроля
раскрытия.
import React, { useState } from 'react';
import { List, ListItem, ListItemText, Collapse, ListItemIcon } from '@mui/material';
import InboxIcon from '@mui/icons-material/Inbox';
import ExpandLess from '@mui/icons-material/ExpandLess';
import ExpandMore from '@mui/icons-material/ExpandMore';
function NestedListExample() {
const [open, setOpen] = useState(false);
const handleClick = () => {
setOpen(!open);
};
return (
<List sx={{ width: '100%', maxWidth: 360, bgcolor: 'background.paper' }}>
<ListItem button onCl ick={handleClick}>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary="Папка 1" />
{open ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={open} timeout="auto" unmountOnExit>
<List component="div" disablePadding>
<ListItem sx={{ pl: 4 }}>
<ListItemText primary="Файл 1-1" />
</ListItem>
<ListItem sx={{ pl: 4 }}>
<ListItemText primary="Файл 1-2" />
</ListItem>
</List>
</Collapse>
</List>
);
}
export default NestedListExample;
Управление состоянием раскрытия Для каждого
вложенного списка нужно использовать отдельное состояние. При
динамическом рендеринге списков удобно хранить объект или массив флагов
open для разных элементов.
Отступы и стилизация Для создания визуальной
иерархии используют sx={{ pl: 4 }}, где pl —
padding-left. Значение увеличивается с каждым уровнем
вложенности.
Иконки для раскрытия/сворачивания Компоненты
ExpandLess и
ExpandMore помогают пользователю понимать
текущий статус вложенного списка. Их можно динамически менять на основе
состояния.
Производительность Для больших списков
рекомендуется использовать unmountOnExit в компоненте
Collapse, чтобы скрытые элементы не рендерились в DOM до
раскрытия.
В MUI легко строить списки на основе данных из массива объектов:
const data = [
{
id: 1,
name: 'Папка A',
children: [
{ id: 11, name: 'Файл A1' },
{ id: 12, name: 'Файл A2' },
],
},
{
id: 2,
name: 'Папка B',
children: [
{ id: 21, name: 'Файл B1' },
{ id: 22, name: 'Файл B2' },
],
},
];
Рекурсивный рендер элементов:
function RecursiveList({ items }) {
const [openIds, setOpenIds] = useState([]);
const handleClick = (id) => {
setOpenIds((prev) =>
prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id]
);
};
return (
<List>
{items.map((item) => (
<div key={item.id}>
<ListItem button onCl ick={() => handleClick(item.id)}>
<ListItemText primary={item.name} />
{item.children ? (openIds.includes(item.id) ? <ExpandLess /> : <ExpandMore />) : null}
</ListItem>
{item.children && (
<Collapse in={openIds.includes(item.id)} timeout="auto" unmountOnExit>
<RecursiveList items={item.children} />
</Collapse>
)}
</div>
))}
</List>
);
}
ARIA-атрибуты Для вложенных списков полезно
использовать aria-expanded, aria-controls на
кнопках, управляющих раскрытием, чтобы улучшить доступность.
Клавиатурная навигация Элементы с
button={true} автоматически получают возможность навигации
с клавиатуры, что важно для пользователей с ограничениями.
Согласованность дизайна Следует использовать одинаковые отступы, размеры шрифтов и иконки на всех уровнях вложенности, чтобы интерфейс оставался предсказуемым и читабельным.
Анимация раскрытия Collapse
добавляет плавность при открытии и закрытии списков, предотвращая резкое
изменение интерфейса и улучшая пользовательский опыт.
Вложенные списки MUI обеспечивают гибкую структуру для организации элементов интерфейса, позволяют легко управлять состояниями раскрытия и поддерживают высокую производительность даже при больших объемах данных.