dssoca docs
GitHub repository

BottomNav

Fixed, thumb-reachable bottom tab bar.

A fixed, bottom-anchored row of equal-width icon+label tabs for mobile/compact app shells: a blurred, elevated `<nav>` + `<ul>/<li>` list with an active highlight, optional per-tab count badges, and safe-area inset padding. Tabs can be real links (`href`) or selection buttons. Ported from a mobile bottom-nav pattern.

Demo

live · storybook Open in Storybook

Demo loads from https://dssoca-storybook.vercel.app/. Run pnpm storybook for it to render locally.

Usage

svelte
<script>
  import { BottomNav } from 'dssoca';

  let active = $state('home');
  const items = [
    { id: 'home',     label: 'Home',     icon: 'grid' },
    { id: 'services', label: 'Services', icon: 'flex' },
    { id: 'activity', label: 'Activity', icon: 'activity', badge: 3 },
    { id: 'account',  label: 'Account',  icon: 'user' },
  ];
</script>

<BottomNav {items} {active} onSelect={(id) => (active = id)} />

Exports the `BottomNavItem` type from `dssoca`. Fixed to the viewport bottom with a blurred/elevated background; the bar height derives from `--ss-bottom-nav-h` (tracks `--ss-shell-top-h`) so it rescales with the size axis. Each tab is a ≥44px hit target (WCAG 2.5.8) and reserves `env(safe-area-inset-bottom)`. A tab renders as `<a href>` when `href` is set, otherwise a `<button>` (a `disabled` tab always renders as a natively disabled `<button>`, even with `href`); count `badge`s fold into the tab's accessible name. The count badge's position/box/type rescale with the size axis via the `--ss-bottom-nav-badge-*` tokens (top, dx, min-w, h, fs, px).

Props

PropTypeDefaultDescription
itemsBottomNavItem[]Tabs ({ id, label, icon, href?, badge?, disabled? }) rendered left → right in equal-width columns; has a built-in default. A `disabled` tab renders inert: no navigation/`onSelect`, `aria-disabled="true"`, skipped by the tab order.
activestringId of the active tab; highlighted and marked `aria-current="page"`.
onSelect(id: string) => voidFired with the tab id on activation (also fires for `href` tabs as an SPA fallback).
ariaLabelstring'Primary'Accessible name for the wrapping `<nav>` landmark.
size'sm' | 'md' | 'lg'Per-instance size override; inherits the ancestor `data-size-variant` when unset.