# Switch
> Switch represents a physical switch that allows users to turn things on or off, where choosing an option results in an action.

## Import

```js
import { Switch } from '@gemini-suite/vera-react';
```

Switch is a compound component that consists of multiple parts:

- `Switch.Root`: The wrapper that contains all the parts of a switch and provides context for its children.
- `Switch.Label`: The label of the switch.
- `Switch.Indicator`: The visual indicator of the switch state.
- `Switch.On`: The text for the on state.
- `Switch.Off`: The text for the off state.

## Examples

### Basic

Use `Switch` when you need to represent the switching between two mutually exclusive states or on-off state.

`Switch` works in an uncontrolled way by default, meaning each `Switch` component instance is responsible for managing its own state internally.

```jsx
<Flex flow="column">
  <Switch.Root>
    <Switch.Label>{'Apply strategy to all products'}</Switch.Label>
    <Switch.Indicator />
  </Switch.Root>
  <Switch.Root defaultIsActive>
    <Switch.Label>{'Use simulated data service'}</Switch.Label>
    <Switch.Indicator>
      <Switch.On>{'On'}</Switch.On>
      <Switch.Off>{'Off'}</Switch.Off>
    </Switch.Indicator>
  </Switch.Root>
</Flex>
```

### Controlled Switch

You can easily make the switch controlled, by passing your own state to `isActive` prop.
`onIsActiveChange` handler is called when the state of the switch changes, allowing you to sync state.

```jsx
() => {
  const [state, setState] = React.useState(false);

  return (
    <Switch.Root isActive={state} onIsActiveChange={setState}>
      <Switch.Label>{'Pause strategies when logging out'}</Switch.Label>
      <Switch.Indicator>
        <Switch.On>{'On'}</Switch.On>
        <Switch.Off>{'Off'}</Switch.Off>
      </Switch.Indicator>
    </Switch.Root>
  );
};
```

### Sizes

Vera provides two `Switch` sizes ‐ `medium` and `small`, with the `medium` size used by default.

```jsx
<Flex flow="column">
  <Switch.Root size="medium">
    <Switch.Label>{'Enable sound alerts?'}</Switch.Label>
    <Switch.Indicator>
      <Switch.On>{'On'}</Switch.On>
      <Switch.Off>{'Off'}</Switch.Off>
    </Switch.Indicator>
  </Switch.Root>
  <Switch.Root size="small">
    <Switch.Label>{'Enable sound alerts?'}</Switch.Label>
    <Switch.Indicator>
      <Switch.On>{'On'}</Switch.On>
      <Switch.Off>{'Off'}</Switch.Off>
    </Switch.Indicator>
  </Switch.Root>
</Flex>
```

#### Multi-sizing

Vera provides `applySizes` utility, which lets you specify size "scopes" within your app.
All controls within a scope will share the same size unless overwritten on a per-control basis.

```jsx
<Flex
  className={applySizes({
    control: 'small'
  })}
  wrap="wrap"
  cross="stretch"
>
  <FormField.Root as={Flex} flow="column">
    <FormField.Label>{'Amount'}</FormField.Label>
    <TextInput trailingVisual="MW" />
  </FormField.Root>
  <FormField.Root as={Flex} flow="column">
    <FormField.Label>{'Label'}</FormField.Label>
    <FlexItem grow="1" as={Flex}>
      <Switch.Root defaultIsActive>
        <Switch.Indicator>
          <Switch.On>{'On'}</Switch.On>
          <Switch.Off>{'Off'}</Switch.Off>
        </Switch.Indicator>
      </Switch.Root>
    </FlexItem>
  </FormField.Root>
</Flex>
```

### Disabled Switch

```jsx
<Flex flow="column">
  <Switch.Root isActive isDisabled>
    <Switch.Label>{'Pause strategies when logging out'}</Switch.Label>
    <Switch.Indicator>
      <Switch.On>{'On'}</Switch.On>
      <Switch.Off>{'Off'}</Switch.Off>
    </Switch.Indicator>
  </Switch.Root>
  <Switch.Root isDisabled>
    <Switch.Label>{'Pause strategies when logging out'}</Switch.Label>
    <Switch.Indicator>
      <Switch.On>{'On'}</Switch.On>
      <Switch.Off>{'Off'}</Switch.Off>
    </Switch.Indicator>
  </Switch.Root>
</Flex>
```

### Labels

It's recommended to use "On" or "Off" text labels unless there are other labels (no longer than three of four characters) that are more specific for the setting.

```jsx
<Flex flow="column">
  <Switch.Root>
    <Switch.Label>{'Trigger execution on orderbook change'}</Switch.Label>
    <Switch.Indicator>
      <Switch.On>{'On'}</Switch.On>
      <Switch.Off>{'Off'}</Switch.Off>
    </Switch.Indicator>
  </Switch.Root>
  <Switch.Root>
    <Switch.Label>{'Show recently added items'}</Switch.Label>
    <Switch.Indicator>
      <Switch.On>{'Show'}</Switch.On>
      <Switch.Off>{'Hide'}</Switch.Off>
    </Switch.Indicator>
  </Switch.Root>
</Flex>
```

### HTML Form integration

When used in the context of an HTML form, `Switch` automatically renders hidden input element that is kept in sync with the switch state.

You just need to provide `name` property (and optionally `value`) that will be used when submitting the form.

```jsx
() => {
  const handleSubmit = event => {
    event.preventDefault();
    const formData = new FormData(event.currentTarget);
    const formJson = Object.fromEntries(formData.entries());
    alert(JSON.stringify(formJson));
  };

  return (
    <form onSubmit={handleSubmit}>
      <Flex flow="column" cross="start">
        <Switch.Root name="notifications">
          <Switch.Label>{'Enable notifications?'}</Switch.Label>
          <Switch.Indicator>
            <Switch.On>{'On'}</Switch.On>
            <Switch.Off>{'Off'}</Switch.Off>
          </Switch.Indicator>
        </Switch.Root>
        <Button type="submit">{'Submit'}</Button>
      </Flex>
    </form>
  );
};
```

---

## API Reference

### Switch.Root

| Name               | Type                          | Default | Description                                                                                                                                                                                                                                  | Required |
| ------------------ | ----------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `css`              | `StitchesCss`                 |         | Apply styles directly to a component in a similar way how you would define inline styles. Vera uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries or variants. |          |
| `isActive`         | `boolean`                     | `false` | The controlled active state of the switch. Use in conjunction with `onIsActiveChange`.                                                                                                                                                       |          |
| `defaultIsActive`  | `boolean`                     |         | The active state of the switch when it's first rendered. Use when you do not need to control active state.                                                                                                                                   |          |
| `onIsActiveChange` | `(isActive: boolean) => void` |         | Event handler called when the active state of the switch changes.                                                                                                                                                                            |          |
| `isDisabled`       | `boolean`                     | `false` | When `true`, the switch will be disabled, preventing the user from interacting with it.                                                                                                                                                      |          |
| `size`             | `"medium" \| "small"`         |         | The size of the switch.                                                                                                                                                                                                                      |          |
| `name`             | `string`                      |         | Name attribute of the hidden input element, used when submitting an HTML form.                                                                                                                                                               |          |
| `value`            | `string`                      | `"on"`  | The value of the switch, used when submitting an HTML form, if it is checked.                                                                                                                                                                |          |

### Switch.Label

| Name  | Type          | Default | Description                                                                                                                                                                                                                                   | Required |
| ----- | ------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `css` | `StitchesCss` |         | Apply styles directly to a component in a similar way how you would define inline styles. Vera uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries, or variants. |          |

### Switch.Indicator

<Callout variant="tip">

`Switch.Indicator` extends `React.ButtonHTMLAttributes`.

</Callout>

### Switch.On

<Callout variant="tip">

`Switch.On` extends `React.SpanHTMLAttributes`.

</Callout>

### Switch.Off

<Callout variant="tip">

`Switch.Off` extends `React.SpanHTMLAttributes`.

</Callout>
