Topbar
App-shell top bar with tabs.
The application top bar: brand, a tab strip (buttons or real links), optional right-aligned chrome (services summary, stats, ⌘K chip, live clock), and a user control. Adds a skip link, a command-menu hook (Cmd+K on Apple platforms, Ctrl+K elsewhere — registered through the shortcut registry), custom brand/user snippets, and an optional sticky position. Uses header/nav landmarks and keyboard tab navigation, and degrades gracefully to a plain brand + tabs bar when the built-in chrome is opted out.
Demo
Usage
<script>
import { Topbar } from 'dssoca';
</script>
<!-- Link tabs: object tabs with href render real <a href> elements; the
active tab is matched by id and carries aria-current="page". -->
<Topbar
active="work"
tabs={[
{ id: 'home', label: 'Home', href: '/' },
{ id: 'work', label: 'Work', href: '/work' },
{ id: 'about', label: 'About', href: '/about' }
]}
/>
<!-- Minimal Topbar: no services dot, no clock, no stats; the ⌘K chip is
auto-hidden because no onCommand handler is passed. -->
<Topbar
active="work"
tabs={[{ id: 'work', href: '/work' }]}
services={false}
clock={false}
stats={[]}
/>Active tabs carry `aria-current="page"`. Button tabs use a roving tabindex (arrow keys move focus, Home/End jump); link tabs stay in the natural tab order so they work without JS, while still supporting the arrow keys. The command shortcut is registry-backed (id `ss:topbar-command`, `mod+k`): it lists in ShortcutsHelp and obeys `shortcuts.setEnabled()` / `shortcuts.remap()` — it fires on the platform modifier only (Cmd+K on Apple, Ctrl+K elsewhere); remap to `'mod+k, ctrl+k'` if you want both. Don't pair it with a default-shortcut SearchPalette: both bind `mod+k` and the last one mounted wins — give one of them the chord (e.g. `shortcut={false}` on the palette, or skip `onCommand`). Responsive behavior is built in: the tab strip shrinks and scrolls horizontally instead of overflowing the bar, the optional stat segments hide below 720px, and the strip hides below 520px (pair with BottomNav for mobile navigation, or pass `tabs={[]}` to drop the strip entirely) — never target `.ss-topbar` internals from global CSS.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
active | string | 'overview' | Active tab id. |
tabs | Array<string | { id; label?; href? }> | — | Tab strip (has a built-in default set). Strings are shorthand for `{ id, label: id }`; `label` defaults to `id`; tabs with `href` render as real `<a href>` links (SSR-friendly). |
user | string | — | Current user label. |
onTab | (tab: string) => void | — | Fired with the tab id on activation (also for `href` tabs, as an SPA fallback). |
onCommand | () => void | — | Fired when the command menu is opened (chip click or mod+K — Cmd+K on Apple platforms, Ctrl+K elsewhere). The chip (a `Kbd` with a platform-true `aria-keyshortcuts`) and the shortcut only exist when this is provided. |
onUser | () => void | — | Fired when the user chip is activated (when no `userMenu` snippet given). |
userMenu | Snippet | — | Custom user/avatar control on the right; overrides the default user button. |
brand | Snippet | — | Custom brand mark + name; defaults to the built-in logo. |
stats | { key; value; title? }[] | — | Right-aligned stat segments; defaults to built-in homelab stats. Pass `[]` to remove. |
services | boolean | { up: number; total: number } | true | Services status segment: `true` keeps the built-in 6/7 demo summary, an object renders real numbers, `false` removes it. |
clock | boolean | true | Show the live clock segment; `false` removes it. |
skipTarget | string | '#main' | Anchor the skip link jumps to. |
sticky | boolean | true | Stick the header to the top of the viewport. |
ariaLabel | string | 'Primary' | Accessible name for the tab-strip `<nav>` landmark (distinguishes it from other navs on the page). |
size | 'sm' | 'md' | 'lg' | — | Per-instance size override; inherits the ancestor `data-size-variant` when unset. |