В библиотеке MUI (Material-UI) управление раскрытием панелей реализуется с помощью компонента Accordion. Этот компонент предоставляет удобный способ создания разворачивающихся блоков контента, где пользователь может открывать и закрывать секции для отображения дополнительной информации. Контроль раскрытия панелей может быть реализован как неуправляемый компонент (состояние внутреннее), так и управляемый компонент (состояние контролируется извне).
Accordion имеет следующие ключевые свойства:
expanded – булево значение, определяющее, раскрыта ли
панель. Используется для управляемого компонента.onChange – функция-обработчик, вызываемая при изменении
состояния панели.disabled – блокирует раскрытие панели.TransitionProps – свойства для управления анимацией
раскрытия.Пример простого контролируемого Accordion:
import React, { useState } from 'react';
import Accordion from '@mui/material/Accordion';
import AccordionSummary from '@mui/material/AccordionSummary';
import AccordionDetails from '@mui/material/AccordionDetails';
import Typography from '@mui/material/Typography';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
function ControlledAccordion() {
const [expanded, setExpanded] = useState(false);
const handleChange = (panel) => (event, isExpanded) => {
setExpanded(isExpanded ? panel : false);
};
return (
<div>
<Accordion expanded={expanded === 'panel1'} onCha nge={handleChange('panel1')}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography>Панель 1</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography>Контент панели 1</Typography>
</AccordionDetails>
</Accordion>
<Accordion expanded={expanded === 'panel2'} onCha nge={handleChange('panel2')}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography>Панель 2</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography>Контент панели 2</Typography>
</AccordionDetails>
</Accordion>
</div>
);
}
В данном примере expanded задаёт активную панель, а
handleChange переключает состояние раскрытия. Используется
логика «только одна панель открыта одновременно», что часто требуется в
интерфейсах.
Если нужно разрешить пользователю открывать сразу несколько панелей, состояние можно хранить в виде объекта или массива:
const [expandedPanels, setExpandedPanels] = useState([]);
const handleMultiChange = (panel) => (event, isExpanded) => {
setExpandedPanels(prev =>
isExpanded
? [...prev, panel]
: prev.filter(p => p !== panel)
);
};
Каждая панель проверяет, присутствует ли её идентификатор в массиве
expandedPanels:
<Accordion
expanded={expandedPanels.includes('panel1')}
onCha nge={handleMultiChange('panel1')}
>
Такой подход позволяет реализовать интерфейсы с множественными раскрытиями, например, FAQ или сложные фильтры.
MUI использует компонент Collapse для анимации
раскрытия. Через свойство TransitionProps можно настраивать
длительность и тип анимации:
<Accordion
TransitionProps={{ timeout: 500 }}
>
Также можно полностью контролировать и кастомизировать иконку
раскрытия через свойство expandIcon в
AccordionSummary:
<AccordionSummary expandIcon={<CustomIcon />}>
Для стилизации отдельных частей панели применяются классы и sx-параметры:
sx позволяет писать инлайн-стили в формате системы
MUI.classes используется для точечной замены стандартных
стилей, например, root, expanded,
summary, details.Пример:
<Accordion
sx={{
border: '1px solid #ccc',
borderRadius: 2,
'&.Mui-expanded': {
backgroundColor: '#f0f0f0',
}
}}
>
Часто требуется полностью контролировать состояние раскрытия панелей
из родительского компонента, например, для синхронизации с сервером или
локальным хранилищем. В этом случае expanded и
onChange используют пропсы, передаваемые извне:
<Accordion
expanded={props.expandedPanels.includes('panel1')}
onCha nge={props.handlePanelChange('panel1')}
>
Такое решение обеспечивает единый источник правды для состояния, что особенно важно в крупных приложениях с множественными компонентами.
Если количество панелей заранее неизвестно, удобно создавать их динамически через массив объектов:
const panels = [
{ id: 'panel1', title: 'Панель 1', content: 'Контент 1' },
{ id: 'panel2', title: 'Панель 2', content: 'Контент 2' },
];
panels.map(panel => (
<Accordion
key={panel.id}
expanded={expanded === panel.id}
onCha nge={handleChange(panel.id)}
>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography>{panel.title}</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography>{panel.content}</Typography>
</AccordionDetails>
</Accordion>
));
Такой подход повышает масштабируемость интерфейса и упрощает поддержку кода.
expanded и onChange.TransitionProps, sx и
classes.Контроль раскрытия панелей в MUI сочетает простоту использования с гибкостью, обеспечивая полный контроль над поведением компонентов и внешним видом.