# Switch

## Usage

Switch toggles a single setting on or off. It renders `role="switch"`, not a
native form control, so associate an accessible name with `aria-label` or
`aria-labelledby`.

## Checked and disabled states

Use `checked` with `onCheckedChange` in React, or `[(checked)]` in Angular.
`defaultChecked` captures the initial uncontrolled state. A controlled switch
emits a request but does not change until its owner supplies the new value.
Use `disabled` to prevent interaction.

**React**

```tsx
import { useState } from 'react';
import { Switch } from '@udixio/ui-react';

export default function SwitchStatesReact() {
  const [checked, setChecked] = useState(false);

  return (
    <div className="flex flex-wrap items-center gap-6">
      <Switch
        aria-label="Controlled"
        checked={checked}
        onCheckedChange={setChecked}
      />
      <Switch aria-label="Default checked" defaultChecked />
      <Switch aria-label="Disabled" disabled />
      <Switch aria-label="Disabled and checked" defaultChecked disabled />
    </div>
  );
}
```

**Angular**

```ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { Switch } from '@udixio/ui-angular';

@Component({
  selector: 'switch-states-angular-example',
  standalone: true,
  imports: [Switch],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <div class="flex flex-wrap items-center gap-6">
      <lib-switch aria-label="Controlled" [(checked)]="checked" />
      <lib-switch aria-label="Default checked" defaultChecked />
      <lib-switch aria-label="Disabled" disabled />
      <lib-switch aria-label="Disabled and checked" defaultChecked disabled />
    </div>
  `,
})
export class SwitchStatesAngular {
  protected checked = false;
}
```

## With icons

Provide `activeIcon` and/or `inactiveIcon` to display inside the thumb. The
thumb slide between positions is driven by a shared `@udixio/core/dom` Motion
controller, so React and Angular animate identically.

**React**

```tsx
import { useState } from 'react';
import { Switch } from '@udixio/ui-react';
import { iDarkMode } from '@udixio/icons-rounded-400/dark_mode';
import { iLightMode } from '@udixio/icons-rounded-400/light_mode';

export default function SwitchIconsReact() {
  const [checked, setChecked] = useState(true);

  return (
    <Switch
      aria-label="Theme"
      checked={checked}
      onCheckedChange={setChecked}
      activeIcon={iLightMode}
      inactiveIcon={iDarkMode}
    />
  );
}
```

**Angular**

```ts
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { iDarkMode } from '@udixio/icons-rounded-400/dark_mode';
import { iLightMode } from '@udixio/icons-rounded-400/light_mode';
import { Switch } from '@udixio/ui-angular';

@Component({
  selector: 'switch-icons-angular-example',
  standalone: true,
  imports: [Switch],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <lib-switch
      aria-label="Theme"
      [(checked)]="checked"
      [activeIcon]="lightIcon"
      [inactiveIcon]="darkIcon"
    />
  `,
})
export class SwitchIconsAngular {
  protected checked = true;
  protected readonly lightIcon = iLightMode;
  protected readonly darkIcon = iDarkMode;
}
```

## Accessibility

Switch exposes `aria-checked` and toggles with a click or with Space/Enter
when focused. It never renders a visible label on its own; pair it with
`aria-label`, `aria-labelledby`, or a visible label element referencing it
through your own markup.
