codefast/ui

Command Palette

Search for a command to run...

Source
Form

Switch

Toggle control for boolean settings. Fires onCheckedChange with the new boolean value.

Examples

Sizes

Two sizes: sm and the default.

17 lines
import { Field, FieldGroup, FieldLabel } from "@codefast/ui/field";
import { Switch } from "@codefast/ui/switch";

export function SwitchSizes() {
  return (
    <FieldGroup className="w-full max-w-40">
      <Field orientation="horizontal">
        <Switch id="switch-size-sm" size="sm" />
        <FieldLabel htmlFor="switch-size-sm">Small</FieldLabel>
      </Field>
      <Field orientation="horizontal">
        <Switch id="switch-size-default" size="default" />
        <FieldLabel htmlFor="switch-size-default">Default</FieldLabel>
      </Field>
    </FieldGroup>
  );
}

Disabled

Non-interactive in both the on and off positions.

11 lines
import { Field, FieldLabel } from "@codefast/ui/field";
import { Switch } from "@codefast/ui/switch";

export function SwitchDisabled() {
  return (
    <Field orientation="horizontal" data-disabled className="w-fit">
      <Switch id="switch-disabled-unchecked" disabled />
      <FieldLabel htmlFor="switch-disabled-unchecked">Disabled</FieldLabel>
    </Field>
  );
}

Choice Card

Card-style selection where FieldLabel wraps the entire Field for a clickable card pattern.

27 lines
import { Field, FieldContent, FieldDescription, FieldGroup, FieldLabel, FieldTitle } from "@codefast/ui/field";
import { Switch } from "@codefast/ui/switch";

export function SwitchChoiceCard() {
  return (
    <FieldGroup className="w-full max-w-sm">
      <FieldLabel htmlFor="switch-share">
        <Field orientation="horizontal">
          <FieldContent>
            <FieldTitle>Share across devices</FieldTitle>
            <FieldDescription>Focus is shared across devices, and turns off when you leave the app.</FieldDescription>
          </FieldContent>
          <Switch id="switch-share" />
        </Field>
      </FieldLabel>
      <FieldLabel htmlFor="switch-notifications">
        <Field orientation="horizontal">
          <FieldContent>
            <FieldTitle>Enable notifications</FieldTitle>
            <FieldDescription>Receive notifications when focus mode is enabled or disabled.</FieldDescription>
          </FieldContent>
          <Switch id="switch-notifications" defaultChecked />
        </Field>
      </FieldLabel>
    </FieldGroup>
  );
}

Description

A control that allows the user to toggle between checked and not checked.

Focus is shared across devices, and turns off when you leave the app.

14 lines
import { Field, FieldContent, FieldDescription, FieldLabel } from "@codefast/ui/field";
import { Switch } from "@codefast/ui/switch";

export function SwitchDescription() {
  return (
    <Field orientation="horizontal" className="max-w-sm">
      <FieldContent>
        <FieldLabel htmlFor="switch-focus-mode">Share across devices</FieldLabel>
        <FieldDescription>Focus is shared across devices, and turns off when you leave the app.</FieldDescription>
      </FieldContent>
      <Switch id="switch-focus-mode" />
    </Field>
  );
}

Invalid

Add the aria-invalid prop to the Switch component to indicate an invalid state. Add the data-invalid prop to the Field component for styling.

You must accept the terms and conditions to continue.

14 lines
import { Field, FieldContent, FieldDescription, FieldLabel } from "@codefast/ui/field";
import { Switch } from "@codefast/ui/switch";

export function SwitchInvalid() {
  return (
    <Field orientation="horizontal" className="max-w-sm" data-invalid>
      <FieldContent>
        <FieldLabel htmlFor="switch-terms">Accept terms and conditions</FieldLabel>
        <FieldDescription>You must accept the terms and conditions to continue.</FieldDescription>
      </FieldContent>
      <Switch id="switch-terms" aria-invalid />
    </Field>
  );
}

RTL

Right-to-left layout support for languages such as Arabic and Hebrew.

Translations are AI-generated for demonstration and may be imperfect.

يتم مشاركة التركيز عبر الأجهزة، ويتم إيقاف تشغيله عند مغادرة التطبيق.

45 lines
import { Field, FieldContent, FieldDescription, FieldLabel } from "@codefast/ui/field";
import { Switch } from "@codefast/ui/switch";

import type { Translations } from "#/features/components-catalog/components/detail/language";
import { useTranslation } from "#/features/components-catalog/components/detail/language-context";

const translations: Translations = {
  en: {
    dir: "ltr",
    values: {
      label: "Share across devices",
      description: "Focus is shared across devices, and turns off when you leave the app.",
    },
  },
  ar: {
    dir: "rtl",
    values: {
      label: "المشاركة عبر الأجهزة",
      description: "يتم مشاركة التركيز عبر الأجهزة، ويتم إيقاف تشغيله عند مغادرة التطبيق.",
    },
  },
  he: {
    dir: "rtl",
    values: {
      label: "שיתוף בין מכשירים",
      description: "המיקוד משותף בין מכשירים, וכבה כשאתה עוזב את האפליקציה.",
    },
  },
};

export function SwitchRtl() {
  const { dir, t } = useTranslation(translations, "ar");

  return (
    <Field orientation="horizontal" className="max-w-sm" dir={dir}>
      <FieldContent>
        <FieldLabel htmlFor="switch-focus-mode-rtl" dir={dir}>
          {t.label}
        </FieldLabel>
        <FieldDescription dir={dir}>{t.description}</FieldDescription>
      </FieldContent>
      <Switch id="switch-focus-mode-rtl" dir={dir} />
    </Field>
  );
}

Usage

The minimal import and composition — see Examples below for styled, real-world variants.

11 lines
import { Label } from "@codefast/ui/label";
import { Switch } from "@codefast/ui/switch";

export function SwitchUsage() {
  return (
    <div className="flex items-center gap-2">
      <Switch id="airplane-mode" />
      <Label htmlFor="airplane-mode">Airplane Mode</Label>
    </div>
  );
}

Anatomy

How the parts nest — every slot the component exposes, in composition order.

Switch

Features

  • Two sizes (default, sm) with a matching thumb size.
  • RTL-aware out of the box — the thumb translates the correct direction under dir="rtl" with no extra config.
  • Built on Radix Switch; exposes role="switch" with a live aria-checked.

API reference

Props for each part of the component. All native element props are also forwarded.

Switch

A toggle built on Radix Switch.

checkedboolean

The controlled checked state.

defaultCheckedboolean

The checked state when initially rendered (uncontrolled).

Defaultfalse

onCheckedChange(checked: boolean) => void

Called when the checked state changes.

size"default" | "sm"

Track and thumb size.

Default"default"

disabledboolean

Blocks interaction and dims the control.

Defaultfalse

Accessibility

Built to be keyboard-navigable and screen-reader friendly out of the box.

KeyFunction
TabMoves focus to the switch.
SpaceToggles the switch.
EnterToggles the switch.
  • Has role=switch with aria-checked reflecting the current state.
  • Associate a Label via htmlFor / id, or wrap the control, so it has a name.
  • Use a Checkbox instead when the change should only apply after a form submit.

Guidelines

Conventions that keep usage consistent across an app.

Do

  • Use for settings that take effect immediately.
  • Make the label describe the on state (e.g. “Email notifications”).

Don’t

  • Don’t use a switch where a Checkbox (deferred submit) is expected.
  • Don’t require a separate Save button for a switch that applies instantly.

Explore further

Ready to integrate?

Follow the Getting Started guide to install @codefast/ui, or browse the full component gallery.