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

Popover

Popover — составной компонент для немодального плавающего содержимого, привязанного к триггеру.

Паттерны

Быстрые действия

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

  • Несколько небольших действий должны оставаться привязанными к одному триггеру.

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

  • Держите содержимое компактным.
  • Предпочитайте списки действий или короткие сгруппированные команды содержимому с длинными абзацами.
  • Контролируйте open и закрывайте поповер, когда выполняется действие: сам он не закроется.

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

  • Быстрый контекстный доступ.
  • Легко перегрузить слишком большим числом действий.
menu-closes-on-select.tsx · 46 строк
import { useState } from 'react';
import {
  Button,
  Popover,
  PopoverContent,
  PopoverTrigger,
  Text,
} from '@vega-ui/react';

const actions = ['Duplicate', 'Move to folder', 'Download as PDF', 'Archive'];

export default function MenuClosesOnSelect() {

Переименование на месте

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

  • Маленькая форма должна оставаться рядом со своим триггером.

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

  • Делайте валидацию и отправку простыми.

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

  • Эффективно для небольших правок.
  • Слишком мало места для длинных форм.
inline-rename-flow.tsx · 58 строк
import { useId, useState, type CSSProperties, type FormEvent } from 'react';
import {
  Button,
  Heading,
  Icon,
  IconButton,
  Label,
  Popover,
  PopoverContent,
  PopoverTrigger,
  TextField,
  TextFieldInput,

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

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

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

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

  • Держите содержимое узким и легко просматриваемым.
  • Не превращайте меню в полноценный экран настроек.

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

  • Сильная пространственная связь с триггером.
  • Хуже подходит, когда в содержимом появляется много полей формы или деструктивные действия.
anchored-user-menu.tsx · 35 строк
import {
  Button,
  Popover,
  PopoverContent,
  PopoverTrigger,
  Separator,
  Text,
} from '@vega-ui/react';

export default function AnchoredUserMenu() {
  return (
    <Popover role='dialog' placement='bottom-end'>

Сравнение

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

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

Popover или Tooltip

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

  • содержимое богаче простой подсказки
  • оно может содержать действия или элементы управления формы

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

  • содержимое — исключительно дополнительная информация

Popover или Dialog

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

  • взаимодействие немодальное и лёгкое
  • пользователь должен сохранять контекст страницы и не попадать в модальный сценарий с ловушкой фокуса

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

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

Popover или Drawer

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

  • содержимое короткое и привязанное

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

  • содержимое разрастается в сценарий боковой панели

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

  • содержимое контекстное и короткое
  • интерфейс должен оставаться немодальным
  • привязанное расположение — часть модели взаимодействия

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

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

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

Поповер кажется слишком тяжёлым

Симптом

Технически содержимое работает, но оверлей кажется слишком большим или модальным.

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

Задаче место в Dialog или Drawer.

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

  • Оцените объём содержимого и критичность задачи.

Исправление

  • Переключитесь на более строгий оверлей, когда сценарий перестаёт быть лёгким.

Расположение ломается в прокручиваемых контейнерах

Симптом

Плавающий слой выглядит оторванным от триггера.

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

Не протестированы реальный контейнер или стек оверлеев.

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

  • Поместите поповер в реальную прокручиваемую или обрезающую раскладку.

Исправление

  • Повторно протестируйте точную структуру контейнеров из продакшена.
  • PopoverContent рендерится в верхнем слое, поэтому overflow и z-index у предков не обрезают и не перекрывают его; ищите проблему в расположении.

Вложенные поповеры сбивают с толку

Симптом

С поповерами внутри поповеров состояние открытия и порядок фокуса становятся неясными.

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

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

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

  • Протестируйте открытие и закрытие вложенных поповеров.

Исправление

  • Упростите сценарий или переключитесь на более крупный паттерн оверлея.

Смысл триггера непонятен без поповера

Симптом

Пользователи понимают триггер только после открытия поповера.

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

Триггер опирается на плавающее содержимое как на основную подпись или объяснение.

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

  • Скройте поповер и проверьте, понятен ли триггер сам по себе.
  • Протестируйте сценарии с клавиатурой и скринридером.

Исправление

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

Поповер не открывается с собственного триггера

Симптом

Клик по собственному дочернему элементу PopoverTrigger asChild ничего не делает.

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

Дочерний элемент не рендерит <button>, поэтому нативный popovertarget не действует.

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

  • Посмотрите элемент триггера и убедитесь, что это <button> с popovertarget.

Исправление

  • Используйте в качестве дочернего элемента asChild компонент Button или другой компонент, который рендерит <button>.