Collapse для раскрывающегося контента

Компонент Collapse из библиотеки MUI предназначен для создания анимации сворачивания и разворачивания контента. Он управляет видимостью дочерних элементов, плавно изменяя их высоту. Основное свойство компонента — in, которое принимает булево значение и определяет, открыт или закрыт блок.

Пример базового использования:

import React, { useState } from 'react';
import { Collapse, Button, Box } from '@mui/material';

function SimpleCollapse() {
  const [open, setOpen] = useState(false);

  return (
    <Box>
      <Button onCl ick={() => setOpen(!open)}>
        {open ? 'Скрыть' : 'Показать'}
      </Button>
      <Collapse in={open}>
        <Box sx={{ padding: 2, bgcolor: 'grey.200' }}>
          Содержимое, которое раскрывается
        </Box>
      </Collapse>
    </Box>
  );
}

Ключевые моменты:

  • Свойство in управляет состоянием раскрытия.
  • Компонент плавно анимирует изменение высоты.
  • Любой контент внутри Collapse сохраняет своё состояние при сворачивании.

Свойства компонента Collapse

  1. in — булево значение, определяет, открыт или закрыт блок.
  2. timeout — время анимации в миллисекундах или один из предустановленных вариантов 'auto', 'enter', 'exit'. 'auto' вычисляет длительность в зависимости от высоты содержимого.
  3. collapsedSize — задаёт высоту компонента в свернутом состоянии (по умолчанию 0). Полезно для частичного сворачивания, например, для создания мини-превью.
  4. orientation — направление анимации: 'vertical' (по умолчанию) или 'horizontal'. Позволяет анимировать раскрытие по горизонтали.
  5. sx — стандартное MUI свойство для стилизации, совместимо с темой и системой MUI.

Пример использования collapsedSize:

<Collapse in={open} collapsedSize={40}>
  <Box sx={{ bgcolor: 'lightblue', padding: 1 }}>
    Контент частично виден при свернутом состоянии
  </Box>
</Collapse>

Горизонтальное раскрытие

По умолчанию анимация происходит вертикально, но с помощью свойства orientation можно переключить её на горизонтальную. Это полезно для боковых панелей или меню.

<Collapse in={open} orientation="horizontal">
  <Box sx={{ width: 200, bgcolor: 'secondary.main', padding: 1 }}>
    Горизонтальное раскрытие
  </Box>
</Collapse>

Особенности:

  • Для горизонтального режима важно задавать ширину (width) содержимого.
  • Анимация по ширине менее распространена, поэтому часто требуется дополнительная стилизация для плавности.

Комбинирование Collapse с другими компонентами

Collapse часто используется совместно с List, Accordion, Card и другими компонентами для создания интерактивных интерфейсов.

Пример раскрывающегося списка:

import { List, ListItem, ListItemText } from '@mui/material';

function CollapsibleList() {
  const [open, setOpen] = useState(false);

  return (
    <List>
      <ListItem button onCl ick={() => setOpen(!open)}>
        <ListItemText primary="Раздел 1" />
      </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>
  );
}

Особенности:

  • unmountOnExit удаляет содержимое из DOM при сворачивании, что может уменьшить нагрузку на страницу.
  • timeout="auto" позволяет автоматически подбирать скорость анимации.

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

При использовании большого количества компонентов Collapse стоит учитывать несколько моментов:

  1. unmountOnExit — полезно для списков с динамическим содержимым, чтобы не держать лишние элементы в DOM.
  2. lazy loading — загружать содержимое только при разворачивании.
  3. memoization — если содержимое сложное, оборачивать в React.memo или useMemo, чтобы избежать лишних ререндеров.

Пример с ленивой загрузкой:

<Collapse in={open} unmountOnExit>
  {open && <HeavyContent />}
</Collapse>

Анимация и кастомизация

MUI позволяет изменять параметры анимации через timeout и easing:

<Collapse
  in={open}
  timeout={500}
  sx={{
    transition: theme => theme.transitions.create('height', {
      duration: 500,
      easing: theme.transitions.easing.easeInOut,
    }),
  }}
>
  <Box sx={{ padding: 2, bgcolor: 'success.light' }}>
    Анимированный контент
  </Box>
</Collapse>

Рекомендации:

  • Использовать стандартные easing функции MUI для согласованного поведения.
  • Для сложных анимаций можно комбинировать Collapse с Grow или Fade.

Полезные паттерны использования

  1. Раскрывающиеся панели внутри Card — создание интерактивных карточек с дополнительной информацией.
  2. Аккордеонные меню — реализация вложенных списков с плавным разворачиванием.
  3. Пошаговые формы — скрытие и раскрытие частей формы в зависимости от прогресса пользователя.
  4. Тултипы и подсказки — комбинирование с Popover или Tooltip для раскрывающихся пояснений.

Важные советы

  • Высота содержимого: Collapse плавно анимирует только высоту/ширину. Если содержимое меняет размер динамически, анимация может быть прервана.
  • Состояние компонента: Свойство in должно быть привязано к управляемому состоянию, чтобы компоненты оставались предсказуемыми.
  • Стилизация: Использовать sx и встроенные темы для соблюдения дизайна и единообразия интерфейса.

Эффективное применение Collapse позволяет создавать динамичные, отзывчивые интерфейсы с минимальными усилиями и плавной анимацией.