Sidebar
Sidebar — постоянная тёмная колонка глобальной навигации: шапка держит только кнопку сворачивания у правого края (бренд продукта живёт в Header), пункты несут иконку из словаря канона, счётчик-плашку, индикатор тревоги и подразделы, границы групп — линии. Текущий маршрут задаёт value: пункт получает aria-current, подложку с рамкой (тень и градиент рамки — значения скина), а группа с текущим подразделом раскрывается на месте; подпункты отмечены рельсой слева и точкой, которая загорается под указателем и остаётся у текущего. В свёрнутом виде остаются иконки, счётчик скрыт, знак подразделов уходит в круглый бейдж у угла пункта, подвал скрыт, подразделы группы открываются в панели справа.
Статус: draft · в системе с 2026-08 · интерактивность: always (всегда)
Когда использовать
- Приложению нужна постоянная навигация между несколькими глобальными разделами.
- Часть разделов имеет второй уровень, который должен быть виден рядом с текущим маршрутом.
- Пользователь хочет сузить навигацию до иконок и вернуть подписи одним действием.
Не использовать:
- Навигация ведёт по разделам одной страницы — используй Page Navigation.
- Нужен путь от верхнего уровня к текущей странице — это Breadcrumbs.
- Пункты меняют значение формы, а не маршрут — это Tabs, Toggle Group или Radio.
Альтернативы:
page-navigation— разделы одной страницы внутри содержимого, а не глобальные маршрутыbreadcrumbs— путь к текущей странице без постоянной колонкиtabs— равноправные панели в пределах одного контекста
Навигация приложения
Тёмная колонка с кнопкой сворачивания, линия-граница, счётчик, индикатор тревоги и раскрытая группа с текущим подразделом.
<!--
🟢
Навигация приложения: тёмная колонка с кнопкой сворачивания в шапке,
линии-границы перед «Campaigns» и «Documentation», счётчик у «Creatives»,
индикатор тревоги у «Finance» и раскрытая группа «Reports» с текущим
подразделом «Countries». Иконки — ближайшие по смыслу из словаря канона.
Подвал несёт версию продукта.
-->
<script>
import Sidebar from "$lib/ui/Sidebar.svelte";
const items = [
{ value: "dashboard", label: "Dashboard", icon: "SquaresFour" },
{ value: "finance", label: "Finance", icon: "CurrencyDollar", indicator: true },
{ type: "separator" },
{ value: "campaigns", label: "Campaigns", icon: "Megaphone" },
{ value: "creatives", label: "Creatives", icon: "Eye", count: 128 },
{ value: "optimization", label: "Optimization lists", icon: "Funnel" },
{
value: "reports",
label: "Reports",
icon: "ChartBar",
children: [
{ value: "reports/dates", label: "Dates" },
{ value: "reports/countries", label: "Countries" },
{ value: "reports/sources", label: "Sources" },
],
},
{ type: "separator" },
{ value: "documentation", label: "Documentation", icon: "Question" },
];
let value = $state("reports/countries");
</script>
<div class="frame">
<Sidebar {items} bind:value>
{#snippet footer()}
<span>v2.14.0</span>
{/snippet}
</Sidebar>
</div>
<style>
.frame {
display: flex;
height: 640px;
overflow: hidden;
border: var(--bw-1) solid var(--c-border);
border-radius: var(--r-m);
background: var(--c-bg);
}
</style>
Свёрнутый вид
Только иконки, счётчик скрыт, знак подразделов в бейдже у угла; группа открывает подразделы в панели справа, подвал скрыт, кнопка сверху возвращает подписи.
<!--
🟢
Свёрнутый вид: колонка сжата до иконок, подписи остаются в дереве
доступности, счётчик у «Creatives» скрыт, индикатор тревоги у «Campaigns»
остаётся на месте, знак подразделов «Reports» уходит в круглый бейдж у угла
пункта. Группа открывает подразделы в панели справа, подвал скрыт, а кнопка
сверху возвращает подписи и подвал. Текущий раздел — «Creatives».
-->
<script>
import Sidebar from "$lib/ui/Sidebar.svelte";
const items = [
{ value: "dashboard", label: "Dashboard", icon: "SquaresFour" },
{ value: "campaigns", label: "Campaigns", icon: "Megaphone", indicator: true },
{ value: "creatives", label: "Creatives", icon: "Eye", count: 128 },
{ type: "separator" },
{
value: "reports",
label: "Reports",
icon: "ChartBar",
children: [
{ value: "reports/dates", label: "Dates" },
{ value: "reports/countries", label: "Countries" },
],
},
{ value: "documentation", label: "Documentation", icon: "Question" },
];
let value = $state("creatives");
let collapsed = $state(true);
</script>
<div class="frame">
<Sidebar {items} bind:value bind:collapsed>
{#snippet footer()}
<span>v2.14.0</span>
{/snippet}
</Sidebar>
</div>
<style>
.frame {
display: flex;
height: 520px;
overflow: hidden;
border: var(--bw-1) solid var(--c-border);
border-radius: var(--r-m);
background: var(--c-bg);
}
</style>