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

Listbox

Listbox — всегда видимый список, в котором выбирают один или несколько вариантов, как в нативном select с size.

Обзор

Собственных переменных у Listbox нет. Список — простая прокручиваемая поверхность на глобальных токенах, а его строки — элементы Option, которые стилизуются переменными --option-*. Высота, ширина и рамка задаются списку обычным CSS.

Публичные CSS-переменные

Эти переменные принадлежат строкам-вариантам, которые рендерит ListboxOption.

Pickup point
Courier to the door
Parcel locker
ПеременнаяЗначениеВлияет на
Высота строки, задаётся через sizeListboxOption
В этом состоянии изменений не видно
Скругление строки как доля её высотыListboxOption
В этом состоянии изменений не видно
Цвет текстаListboxOption
В этом состоянии изменений не видно
Фон по умолчаниюListboxOption
В этом состоянии изменений не видно
Фон при наведении и у активного вариантаListboxOption
В этом состоянии изменений не видно
Фон при нажатииListboxOption
В этом состоянии изменений не видно

Сам список читает глобальные токены:

ТокенГде используетсяНазначение
--surface-secondaryListboxФон списка
--focus-colorListboxКольцо фокуса списка

Переменные частей

Listbox

Задаётся в packages/ui/src/Listbox/style.module.css. Список — flex-колонка с padding: var(--spacing-4), gap: var(--spacing-3), border-radius: var(--spacing-8) и overflow: auto. У него нет рамки и нет ограничения высоты: он растёт вместе с вариантами, пока вы не зададите height или max-height, а дальше прокручивается.

ListboxGroup

Flex-колонка с тем же gap: var(--spacing-3), что и у списка, поэтому варианты в группах и без них идут в одном ритме. Своей поверхности и стиля заголовка у группы нет — заголовок оформляйте сами.

ListboxOption

ListboxOption объявляет все переменные --option-* на самой строке, поэтому значения, заданные на Listbox, до неё не доходят. Переопределяйте их селектором, который нацелен на строки, или через style у каждого варианта.

size на списке задаёт --option-height и шрифтовую шкалу всех строк, а size на варианте его переопределяет:

  • xs: var(--spacing-16)
  • sm: var(--spacing-18)
  • md: var(--spacing-21), по умолчанию
  • lg: var(--spacing-24)
  • xl: var(--spacing-26)

Высота фиксированная, поэтому строкам с двумя строками содержимого нужен height: 'auto'.

Взаимодействие состояний и вариантов

  • aria-selected='true' переключает строку на основные цвета.
  • data-active='true' отмечает вариант, на который список указывает через aria-activedescendant, и даёт ему фон наведения, чтобы позиция с клавиатуры была видна, пока фокус на списке.
  • :focus-visible на списке рисует обводку 2px цветом --focus-color. Сами варианты фокус никогда не получают.
  • aria-disabled='true' на строке включает цвет отключённого текста и курсор not-allowed; disabled на списке ставит его всем строкам.
  • С multiple соседние выбранные строки сливаются: смежные углы становятся прямыми, а зазор между строками заполняется, так что серия выбранных вариантов читается как один блок.

Значения размера, выбранного и отключённого состояний лежат в :where(), который не добавляет специфичности к классу строки, поэтому их переопределяет ваш селектор из двух классов или атрибутов.

Примеры

Выбранные строки другого цвета

Класс на списке нацеливается на его строки и переназначает цвета выбранного состояния и скругление, не трогая невыбранные строки.

selected-rows-color.tsx · 18 строк
import { Listbox, ListboxOption } from '@vega-ui/react';
import './examples.css';

export default function SelectedRowsColor() {
  return (
    <Listbox
      aria-label='Reminder before the meeting'
      defaultValue='10'
      className='listbox-accent'
      style={{ width: '100%', maxWidth: 280, border: '1px solid var(--separator-opaque)' }}
    >
      <ListboxOption value='0'>At the start time</ListboxOption>
.listbox-accent [role='option'][aria-selected='true'] {
  --option-background-color: var(--color-green-accent-800);
  --option-background-color-hover: var(--color-green-accent-900);
  --option-background-color-active: var(--color-green-accent-1000);
}

.listbox-accent [role='option'] {
  --option-br-ratio: 0.5;
}

Компактные строки в списке фиксированной высоты

size='sm' делает все строки ниже, а maxHeight превращает список в прокручиваемую область, которая держит активный вариант в поле зрения.

many-options.tsx · 32 строки
import { Listbox, ListboxOption, Text } from '@vega-ui/react';
import { useState } from 'react';

const builds = Array.from({ length: 300 }, (_, index) => {
  const number = 1480 - index;
  const branch = index % 7 === 0 ? 'release/4.2' : 'main';
  return { value: number, label: `Build ${number}`, branch };
});

export default function ManyOptions() {
  const [build, setBuild] = useState<number | null>(1480);

Слитые выбранные строки

С multiple выберите соседние начинки — выбранные строки сольются в один блок.

several-choices.tsx · 37 строк
import { Button, Listbox, ListboxOption, Text } from '@vega-ui/react';
import { useState } from 'react';

const toppings = [
  { value: 'cheese', label: 'Extra mozzarella', price: 1.5 },
  { value: 'mushrooms', label: 'Mushrooms', price: 1 },
  { value: 'olives', label: 'Black olives', price: 1 },
  { value: 'pepperoni', label: 'Pepperoni', price: 2 },
  { value: 'jalapenos', label: 'Jalapeños', price: 0.5 },
];

export default function SeveralChoices() {

Что не переопределять

  • outline списка в :focus-visible: это единственный индикатор фокуса, потому что варианты фокус не получают
  • фон строк с data-active='true': по нему пользователи клавиатуры видят, где находятся
  • цвета выбранного состояния так, что выбранные и невыбранные строки становятся похожи
  • overflow списка: без него список с ограничением высоты перестаёт прокручиваться, и активный вариант может уйти из поля зрения