Skip to content
CodeAtlas UI

Inputs

Switch

Toggle control for binary on/off settings, built on Bits UI.

<script>
  import { Switch } from "@codeatlasdev/ui";
  let enabled = $state(false);
</script>

<Switch label="Notifications" bind:checked={enabled} />

Without a visible label, always pass aria-label (or aria-labelledby) so the switch has an accessible name. The track is 44px wide, so it is comfortable to hit on touch screens.

Basic

Default off and on states.

Code
svelte
<script lang="ts">
  import { Switch } from '@codeatlasdev/ui';

  let notifications = $state(true);
  let darkMode = $state(false);
</script>

<Switch label="Off by default" bind:checked={darkMode} />
<Switch label="On by default" bind:checked={notifications} />

Disabled

Code
svelte
<script lang="ts">
  import { Switch } from '@codeatlasdev/ui';
</script>

<Switch disabled label="Disabled off" />
<Switch checked disabled label="Disabled on" />

Without label

Provide aria-label when no visible label is rendered.

Code
svelte
<script lang="ts">
  import { Switch } from '@codeatlasdev/ui';

  let analytics = $state(false);
</script>

<Switch bind:checked={analytics} aria-label="Analytics" />
<Switch checked aria-label="Always on" />

Settings list

Common pattern: a row with title, helper text and a trailing switch.

Email notifications

Receive updates about your account activity.

Dark mode

Switch between light and dark appearance.

Usage analytics

Help improve the product by sharing usage data.

Code
svelte
<script lang="ts">
  import { Switch } from '@codeatlasdev/ui';

  let email = $state(true);
  let dark = $state(false);
  let analytics = $state(false);
</script>

<div class="settings-list">
  <div class="settings-item">
    <div>
      <p class="settings-item__title">Email notifications</p>
      <p class="settings-item__sub">Receive updates about your account activity.</p>
    </div>
    <Switch bind:checked={email} aria-label="Email notifications" />
  </div>
  <div class="settings-item">
    <div>
      <p class="settings-item__title">Dark mode</p>
      <p class="settings-item__sub">Switch between light and dark appearance.</p>
    </div>
    <Switch bind:checked={dark} aria-label="Dark mode" />
  </div>
  <div class="settings-item">
    <div>
      <p class="settings-item__title">Usage analytics</p>
      <p class="settings-item__sub">Help improve the product by sharing usage data.</p>
    </div>
    <Switch bind:checked={analytics} aria-label="Usage analytics" />
  </div>
</div>

<style>
  .settings-list {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 480px;
    border: 1px solid var(--ca-outline-subtle);
    border-radius: var(--ca-radius-lg);
    overflow: hidden;
  }

  .settings-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ca-space-4);
    padding: var(--ca-space-4) var(--ca-space-5);
    border-bottom: 1px solid var(--ca-outline-subtle);
  }

  .settings-item:last-child {
    border-bottom: none;
  }

  .settings-item__title {
    margin: 0 0 2px;
    font-size: var(--ca-font-size-body2);
    font-weight: 500;
    color: var(--ca-text-primary);
  }

  .settings-item__sub {
    margin: 0;
    font-size: var(--ca-font-size-caption);
    color: var(--ca-text-secondary);
  }
</style>

Props

PropTypeDefaultDescription
checkedbooleanfalseBindable on/off state.
disabledbooleanfalseDisables interaction.
labelstring–Visible label rendered beside the switch.
aria-labelstring–Accessible name used when no visible label is rendered.
aria-labelledbystring–Id of an element that names the switch. Ignored when label is set.
classstring–Extra classes on the wrapper.
onchange(checked: boolean) => void–Called when the state changes.