Switch
Turn a setting on or off and apply it immediately.
import { Switch } from '@youj/react'
Installation & usage
npm i @youj/reactFor an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.
Use Switch for settings that apply immediately, such as muting a channel or turning on previews. For a value saved with a form, use a Checkbox. For named alternatives such as light and dark, use a Toggle Group or Radio Group.
import { Field, FieldLabel, Switch } from '@youj/react'
export function AirplaneMode() {
return (
<Field orientation="horizontal">
<Switch />
<FieldLabel>Airplane mode</FieldLabel>
</Field>
)
}In a settings row, put the label and its description in a FieldContent first and the switch last, so the label leads and the control lines up at the end of every row.
Description
A list of project settings, each with a label, a description and a switch.
A switch that applies its change as soon as it is flipped.
A switch promises that the change has already happened. Reflect it right away, in the same view, and don't pair it with a Save button. If the change can fail, show that too, and flip the switch back.
Switches in each size and state.
size="sm" fits dense rows and tables, and size="lg" suits touch-first and spacious settings. disabled on the Field dims the label with the switch. readOnly keeps the value but ignores presses.
A settings list with liquid switches.
variant="liquid" draws the thumb as a glass droplet on a wider track. It stretches as it travels, overshoots its end and settles, and the accent pours into the track behind it. Everything else is the same switch: the role, the keyboard, the props and the Field wiring. Use it where the product has a softer, more playful look; keep one variant per screen.
Liquid switches in each size, and disabled.
The liquid track is wider than the default one at every size, to give the droplet room to stretch. The thumb catches a little of the accent in its lower edge as it crosses the fill, and its highlight stays at the top in both themes.
Code
switch-demo.tsx, the Demo story. The component itself comes from the package.
Reference
Propssize, variant, sound (3)
Props
| Prop | Type | |
|---|---|---|
size | 'sm' | 'default' | 'lg'default 'default' | 'default' |
variant | 'default' | 'liquid'
default 'default' | 'default' |
sound | booleanWith sound on ( default true | true |
Other props pass through: extends SwitchPrimitive.Root.Props. | ||
| Data attribute | Values |
|---|---|
data-size | sm, default, lg |
data-variant | default, liquid |
data-checked, data-unchecked, data-disabled | Base UI's state |
It also takes Base UI's checked, defaultChecked, onCheckedChange, disabled, readOnly, required, name and value. The required default comes from the surrounding Field.
MotionThumb travel, track color, press, liquid · reduced motion
Motion
| Moment | Tokens | ||
|---|---|---|---|
| Thumb travelone thumb width, mirrored under right-to-left | spring.snappy0.2s, bounce 0 | 0.2s, bounce 0 | |
| Track coloroff to on | duration.fastease.standard140ms · cubic-bezier(0.2, 0, 0, 1) | 140mscubic-bezier(0.2, 0, 0, 1) | |
| Pressthe thumb squeezes to 85% | duration.instantease.standard80ms · cubic-bezier(0.2, 0, 0, 1) | 80mscubic-bezier(0.2, 0, 0, 1) |
Reduced motion
The thumb jumps to its end and doesn't squeeze on press. The track still changes color.
The spring drives a single value from 0 to 1, and CSS turns it into the thumb's translate. A switch flipped back mid-flight retargets the spring from where the thumb is, so rapid toggling never jumps.
Liquid
| Moment | Tokens | ||
|---|---|---|---|
| Droplet travelovershoots its end and settles | spring.settle0.45s, bounce 0.3 | 0.45s, bounce 0.3 | |
| Stretchup to 30% wider and 18% flatter with the spring’s speed, squashed against the end while it overshoots | spring.settle0.45s, bounce 0.3 | 0.45s, bounce 0.3 | |
| Fillthe accent, clipped to the traveled part of the track, follows the same value | spring.settle0.45s, bounce 0.3 | 0.45s, bounce 0.3 | |
| Pressthe droplet swells to 110% | duration.instantease.standard80ms · cubic-bezier(0.2, 0, 0, 1) | 80mscubic-bezier(0.2, 0, 0, 1) |
Reduced motion
The plain switch's: the droplet jumps to its end, doesn't stretch or swell, and the fill shows at once.
The liquid switch springs on settle, the kit's one spring that overshoots, so the droplet lands with a small wobble. Its stretch is read from the spring's speed, so a rapid toggle that retargets mid-flight stretches it the right amount.
Reduced motion
The thumb moves to its end at once and the press doesn't squeeze it. The thumb's position and the track color still show the state. The liquid droplet does the same: no stretch, no swell, and the fill shows at once.
AccessibilityKeyboard, ARIA
Accessibility
- It's a
switchrole witharia-checked.Spacetoggles it. - A
FieldLabelin the sameFieldnames it. Outside aField, give itaria-label, or pairLabel htmlForwith the switch'sid. - In both states the thumb clears 3:1 against the track, and the track clears 3:1 against the page. The liquid droplet is a near-white glass on the same off track and the accent fill. The thumb's side shows the state too, so it doesn't rest on color alone.
- The hit area extends past the track, and grows on touch screens.