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

tngToggle gives a native <button> pressed semantics, while tngToggleGroup coordinates shared selection when multiple toggles belong to one decision surface.

tngToggle

Attach the directive to a native button. The directive keeps keyboard behavior native, reflects aria-pressed, and supports both controlled and uncontrolled usage.

Standalone toggle

html
<button
  tngToggle
  [pressed]="showGrid()"
  ariaLabel="Grid view"
  (pressedChange)="showGrid.set($event)"
>
  Grid
</button>
InputTypeDefaultDetails
tngToggleValuestring | nullnullItem identity when the toggle participates in a group.
pressedboolean | null | '' | 'true' | 'false'nullControlled pressed state for standalone usage.
defaultPressedboolean | '' | stringfalseInitial pressed state when the toggle manages itself.
disabledboolean | '' | stringfalseDisables interaction and reflects disabled attributes.
ariaLabel, ariaLabelledby, ariaDescribedBystring | nullnullAccessible naming and helper-text hooks.
pressedChangeEventEmitter<boolean>n/aEmits the next pressed state after interaction.

When a grouped toggle has a non-empty tngToggleValue, the group owns its visual pressed state. In that case, use the group outputs instead of standalone pressed control.

tngToggleGroup

Add the group directive to any container when toggles should share a selection model. Single-selection groups emit valueChange; multi-selection groups emit valuesChange.

Single-select group

html
<div
  tngToggleGroup
  selectionMode="single"
  ariaLabel="View mode"
  [value]="viewMode()"
  (valueChange)="onViewModeChange($event)"
>
  <button tngToggle tngToggleValue="grid">Grid</button>
  <button tngToggle tngToggleValue="list">List</button>
  <button tngToggle tngToggleValue="split">Split</button>
</div>
InputTypeDefaultDetails
selectionMode'single' | 'multiple''multiple'Switches between single-choice and multi-select behavior.
orientation'horizontal' | 'vertical''horizontal'Orientation hook for layout and accessibility messaging.
value, defaultValuestring | nullnullControlled and uncontrolled single-select values.
values, defaultValuesreadonly string[][]Controlled and uncontrolled multiple-select values.
disabledboolean | '' | stringfalseDisables every child toggle through the shared group state.
ariaLabel, ariaLabelledbystring | nullnullAccessible name for the group region.
valueChange, valuesChangeEventEmittern/aSelection outputs for single or multiple mode.

Reflected attributes

SelectorApplied onPurpose
data-slot="toggle"Toggle buttonStable styling hook for the primitive button.
data-state="on" | "off"Toggle buttonPressed state styling and animation hook.
data-disabledToggle button + groupDisabled styling for item and shared surface.
data-focused, data-focus-visibleToggle buttonFocus and keyboard-focus differentiation.
data-slot="toggle-group"Group hostStable hook for container styling.
data-selection-mode, data-orientationGroup hostLayout and state styling hooks on the container.
role="group"Group hostCommunicates grouped semantics to assistive technology.

Change handling

Standalone toggles emit booleans. Groups emit the selected value or values depending on the selection mode.

State handling

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

type ToggleViewMode = 'grid' | 'list' | 'split';

readonly viewMode = signal<ToggleViewMode>('grid');

function onViewModeChange(value: string | null): void {
  if (value === 'grid' || value === 'list' || value === 'split') {
    viewMode.set(value);
  }
}

function onBoldPressedChange(nextPressed: boolean): void {
  boldEnabled.set(nextPressed);
}