Дерево
Дерево показывает вложенные элементы, например файлы и папки, строками, которые раскрываются и сворачиваются на любую глубину.
<tk-tree label="Files"></tk-tree>
<tk-tree label="Files"></tk-tree>
<script type="module">
const tree = document.querySelector('tk-tree');
tree.data = [
{ id: 'src', label: 'src', children: [
{ id: 'components', label: 'components', children: [{ id: 'button', label: 'button.ts' }] },
{ id: 'index', label: 'index.ts' },
] },
{ id: 'readme', label: 'README.md' },
];
tree.expanded = ['src'];
</script>Анатомия
| Часть | Что это |
|---|---|
tk-tree |
всё дерево; одна остановка Tab |
| узел | одна строка с подписью; узлы берутся из свойства data |
| шеврон | у узла с детьми; поворачивается, когда узел раскрыт |
| группа | дети узла с отступом на один шаг |
Узел — это { id, label, children? }. Узел без children — конечный. Дерево не меняет
ваш data: что раскрыто и что выбрано, оно хранит само.
Выбор
selection |
Что делает |
|---|---|
none (по умолчанию) |
ничего не выбирается; для навигации |
single |
один узел за раз; выбор другого заменяет его |
multiple |
сколько угодно узлов |
tree.selection = 'multiple';
tree.selected = ['button', 'index'];
tree.addEventListener('tk-selection-change', (e) => console.log(e.detail.selected));Выбрать не значит открыть. Space или клик выбирают узел; Enter или клик ещё и отправляют
tk-activate, то есть «открой его». Файловому менеджеру обычно нужно и то и другое.
Стрелки никогда не меняют выбор, поэтому разрозненные узлы легко выбрать с клавиатуры: стрелкой к узлу, Space, стрелкой к следующему, снова Space.
Размеры
Размер один. Для более плотного списка задайте дереву --tk-tree-row-height, отступ
уровня меняет --tk-tree-indent.
Когда использовать
- Дерево — для вложенных данных, по которым ходят: файловый менеджер, выбор категории, оргструктура.
- Если у строк есть столбцы, берите
Data table сexpandable. - Для одного уровня разделов с заголовками берите
Accordion , для одного раскрывающегося блока —Collapsible . - Если строки — ссылки на другие страницы, берите
Sidebar . - Для плоского списка вариантов берите
Select ,Multiselect илиRadio group . - Вкладывайте только со смыслом. Дерево глубиной в два элемента — это список с лишними нажатиями.
| Tree | Sidebar | Accordion | |
|---|---|---|---|
| Строки — это | элементы, которые выбирают или изучают | ссылки на страницы | разделы с заголовками |
| Глубина | любая | строки с вложенными строками | один |
| Остановки Tab | одна на всё дерево | по одной на строку | по одной на раздел |
Текст
- Пишите названия, а не предложения: «Счета», «Выручка Q3.xlsx».
- Подписи короткие. Длинная подпись обрезается многоточием.
- Не нумеруйте уровни в подписи, как «1.2.3 Бюджет». Дерево само сообщает уровень.
Можно / нельзя
| ✅ Можно | ❌ Нельзя |
|---|---|
| Дерево для вложенных данных | Дерево для плоского списка вариантов |
| Data table, если у строк есть столбцы | Столбцы в подписях узлов |
| Sidebar для ссылок на страницы | Навигация сайта в виде дерева |
| Называть узлы как файлы: «Счета» | «Нажмите здесь, чтобы увидеть счета» |
label у дерева |
Дерево без имени |
Связанные
Data table : вложенные строки со столбцами.Sidebar : вложенные ссылки на страницы.Accordion иCollapsible : плоские разделы, которые раскрываются и сворачиваются.
API
Атрибуты
| Атрибут | Тип | По умолчанию | Что делает |
|---|---|---|---|
label |
string | — | доступное имя дерева; обязателен |
selection |
none | single | multiple |
none |
что можно выбрать |
Свойства
| Свойство | Тип | Что делает |
|---|---|---|
data |
TreeNode[] |
узлы: { id: string; label: string; children?: TreeNode[] } |
expanded |
string[] |
id узлов, раскрытых в начале |
selected |
string[] |
id узлов, выбранных в начале |
expandedItems |
string[], только чтение |
id раскрытых узлов сейчас |
selectedItems |
string[], только чтение |
id выбранных узлов сейчас |
Методы
expand(id)иcollapse(id): раскрывают или сворачивают один узел.setExpanded(ids)иsetSelected(ids): заменяют набор раскрытых или выбранных узлов.focusItem(id): переводит фокус на узел.
События
| Событие | Detail | Можно отменить | Когда |
|---|---|---|---|
tk-toggle |
{ id, open } |
да | перед тем как узел раскроется или свернётся |
tk-selection-change |
{ selected } |
да | перед тем как изменится выбор |
tk-activate |
{ id } |
нет | на узле нажали Enter или кликнули по нему |
Отмените tk-toggle или tk-selection-change, чтобы хранить состояние у себя:
tree.addEventListener('tk-activate', (e) => openFile(e.detail.id));
tree.addEventListener('tk-toggle', (e) => {
e.preventDefault();
store.toggle(e.detail.id);
tree.setExpanded(store.openIds);
});CSS
--tk-tree-row-height: минимальная высота строки; по умолчаниюspace-32.--tk-tree-indent: отступ одного уровня; по умолчаниюspace-16.
Токены
| Часть | Токены |
|---|---|
| узел | text/default, Body Small (14/20), radius-8 |
| наведение / нажатие | state/hover / state/press |
| выбранный узел | state/on; под курсором state/on-hover |
| шеврон | icon/secondary, icon-size-16 |
| рамка фокуса | border/accent/focus, внутри строки |
Значения по темам:
Доступность
Встроено:
- Дерево с вложенными группами; каждый узел сообщает свой уровень и место, например «уровень 2, 3 из 7».
- Одна остановка Tab, внутри работают стрелки, поэтому не нужно проходить Tab по каждому файлу.
- С
selection="multiple"дерево отмечено как допускающее несколько выбранных, и каждый узел сообщает, выбран ли он. - Набор буквы переводит к следующему узлу, который с неё начинается.
- При уменьшенной анимации шеврон поворачивается без движения.
На вашей стороне:
- Задайте дереву
label. - Обрабатывайте
tk-activate: само дерево ничего не открывает и никуда не переходит.
| Клавиша | Действие |
|---|---|
Down / Up |
к следующему или предыдущему видимому узлу; выбор не меняет |
Right |
раскрывает свёрнутый узел; на раскрытом переходит к первому ребёнку |
Left |
сворачивает раскрытый узел; иначе переходит к родителю |
Home / End |
к первому или последнему видимому узлу |
Enter |
отправляет tk-activate |
| буква или цифра | к следующему узлу, который начинается с набранного |
Space |
выбирает узел в фокусе или снимает выбор |
Shift + Down / Up |
переходит и выбирает следующий или предыдущий узел (multiple) |
Cmd / Ctrl + A |
выбирает все узлы (multiple) |
Пределы контраста
- Выбранный узел: в светлой и тёмной теме его подложка такая же, как у узла под курсором. Скринридер всегда сообщает выбор. Если он должен читаться с первого взгляда, покажите его ещё где-то.