Перейти к содержимому
v2.5.0
English
Русский
Документация

Collapsible

Collapsible — составной компонент для одной раскрывающейся области с триггером и поверхностью содержимого.

Паттерны

Блок расширенных фильтров

Когда использовать:

  • Один второстепенный блок формы должен оставаться скрытым, пока не понадобится.

Заметки по композиции:

  • Триггер должен явно говорить, что станет доступно после раскрытия.
  • Аккуратно обращайтесь со скрытыми ошибками формы, если раздел можно свернуть.

Компромиссы:

  • Основная форма остаётся компактной.
  • При слабых подписях может слишком хорошо прятать сложность или валидацию.
advanced-filters.tsx · 64 строки
import { useState } from 'react';
import {
  Button,
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
  Label,
  Text,
  TextField,
  TextFieldInput,
} from '@vega-ui/react';

Встроенная справка

Когда использовать:

  • Один второстепенный блок пояснений должен оставаться рядом с текущим содержимым.

Заметки по композиции:

  • Держите скрытое содержимое достаточно коротким, чтобы триггер по-прежнему воспринимался как встроенное раскрытие.
  • Предпочитайте Collapsible вместо Popover, когда пояснение должно оставаться в потоке документа.

Компромиссы:

  • Сохраняет поток чтения и непрерывность раскладки.
  • Хуже подходит для насыщенного интерактивного содержимого или содержимого с большими задачами.
price-breakdown.tsx · 34 строки
import { Button, Collapsible, CollapsibleContent, CollapsibleTrigger, Text } from '@vega-ui/react';

const lines = [
  { label: 'Team plan · 8 seats × $12', amount: '$96.00' },
  { label: 'Extra storage · 200 GB', amount: '$20.00' },
  { label: 'Annual discount −10%', amount: '−$11.60' },
  { label: 'VAT 19%', amount: '$19.84' },
];

export default function PriceBreakdown() {
  return (
    <div style={{ display: 'grid', gap: 'var(--spacing-6)', width: '100%', maxWidth: 360 }}>

Второстепенные детали в оверлеях

Когда использовать:

  • Выдвижная панель (Drawer) или диалог содержит один необязательный блок деталей, который по умолчанию должен быть скрыт.

Заметки по композиции:

  • Содержимое collapsible должно явно оставаться второстепенным по отношению к основной задаче.
  • Проверяйте динамическую высоту на реалистичном содержимом оверлея.

Компромиссы:

  • Добавляет постепенное раскрытие без ещё одного оверлея.
  • При злоупотреблении плотные панели сложнее просматривать.
error-details-dialog.tsx · 65 строк
import type { CSSProperties } from 'react';
import {
  Button,
  Collapsible,
  CollapsibleContent,
  CollapsibleTrigger,
  Dialog,
  DialogClose,
  DialogContent,
  DialogTrigger,
  Heading,
  Icon,

Сравнение

Быстрое правило выбора

Используйте Collapsible, когда достаточно одного отдельного раскрывающегося раздела.

Collapsible или Accordion

Используйте Collapsible, когда:

  • функции нужен один раскрывающийся блок
  • координация общего состояния между разделами не нужна

Используйте Accordion, когда:

  • несколько связанных разделов должны использовать одну модель состояния открытия

Главный компромисс: Collapsible легче и проще, а Accordion даёт согласованное групповое раскрытие.

Collapsible или Popover

Используйте Collapsible, когда:

  • содержимое должно оставаться встроенным в поток страницы

Используйте Popover, когда:

  • содержимое должно всплывать рядом с триггером

Главный компромисс: Collapsible сохраняет непрерывность раскладки, а Popover даёт более сильное локальное отделение.

Выбирайте этот компонент, когда

  • Достаточно одного раскрывающегося раздела.
  • Содержимое должно оставаться встроенным.
  • Функции нужна только простая модель раскрытия «триггер — содержимое».

Не выбирайте этот компонент, когда

  • Несколько разделов должны координироваться.
  • Содержимое должно вести себя как всплывающий оверлей.
  • Функции нужно модальное поведение или групповая навигация.

Решение проблем

Состояния открытия и скрытия рассинхронизированы

Симптом

Логика родителя видит open, но содержимое ещё в процессе визуального перехода или уже скрыто.

Вероятная причина

Функция считает onChangeOpen и onChangeHidden одним и тем же сигналом жизненного цикла.

Как проверить

  • Логируйте оба колбэка при открытии и закрытии.
  • Сравните визуальное состояние с моментами вызова колбэков.

Исправление

  • Используйте onChangeOpen для владения состоянием.
  • Используйте onChangeHidden, только когда раскладка или измерения зависят от фактической видимости.

Пользовательский триггер перестаёт вести себя как триггер

Симптом

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

Вероятная причина

asChild использован с элементом, который не сохраняет поведение триггера.

Как проверить

  • Изучите отрендеренный элемент триггера.
  • Проверьте клик и поведение клавиатуры, а не только внешний вид.

Исправление

  • Используйте с asChild семантически подходящий дочерний элемент.
  • Триггер должен оставаться явно интерактивным и доступным с клавиатуры.

Динамическая высота содержимого обрезается или прыгает

Симптом

Раскрытое содержимое обрезается, прыгает или странно анимируется при изменении внутреннего содержимого.

Вероятная причина

Раздел проверяли только с коротким статичным содержимым, а не с реальной динамической раскладкой.

Как проверить

  • Раскройте раздел с реалистичным асинхронным содержимым или содержимым переменной высоты.
  • Проверьте переход при росте и сворачивании содержимого.

Исправление

  • Проверяйте на репрезентативном содержимом.
  • Делайте осторожные допущения о переходе высоты, когда содержимое сильно динамическое.