Getting StartedInstall and bootstrap headless foundations 4
LayoutHeadless structural primitives for expandable and container patterns 6
OverlayHeadless modal and floating layer behavior 3
FeedbackHeadless notification and status communication patterns 5
FormHeadless input and selection contracts 17
UtilityReusable action, identity, and clipboard behavior 6
NavigationHeadless trails, trees, menus, and command surfaces 7

API reference

Headless switch is a directive attached to button[tngSwitch]. It does not emit a custom Angular output or render a wrapper for you. Your app owns the thumb markup, the surrounding copy, and the state transitions.

Directive attachment

html
<button
  tngSwitch
  [checked]="releaseReady()"
  ariaLabel="Release ready"
  (click)="releaseReady.update(value => !value)"
>
  <span class="switch-thumb" aria-hidden="true"></span>
</button>

Recommended labeled row

html
<div class="switch-row">
  <button
    tngSwitch
    [checked]="notificationsEnabled()"
    ariaLabel="Notifications"
    (click)="notificationsEnabled.update(value => !value)"
  >
    <span class="switch-thumb" aria-hidden="true"></span>
  </button>
  <div class="switch-copy">
    <span class="switch-copy__title">Notifications</span>
    <span class="switch-copy__meta">Send release alerts to the on-call team.</span>
  </div>
</div>
InputTypeDefaultNotes
checkedboolean | '' | stringfalseControls the ARIA state and the data-state hook.
disabledboolean | '' | stringfalseBlocks interaction and reflects disabled plus data-disabled.
requiredboolean | '' | stringfalseReflects to aria-required for assistive technology.
ariaLabelstring | nullnullAccessible name for the switch button when visible copy is separate.

Reflected attributes

The directive reflects a minimal state contract onto the host button so your CSS can style checked, unchecked, and disabled states without extra wrapper logic.

AttributeWhen presentPurpose
role="switch"AlwaysDeclares switch semantics on the button host.
type="button"AlwaysPrevents accidental form submission.
aria-checkedAlwaysMirrors the current on/off state as true or false.
aria-requiredWhen requiredSignals mandatory state to assistive technology.
data-stateAlwayschecked or unchecked styling hook.
data-disabledWhen disabledConvenient disabled styling hook.
data-slot="switch"AlwaysStable selector anchor for theme or utility CSS.

Change handling

Headless switch does not own state updates. Listen to click and update the parent signal or store yourself.

switch-state.ts

ts
import { signal } from '@angular/core';

readonly notificationsEnabled = signal(false);

onNotificationsToggle(): void {
  this.notificationsEnabled.update((value) => !value);
}

Because the primitive is a button, adjacent text is only visual. If the label copy sits outside the button, keep ariaLabel in sync with that visible text.