suiss/uim · React Native Component

Switch

A toggle switch for turning a single setting on or off.

Switch is an open-source mobile component from suiss/uim for React Native and Expo, with SwiftUI and Jetpack Compose versions built from the same design tokens. The @esuiss/uim CLI copies its source into your project, so you own the code.

iOS
Switch on iOS in light mode

Switch is a pressable track with a round thumb that slides between the off and on positions. The thumb animates with Reanimated and stretches slightly while pressed. It comes in two sizes, default and sm, and has an invalid state that adds a danger-colored border.

Use a switch for settings that take effect immediately. For choices that are submitted later, use Checkbox.

Installation

$ pnpm dlx @esuiss/uim@latest add switch

Manual

  1. Install the dependencies:
npx expo install cn react-native-reanimated react-native-worklets
  1. Add the pieces it builds on: the primitives components/primitives/switch.tsx, components/primitives/use-render.tsx.

  2. Copy the source into components/ui/switch.tsx:

uniwind/components/ui/switch.tsx
import { cn } from "cn"
import * as React from "react"
import type { GestureResponderEvent } from "react-native"
import Animated, {
  Easing,
  ReduceMotion,
  useAnimatedStyle,
  withTiming,
} from "react-native-reanimated"
import * as SwitchPrimitives from "@/components/primitives/switch"
import { resolveClassName } from "@/components/primitives/use-render"

type SwitchSize = "default" | "sm"

const HIT_SLOP = { top: 8, bottom: 8, left: 12, right: 12 }
  1. Update the import paths to match your project.

Usage

import { Switch } from "@/components/ui/switch"
<SwitchDemo />

Use defaultChecked for an uncontrolled switch, or checked with onCheckedChange to control it.

A switch has no visible text of its own. Pair it with a Label and link them with accessibilityLabelledBy and the label's nativeID, or set an accessibilityLabel. Give the Label an onPress that toggles the value if the label should be pressable too.

The switch has a hit slop around it, so it is easier to press than its visual size.

Examples

Checked

A switch that starts on.

iOS
Switch (checked) on iOS in light mode

Sizes

The sm and default sizes side by side.

iOS
Switch (sizes) on iOS in light mode

With label

A controlled switch next to a pressable label.

iOS
Switch (with label) on iOS in light mode

With description

A switch with a label and a line of supporting text.

iOS
Switch (with description) on iOS in light mode

Disabled

Disabled switches in the off and on states.

iOS
Switch (disabled) on iOS in light mode

Invalid

A switch with the invalid border next to its label.

iOS
Switch (invalid) on iOS in light mode

API Reference

Switch

ExtendsReact.ComponentProps<typeof SwitchPrimitives.Root>
PropType
About
default or sm.
Type
SwitchSize
Default
"default"
About
Adds a danger-colored border when not disabled.
Type
boolean
Default
—

Accessibility

  • The root has the switch role and reports checked and disabled in its accessibility state, so VoiceOver and TalkBack announce whether it is on.
  • The thumb is hidden from the accessibility tree.
  • Label every switch with accessibilityLabel or accessibilityLabelledBy.
  • The thumb animation follows the system reduce motion setting.

Notes

  • The track uses bg-accent when on and bg-label-quaternary when off, with bg-accent-disabled and bg-control-disabled for the disabled states.
  • The thumb uses bg-surface, or bg-label in dark mode.
  • Light and dark colors follow the system appearance.