Page Navigation
Page Navigation — карточка-остров разделов текущей страницы с поверхностью, радиусом и тенью острова. Пункт несёт подпись, необязательную иконку из словаря канона и точку-маркер, после подписи — иконку ошибки раздела по флагу error, а справа — сниппет счётчиков раздела. Группы разделяет запись { type: "separator" }, которую рисует Divider. Текущий раздел задаёт value: пункт получает aria-current и ту же подложку, что под указателем; вложенных уровней у списка нет.
Статус: draft · в системе с 2026-08 · интерактивность: always (всегда)
Когда использовать
- У редактируемой сущности несколько разделов, между которыми переключаются в пределах одной страницы.
- Нужно отметить раздел с изменениями точкой-маркером рядом с подписью или раздел с ошибкой иконкой после подписи.
- Рядом с разделом нужен счётчик или бейдж, не встроенный в саму подпись.
Не использовать:
- Навигация ведёт между глобальными разделами приложения — это Sidebar.
- Нужен путь от верхнего уровня к текущей странице — это Breadcrumbs.
- Разделы равноправны и переключают панели контента на месте — это Tabs.
Альтернативы:
sidebar— постоянная колонка глобальной навигации приложенияbreadcrumbs— путь к текущей странице, а не список её разделовtabs— равноправные панели контента в одном контексте
Разделы страницы
Карточка разделов редактируемой сущности с текущим разделом и иконками.
<!--
🟢
Карточка-остров разделов редактируемой сущности. Текущий раздел —
«Targeting»: та же подложка, что под указателем, подпись и иконка цветом
не меняются. Иконки — ближайшие по смыслу из словаря канона.
-->
<script>
import PageNavigation from "$lib/ui/PageNavigation.svelte";
const items = [
{ value: "general", label: "General", icon: "Gear" },
{ value: "targeting", label: "Targeting", icon: "MagnifyingGlass" },
{ value: "budget", label: "Budget", icon: "CurrencyDollar" },
{ value: "schedule", label: "Schedule", icon: "CalendarBlank" },
{ value: "audience", label: "Audience", icon: "Eye" },
];
let value = $state("targeting");
</script>
<PageNavigation {items} bind:value />
Маркеры, ошибки и счётчики
Точка-маркер у разделов с изменениями, иконка ошибки у раздела с невалидными полями и счётчик раздела в сниппете справа.
<!--
🟢
Точка-маркер у разделов с изменениями, иконка ошибки у раздела с невалидными
полями и счётчик раздела в сниппете справа. «Targeting» и «Budget» помечены
точкой, у «Budget» дополнительно иконка ошибки; сниппет extra кладёт счётчик
незаполненных полей раздела на плашку — кегль и цвет даёт контейнер extra,
плашка остаётся примером продукта.
-->
<script>
import PageNavigation from "$lib/ui/PageNavigation.svelte";
const items = [
{ value: "general", label: "General", icon: "Gear" },
{ value: "targeting", label: "Targeting", icon: "MagnifyingGlass", indicator: true },
{ value: "budget", label: "Budget", icon: "ArrowsClockwise", indicator: true, error: true },
{ value: "audience", label: "Audience", icon: "Eye" },
];
const counts = { targeting: 2, budget: 1 };
let value = $state("general");
</script>
<PageNavigation {items} bind:value>
{#snippet extra(item)}
{#if counts[item.value]}
<span class="count">{counts[item.value]}</span>
{/if}
{/snippet}
</PageNavigation>
<style>
.count {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: var(--sp-3);
height: var(--sp-3);
padding: 0 var(--sp-1);
border-radius: var(--r-s);
background: var(--c-surface-2);
font-weight: var(--fw-bold);
}
</style>
Группы разделов
Разделители между группами разделов.
<!--
🟢
Разделители между группами разделов: три группы пунктов без иконок, между
ними записи { type: "separator" }, которые компонент рисует линией Divider.
Ближе всего к виду эталона — карточка с одними подписями.
-->
<script>
import PageNavigation from "$lib/ui/PageNavigation.svelte";
const items = [
{ value: "general", label: "General" },
{ value: "targeting", label: "Targeting" },
{ type: "separator" },
{ value: "budget", label: "Budget" },
{ value: "schedule", label: "Schedule" },
{ type: "separator" },
{ value: "creatives", label: "Creatives" },
{ value: "audience", label: "Audience" },
];
let value = $state("budget");
</script>
<PageNavigation {items} bind:value />