Skip to content
Fleetline

Sidebar navigation

Usage

Use the side nav for the pages inside one area of Fleetline when there are more than five (the workshop: work orders, inspections, parts, vehicles, mechanics). For the 4–6 top-level areas use the top nav.

Anatomy

  1. Collapse button — .side-nav__collapse (aria-expanded)
  2. Section heading — .side-nav__heading
  3. Link — a.side-nav__link with icon, label, optional count
  4. Nested group — details.side-nav__group + summary.side-nav__summary + chevron
  5. Current indicator — inline-start bar, selected fill, semibold (aria-current="page")

Examples

Section headings use the next heading level of the page (h2 in an app shell; h4 inside this docs page). States marked hover, focus-visible and active are frozen with .is-hover, .is-focus-visible, .is-active. Those classes share their rule with the real pseudo-class, so what you see is exactly what users get. Never use them in product code.

Sidebar navigation

Live: the collapse button switches to the icon rail and remembers the choice.

Icon rail: names stay in the accessibility tree; hovering shows them as tooltips.

<nav class="side-nav" aria-label="Workshop" data-persist="fleetline-side-nav">
  <div class="side-nav__header">
    <button type="button" class="icon-btn icon-btn--sm side-nav__collapse" aria-expanded="true" aria-label="Collapse navigation">
      <svg class="icon-btn__icon side-nav__collapse-icon" aria-hidden="true" focusable="false"><use href="#icon-panel-left-close"></use></svg>
    </button>
  </div>
  <div class="side-nav__section">
    <h2 class="side-nav__heading" id="nav-workshop">Workshop</h2>
    <ul class="side-nav__list" aria-labelledby="nav-workshop">
      <li><a class="side-nav__link" href="/workshop">…<span class="side-nav__label">Overview</span></a></li>
      <li>
        <details class="side-nav__group" open>
          <summary class="side-nav__link side-nav__summary">…<span class="side-nav__label">Work orders</span>…</summary>
          <ul class="side-nav__list side-nav__list--nested">
            <li><a class="side-nav__link" href="/work-orders/open" aria-current="page"><span class="side-nav__label">Open work orders</span></a></li>
          </ul>
        </details>
      </li>
      <li><a class="side-nav__link" href="/inspections">…<span class="side-nav__label">Inspections</span><span class="side-nav__count">4</span></a></li>
    </ul>
  </div>
</nav>
<script type="module">import { init } from "./js/side-nav.js"; init();</script>

API

HookValuesPurpose
.side-navblock class<nav aria-label> sidebar
[data-collapsed]attribute (set by JS)Icon rail
data-persistattributelocalStorage key for the collapse state
.side-nav__header | __collapse | __section | __heading | __list | __list--nested | __link | __icon | __label | __count | __group | __summary | __chevronpartsSee anatomy
aria-current="page"attributeCurrent page
aria-expanded (collapse button)attributeExpanded / collapsed

Do and don't

Workshop → Work orders → Open work orders

Do keep nesting to two levels and mark the current page.

Fleet → Vans → Electric → North Yard → KX-219

Don't use the side nav as a data tree — that's a tree view or a filtered table.

Accessibility

Keyboard interaction
KeyBehavior
TabMoves through the collapse button, links and group summaries
EnterFollows a link
Enter / Space (summary)Expands / collapses a nested group
Enter / Space (collapse)Switches between full and icon rail

Tokens

Custom propertyPurpose
--color-bg-surface, --color-border-defaultPanel
--color-selected-bg | -fg | -borderCurrent link
--color-action-ghost-bg-hoverHover
--size-control-md | -smLink height (comfortable / compact)
--color-bg-mutedCount pill
--motion-duration-baseCollapse width transition (off with reduced motion)