Skip to content

Switch โ€‹

A boolean toggle with sizes, color variants, optional loading state, and slot-overridable label and sublabel text. Toggle Vue / CSS to switch the live demo and source together.

The look is Basecoat's .input[type="checkbox"][role="switch"] (see Theme): a 32 ร— 18.4px pill with a 1px transparent border and an xs shadow, --input when off and --primary when on, carrying a 16px --background thumb that travels calc(100% - 2px). That thumb is exactly the checkbox box (the control step ร— 4/9), so a switch, a checkbox and a radio in one column share one scale โ€” and every size derives from it. Dark mode is built in (the thumb flips to --foreground when off, --primary-foreground when on).

Basic โ€‹

Single switch with a label.

Vue SFC

Sizes โ€‹

Small, medium and large.

Vue SFC

Colors โ€‹

Pick a colour and every state takes it โ€” the on-track re-paints live; the disabled switch shows it dimmed.

Vue SFC

States โ€‹

Disabled, loading and pre-checked.

Vue SFC

Sublabel โ€‹

sublabel adds a smaller second line under the label. description still works as another name for it, and both share one value.

Vue SFC

Slots โ€‹

Custom label and sublabel via named slots: slot="label" and slot="sublabel" (the older slot="description" still works).

Vue SFC

Event: change โ€‹

Listen to change to react to toggling.

Vue SFC

Event log โ€‹

Live log of change events.

Vue SFC

Customized โ€‹

Compose a card-style switch with your own CSS โ€” the library ships no helper. The .switch-card class is applied to the root via cssClass (Vue) / directly (CSS).

Vue SFC

CSS Variables โ€‹

Vue SFC

Every switch is themed through --mono-switch-* custom properties. Setting one on the element, on any wrapper/ancestor, or inline all work โ€” custom properties inherit, and they pierce the shadow-DOM boundary, so the same overrides apply to <mono-switch> and the shadow build. The color prop sets the accent, but an explicit --mono-switch-accent override always wins. To re-skin globally, set the underlying tokens (--input, --primary, --ring โ€ฆ) โ€” or switch flavor.

VariableDefaultControls
--mono-switch-accent--primary (set by color)Track colour when ON
--mono-switch-track-off--mono-mode-surface-strong (--input, dark --input/80)Track colour when OFF
--mono-switch-thumb / --mono-switch-thumb-checked--background (dark: --foreground / --primary-foreground)Thumb colour off / on
--mono-switch-thumb-shadow / --mono-switch-shadownone / --mono-shadow-xsThumb / track shadow
--mono-switch-radius / --mono-switch-thumb-radius--mono-radius-fullTrack / thumb corner (sera squares both off, rhea uses 2xl)
--mono-switch-border-width / -border-color / -checked-border-color--mono-border-width / transparent / sameTrack border โ€” currentColor resolves to the accent, which is how luma, sera and rhea outline the ON track
--mono-switch-ring-color / -ring-width / -ring-alpha--ring / --mono-ring-width / --mono-ring-alphaFocus-visible ring
--mono-switch-track-height-<size> (or -track-height for all)--mono-control-height-<size> ร— 23/45 (18.4px at md)Track height โ€” everything else derives from it
--mono-switch-track-ratio / --mono-switch-track-width1.7391 (32 / 18.4)Track width, as a multiple of its height or outright
--mono-switch-thumb-ratio0.8696 (16 / 18.4)Thumb size, as a share of the track height
--mono-switch-gap (or -gap-<size>)2 ร— --mono-spacing at md, 1.25 โ†’ 3.5 across the scaleGap between track and label
--mono-switch-label-font-<size> / -label-font-weight / -label-line-height--mono-text-sm at md / --mono-label-font-weight / --mono-leading-snugLabel
--mono-switch-description-font-<size>13px at mdDescription
--mono-switch-text / --mono-switch-description--foreground / --muted-foregroundLabel / description ink

Label metrics and the cap-band alignment are checkbox's, and the thumb is its box โ€” a perf spec asserts both, plus the 1.15 track ratio that makes the pair read as one scale.

Deprecated and honoured as no-ops until 2.0: --mono-switch-track-off-hover (Basecoat has no hover on the track), --mono-switch-ring (use -ring-color), --mono-switch-thumb-inset-ratio (the thumb parks flush inside the border).

Types โ€‹

Importimport { SwitchProps } from 'mono-helper'
PropValueDefaultDescription
modelValuebooleanโ€”Two-way bound on/off state of the switch.
checkedbooleanโ€”Whether the switch is checked (kept in sync with modelValue).
color'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'teal' | 'purple' | 'neutral' | 'dark'โ€”Color theme of the switch.
size'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'โ€”Size of the switch.
disabledbooleanโ€”Disables interaction with the switch.
loadingbooleanโ€”Shows a loading state and blocks interaction.
labelstringโ€”Text label shown next to the switch.
sublabelstringโ€”Secondary line under the label. `slot="sublabel"` replaces it.
descriptionstringโ€”The same as `sublabel` โ€” still accepted, both names share one value.
valuestringโ€”Value submitted with the form when checked.
namestringโ€”Form field name for the underlying input.
ariaLabelTextstringโ€”Accessible label for screen readers.
ariaLabelstringโ€”โ€”
cssClassSwitchCssClassโ€”Per-part class overrides for styling internal elements.
visiblebooleanโ€”Whether the control is shown. Defaults to `true`.
visibleType'none' | 'invisible'โ€”How it hides when `visible` is `false`. Defaults to `'none'`.