Skip to content
Navigation

Switch

Added 14 October 2026

React

Codecomponents/react/switch-demo.tsx
import {Switch, Label} from '@stroeer-labs/design-library/react';

export function SwitchDemo() {
    return (
        <div className="space-y-6">
            <div className="space-y-2">
                <p className="text-xs font-medium text-muted-foreground">Default</p>
                <div className="flex items-center gap-3">
                    <Switch id="airplane" />
                    <Label htmlFor="airplane">Airplane mode</Label>
                </div>
            </div>
            <div className="space-y-2">
                <p className="text-xs font-medium text-muted-foreground">On by default</p>
                <div className="flex items-center gap-3">
                    <Switch id="wifi" defaultChecked />
                    <Label htmlFor="wifi">Wi-Fi</Label>
                </div>
            </div>
            <div className="space-y-2">
                <p className="text-xs font-medium text-muted-foreground">Disabled</p>
                <div className="flex items-center gap-3">
                    <Switch id="bluetooth-off" disabled />
                    <Label htmlFor="bluetooth-off">Bluetooth</Label>
                </div>
                <div className="flex items-center gap-3">
                    <Switch id="location-on" disabled defaultChecked />
                    <Label htmlFor="location-on">Location (locked on)</Label>
                </div>
            </div>
            <div className="space-y-2">
                <p className="text-xs font-medium text-muted-foreground">Card</p>
                {/* Settings row: the whole label toggles the nested switch, and the row fills in when checked
                    via has-[[aria-checked=true]]. Upstream shadcn/spartan hardcode blue-* here; we map to
                    bg-muted per the no-built-in-palette rule. Canonical — the Angular demo mirrors this. */}
                <Label className="flex items-center justify-between gap-3 rounded-lg border border-border/50 p-3 hover:bg-muted/50 has-[[aria-checked=true]]:bg-muted">
                    <div className="grid gap-1.5 font-normal">
                        <p className="text-sm leading-none font-medium">Marketing emails</p>
                        <p className="text-sm text-muted-foreground">Receive emails about new products and features.</p>
                    </div>
                    <Switch id="marketing" defaultChecked />
                </Label>
            </div>
        </div>
    );
}

Angular

Codecomponents/angular/switch-demo.ts
import '@angular/compiler';
import {Component} from '@angular/core';
import {HlmSwitchImports, HlmLabelImports} from '@stroeer-labs/design-library/angular';

@Component({
    selector: 'dl-switch-demo',
    standalone: true,
    imports: [HlmSwitchImports, HlmLabelImports],
    template: `
    <div class="space-y-6">
      <div class="space-y-2">
        <p class="text-xs font-medium text-muted-foreground">Default</p>
        <div class="flex items-center gap-3">
          <hlm-switch inputId="airplane" />
          <label hlmLabel for="airplane">Airplane mode</label>
        </div>
      </div>
      <div class="space-y-2">
        <p class="text-xs font-medium text-muted-foreground">On by default</p>
        <div class="flex items-center gap-3">
          <hlm-switch inputId="wifi" [checked]="true" />
          <label hlmLabel for="wifi">Wi-Fi</label>
        </div>
      </div>
      <div class="space-y-2">
        <p class="text-xs font-medium text-muted-foreground">Disabled</p>
        <div class="flex items-center gap-3">
          <hlm-switch inputId="bluetooth-off" disabled />
          <label hlmLabel for="bluetooth-off">Bluetooth</label>
        </div>
        <div class="flex items-center gap-3">
          <hlm-switch inputId="location-on" disabled [checked]="true" />
          <label hlmLabel for="location-on">Location (locked on)</label>
        </div>
      </div>
      <div class="space-y-2">
        <p class="text-xs font-medium text-muted-foreground">Card</p>
        <!-- Settings row: the whole label toggles the nested switch, and the row fills in when checked via
             has-[[aria-checked=true]]. Upstream shadcn/spartan hardcode blue-* here; we map to bg-muted per
             the no-built-in-palette rule. Mirrors the React switch demo. -->
        <label hlmLabel class="flex items-center justify-between gap-3 rounded-lg border border-border/50 p-3 hover:bg-muted/50 has-[[aria-checked=true]]:bg-muted">
          <div class="grid gap-1.5 font-normal">
            <p class="text-sm leading-none font-medium">Marketing emails</p>
            <p class="text-sm text-muted-foreground">Receive emails about new products and features.</p>
          </div>
          <hlm-switch inputId="marketing" [checked]="true" />
        </label>
      </div>
    </div>
  `,
})
export class SwitchDemoComponent {}