Switch
A setting that is on or off, and takes effect at once. Press it, or use Space or Enter.
The preview needs JavaScript. The code is in the Code tab.
<template>
<div>
<Switch>Notifications</Switch>
<Switch checked>Dark mode</Switch>
</div>
</template>
Installation
npx @pixelscriptio/tessera add Switchpnpm exec tessera add Switchyarn tessera add Switchbunx @pixelscriptio/tessera add Switch- Works with Tessera 0.9.0 or newer.
Copy and paste the code into your project
Put it in
system/components.system/components/Switch.tess <contract> { "name": "Switch", "role": "switch", "description": "A setting that is on or off, and takes effect at once. Press it, or use Space or Enter.", "since": "0.5.0", "parts": ["root", "track", "thumb", "label"], "variants": { "size": ["md", "sm"] // first value is the default }, "states": ["hover", "focus-visible", "checked", "disabled"], "behavior": "toggle", "slots": { "default": "the label" }, "events": { "toggle": "fired with { checked, source } when the person changes it; the checked prop sets it from outside" }, "preview": { "slots": { "default": "Notifications" } } } </contract> <script> const { checked, disabled } = props({ checked: false, disabled: false }) // The component owns the state, starts from the prop and follows it when it changes. const on = state(checked.value) effect(() => { on.value = checked.value }) function change(detail) { on.value = detail.checked emit('toggle', detail) } </script> <template> <button class="root" type="button" role="switch" :aria-checked="on ? 'true' : 'false'" :disabled="disabled" @toggle="change($event)" > <span class="track"><span class="thumb"></span></span> <span class="label"><slot /></span> </button> </template> <style> .root { display: inline-flex; align-items: center; gap: $space.3; padding: $space.1 0; border: 0; background: transparent; color: $color.text.default; font-family: var(--t-font-family-sans); font-size: $font.size.sm; cursor: pointer; &:focus-visible { outline: 2px solid $color.focus.ring; outline-offset: 2px; } &:disabled { opacity: $opacity.disabled; cursor: not-allowed; } &[data-size='sm'] { font-size: $font.size.sm; } } .track { display: inline-flex; align-items: center; box-sizing: content-box; width: $space.8; height: $space.5; padding: 0 $space.0-5; border: 1px solid $color.border.strong; border-radius: $radius.full; background: $color.surface.hover; transition-duration: $motion.duration.fast; } .thumb { width: $space.4; height: $space.4; border-radius: $radius.full; background: $color.text.muted; transition-duration: $motion.duration.fast; } .root[data-size='sm'] .track { width: $space.6; height: $space.4; } .root[data-size='sm'] .thumb { width: $space.3; height: $space.3; } .root:hover:not(:disabled) .track { border-color: $color.text.default; } .root[aria-checked='true'] .track { border-color: $color.action.primary.bg; background: $color.action.primary.bg; } .root[aria-checked='true'] .thumb { background: $color.action.primary.fg; transform: translateX($space.3); } .root[data-size='sm'][aria-checked='true'] .thumb { transform: translateX($space.3); } .label:empty { display: none; } </style>Check your design tokens
Your design system needs these.
tessera addreports the ones that are missing; by hand, runnpx @pixelscriptio/tessera check.color.action.primary.bgcolor.action.primary.fgcolor.border.strongcolor.focus.ringcolor.surface.hovercolor.text.defaultcolor.text.mutedfont.size.smmotion.duration.fastopacity.disabledradius.fullspace.0-5space.1space.3space.4space.5space.6space.8
Usage
Using Switch
Use a switch for a setting that takes effect at once, such as "Dark mode". For a choice that is saved with a form, use a Checkbox.
- The label names the setting, and does not change when it is on: "Notifications", not "Turn notifications on".
- It starts off. Set
checkedto start it on, or to change it from outside. - The
toggleevent says where it is going:{ checked, source }. - Space and Enter both toggle it.
The preview needs JavaScript. The code is in the Code tab.
<template>
<div>
<Switch>Notifications</Switch>
<Switch checked>Dark mode</Switch>
</div>
</template>
API reference
Variants
| Variant | Values |
|---|---|
size | md default sm |
Slots
| Slot | Content |
|---|---|
default | the label |
Events
| Event | When |
|---|---|
toggle | fired with { checked, source } when the person changes it; the checked prop sets it from outside |
Anatomy
| Role | switch |
| Behavior | toggle |
| Parts | root track thumb label |
| States | hover focus-visible checked disabled |
| Since | 0.5.0 |
Design tokens it uses
Your design system needs these. tessera add checks that it has them, and can add the ones it lacks.
color.action.primary.bg color.action.primary.fg color.border.strong color.focus.ring color.surface.hover color.text.default color.text.muted font.size.sm motion.duration.fast opacity.disabled radius.full space.0-5 space.1 space.3 space.4 space.5 space.6 space.8
Checksum
835aadba60256765642688a06ba48c0a56109325fabc9fea12a98366b0cd5aeb