Вложенные аккордеоны

В библиотеке MUI (Material-UI) компонент Accordion используется для организации контента в сворачиваемые панели. В случае сложных интерфейсов часто требуется реализовать вложенные аккордеоны, когда внутри одной панели находятся другие аккордеоны, обеспечивая структурированное отображение данных.


Основы компонента Accordion

Компонент Accordion состоит из трёх основных частей:

  • Accordion – контейнер аккордеона.
  • AccordionSummary – заголовок, который отображается всегда и служит триггером для открытия панели.
  • AccordionDetails – содержимое панели, которое раскрывается при клике на заголовок.

Простейший пример:

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';


  }
    aria-controls="panel1-content"
    id="panel1-header"
  >
    Заголовок панели
  
  
    Содержимое панели
  

Принципы вложенности

Вложенные аккордеоны создаются путем размещения одного компонента Accordion внутри AccordionDetails другого. Основные моменты, на которые следует обратить внимание:

  1. Отделение состояния – каждая панель должна управлять своим состоянием открытости отдельно, если требуется независимое раскрытие.
  2. Управление идентификаторамиaria-controls и id должны быть уникальными для каждой вложенной панели, чтобы обеспечить корректную доступность.
  3. Стилизация и отступы – внутренние панели рекомендуется смещать визуально с помощью sx={{ ml: 2 }} или аналогичных свойств, чтобы подчеркнуть вложенность.

Пример вложенного аккордеона:


  }>
    Внешний аккордеон
  
  
    Основное содержимое внешнего аккордеона
    
    
      }>
        Внутренний аккордеон 1
      
      
        Содержимое внутреннего аккордеона 1
      
    
    
    
      }>
        Внутренний аккордеон 2
      
      
        Содержимое внутреннего аккордеона 2
      
    

  

Управление состоянием открытости

MUI поддерживает два подхода к управлению состоянием: неуправляемые и управляемые аккордеоны.

Неуправляемые:

  • Раскрытие панели происходит автоматически при клике на AccordionSummary.
  • Не требует явного состояния expanded.

Управляемые:

  • Позволяет контролировать, какая панель открыта в любой момент.
  • Используются пропсы expanded и onChange.

Пример управляемого вложенного аккордеона:

const [expandedOuter, setExpandedOuter] = React.useState(false);
const [expandedInner, setExpandedInner] = React.useState(false);

 setExpandedOuter(!expandedOuter)}>
  }>
    Внешний аккордеон
  
  
     setExpandedInner(!expandedInner)}>
      }>
        Внутренний аккордеон
      
      
        Содержимое внутреннего аккордеона
      
    
  

Продвинутая стилизация

  1. Изменение цвета фона и текста:

  
    Панель с кастомным стилем
  
  1. Изменение отступов для вложенных аккордеонов:

  
    
      Вложенный аккордеон
    
  
  1. Анимация раскрытия: MUI по умолчанию использует плавное раскрытие, но можно изменить продолжительность через проп TransitionProps:

  
    Панель с медленным раскрытием
  

Использование вложенных аккордеонов в списках

Вложенные аккордеоны часто комбинируют с компонентами List и ListItem для создания сложных меню или FAQ. Основные рекомендации:

  • Внутри AccordionDetails можно разместить для упорядочивания контента.
  • Использовать disablePadding для списков, чтобы избежать лишних отступов.

Пример:


  
    FAQ Категория 1
  
  
    
      
        
          
            Вопрос 1
          
          
            Ответ на вопрос 1
          
        
      
      
        
          
            Вопрос 2
          
          
            Ответ на вопрос 2
          
        
      
    
  

Оптимизация производительности

При большом количестве вложенных аккордеонов:

  • Использовать lazy rendering через unmountOnExit в Accordion, чтобы не держать все детали в DOM.
  • Контролировать состояние управления открытости, чтобы избежать лишних перерендеров.

Пример:


  
    Оптимизированная панель