Sidebar
App-shell navigation sidebar.
The application sidebar: grouped, icon-led navigation rendered as proper `<nav>` + `<ul>/<li>`. Items can link (`href`), carry a status dot and a square `badge`, and nest one level of children with the disclosure pattern. Collapses to an icon-only rail.
Demo
Usage
<script>
import { Sidebar } from 'dssoca';
let active = $state('hub');
let collapsed = $state(false);
</script>
<Sidebar
{active}
{collapsed}
onSelect={(id) => (active = id)}
onToggleCollapsed={(c) => (collapsed = c)}
/>Exports the `SideItem`, `SideGroup`, and `SideStatus` types from `dssoca`. `SideItem` gains `href`, `external` (off-site `href`: new tab, safe `rel`, external glyph, announced — the docs nav uses it for the Inspirations site), `badge`, optional `icon` (omit for a text-only item), and one level of nested `children`. The rail stretches to fill its host container’s height (`min-height: 100%`), so the border/background span the full screen or column; it still grows past the viewport when the nav is long.
HTML
CSS only — static markup The exact markup the component renders, generated at build time. Use it with dssoca/vanilla.css — see Plain HTML & CSS.
<nav class="ss-side" aria-label="Sidebar">
<div class="section" id="ss-side-sec-0">Main</div>
<ul class="list" aria-labelledby="ss-side-sec-0">
<li class="row">
<div class="item active" role="button" tabindex="0" aria-current="page">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter" class="ss-icon" style="width:13px;height:13px" aria-hidden="true" focusable="false">
<path d="M4 11l8-8 8 8"/>
<path d="M6 9v12h12V9"/>
<path d="M10 21v-6h4v6"/>
</svg>
<span class="label">Hub</span>
</div>
</li>
<li class="row">
<div class="item" role="button" tabindex="0">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square" stroke-linejoin="miter" class="ss-icon" style="width:13px;height:13px" aria-hidden="true" focusable="false">
<path d="M4 6h16M4 12h16M4 18h10"/>
</svg>
<span class="label">Logs</span>
<span class="badge">3</span>
<span class="dot" aria-hidden="true"></span>
</div>
</li>
</ul>
</nav>Static navigation; disclosures need your own JS.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
active | string | 'hub' | Active item id. |
groups | SideGroup[] | — | Sections of items ({ id, label, icon?, status?, href?, external?, badge?, children? }); has a built-in default. `external` (with `href`) opens in a new tab with `rel="noopener noreferrer"`, a trailing external glyph and an "(opens in a new tab)" announcement. |
onSelect | (id: string) => void | — | Selection handler. |
collapsed | boolean | false | Collapse to an icon-only rail; labels/section text are hidden. |
onToggleCollapsed | (collapsed: boolean) => void | — | Fired when the built-in collapse toggle is pressed. |
size | 'sm' | 'md' | 'lg' | — | Per-instance size override; inherits the ancestor `data-size-variant` when unset. |