Switch
Turns a setting on or off straight away, with no Save button.
SourcePackage @weft-js/warpPlayground
Preview
tsx
import { state } from '@weft-js/core'import { Switch } from '@weft-js/warp'export function Basic() { const on = state(true) return <Switch checked={on.value} onChange={(e: Event & { currentTarget: HTMLInputElement }) => (on.value = e.currentTarget.checked)}>Preview deploys</Switch>}Installation
npm install @weft-js/warpUsage
tsx
import { Switch } from '@weft-js/warp'<Switch>Preview deploys</Switch>Placement
placement picks the side the switch sits on.
tsx
import { Stack, Switch } from '@weft-js/warp'export function Placement() { return ( <Stack gap="related"> <Switch checked>Preview deploys</Switch> <Switch checked placement="start">Preview deploys</Switch> </Stack> )}Sizes
Use size to pick sm or md.
tsx
import { Stack, Switch } from '@weft-js/warp'export function Sizes() { return ( <Stack gap="related"> <Switch size="sm" checked>Preview deploys</Switch> <Switch checked>Preview deploys</Switch> </Stack> )}With a hint
A switch's hint is a quieter second line under its label.
tsx
import { Switch } from '@weft-js/warp'export function Hint() { return ( <Switch checked hint="Every pull request gets its own address.">Preview deploys</Switch> )}States
A switch can be on or off, show a hint, or be disabled either way.
tsx
import { Grid, Stack, Switch, Text } from '@weft-js/warp'export function States() { return ( <Grid cols={3} gap="group"> <Cell name="Off"><Switch>Preview deploys</Switch></Cell> <Cell name="On"><Switch checked>Preview deploys</Switch></Cell> <Cell name="Hint"><Switch hint="Every pull request gets its own address.">Preview deploys</Switch></Cell> <Cell name="Disabled off"><Switch disabled>Preview deploys</Switch></Cell> <Cell name="Disabled on"><Switch checked disabled>Preview deploys</Switch></Cell> </Grid> )}const Cell = (p: { name: string; children?: unknown }) => ( <Stack gap="tight"> <Text role="caption" subtle>{p.name}</Text> {p.children} </Stack>)Settings that apply at once
Each flip takes effect and says so.
tsx
import { state } from '@weft-js/core'import { Stack, Switch, Toaster, toast } from '@weft-js/warp'export function Settings() { const previews = state(true) const analytics = state(false) const paused = state(false) const say = (title: string, on: boolean) => toast.show({ title: `${title} ${on ? 'on' : 'off'}` }) return ( <Stack gap="group" divided> <Switch checked={previews.value} hint="Every pull request gets its own address." onChange={(e: Event & { currentTarget: HTMLInputElement }) => say('Preview deploys', (previews.value = e.currentTarget.checked))}>Preview deploys</Switch> <Switch checked={analytics.value} hint="Adds about 1 KB to each page." onChange={(e: Event & { currentTarget: HTMLInputElement }) => say('Web analytics', (analytics.value = e.currentTarget.checked))}>Web analytics</Switch> <Switch checked={paused.value} hint="Takes the project offline until you switch it back." onChange={(e: Event & { currentTarget: HTMLInputElement }) => say('Pause', (paused.value = e.currentTarget.checked))}>Pause project</Switch> <Toaster /> </Stack> )}When to use
Playground
Size
Placement
import { Switch } from '@weft-js/warp'<Switch checked>Preview deploys</Switch>Accessibility
- Space
- Toggles
- A real checkbox with the
switchrole, so it reads as on or off. - Keep the label the same in both states. Say what it controls, not what it's doing.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | false | Whether it is on. You own this value. |
hint | unknown | — | A short line under the label. |
size | "sm" | "md" | — | sm or md. |
placement | "start" | "end" | 'end' | Which side of the label the switch sits on. |
children | unknown | — | What it contains. |
Parts
Every element carries a stable name, so you can style it from your own CSS: [data-scope="switch"] [data-part="track"]
trackrail-fillrail-hoverthumblabelhint