Inputs@knitui/components
Switch
Switch is a toggle control built on a styled Box track and thumb. It supports controlled and uncontrolled modes, inline labels, on/off track labels, a thumb icon slot, and a Switch.Group for multi-select scenarios.
import { Switch } from "@knitui/components";Usage
import { Switch } from "@knitui/components";
<Switch label="Push notifications" onChange={setEnabled} />;Uncontrolled by default; pass checked + onChange to control it. As with the
other inputs, description and error are wired to the control for you.
onLabel / offLabel render inside the track, and thumbIcon puts a glyph on
the thumb itself — useful when colour alone shouldn't carry the state:
<Switch label="Dark mode" onLabel="ON" offLabel="OFF" />A switch implies its change takes effect immediately. If the value needs a Save button to matter, a checkbox is the more honest control.
When to use something else
- A value that only applies once a form is submitted →
Checkbox - One of several mutually exclusive options →
RadioorSegmentedControl
Examples
Sizes
All seven sizes side by side for a quick visual comparison.
Loading example…
Shadows
Elevation shadow ladder applied to the track via the inherited shadow prop.
Loading example…
Disabled
Disabled state — the switch is non-interactive and visually dimmed.
Loading example…
Track Labels
On/off labels rendered inside the track, behind the thumb.
Loading example…
Thumb Icon
An icon rendered inside the thumb replaces the default dot indicator.
Loading example…
Themes
Accent colour comes from the Tamagui theme prop.
Loading example…
Label Left
Label placed to the left of the track.
Loading example…
With Description And Error
Description and error slot — rendered below the label when provided.
Loading example…
Controlled
Fully controlled switch — the parent manages checked state via React.useState.
Loading example…
Group
Switch.Group manages a set of switches as a multi-select; maxSelectedValues caps the selection.
Loading example…
Group Read Only
A read-only Switch.Group keeps the current values visible but prevents toggling them.
Loading example…
Controlled Group
Controlled Switch.Group — parent tracks the selected values array.
Loading example…
Styles
Per-slot styles targets individual parts — here the track, thumb and label.
Loading example…
Props
| Prop | Type | Default | Description |
|---|---|---|---|
aria-describedby | string | undefined | — | Ids of external description elements; merged with description/error ids. |
aria-label | string | undefined | — | Accessible label when no visible label is provided. |
aria-labelledby | string | undefined | — | Id of an external label element. Defaults to the visible label id. |
checked | boolean | undefined | — | Controlled checked state. |
defaultChecked | boolean | undefined | false | Initial checked state for the uncontrolled case. |
description | ReactNode | — | Description rendered below the label. |
disabled system | boolean | undefined | false | Disables the switch. |
error | ReactNode | — | Error rendered below the description (string nodes get the error theme). |
id | string | undefined | — | Id used to bind the control and label; auto-generated when omitted. |
label | ReactNode | Switch | Label content rendered next to the control. |
labelPosition | "left" | "right" | undefinedleft · right | 'right' | Position of the label relative to the track. |
offLabel | ReactNode | — | Inner label shown in the track when unchecked. |
onChange | ((checked: boolean) => void) | undefined | — | Called with the next checked state. Mirrors Mantine's `onChange` name; the payload is a boolean (not a DOM event) because the kit is cross-platform. |
onCheckedChange | ((checked: boolean) => void) | undefined | — | — |
onLabel | ReactNode | — | Inner label shown in the track when checked. |
radius system | string | number | undefined | — | — |
rootRef | Ref<TamaguiElement> | undefined | — | Ref of the root wrapper element. |
shadow system | "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefined | — | — |
size system | "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefinedxxs · xs · sm · md · lg · xl · xxl | 'sm' | Controls the height, width and thumb dimensions of the track. |
styles system | SlotStyles<SwitchStyles> | undefined | — | Uniform per-slot style passthrough — sugar over the composable parts. Own slots: `track` / `thumb` / `thumbIndicator` / `trackLabel`; plus the inherited chrome slots `label` / `description` / `error` / `root` forwarded to the `InlineControl`. |
theme system | ThemeName | null | undefined | — | Applies a theme to this element |
thumbIcon | ReactNode | — | Icon rendered inside the thumb. |
value | string | undefined | — | Value reported to a surrounding `Switch.Group`. |
withThumbIndicator | boolean | undefined | true | Show a coloured dot inside the thumb. |
Style slots
Every part of Switch can be styled through the styles prop. Explicit props on the component always win over slot styles.
| Slot | Targets |
|---|---|
description | The description Text rendered below the label. |
error | The error Text rendered below the description. |
label | The label Text. |
root | The outer InlineControlRoot row. |
thumb | Props for the sliding SwitchThumb. |
thumbIndicator | Props for the dot inside the thumb (SwitchThumbIndicator). |
track | Props for the pill SwitchTrack. |
trackLabel | Props for the on/off label rendered in the track (SwitchTrackLabel). |
Accessibility & DOM props (2)
| Prop | Type |
|---|---|
key | Key | null | undefined |
ref | Ref<TamaguiElement> | undefined |
Plus 495 inherited style props from Box — the full Tamagui/React Native style surface, including token shorthands like p, mx, bg and c. See Tokens for the scales they accept, or the full list.
Accessibility
On the web the control carries role="switch" with aria-checked — announced as
"switch, on/off" rather than "checkbox, checked", which is the distinction users of
screen readers rely on to know the change is immediate.
Focus and key handling come from the shared
useKeyboardActions hook, as the track is a
styled Box rather than a native input.
| Key | Action |
|---|---|
| Tab | Move focus to the switch |
| Space / Enter | Toggle |
- Name it. Use
label, oraria-label/aria-labelledbywhen the label is rendered elsewhere. descriptionanderrorare referenced viaaria-describedby.disabledsetsaria-disabledand removes the switch from the tab order.onLabel/offLabelare decoration inside the track — they are not a substitute for a name, since they describe the states, not the setting.