Меню
Меню — список действий, который открывается от кнопки. Выбор пункта выполняет команду; никакое значение не сохраняется. Его ещё называют выпадающим меню, меню действий или меню «ещё».
<tk-menu>
<tk-tooltip slot="trigger" type="label">
<tk-icon-button label="Row actions"><tk-icon name="more-horizontal"></tk-icon></tk-icon-button>
</tk-tooltip>
<tk-menu-item>Rename</tk-menu-item>
<tk-menu-item>Duplicate</tk-menu-item>
<tk-menu-item>Archive</tk-menu-item>
</tk-menu>Анатомия
| Часть | Что это |
|---|---|
| триггер | ваша кнопка в слоте trigger; получает ARIA меню |
| панель | список; ширина 160–288px, по содержимому |
| пункт | tk-menu-item: одна строка высотой от 32px |
| галочка | ✓ у отмеченных пунктов; если хоть один пункт можно отметить, место под неё есть в каждой строке |
| иконка | иконка 16px в слоте icon, по желанию |
| описание | вторая строка, по желанию |
| trailing | подсказка или бейдж в слоте trailing, по желанию |
| разделитель | tk-divider или <hr>: линия между группами |
| группа | tk-menu-group: раздел с заголовком |
| подменю | вложенный tk-menu, открывается от родительской строки |
Пункты
<tk-menu>
<tk-button slot="trigger">View<tk-icon slot="icon-end" name="chevron-down"></tk-icon></tk-button>
<tk-menu-item type="checkbox" checked>Show grid</tk-menu-item>
<tk-menu-item type="checkbox">Snap to grid</tk-menu-item>
<tk-divider></tk-divider>
<tk-menu-group label="Sort by">
<tk-menu-item type="radio" checked>Name</tk-menu-item>
<tk-menu-item type="radio">Date modified</tk-menu-item>
</tk-menu-group>
</tk-menu>command(по умолчанию): выполняет действие и закрывает меню.checkbox: включает или выключает параметр вида, например сетку. Меню остаётся открытым, чтобы можно было поменять несколько.radio: выбирает один вариант в своёмtk-menu-groupи закрывает меню. Кладите радиопункты в группу с заголовком.- Отмеченные пункты меняют то, как выглядит экран (порядок сортировки, видимые колонки,
плотность), и изменение применяется сразу. Значение формы они не хранят: для этого есть
Select . preventDefault()вclickпункта отменяет и смену отметки, и закрытие, например чтобы сначала спросить. Изменениеcheckedиз кода событий не вызывает.
Опасное действие
<tk-menu> <tk-button slot="trigger">Project</tk-button> <tk-menu-item>Rename</tk-menu-item> <tk-menu-item>Duplicate</tk-menu-item> <tk-divider></tk-divider> <tk-menu-item danger>Delete project…</tk-menu-item> </tk-menu>
dangerотмечает действие, которое теряет данные. Работает только на пунктахcommand.- Ставьте его последним, после разделителя.
- Всегда подтверждайте его
диалогом подтверждения ; в конце подписи ставьте «…», чтобы показать, что будет ещё шаг. - Красный означает потерю данных, а не выход: «Покинуть команду» не красная. Называйте действие в подписи.
Иконки, описания и подсказки
<tk-menu> <tk-button slot="trigger">Edit</tk-button> <tk-menu-item><tk-icon slot="icon" name="copy"></tk-icon>Copy<span slot="trailing">⌘C</span></tk-menu-item> <tk-menu-item description="Everyone with the link can view"><tk-icon slot="icon" name="link"></tk-icon>Copy link</tk-menu-item> <tk-menu-item disabled><tk-icon slot="icon" name="trash"></tk-icon>Move to trash</tk-menu-item> </tk-menu>
- Иконки: у всех пунктов или ни у одного. Размер и цвет задаёт меню.
- Описания: редко и коротко; в большинстве меню у пункта одна строка.
- Trailing: подсказка о сочетании клавиш или бейдж, просто текстом. Само сочетание это не настраивает, клавишу подключаете вы. Скринридер читает его после подписи, поэтому коротко. Ничего интерактивного.
Состояния
Наведение и фокус с клавиатуры выглядят одинаково: лёгкая заливка строки. Наведение на пункт переносит на него фокус.
disabled: пункт остаётся в меню, до него можно дойти стрелками, но он ничего не делает. Так видно, что команда существует. Если все пункты недоступны по одной причине, отключите триггер.- Прячьте пункты, которые человеку никогда не будут доступны, например действия только для админа.
checked: показывает ✓ у пунктовcheckboxиradio.
Открытие и закрытие
При открытии фокус переходит на первый пункт (на последний при ↑).
| Как закрыть | Куда уходит фокус |
|---|---|
Esc |
на триггер; диалог вокруг меню остаётся открытым |
| выбор команды или радиопункта | на триггер, если действие само не переводит фокус, например открывая диалог |
выбор пункта checkbox |
меню остаётся открытым |
Tab / Shift+Tab |
на следующий или предыдущий элемент; ничего не выполняется |
| клик снаружи | туда, куда кликнули |
| повторный клик по триггеру | на триггер |
- Меню открывается под триггером, а у нижнего края экрана — над ним. Оно следует за триггером при прокрутке, и контейнер его не обрезает.
- Длинные подписи обрезаются многоточием. Меню не прокручивается: держите в нём примерно до 12 пунктов.
Триггеры
tk-buttonс подписью и иконкойchevron-down— для действий страницы. Не повторяйте её слово в пунктах: «Экспорт» открывает «PDF» и «CSV», а не «Экспорт в PDF».tk-icon-buttonс иконкойmore-horizontalвTooltip type="label"— для дополнительных действий, например в строке таблицы. Называйте область: «Действия со строкой», «Другие действия».
Контекстные меню
<tk-menu trigger="context" label="File actions"> <div slot="trigger">Quarterly report.pdf</div> <tk-menu-item>Open</tk-menu-item> <tk-menu-item>Rename</tk-menu-item> <tk-menu-item>Download</tk-menu-item> </tk-menu>
С trigger="context" в слоте trigger лежит область, по которой кликают правой кнопкой.
В остальном меню то же. Открывается тремя способами:
- Правый клик в области: меню открывается у указателя.
- Долгое нажатие на сенсорном экране, 500 мс; движение или прокрутка его отменяют.
Shift+F10или клавишаContextMenu, когда фокус внутри области. Если область не получает фокус, меню делает её фокусируемой.
Правила контекстного меню:
- Назовите меню через
labelилиaria-labelна области. Текст области именем не становится никогда. - Каждая команда должна быть доступна и с основного экрана. Про правый клик не догадаться, а на сенсорном экране и с клавиатуры его могут не найти.
- Прячьте пункты, которые здесь неприменимы, а не отключайте их.
- Без подсказок о сочетаниях клавиш.
- Самые вероятные команды — первыми, ближе к указателю.
Вне области собственное контекстное меню браузера работает как обычно.
Подменю
<tk-menu>
<tk-button slot="trigger">Actions</tk-button>
<tk-menu-item>Rename</tk-menu-item>
<tk-menu>
<tk-menu-item slot="trigger">Share</tk-menu-item>
<tk-menu-item>Email</tk-menu-item>
<tk-menu-item>Copy link</tk-menu-item>
</tk-menu>
</tk-menu>Подменю — это tk-menu внутри меню, у которого триггер — tk-menu-item, родительская
строка. Строка получает шеврон и ARIA, а подменю берёт имя у строки.
- Наведение, клик,
Enter,Spaceили→открывают его. Родительская строка только открывает подменю и никогда не выполняет команду. - Если вести указатель по диагонали от строки в открытое подменю, оно не закроется.
←илиEscзакрывают подменю и возвращают фокус на его строку.- Выбор пункта закрывает все уровни и возвращает фокус на триггер.
- Подменю открывается в ту сторону, где есть место. Отключённая родительская строка его не открывает.
- Набор радиопунктов и колонка ✓ у каждого уровня свои.
Подменю — редко:
- Только один уровень, примерно до 5 пунктов.
- Не для выбора значения и не просто для порядка: для этого есть заголовок группы.
- Если меню открывают ради подменю, сделайте подменю самим меню.
- Избегайте их на экранах для касаний.
Когда использовать
- Меню — для 3–12 связанных действий, которым на экране не хватает места, например действий в строке таблицы. Если их меньше, покажите кнопки. Если больше, разделите меню или пересмотрите экран.
- Главное действие экрана держите на виду, никогда не в меню.
- Чтобы выбрать значение, которое сохраняется или уходит с формой, берите
Select илиCombobox . - Для ссылок берите
Navigation menu илиSidebar . Если пункт что-то делает, это пункт меню; если ведёт куда-то, это ссылка. - Меню открывается от кнопки, по клику. Никогда от ссылки и никогда при наведении.
Текст
- Подпись начинается с глагола, добавьте существительное, если глагола мало. Заглавная буква только в начале.
- Ставьте «…» в конце, если действию до завершения нужны ещё данные.
- Частые и важные пункты — первыми, связанные — рядом, опасные — последними.
- Заголовки групп: одно-два слова, заглавная только в начале, без знаков препинания.
Подробнее в
Можно / нельзя
| ✅ Можно | ❌ Нельзя |
|---|---|
| Держать главное действие на виду | Прятать его в меню |
| Опасный пункт последним, с «…» и подтверждением | Удалять что-то прямо из меню |
| Select для значения формы | Отмеченные пункты как ответ формы |
| Иконки у всех пунктов или ни у одного | Строки с иконками вперемешку со строками без |
| «Экспорт» → «PDF», «CSV» | «Экспорт» → «Экспорт в PDF», «Экспорт в CSV» |
| Открывать от кнопки, по клику | Открывать от ссылки или при наведении |
| Подменю в один уровень | Подменю в подменю |
| Дублировать команды контекстного меню в интерфейсе | Делать правый клик единственным путём к действию |
Связанные
Select иCombobox : выбор значения.Navigation menu иSidebar : ссылки, а не действия.Icon button иTooltip : триггер для дополнительных действий.Dialog : подтверждение, которое открывает опасный пункт.Split button : главное действие с меню связанных.
API
tk-menu
| Атрибут | Тип | По умолчанию | Что делает |
|---|---|---|---|
label |
string | имя триггера | доступное имя меню; в режиме context запасной вариант — aria-label области, но не её текст |
trigger |
button | context |
button |
открывается от кнопки или от правого клика, долгого нажатия и Shift+F10 на области |
| Слот | Содержимое |
|---|---|
trigger |
одна кнопка; tk-menu-item у подменю; область в режиме context |
| по умолчанию | tk-menu-item, tk-menu-group, tk-divider или <hr> и вложенные tk-menu |
CSS: ::part(menu), панель. Методов нет: меню открывает триггер.
tk-menu-item
| Атрибут | Тип | По умолчанию | Что делает |
|---|---|---|---|
type |
command | checkbox | radio |
command |
что делает выбор пункта |
checked |
boolean | false |
отметка пунктов checkbox и radio |
description |
string | нет | вторая строка |
danger |
boolean | false |
отмечает разрушительную команду |
disabled |
boolean | false |
доступен с клавиатуры, ничего не делает |
| Слот | Содержимое |
|---|---|
| по умолчанию | подпись |
icon |
один tk-icon |
trailing |
короткая подсказка или бейдж, не интерактивные |
CSS: ::part(row), строка.
tk-menu-group
| Атрибут | Тип | По умолчанию | Что делает |
|---|---|---|---|
label |
string | нет | заголовок раздела; обязателен. Ещё задаёт набор радиопунктов |
События
Своих событий нет. Слушайте click на пункте.
Токены
| Часть | Токены |
|---|---|
| панель | surface/raised, shadow-2, radius-16, отступ space-4; в контрастной теме рамка 1px border/default |
| пункт | text/default, Body Small; иконка icon/secondary; строки radius-12 |
| наведение, фокус | state/hover |
| нажатие | state/press |
| опасный | text/error, icon/error; state/error/hover при наведении и фокусе, state/error/press при нажатии |
| отключённый | text/disabled, icon/disabled |
| галочка | icon/accent, icon-size-16 |
| описание, подсказка, заголовок группы | text/secondary |
| разделитель | border/default |
Значения по темам:
Доступность
Встроено:
- Триггер получает
aria-haspopup="menu"иaria-expanded. Панель —menuс именем изlabelили триггера; пункты —menuitem,menuitemcheckboxилиmenuitemradioс состояниями отметки и отключения. - Меню, его подменю и пункты — одна остановка
Tab. При открытии фокус переходит внутрь и возвращается так, как сказано в таблице закрытия. - До отключённых пунктов можно дойти, и фокус на них виден. ✓ и шевроны скрыты от скринридеров.
- Область контекстного меню получает
aria-haspopup,aria-keyshortcuts="Shift+F10"и остановку Tab, если её не было. - Каждая строка не ниже 32px. При увеличении панель остаётся в видимой части окна.
На вашей стороне:
- Назовите контекстное меню через
labelи сделайте каждую команду доступной без него. - Называйте разрушительное действие в подписи опасного пункта: одного цвета мало.
- Пишите описания коротко: их читают после подписи.
| Клавиша | Триггер | Открытое меню |
|---|---|---|
Enter / Space |
открывает; фокус на первом пункте | выбирает пункт |
↓ / ↑ |
открывает; фокус на первом или последнем пункте | следующий или предыдущий пункт, включая отключённые; по кругу не идёт |
Home / End |
— | первый или последний пункт |
| буквы | — | переход к следующему пункту, который с них начинается |
Esc |
— | закрывает меню или только подменю |
Tab |
уходит | закрывает, ничего не выполняя |
→ |
— | открывает подменю |
← |
— | закрывает подменю |
Shift+F10 / ContextMenu |
открывает контекстное меню | — |
При письме справа налево → и ← меняются местами.