Components / Layout & Navigation / Sidebar
Sidebar stable
The app sidebar as a part: sections, collapsible groups, badges, an icon rail variant, and the user at the foot.
<div style="display:flex;border:1px solid var(--k-line);border-radius:14px;overflow:hidden;max-width:620px;background:var(--k-bg)">
<nav class="k-side" data-side aria-label="Sidebar preview">
<div class="k-side-brand"><span class="k-side-mark"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="M12 3.5 2.5 8.5 12 13.5l9.5-5L12 3.5Z"/><path d="m2.5 12.8 9.5 5 9.5-5"/></svg></span>Northwind</div>
<div class="k-side-sec">MAIN</div>
<div class="k-side-nav">
<a class="k-side-item on" href="#"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="m3 11 9-8 9 8"/><path d="M5 9.5V20a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V9.5"/></svg><span class="k-side-t">Overview</span></a>
<div class="k-side-group open">
<button class="k-side-item" type="button" data-side-toggle aria-expanded="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Z"/></svg><span class="k-side-t">Projects</span><svg class="k-side-chev" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg></button>
<div class="k-side-sub">
<a class="k-side-item" href="#"><span class="k-side-t">Website rebuild</span></a>
<a class="k-side-item" href="#"><span class="k-side-t">Mobile app</span></a>
<a class="k-side-item" href="#"><span class="k-side-t">Brand refresh</span></a>
</div>
</div>
<a class="k-side-item" href="#"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><rect x="3.5" y="5" width="17" height="16" rx="2"/><path d="M3.5 10h17M8 3v4M16 3v4"/></svg><span class="k-side-t">Calendar</span><span class="k-side-badge">3</span></a>
<a class="k-side-item" href="#"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="M6 20v-6M12 20V4M18 20v-9"/><path d="M3.5 20.5h17"/></svg><span class="k-side-t">Reports</span></a>
</div>
<div class="k-side-sec">MANAGE</div>
<div class="k-side-nav">
<a class="k-side-item" href="#"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><circle cx="9" cy="8.5" r="3.4"/><path d="M2.8 20c.7-3.4 3.2-5.2 6.2-5.2s5.5 1.8 6.2 5.2"/><path d="M16 5.4a3.4 3.4 0 0 1 0 6.4M18.5 15.4c1.5.8 2.5 2.4 2.9 4.6"/></svg><span class="k-side-t">Team</span></a>
<a class="k-side-item" href="#"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="M3 6h10M17 6h4M3 12h4M11 12h10M3 18h12M19 18h2"/><circle cx="15" cy="6" r="2"/><circle cx="9" cy="12" r="2"/><circle cx="17" cy="18" r="2"/></svg><span class="k-side-t">Settings</span></a>
</div>
<div class="k-side-user"><span class="k-side-ava">AR</span><span class="k-side-umeta"><span class="k-side-uname">Aoki Ren</span><br><span class="k-side-urole">Workspace admin</span></span></div>
</nav>
<div style="flex:1;padding:20px;min-width:0">
<p style="font-size:15px;font-weight:600">Overview</p>
<p style="font-size:13px;color:var(--k-ink-2);line-height:1.8;margin-top:6px">The sidebar is the part; this column is just the room it stands in. Try the Projects group — it folds. The current page carries the vermillion core on its icon, and the user sits at the foot, out of the way until needed.</p>
</div>
</div>/* KATA Sidebar — the app sidebar as a part: sections, collapsible groups,
an icon rail, and the user at the foot. The current page carries the
vermillion core on its icon, like the app shell and the templates. */
.k-side{width:230px;flex:none;display:flex;flex-direction:column;background:var(--k-bg);border-right:1px solid var(--k-line);padding:14px 10px;font-family:var(--k-font);color:var(--k-ink);text-align:left}
.k-side-brand{display:flex;align-items:center;gap:9px;padding:2px 8px 12px;font-size:14px;font-weight:600}
.k-side-mark{width:24px;height:24px;border-radius:7px;background:var(--k-ink);color:var(--k-on-color);display:flex;align-items:center;justify-content:center;flex:none}
.k-side-sec{font-size:10.5px;letter-spacing:.09em;font-weight:600;color:var(--k-ink-3);margin:14px 8px 5px}
.k-side-nav{display:grid;gap:2px}
.k-side-item{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:8px;font-size:13.5px;color:var(--k-ink-2);text-decoration:none;cursor:pointer;background:none;border:0;width:100%;text-align:left;font-family:inherit}
.k-side-item:hover{background:var(--k-bg-soft);color:var(--k-ink)}
.k-side-item.on{background:var(--k-bg-soft);color:var(--k-ink);font-weight:550}
.k-side-item.on svg{color:var(--k-core)}
.k-side-item svg{flex:none}
.k-side-badge{margin-left:auto;font-size:11px;font-weight:600;background:var(--k-bg-soft);border:1px solid var(--k-line);color:var(--k-ink-2);border-radius:99px;padding:1px 7px}
.k-side-item.on .k-side-badge{background:var(--k-bg)}
.k-side-chev{margin-left:auto;transition:transform .18s}
.k-side-group.open .k-side-chev{transform:rotate(180deg)}
.k-side-sub{display:none;gap:2px;margin:2px 0 2px 25px}
.k-side-group.open .k-side-sub{display:grid}
.k-side-sub .k-side-item{font-size:13px;padding:6px 10px}
.k-side-user{margin-top:auto;display:flex;align-items:center;gap:9px;padding:12px 8px 2px;border-top:1px solid var(--k-line)}
.k-side-ava{width:30px;height:30px;border-radius:50%;background:var(--k-ink);color:var(--k-on-color);display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;flex:none}
.k-side-uname{font-size:13px;font-weight:550;line-height:1.3}
.k-side-urole{font-size:11.5px;color:var(--k-ink-3)}
.k-side.rail{width:60px;padding:14px 8px;align-items:center}
.k-side.rail .k-side-brand{padding:2px 0 12px}
.k-side.rail .k-side-nav{justify-items:center}
.k-side.rail .k-side-item{justify-content:center;padding:9px 0;width:40px}
.k-side.rail .k-side-t,.k-side.rail .k-side-sec,.k-side.rail .k-side-badge,.k-side.rail .k-side-chev,.k-side.rail .k-side-umeta{display:none}
.k-side.rail .k-side-user{justify-content:center;padding:12px 0 2px}
@media (prefers-reduced-motion:reduce){.k-side-chev{transition:none}}
// KATA Sidebar — collapsible groups. Everything else is plain links.
document.querySelectorAll('[data-side-toggle]').forEach(function (btn) {
btn.addEventListener('click', function () {
var group = btn.closest('.k-side-group');
if (!group) return;
var open = group.classList.toggle('open');
btn.setAttribute('aria-expanded', open ? 'true' : 'false');
});
});
Installation
CLI
node kata-ui.mjs add sidebar
Writes the part’s CSS and JS into your project. New to the CLI? See the CLI doc.
Manual
- Load
tokens.cssonce, before any part. - Copy the CSS tab into your stylesheet.
- Copy the HTML where it belongs. The part has a script — include it after the markup; it initializes itself.
Examples
Icon rail
<div style="display:flex;border:1px solid var(--k-line);border-radius:14px;overflow:hidden;max-width:480px;background:var(--k-bg)">
<nav class="k-side rail" data-side aria-label="Rail preview">
<div class="k-side-brand"><span class="k-side-mark"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="M12 3.5 2.5 8.5 12 13.5l9.5-5L12 3.5Z"/><path d="m2.5 12.8 9.5 5 9.5-5"/></svg></span></div>
<div class="k-side-nav">
<a class="k-side-item on" href="#" title="Overview"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="m3 11 9-8 9 8"/><path d="M5 9.5V20a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V9.5"/></svg><span class="k-side-t">Overview</span></a>
<a class="k-side-item" href="#" title="Projects"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Z"/></svg><span class="k-side-t">Projects</span></a>
<a class="k-side-item" href="#" title="Calendar"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><rect x="3.5" y="5" width="17" height="16" rx="2"/><path d="M3.5 10h17M8 3v4M16 3v4"/></svg><span class="k-side-t">Calendar</span></a>
<a class="k-side-item" href="#" title="Reports"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="M6 20v-6M12 20V4M18 20v-9"/><path d="M3.5 20.5h17"/></svg><span class="k-side-t">Reports</span></a>
<a class="k-side-item" href="#" title="Team"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><circle cx="9" cy="8.5" r="3.4"/><path d="M2.8 20c.7-3.4 3.2-5.2 6.2-5.2s5.5 1.8 6.2 5.2"/><path d="M16 5.4a3.4 3.4 0 0 1 0 6.4M18.5 15.4c1.5.8 2.5 2.4 2.9 4.6"/></svg><span class="k-side-t">Team</span></a>
<a class="k-side-item" href="#" title="Settings"><svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="M3 6h10M17 6h4M3 12h4M11 12h10M3 18h12M19 18h2"/><circle cx="15" cy="6" r="2"/><circle cx="9" cy="12" r="2"/><circle cx="17" cy="18" r="2"/></svg><span class="k-side-t">Settings</span></a>
</div>
<div class="k-side-user"><span class="k-side-ava">AR</span></div>
</nav>
<div style="flex:1;padding:20px;min-width:0">
<p style="font-size:15px;font-weight:600">The rail</p>
<p style="font-size:13px;color:var(--k-ink-2);line-height:1.8;margin-top:6px">Same part, one class narrower. Labels hide visually and stay in the markup; every icon keeps its title. For tools whose users live in the content, not the nav.</p>
</div>
</div>In dark
<div data-theme="dark" style="border-radius:14px;padding:14px;background:var(--k-zinc-950)">
<div style="display:flex;border:1px solid var(--k-line);border-radius:12px;overflow:hidden;background:var(--k-bg)">
<nav class="k-side" data-side aria-label="Dark sidebar preview">
<div class="k-side-brand"><span class="k-side-mark"><svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="M12 3.5 2.5 8.5 12 13.5l9.5-5L12 3.5Z"/><path d="m2.5 12.8 9.5 5 9.5-5"/></svg></span>Northwind</div>
<div class="k-side-sec">MAIN</div>
<div class="k-side-nav">
<a class="k-side-item" href="#"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="m3 11 9-8 9 8"/><path d="M5 9.5V20a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V9.5"/></svg><span class="k-side-t">Overview</span></a>
<a class="k-side-item on" href="#"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="M18 16H6c.6-1.2 1-2.6 1-4.5V10a5 5 0 0 1 10 0v1.5c0 1.9.4 3.3 1 4.5Z"/><path d="M10 20a2 2 0 0 0 4 0"/></svg><span class="k-side-t">Activity</span><span class="k-side-badge">9</span></a>
<a class="k-side-item" href="#"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8l-5-5Z"/><path d="M14 3v5h5M9 13h6M9 17h6"/></svg><span class="k-side-t">Documents</span></a>
<a class="k-side-item" href="#"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="square" stroke-linejoin="bevel" aria-hidden="true"><path d="M3 6h10M17 6h4M3 12h4M11 12h10M3 18h12M19 18h2"/><circle cx="15" cy="6" r="2"/><circle cx="9" cy="12" r="2"/><circle cx="17" cy="18" r="2"/></svg><span class="k-side-t">Settings</span></a>
</div>
<div class="k-side-user"><span class="k-side-ava">AR</span><span class="k-side-umeta"><span class="k-side-uname">Aoki Ren</span><br><span class="k-side-urole">Workspace admin</span></span></div>
</nav>
<div style="flex:1;padding:20px;min-width:0">
<p style="font-size:15px;font-weight:600">Activity</p>
<p style="font-size:13px;color:var(--k-ink-2);line-height:1.8;margin-top:6px">Nothing about the part changes in the dark — the tokens turn, the core stays vermillion. This whole frame is one data-theme attribute.</p>
</div>
</div>
</div>Usage
Drop it at the left edge of an app frame. The current page is marked by the vermillion core on its icon — the same mark the App Shell block and the templates use. Groups collapse with the small script; without the script they stay exactly as written, so write the important one open.
Accessibility
A real nav landmark of links; group buttons carry aria-expanded and the sub-list is plain links. In the rail the label is hidden visually, never removed — keep it in the markup and add a title so the icon still has a name.
Anatomy
The public surface of this part, read from its own source. Class names are the API — the CSS tab above is the full contract.
.k-side | class |
.k-side-brand | class |
.k-side-mark | class |
.k-side-sec | class |
.k-side-nav | class |
.k-side-item | class |
.on | class |
.k-side-badge | class |
.k-side-chev | class |
.k-side-group | class |
.open | class |
.k-side-sub | class |
.k-side-user | class |
.k-side-ava | class |
+5 more | classes — see the CSS tab |
data-side | data hook |
data-side-toggle | data hook |
aria-label | ARIA |
aria-hidden | ARIA |
aria-expanded | ARIA |
Related parts
Accordion beta
Disclosure built on native <details>. Zero JavaScript, keyboard and find-in-page included.
Bottom Navigation stable
The mobile app tab bar: three to five destinations under the thumb, the current one lit with the core.
Breadcrumbs beta
Where you are, as a path. The last crumb is the page itself — not a link.
Collapsible stable
One disclosure on its own: a trigger row and the region it folds away. The Accordion is this, grouped.