Отображение данных
Тег
Произвольная метка, которую завёл пользователь. Её можно снять — и это главное отличие от бейджа, у которого пять значений из словаря библиотеки и снять его нельзя.
Разметка
<span class="inst-tag">worldgen<button class="inst-tag-remove" type="button" aria-label="Убрать метку worldgen"></button></span>
<span class="inst-tag">ночной<button class="inst-tag-remove" type="button" aria-label="Убрать метку ночной"></button></span>
<span class="inst-tag">приоритет:высокий</span>
Контракт
| Что | Обязательно | Почему |
|---|---|---|
Настоящая <button> для снятия |
да | Крестик текстом нельзя нажать с клавиатуры и нечем озвучить |
aria-label со словом метки |
да | «Убрать метку worldgen», а не «Убрать»: ряд из десяти «Убрать» на слух неразличим |
| Перевод фокуса после снятия | да, на приложении | Исчезнувший элемент уводит фокус в никуда |
| Кнопка снятия | нет | Добавляется только там, где снятие возможно |
Доступность
| Кнопка снятия | Настоящая <button>, а не крестик текстом: её надо уметь нажать с клавиатуры и озвучить |
| Имя кнопки | aria-label со словом метки: «Убрать метку worldgen», а не «Убрать». Ряд из десяти кнопок «Убрать» на слух неразличим |
| Фокус после снятия | Уходит в никуда, если элемент исчез. Приложение обязано перевести его на следующий тег или на контейнер |
| Цель нажатия | Глиф — --size-chevron, то есть 10px. Это ниже 24px по WCAG 2.5.8: область нажатия расширяется псевдоэлементом, сам глиф остаётся мелким |
| Тон | У тега его нет, поэтому вопрос «цвет как единственный носитель» не возникает |
Варианты
Без кнопки снятия
Разметка
<span class="inst-tag">только чтение</span>
<span class="inst-tag">приоритет:высокий</span>
Кнопка добавляется только там, где снятие действительно возможно. Крестик, который ничего не делает, хуже его отсутствия.
JS
Подключите модуль один раз на страницу — инициализировать компоненты по
отдельности не нужно, instrument.js работает делегированием и видит узлы, пришедшие
позже.
<script type="module" src="instrument.js"></script>
Что делает instrument.js
Пример в шапке живой: нажмите крестик — тег снимется, а фокус уйдёт на соседний.
Нажатие на .inst-tag-remove снимает тег и переводит фокус на соседний
крестик — иначе удалённый элемент уводит фокус в никуда, и человек с
клавиатуры оказывается в начале документа.
События
inst:remove всплывает с тега, detail — { value }: data-value, если он
есть, иначе текст метки.
Событие отменяемо, и в приложении на данных отменять его — норма: разметку
там пересоздаёт перерисовка, а не instrument.js.
list.addEventListener('inst:remove', (e) => {
e.preventDefault(); // тег останется в разметке
store.dropTag(e.detail.value); // уберёт его перерисовка
});
Опции
| Атрибут | Что делает |
|---|---|
data-value |
Что придёт в detail вместо текста метки — идентификатор вместо человеческого имени |
API
| Имя | Что делает |
|---|---|
| класс | |
inst-tag | Метка |
inst-tag-remove | Кнопка снятия. Настоящая <button>; снятие выполняет [instrument.js](../../foundations/behavior.md) |
| Имя | Значение | Что делает |
|---|---|---|
| атрибут | ||
data-value | — | На .inst-tag. Что придёт в detail события inst:remove вместо текста метки |
| Имя | Значение | Откуда |
|---|---|---|
| токен | ||
--control-h-sm | 24px | база +14: плотность · масштаб |
--radius-sm | 6px | база +4: масштаб |
--text-xs | 0.78125rem | база +4: масштаб |
--space-2 | 4px | одно на все ячейки |
--space-3 | 6px | одно на все ячейки |
--surface-recessed | light-dark(oklch(0 0 0 / 0.060), oklch(1 0 0 / 0.050)) | одно на все ячейки |
--border | light-dark(oklch(0 0 0 / 0.12), oklch(1 0 0 / 0.11)) | одно на все ячейки |
--hairline | 1px | база +1: экран |
--size-chevron | 10px | база +4: масштаб |
--text-muted | light-dark(var(--n-8), var(--n-6)) | одно на все ячейки |
--err-text | light-dark(var(--err-5), var(--err-3)) | база +1: тема |
Почему кит устроен именно так — конституция · Открытый код под MIT, github.com/keshon/instrument