J3W1 / DESIGN SYSTEM
Settings panel
A two-column settings screen composed from the sidebar-nav, fieldset, switch, select, radio-group, text-field, checkbox and button components; below 600px the sidebar becomes a tab strip.
stable · LIGHT DOM · 1.1.0
Light DOM retains static content, native semantics, label relationships and host composition without duplicating controls.
Live variants
default
Example destination: sp keyboard
Example destination: sp notifications
Example destination: sp advanced
<j3w1-settings-panel id="example-settings-panel-default"><form><div class="settings-panel" role="region" aria-labelledby="example-settings-panel-default-sp-title">
<div class="settings-panel-nav">
<nav class="sidebar-nav" aria-label="Settings sections">
<ul class="sidebar-nav-list">
<li class="sidebar-nav-item"><a class="sidebar-nav-link sidebar-nav-current" href="#example-settings-panel-default-sp-appearance" 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">Appearance</span></a></li>
<li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-settings-panel-default-sp-keyboard"><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="4.5" width="11" height="7"></rect><path d="M5 8h6"></path></svg></span><span class="sidebar-nav-label">Keyboard</span></a></li>
<li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-settings-panel-default-sp-notifications"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><path d="M4 11V7a4 4 0 0 1 8 0v4l1 1H3z"></path><path d="M6.5 13.5h3"></path></svg></span><span class="sidebar-nav-label">Notifications</span></a></li>
<li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-settings-panel-default-sp-advanced"><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">Advanced</span></a></li>
</ul>
</nav>
</div>
<div class="settings-panel-content" role="form" aria-labelledby="example-settings-panel-default-sp-title" id="example-settings-panel-default-sp-appearance">
<h2 class="settings-panel-title" id="example-settings-panel-default-sp-title">Appearance</h2>
<p class="settings-panel-lead">Bar, gaps and labels of the workstation. Changes apply to new windows.</p>
<fieldset class="fieldset settings-panel-group">
<legend class="fieldset-legend">Bar and gaps</legend>
<div class="fieldset-body">
<div class="switch-row">
<span class="switch-name" id="example-settings-panel-default-sp-hide-bar-name">Hide the bar</span>
<j3w1-switch><button class="switch settings-panel-demo-target" type="button" role="switch" aria-checked="false" aria-labelledby="example-settings-panel-default-sp-hide-bar-name">
<span class="switch-track"><span class="switch-thumb"></span></span>
<span class="switch-state" aria-hidden="true"><span class="switch-state-off">Off</span><span class="switch-state-on">On</span></span>
</button></j3w1-switch>
</div>
<div class="switch-row">
<span class="switch-name" id="example-settings-panel-default-sp-smart-gaps-name">Smart gaps</span>
<j3w1-switch><button class="switch" type="button" role="switch" aria-checked="true" aria-labelledby="example-settings-panel-default-sp-smart-gaps-name">
<span class="switch-track"><span class="switch-thumb"></span></span>
<span class="switch-state" aria-hidden="true"><span class="switch-state-off">Off</span><span class="switch-state-on">On</span></span>
</button></j3w1-switch>
</div>
<div class="select">
<label class="select-label" for="example-settings-panel-default-sp-wallpaper">Wallpaper</label>
<div class="select-root">
<select class="select-control" id="example-settings-panel-default-sp-wallpaper" aria-describedby="example-settings-panel-default-sp-wallpaper-help example-settings-panel-default-sp-wallpaper-message" name="example-settings-panel-default-sp-wallpaper">
<option value="black" selected="">black</option>
<option value="ember">ember</option>
<option value="ridge">ridge</option>
</select>
<svg class="select-chevron" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M4 6.5l4 4 4-4"></path></svg>
</div>
<p class="select-help" id="example-settings-panel-default-sp-wallpaper-help">Shown only where no window is.</p>
<p class="select-message" id="example-settings-panel-default-sp-wallpaper-message">✕ Choose a wallpaper.</p>
</div>
<fieldset class="radio-group radio-group-horizontal" aria-describedby="example-settings-panel-default-sp-labels-message">
<legend class="radio-group-legend">Bar labels</legend>
<div class="radio-group-options">
<label class="radio-group-option">
<span class="radio-group-control">
<input class="radio-group-input" type="radio" name="example-settings-panel-default-sp-labels" value="zh" checked="">
<span class="radio-group-dot" aria-hidden="true"></span>
</span>
<span class="radio-group-text" lang="zh">中文</span>
</label>
<label class="radio-group-option">
<span class="radio-group-control">
<input class="radio-group-input" type="radio" name="example-settings-panel-default-sp-labels" value="en">
<span class="radio-group-dot" aria-hidden="true"></span>
</span>
<span class="radio-group-text">English</span>
</label>
</div>
<p class="radio-group-message" id="example-settings-panel-default-sp-labels-message">✕ Choose a language.</p>
</fieldset>
<div class="text-field">
<label class="text-field-label" for="example-settings-panel-default-sp-inner-gap">Inner gap</label>
<div class="text-field-root">
<input class="text-field-input text-field-input-numeric" id="example-settings-panel-default-sp-inner-gap" type="number" value="14" min="0" max="64" step="1" placeholder="0" aria-describedby="example-settings-panel-default-sp-inner-gap-help example-settings-panel-default-sp-inner-gap-message" name="example-settings-panel-default-sp-inner-gap">
<span class="text-field-affix" aria-hidden="true">px</span>
<span class="text-field-loading" aria-hidden="true">⋯</span>
</div>
<p class="text-field-help" id="example-settings-panel-default-sp-inner-gap-help">Pixels between windows; the outer gap follows.</p>
<p class="text-field-message" id="example-settings-panel-default-sp-inner-gap-message">✕ Between 0 and 64.</p>
</div>
<fieldset class="checkbox checkbox-group" aria-describedby="example-settings-panel-default-sp-modules-message">
<legend class="checkbox-legend">Bar modules</legend>
<label class="checkbox-option">
<span class="checkbox-control">
<input class="checkbox-input" type="checkbox" name="example-settings-panel-default-sp-modules" value="cpu" checked="">
<svg class="checkbox-check" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M3.5 8.5l3 3 6-6"></path></svg>
<svg class="checkbox-dash" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M4 8h8"></path></svg>
</span>
<span class="checkbox-text">CPU load</span>
</label>
<label class="checkbox-option">
<span class="checkbox-control">
<input class="checkbox-input" type="checkbox" name="example-settings-panel-default-sp-modules" value="memory" checked="">
<svg class="checkbox-check" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M3.5 8.5l3 3 6-6"></path></svg>
<svg class="checkbox-dash" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M4 8h8"></path></svg>
</span>
<span class="checkbox-text">Memory</span>
</label>
<label class="checkbox-option">
<span class="checkbox-control">
<input class="checkbox-input" type="checkbox" name="example-settings-panel-default-sp-modules" value="battery">
<svg class="checkbox-check" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M3.5 8.5l3 3 6-6"></path></svg>
<svg class="checkbox-dash" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M4 8h8"></path></svg>
</span>
<span class="checkbox-text">Battery</span>
</label>
<p class="checkbox-message" id="example-settings-panel-default-sp-modules-message">✕ Choose at least one module.</p>
</fieldset>
</div>
</fieldset>
<div class="settings-panel-footer">
<button class="button settings-panel-apply" type="submit"><span class="button-loading" aria-hidden="true">⋯</span><span class="button-label">Apply</span></button>
<button class="button button-secondary" type="button"><span class="button-loading" aria-hidden="true">⋯</span><span class="button-label">Reset</span></button>
</div>
</div>
</div></form><p role="status" data-form-status=""></p><p id="example-settings-panel-default-sp-keyboard" tabindex="-1" class="j3w1-example-target">Example destination: sp keyboard</p><p id="example-settings-panel-default-sp-notifications" tabindex="-1" class="j3w1-example-target">Example destination: sp notifications</p><p id="example-settings-panel-default-sp-advanced" tabindex="-1" class="j3w1-example-target">Example destination: sp advanced</p></j3w1-settings-panel>narrow
Example destination: sp keyboard
Example destination: sp notifications
Example destination: sp advanced
<j3w1-settings-panel id="example-settings-panel-narrow"><form><div class="settings-panel settings-panel-narrow" role="region" aria-labelledby="example-settings-panel-narrow-sp-title">
<div class="settings-panel-nav">
<nav class="sidebar-nav" aria-label="Settings sections">
<ul class="sidebar-nav-list">
<li class="sidebar-nav-item"><a class="sidebar-nav-link sidebar-nav-current" href="#example-settings-panel-narrow-sp-appearance" 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">Appearance</span></a></li>
<li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-settings-panel-narrow-sp-keyboard"><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="4.5" width="11" height="7"></rect><path d="M5 8h6"></path></svg></span><span class="sidebar-nav-label">Keyboard</span></a></li>
<li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-settings-panel-narrow-sp-notifications"><span class="sidebar-nav-icon" aria-hidden="true"><svg viewBox="0 0 16 16" width="16" height="16" focusable="false"><path d="M4 11V7a4 4 0 0 1 8 0v4l1 1H3z"></path><path d="M6.5 13.5h3"></path></svg></span><span class="sidebar-nav-label">Notifications</span></a></li>
<li class="sidebar-nav-item"><a class="sidebar-nav-link" href="#example-settings-panel-narrow-sp-advanced"><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">Advanced</span></a></li>
</ul>
</nav>
</div>
<div class="settings-panel-content" role="form" aria-labelledby="example-settings-panel-narrow-sp-title" id="example-settings-panel-narrow-sp-appearance">
<h2 class="settings-panel-title" id="example-settings-panel-narrow-sp-title">Appearance</h2>
<p class="settings-panel-lead">Bar, gaps and labels of the workstation. Changes apply to new windows.</p>
<fieldset class="fieldset settings-panel-group">
<legend class="fieldset-legend">Bar and gaps</legend>
<div class="fieldset-body">
<div class="switch-row">
<span class="switch-name" id="example-settings-panel-narrow-sp-hide-bar-name">Hide the bar</span>
<j3w1-switch><button class="switch settings-panel-demo-target" type="button" role="switch" aria-checked="false" aria-labelledby="example-settings-panel-narrow-sp-hide-bar-name">
<span class="switch-track"><span class="switch-thumb"></span></span>
<span class="switch-state" aria-hidden="true"><span class="switch-state-off">Off</span><span class="switch-state-on">On</span></span>
</button></j3w1-switch>
</div>
<div class="switch-row">
<span class="switch-name" id="example-settings-panel-narrow-sp-smart-gaps-name">Smart gaps</span>
<j3w1-switch><button class="switch" type="button" role="switch" aria-checked="true" aria-labelledby="example-settings-panel-narrow-sp-smart-gaps-name">
<span class="switch-track"><span class="switch-thumb"></span></span>
<span class="switch-state" aria-hidden="true"><span class="switch-state-off">Off</span><span class="switch-state-on">On</span></span>
</button></j3w1-switch>
</div>
<div class="select">
<label class="select-label" for="example-settings-panel-narrow-sp-wallpaper">Wallpaper</label>
<div class="select-root">
<select class="select-control" id="example-settings-panel-narrow-sp-wallpaper" aria-describedby="example-settings-panel-narrow-sp-wallpaper-help example-settings-panel-narrow-sp-wallpaper-message" name="example-settings-panel-narrow-sp-wallpaper">
<option value="black" selected="">black</option>
<option value="ember">ember</option>
<option value="ridge">ridge</option>
</select>
<svg class="select-chevron" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M4 6.5l4 4 4-4"></path></svg>
</div>
<p class="select-help" id="example-settings-panel-narrow-sp-wallpaper-help">Shown only where no window is.</p>
<p class="select-message" id="example-settings-panel-narrow-sp-wallpaper-message">✕ Choose a wallpaper.</p>
</div>
<fieldset class="radio-group radio-group-horizontal" aria-describedby="example-settings-panel-narrow-sp-labels-message">
<legend class="radio-group-legend">Bar labels</legend>
<div class="radio-group-options">
<label class="radio-group-option">
<span class="radio-group-control">
<input class="radio-group-input" type="radio" name="example-settings-panel-narrow-sp-labels" value="zh" checked="">
<span class="radio-group-dot" aria-hidden="true"></span>
</span>
<span class="radio-group-text" lang="zh">中文</span>
</label>
<label class="radio-group-option">
<span class="radio-group-control">
<input class="radio-group-input" type="radio" name="example-settings-panel-narrow-sp-labels" value="en">
<span class="radio-group-dot" aria-hidden="true"></span>
</span>
<span class="radio-group-text">English</span>
</label>
</div>
<p class="radio-group-message" id="example-settings-panel-narrow-sp-labels-message">✕ Choose a language.</p>
</fieldset>
<div class="text-field">
<label class="text-field-label" for="example-settings-panel-narrow-sp-inner-gap">Inner gap</label>
<div class="text-field-root">
<input class="text-field-input text-field-input-numeric" id="example-settings-panel-narrow-sp-inner-gap" type="number" value="14" min="0" max="64" step="1" placeholder="0" aria-describedby="example-settings-panel-narrow-sp-inner-gap-help example-settings-panel-narrow-sp-inner-gap-message" name="example-settings-panel-narrow-sp-inner-gap">
<span class="text-field-affix" aria-hidden="true">px</span>
<span class="text-field-loading" aria-hidden="true">⋯</span>
</div>
<p class="text-field-help" id="example-settings-panel-narrow-sp-inner-gap-help">Pixels between windows; the outer gap follows.</p>
<p class="text-field-message" id="example-settings-panel-narrow-sp-inner-gap-message">✕ Between 0 and 64.</p>
</div>
<fieldset class="checkbox checkbox-group" aria-describedby="example-settings-panel-narrow-sp-modules-message">
<legend class="checkbox-legend">Bar modules</legend>
<label class="checkbox-option">
<span class="checkbox-control">
<input class="checkbox-input" type="checkbox" name="example-settings-panel-narrow-sp-modules" value="cpu" checked="">
<svg class="checkbox-check" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M3.5 8.5l3 3 6-6"></path></svg>
<svg class="checkbox-dash" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M4 8h8"></path></svg>
</span>
<span class="checkbox-text">CPU load</span>
</label>
<label class="checkbox-option">
<span class="checkbox-control">
<input class="checkbox-input" type="checkbox" name="example-settings-panel-narrow-sp-modules" value="memory" checked="">
<svg class="checkbox-check" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M3.5 8.5l3 3 6-6"></path></svg>
<svg class="checkbox-dash" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M4 8h8"></path></svg>
</span>
<span class="checkbox-text">Memory</span>
</label>
<label class="checkbox-option">
<span class="checkbox-control">
<input class="checkbox-input" type="checkbox" name="example-settings-panel-narrow-sp-modules" value="battery">
<svg class="checkbox-check" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M3.5 8.5l3 3 6-6"></path></svg>
<svg class="checkbox-dash" aria-hidden="true" focusable="false" width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square"><path d="M4 8h8"></path></svg>
</span>
<span class="checkbox-text">Battery</span>
</label>
<p class="checkbox-message" id="example-settings-panel-narrow-sp-modules-message">✕ Choose at least one module.</p>
</fieldset>
</div>
</fieldset>
<div class="settings-panel-footer">
<button class="button settings-panel-apply" type="submit"><span class="button-loading" aria-hidden="true">⋯</span><span class="button-label">Apply</span></button>
<button class="button button-secondary" type="button"><span class="button-loading" aria-hidden="true">⋯</span><span class="button-label">Reset</span></button>
</div>
</div>
</div></form><p role="status" data-form-status=""></p><p id="example-settings-panel-narrow-sp-keyboard" tabindex="-1" class="j3w1-example-target">Example destination: sp keyboard</p><p id="example-settings-panel-narrow-sp-notifications" tabindex="-1" class="j3w1-example-target">Example destination: sp notifications</p><p id="example-settings-panel-narrow-sp-advanced" tabindex="-1" class="j3w1-example-target">Example destination: sp advanced</p></j3w1-settings-panel>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@1.1.0import '@j3w1/ui/tokens.css';
import '@j3w1/ui/styles/settings-panel.css';
import '@j3w1/ui/register/settings-panel';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.
Copy the complete implementation
npx --package=@j3w1/ui@1.1.0 j3w1-ui copy settings-panel --out ./vendor/j3w1/settings-panelThe 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
| Name | Type / signature | Meaning |
|---|---|---|
disabled | CustomEvent | Disable the native controls owned by this instance. |
loading | CustomEvent | Mark the primary control busy and prevent duplicate activation. |
properties
| Name | Type / signature | Meaning |
|---|---|---|
disabled | boolean | Delegates disabled state to native children. |
name | string | Native control name; application form keys remain explicit. |
methods
| Name | Type / signature | Meaning |
|---|---|---|
refresh | (): void | Reconnect behavior after replacing native child structure. |
focus | (options?: FocusOptions): void | Focus the first usable native control. |
events
| Name | Type / signature | Meaning |
|---|---|---|
j3w1-submit | CustomEvent | Validated local native form values; the host owns saving. |
Dependencies and verification
Registered components: switch. Style dependencies: button, field, text-field, checkbox, radio-group, select, switch, sidebar-nav, fieldset.
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
Purpose
A settings screen that proves the form components compose without new tokens: a section list on the left, one fieldset of preferences on the right, and a footer of actions. It exists to show the pieces together under every state and at every width, not to prescribe a product.
Anatomy
The region landmark; the sidebar-nav with the open section marked by
aria-current and the 2px color.border.selected-indicator; the form
landmark with its h2 in color.text.bright and lead in color.text.muted;
one fieldset with a color.border.divider edge holding two switches (Hide
the bar, Smart gaps), a wallpaper select, the bar-label radio-group (中文 /
English), the inner-gap text-field with a px suffix and the bar-module
checkbox group; a footer rule and the Apply (primary) and Reset (secondary)
buttons. Every part is the component’s own markup and classes.
States
| State | Visual | Non-colour channel |
|---|---|---|
| default | rest tokens of every component on color.surface.default; the open section carries the indicator bar | aria-current |
| focus-visible | the dashed color.interaction.focus.ring on the control holding focus (shown on the first switch); the other controls stay at rest | the ring |
| invalid | the inner-gap field takes the 2px color.status.danger.border and shows its ✕ message; the other controls stay at rest | border width 1 → 2px; glyph; aria-invalid |
| busy | Apply shows the static ⋯ glyph in color.action.primary.text; the form carries aria-busy; nothing shrinks or animates | glyph; aria-busy; cursor: progress |
The composed components keep their own hover, checked, disabled and read-only treatments; this specimen declares only the states the screen adds to them.
Keyboard
Landmarks first: a screen reader’s landmark list offers the region, the navigation and the form by name. Tab walks the section links, then every control in reading order, then Apply and Reset. The radio-group and the select move with arrows inside one stop; the numeric field steps with Up and Down; switches and checkboxes toggle with Space. Nothing traps focus and nothing changes on hover alone.
Accessibility
The region is named by the h2 through aria-labelledby; the nav has its own
label so two navigation landmarks on a page stay distinguishable; the open
section is aria-current="page". The form is named by the same h2 and
carries aria-busy="true" while Apply is in progress, so the pending state
is announced without a live region. Every control has a programmatic label;
every message is linked by aria-describedby. Contrast: title 10.10:1 and
lead 5.66:1 on the panel surface, control boundaries 4.33:1, the indicator
bar 4.57:1, the danger border 4.69:1 on the input surface.
Portability
Three landmarks, native controls and a container query; nothing here needs a script. A host without container queries collapses the sidebar at the 600px viewport breakpoint. The 56rem reference width, the sidebar width and the two-column grid belong to this specimen and are not rules; the specimen proves composition, not a product. Toolkits port each contained component through its own mapping and place them with their native layout.
Non-examples
A rounded, shadowed settings card. A Material-style app bar above the form. Toggle switches with rounded pills or animated thumbs. Section links drawn as filled tabs instead of the indicator bar. A red form background to show that something is invalid. Applying while the controls are dimmed with opacity. A spinner replacing the Apply label.