j3w1 / theme

j3w1 / theme4.0.0

j3w1 / command

  • SPEC Overview
  • SPEC Foundations
  • SPEC Components
  • SPEC Patterns
  • SPEC Tokens
  • SPEC Tools
  • SPEC Workbench
  • SPEC Form builder
  • SPEC Task kit
  • SPEC Recipes
  • SPEC Figma bridge
  • SPEC Report an issue
  • SPEC Implement
  • SPEC For agents
  • SPEC Ports
  • SPEC Releases
  • SPEC Specification
  • DEMO Vue application demo

Sidebar navigation

A vertical list of section links with optional nested groups; the current section carries a 2px inline-start indicator and bright text, and the rail collapses to icons.

stable · light DOM · 4.0.0. Light DOM retains static content, native semantics, label relationships and host composition without duplicating controls.

Live variants

default

Example destination: sn overview

Example destination: sn tokens

Example destination: sn actions

Example destination: sn forms

Example destination: sn ports

Markup
<j3w1-sidebar-nav id="example-sidebar-nav-default"><nav class="sidebar-nav" aria-label="Sections">
  <ul class="sidebar-nav-list">
    <li class="sidebar-nav-item"><a class="sidebar-nav-link sidebar-nav-current" href="#example-sidebar-nav-default-sn-overview" aria-current="page"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><rect x="2.5" y="2.5" width="11" height="11"></rect></svg></span><span class="sidebar-nav-label">Overview</span></a></li>
    <li class="sidebar-nav-item"><a class="sidebar-nav-link sidebar-nav-link-demo-target" href="#example-sidebar-nav-default-sn-tokens"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><circle cx="8" cy="8" r="5.5"></circle></svg></span><span class="sidebar-nav-label">Tokens</span></a></li>
    <li class="sidebar-nav-item">
      <button class="sidebar-nav-link sidebar-nav-group" type="button" aria-expanded="false" aria-controls="example-sidebar-nav-default-sn-components"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><path d="M2.5 4h11M2.5 8h11M2.5 12h11"></path></svg></span><span class="sidebar-nav-label">Components</span><span class="sidebar-nav-chevron" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><path d="M6 4l4 4-4 4"></path></svg></span></button>
      <ul class="sidebar-nav-list sidebar-nav-sublist" id="example-sidebar-nav-default-sn-components" hidden="">
        <li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-sidebar-nav-default-sn-actions"><span class="sidebar-nav-label">Actions</span></a></li>
        <li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-sidebar-nav-default-sn-forms"><span class="sidebar-nav-label">Forms</span></a></li>
      </ul>
    </li>
    <li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-sidebar-nav-default-sn-ports"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><path d="M3 8h10M9 4l4 4-4 4"></path></svg></span><span class="sidebar-nav-label">Ports</span></a></li>
  </ul>
</nav><p id="example-sidebar-nav-default-sn-overview" tabindex="-1" class="j3w1-example-target">Example destination: sn overview</p><p id="example-sidebar-nav-default-sn-tokens" tabindex="-1" class="j3w1-example-target">Example destination: sn tokens</p><p id="example-sidebar-nav-default-sn-actions" tabindex="-1" class="j3w1-example-target">Example destination: sn actions</p><p id="example-sidebar-nav-default-sn-forms" tabindex="-1" class="j3w1-example-target">Example destination: sn forms</p><p id="example-sidebar-nav-default-sn-ports" tabindex="-1" class="j3w1-example-target">Example destination: sn ports</p></j3w1-sidebar-nav>

collapsed

Example destination: sn overview

Example destination: sn tokens

Example destination: sn actions

Example destination: sn forms

Example destination: sn ports

Markup
<j3w1-sidebar-nav id="example-sidebar-nav-collapsed"><nav class="sidebar-nav sidebar-nav-collapsed" aria-label="Sections">
  <ul class="sidebar-nav-list">
    <li class="sidebar-nav-item"><a class="sidebar-nav-link sidebar-nav-current" href="#example-sidebar-nav-collapsed-sn-overview" aria-current="page" aria-label="Overview" title="Overview"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><rect x="2.5" y="2.5" width="11" height="11"></rect></svg></span><span class="sidebar-nav-label">Overview</span></a></li>
    <li class="sidebar-nav-item"><a class="sidebar-nav-link sidebar-nav-link-demo-target" href="#example-sidebar-nav-collapsed-sn-tokens" aria-label="Tokens" title="Tokens"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><circle cx="8" cy="8" r="5.5"></circle></svg></span><span class="sidebar-nav-label">Tokens</span></a></li>
    <li class="sidebar-nav-item">
      <button class="sidebar-nav-link sidebar-nav-group" type="button" aria-expanded="false" aria-controls="example-sidebar-nav-collapsed-sn-components" aria-label="Components" title="Components"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><path d="M2.5 4h11M2.5 8h11M2.5 12h11"></path></svg></span><span class="sidebar-nav-label">Components</span><span class="sidebar-nav-chevron" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><path d="M6 4l4 4-4 4"></path></svg></span></button>
      <ul class="sidebar-nav-list sidebar-nav-sublist" id="example-sidebar-nav-collapsed-sn-components" hidden="">
        <li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-sidebar-nav-collapsed-sn-actions" aria-label="Actions" title="Actions"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><rect x="3" y="5" width="10" height="6"></rect></svg></span><span class="sidebar-nav-label">Actions</span></a></li>
        <li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-sidebar-nav-collapsed-sn-forms" aria-label="Forms" title="Forms"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><path d="M3 5h10M3 8h6M3 11h8"></path></svg></span><span class="sidebar-nav-label">Forms</span></a></li>
      </ul>
    </li>
    <li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-sidebar-nav-collapsed-sn-ports" aria-label="Ports" title="Ports"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><path d="M3 8h10M9 4l4 4-4 4"></path></svg></span><span class="sidebar-nav-label">Ports</span></a></li>
  </ul>
</nav><p id="example-sidebar-nav-collapsed-sn-overview" tabindex="-1" class="j3w1-example-target">Example destination: sn overview</p><p id="example-sidebar-nav-collapsed-sn-tokens" tabindex="-1" class="j3w1-example-target">Example destination: sn tokens</p><p id="example-sidebar-nav-collapsed-sn-actions" tabindex="-1" class="j3w1-example-target">Example destination: sn actions</p><p id="example-sidebar-nav-collapsed-sn-forms" tabindex="-1" class="j3w1-example-target">Example destination: sn forms</p><p id="example-sidebar-nav-collapsed-sn-ports" tabindex="-1" class="j3w1-example-target">Example destination: sn ports</p></j3w1-sidebar-nav>

nested

Example destination: sn overview

Example destination: sn actions

Example destination: sn navigation

Example destination: sn display

Example destination: sn ports

Markup
<j3w1-sidebar-nav id="example-sidebar-nav-nested"><nav class="sidebar-nav" aria-label="Sections">
  <ul class="sidebar-nav-list">
    <li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-sidebar-nav-nested-sn-overview"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><rect x="2.5" y="2.5" width="11" height="11"></rect></svg></span><span class="sidebar-nav-label">Overview</span></a></li>
    <li class="sidebar-nav-item">
      <button class="sidebar-nav-link sidebar-nav-group" type="button" aria-expanded="true" aria-controls="example-sidebar-nav-nested-sn-components"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><path d="M2.5 4h11M2.5 8h11M2.5 12h11"></path></svg></span><span class="sidebar-nav-label">Components</span><span class="sidebar-nav-chevron" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><path d="M6 4l4 4-4 4"></path></svg></span></button>
      <ul class="sidebar-nav-list sidebar-nav-sublist" id="example-sidebar-nav-nested-sn-components">
        <li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-sidebar-nav-nested-sn-actions"><span class="sidebar-nav-label">Actions</span></a></li>
        <li class="sidebar-nav-item"><a class="sidebar-nav-link sidebar-nav-current" href="#example-sidebar-nav-nested-sn-navigation" aria-current="page"><span class="sidebar-nav-label">Navigation</span></a></li>
        <li class="sidebar-nav-item"><a class="sidebar-nav-link sidebar-nav-link-demo-target" href="#example-sidebar-nav-nested-sn-display"><span class="sidebar-nav-label">Display</span></a></li>
      </ul>
    </li>
    <li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-sidebar-nav-nested-sn-ports"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><path d="M3 8h10M9 4l4 4-4 4"></path></svg></span><span class="sidebar-nav-label">Ports</span></a></li>
  </ul>
</nav><p id="example-sidebar-nav-nested-sn-overview" tabindex="-1" class="j3w1-example-target">Example destination: sn overview</p><p id="example-sidebar-nav-nested-sn-actions" tabindex="-1" class="j3w1-example-target">Example destination: sn actions</p><p id="example-sidebar-nav-nested-sn-navigation" tabindex="-1" class="j3w1-example-target">Example destination: sn navigation</p><p id="example-sidebar-nav-nested-sn-display" tabindex="-1" class="j3w1-example-target">Example destination: sn display</p><p id="example-sidebar-nav-nested-sn-ports" tabindex="-1" class="j3w1-example-target">Example destination: sn ports</p></j3w1-sidebar-nav>

Install and register

Use the exact version. If npm publication is pending, install the release tarball from the installation guide.

npm install --save-exact @j3w1/ui@4.0.0
import '@j3w1/ui/tokens.css';
import '@j3w1/ui/styles/sidebar-nav.css';
import '@j3w1/ui/register/sidebar-nav';

Insert the maintained markup above after loading these imports. Its native children provide accessible names and form behavior; the empty custom tag alone does not create a control.

Vue SFC, React, Astro and plain HTML integration →

Copy the complete implementation

npx --package=@j3w1/ui@4.0.0 j3w1-ui copy sidebar-nav --out ./vendor/j3w1/sidebar-nav

The CLI verifies every file before writing and refuses overwrites. Serve the output over HTTP and open index.html. Keep its modules, CSS, tokens and licence notices together.

Public API

attributes

NameType / signatureMeaning
disabledCustomEventDisable the native controls owned by this instance.
loadingCustomEventMark the primary control busy and prevent duplicate activation.

properties

NameType / signatureMeaning
disabledbooleanDelegates disabled state to native children.
namestringNative control name; application form keys remain explicit.
openbooleanNative details expansion when this component contains details.

methods

NameType / signatureMeaning
refresh(): voidReconnect behavior after replacing native child structure.
focus(options?: FocusOptions): voidFocus the first usable native control.

events

NameType / signatureMeaning
j3w1-toggleCustomEventA native disclosure or navigation group changed.

Dependencies and verification

Registered components: none. Style dependencies: none.

Package presence establishes an available implementation. Actual passes depend on the tested artifact and environment. Read specification execution evidence; read packed-consumer evidence; inspect the complete state matrix.

Full implementation manifest, API and token dependency closure

Canonical specification

Sidebar navigation sidebar-nav

  • Family: Navigation
  • Maturity: stable
  • Priority: R1
  • Since: 0.1.0
  • Native control: native nav with nested ul lists; groups are buttons with aria-expanded — APG pattern
  • specified
  • demonstrated

A vertical list of section links with optional nested groups; the current section carries a 2px inline-start indicator and bright text, and the rail collapses to icons.

Report an issue with this component

Open component workbench

Tokens

Focus a role to inspect its values; follow its link for persistent usage and source details.

PartRoleValueUse
root.bgcolor.surface.defaultapproveduse#0d0707D-041 surface.default: color.primitive.modern.panel.
root.bordercolor.border.dividerapproveduse#482b2bD-041 border.divider: color.primitive.modern.divider.
link.textcolor.text.defaultapproveduse#e99499D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
link.bg-hovercolor.interaction.hover.bgapproveduse#1c1010D-041 interaction.hover.bg: color.primitive.modern.hover.
link.bg-pressedcolor.interaction.pressed.bgobserveduse#420f0cPressed fill.
link.ringcolor.interaction.focus.ringobserveduse#e539351px dashed focus ring on controls and rows.
link.indicatorcolor.border.selected-indicatorobserveduse#e539352px indicator bar on the selected tab or nav item.
link.indicator-inactivecolor.border.selected-indicator-inactiveobserveduse#9e231fIndicator bar when the container is not focused.
current.textcolor.text.brightapproveduse#ffa2a7D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
selected.bgcolor.interaction.selection.bgapproveduse#531310Selected row, tab, workspace; D-027 recessed the fill, leaving the 2px indicator and the check to carry selection.
selected.textcolor.interaction.selection.textobserveduse#f4eeeeText on the selection.
selected.ringcolor.interaction.focus.ringobserveduse#e539351px dashed focus ring on controls and rows.
selected.inactive-bgcolor.interaction.selection.inactive-bgobserveduse#420f0cSelection while the container is not focused.
selected.inactive-textcolor.interaction.selection.inactive-textapproveduse#e99499D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
icon.strokecolor.icon.defaultapproveduse#e99499D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills.
group.chevroncolor.icon.decorativeapproveduse#986f72D-041 icon.decorative: color.primitive.modern.control.

Purpose

Moves between the sections of an application: the primary navigation of a settings panel, admin area or documentation site. Tabs switch views inside one section; a tree browses data, not sections.

Anatomy

A nav on color.surface.default with a 1px color.border.divider inline-end edge; otherwise parts as listed in the anatomy.

States

StateVisualNon-colour channel
defaulttext color.text.default; no fill; transparent inline-start edge—
hover→ color.interaction.hover.bgcursor: pointer
focus-visible1px dashed color.interaction.focus.ring at −2pxthe ring
current2px color.border.selected-indicator inline-start bar; text color.text.brightaria-current="page"; the bar
selectedcolor.interaction.selection.bg with color.interaction.selection.text; 1px dashed color.interaction.focus.ring at −2px when focusedaria-selected on a listbox-style rail; the on-fill text
selected+container-inactivecolor.interaction.selection.inactive-bg with color.interaction.selection.inactive-text; no ringlightness drop between the two fills
expandedchevron rotated 90°; sublist shownaria-expanded="true"; the children are present
collapsedlabels visually hidden; icons centred; current bar and fills unchangedlabels remain for assistive technology and as tooltips

current is where the user is; selected is what the user chose in a rail that drives a detail pane. A rail is one or the other, never both.

Keyboard

As in the key table; toggling a group leaves focus on its button. No arrow keys: the rail is a list of links, not a tree.

Accessibility

aria-label on the nav distinguishes the landmark. A rail that drives a detail pane is a listbox with aria-selected, not links. A closed sublist is hidden, so its links leave the tab order. Collapsed labels are clipped, not display: none, so names survive; icon-only links also get a title. Text meets 4.5:1; the indicator 3:1. Rows are at least 24 CSS pixels tall in compact.

Portability

The chevron is an SVG. Toolkits without logical borders draw the bar on the left in LTR and on the right in RTL explicitly. Hosts that cannot hide labels while keeping their names show the full rail.

Non-examples

A filled or rounded current item. The indicator on the inline-end edge. A current item marked by bold alone. Labels removed from the DOM when collapsed. Hidden children left in the tab order. A rail that scrolls horizontally. Icon-only links without an accessible name. Hover that changes the text colour.

Contrast report

13 declared pairs measured on resolved sRGB values with the WCAG 2.x formula; 0 waived (decorative only), 0 failing. A pass is a design target for the named role, not an application-wide conformance claim.

PairStateKindForegroundBackgroundRatioMinResult
sidebar-nav default textdefaulttextcolor.text.default #e99499color.surface.default #0d07078.724.5pass
sidebar-nav hover texthovertextcolor.text.default #e99499color.interaction.hover.bg #1c10108.104.5pass
sidebar-nav focus-visible textfocus-visibletextcolor.text.default #e99499color.surface.default #0d07078.724.5pass
sidebar-nav focus-visible outlinefocus-visibleuicolor.interaction.focus.ring #e53935color.surface.default #0d07074.733pass
sidebar-nav current textcurrenttextcolor.text.bright #ffa2a7color.surface.default #0d070710.454.5pass
sidebar-nav current bordercurrentuicolor.border.selected-indicator #e53935color.surface.default #0d07074.733pass
sidebar-nav selected textselectedtextcolor.interaction.selection.text #f4eeeecolor.interaction.selection.bg #53131012.474.5pass
sidebar-nav selected+container-inactive textselected+container-inactivetextcolor.interaction.selection.inactive-text #e99499color.interaction.selection.inactive-bg #420f0c7.024.5pass
sidebar-nav expanded textexpandedtextcolor.text.default #e99499color.surface.default #0d07078.724.5pass
sidebar-nav collapsed textcollapsedtextcolor.text.default #e99499color.surface.default #0d07078.724.5pass
ring on a selected item when focusedselecteduicolor.interaction.focus.ring #e53935color.interaction.selection.bg #5313103.383pass
group chevron (decorative; aria-expanded carries the state)—uicolor.icon.decorative #986f72color.surface.default #0d07074.621pass
rail edge (decorative)—uicolor.border.divider #482b2bcolor.surface.default #0d07071.581pass

Keys

KeyAction
Tab / Shift+TabMoves through links and group buttons in document order; hidden children are skipped.
EnterFollows a link or toggles a group.
SpaceToggles a group.

For agents

Component JSON ·Implementation brief ·Build a task kit ·

Related: tabs breadcrumbs tree disclosure drawer

Stress fixtures: FX-LONG FX-320 FX-ZOOM-200 FX-I18N FX-RTL FX-RM FX-HC FX-STATE-MATRIX