# 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.

## API

### React

Switches toggle the selection of a single item on or off.

**Status:** beta

**Category:** Input

**Devx**

- Use `checked` with `onCheckedChange` for controlled state, or `defaultChecked` for uncontrolled state.
- The thumb slide is driven by a shared `@udixio/core/dom` Anime.js tween controller, the same one the Angular
  adapter uses -- an accepted exception to the rest of `@udixio/core/dom`, which uses Motion.

**Accessibility**

- Renders `role="switch"` with `aria-checked` and standard Space/Enter activation.

**Limitations**

- The component does not render a visible label; provide one with `aria-label` or `aria-labelledby`.

#### Props

| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `className` | `string \| ClassNameComponent<SwitchInterface>` | No | — | Classes or state-aware element classes applied through the shared style contract. |
| `defaultChecked` | `boolean` | No | `false` | Uncontrolled mode: initial checked state. |
| `checked` | `boolean` | No | — | Controlled mode: explicitly control whether the switch is on. |
| `activeIcon` | `Icon` | No | — | Icon shown inside the thumb while checked. |
| `inactiveIcon` | `Icon` | No | — | Icon shown inside the thumb while unchecked. |
| `disabled` | `boolean` | No | `false` | Prevents interaction. |
| `onCheckedChange` | `(checked: boolean) => void` | No | — | Called once for each accepted checked-state transition. |

### Angular

Switches toggle the selection of a single item on or off.

**Status:** beta

**Category:** Input

**Devx**

- `checked` is controlled; `defaultChecked` initializes uncontrolled use.
- `checkedChange` emits one accepted transition and supports `[(checked)]`.
- The thumb slide is driven by a shared `@udixio/core/dom` Anime.js tween controller, the same one the React
  adapter uses -- an accepted exception to the rest of `@udixio/core/dom`, which uses Motion.

**Accessibility**

- Renders `role="switch"` with `aria-checked` and standard Space/Enter activation.

**Limitations**

- The component does not render a visible label; provide one with `aria-label` or `aria-labelledby`.

#### Inputs

| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `checked` | `boolean \| undefined` | No | — | Controlled mode: explicitly control whether the switch is on. |
| `defaultChecked` | `boolean` | No | `false` | Uncontrolled mode: initial checked state. |
| `activeIcon` | `IconType` | No | — | Icon shown inside the thumb while checked. |
| `inactiveIcon` | `IconType` | No | — | Icon shown inside the thumb while unchecked. |
| `disabled` | `boolean` | No | `false` | Prevents interaction. |
| `ariaLabel` (alias: `aria-label`) | `string \| undefined` | No | — | Accessible-name override when no visible label is available. |
| `ariaLabelledBy` (alias: `aria-labelledby`) | `string \| undefined` | No | — | Id reference for text that labels this switch. |
| `className` | `string \| ClassNameComponent<SwitchInterface>` | No | — | Classes or state-aware element classes applied through the shared style contract. |

#### Outputs

| Name | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `checkedChange` | `boolean` | No | — | Emits an accepted checked-state request and supports `[(checked)]`. |
