Обзор
Собственных переменных у Listbox нет. Список — простая прокручиваемая поверхность на глобальных токенах, а его строки — элементы Option, которые стилизуются переменными --option-*. Высота, ширина и рамка задаются списку обычным CSS.
Публичные CSS-переменные
Эти переменные принадлежат строкам-вариантам, которые рендерит ListboxOption.
| Переменная | Значение | Влияет на |
|---|---|---|
Высота строки, задаётся через sizeListboxOption | В этом состоянии изменений не видно | |
Скругление строки как доля её высотыListboxOption | В этом состоянии изменений не видно | |
Цвет текстаListboxOption | В этом состоянии изменений не видно | |
Фон по умолчаниюListboxOption | В этом состоянии изменений не видно | |
Фон при наведении и у активного вариантаListboxOption | В этом состоянии изменений не видно | |
Фон при нажатииListboxOption | В этом состоянии изменений не видно |
Сам список читает глобальные токены:
| Токен | Где используется | Назначение |
|---|---|---|
--surface-secondary | Listbox | Фон списка |
--focus-color | Listbox | Кольцо фокуса списка |
Переменные частей
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(), который не добавляет специфичности к классу строки, поэтому их переопределяет ваш селектор из двух классов или атрибутов.
Примеры
Выбранные строки другого цвета
Класс на списке нацеливается на его строки и переназначает цвета выбранного состояния и скругление, не трогая невыбранные строки.
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 превращает список в прокручиваемую область, которая держит активный вариант в поле зрения.
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 выберите соседние начинки — выбранные строки сольются в один блок.
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списка: без него список с ограничением высоты перестаёт прокручиваться, и активный вариант может уйти из поля зрения