Skip to content
Destyler UI Destyler UI Destyler UI

Switch

A switch allows users to turn an individual option on or off.

Features

Install

Install the component from your command line.

Terminal window
      
        
npm install @destyler/switch @destyler/vue
Terminal window
      
        
npm install @destyler/switch @destyler/react
Terminal window
      
        
npm install @destyler/switch @destyler/svelte
Terminal window
      
        
npm install @destyler/switch @destyler/solid

Anatomy

Import all parts and piece them together.

<script setup lang="ts">
import * as switchs from '@destyler/switch'
import { normalizeProps, useMachine } from '@destyler/vue'
import { computed, useId } from 'vue'
const [state, send] = useMachine(switchs.machine({
id: useId(),
}))
const api = computed(() =>
switchs.connect(state.value, send, normalizeProps),
)
</script>
<template>
<label v-bind="api.getRootProps()">
<input v-bind="api.getHiddenInputProps()">
<span v-bind="api.getControlProps()" >
<span v-bind="api.getThumbProps()" />
</span>
</label>
</template>
import { normalizeProps, useMachine } from '@destyler/react'
import * as switchs from '@destyler/switch'
import { useId } from 'react'
export default function Switch() {
const [state, send] = useMachine(switchs.machine({
id: useId(),
}))
const api = switchs.connect(state, send, normalizeProps)
return (
<label {...api.getRootProps()} >
<input {...api.getHiddenInputProps()} />
<span {...api.getControlProps()} >
<span {...api.getThumbProps()} />
</span>
</label>
)
}
<script lang="ts">
import * as switchs from '@destyler/switch'
import { normalizeProps, useMachine } from '@destyler/svelte'
const id = $props.id()
const [state, send] = useMachine(switchs.machine({
id,
}))
const api = $derived(switchs.connect(state, send, normalizeProps))
</script>
<label {...api.getRootProps()}>
<input {...api.getHiddenInputProps()}>
<span {...api.getControlProps()} >
<span {...api.getThumbProps()} ></span>
</span>
</label>
import { normalizeProps, useMachine } from '@destyler/solid'
import * as switchs from '@destyler/switch'
import { createMemo, createUniqueId } from 'solid-js'
export default function Switch() {
const [state, send] = useMachine(switchs.machine({
id: createUniqueId(),
}))
const api = createMemo(() => switchs.connect(state, send, normalizeProps))
return (
<label {...api().getRootProps()} >
<input {...api().getHiddenInputProps()} />
<span {...api().getControlProps()} >
<span {...api().getThumbProps()} />
</span>
</label>
)
}

Disabling the switch

To make a switch disabled, set the context’s disabled property to true

const [state, send] = useMachine(
switch.machine({
disabled: true,
}),
)

Making it checked by default

To make a switch checked by default, set the context’s checked property to true

const [state, send] = useMachine(
switch.machine({
checked: true,
}),
)

Listening for changes

When the switch value changes, the onCheckedChange callback is invoked.

const [state, send] = useMachine(
switch.machine({
onCheckedChange(details) {
// details => { checked: boolean }
console.log("switch is:", details.checked ? "On" : "Off")
},
}),
)

Usage within forms

To use switch within forms, use the exposed inputProps from the connect function and ensure you pass name value to the destyler’s context. It will render a hidden input and ensure the value changes get propagated to the form correctly.

const [state, send] = useMachine(
switch.machine({
name: "feature",
}),
)

Styling guide

Earlier, we mentioned that each Switch part has a data-part attribute added to them to select and style them in the DOM.

Focused State

When the switch input is focused, the data-focus attribute is added to the root, control and label parts.

[data-part="root"][data-focus] {
/* styles for root focus state */
}
[data-part="control"][data-focus] {
/* styles for control focus state */
}
[data-part="label"][data-focus] {
/* styles for label focus state */
}

Disabled State

When the switch is disabled, the data-disabled attribute is added to the root, control and label parts.

[data-part="root"][data-disabled] {
/* styles for root disabled state */
}
[data-part="control"][data-disabled] {
/* styles for control disabled state */
}
[data-part="label"][data-disabled] {
/* styles for label disabled state */
}

Invalid State

When the switch is invalid, the data-invalid attribute is added to the root, control and label parts.

[data-part="root"][data-invalid] {
/* styles for root invalid state */
}
[data-part="control"][data-invalid] {
/* styles for control invalid state */
}
[data-part="label"][data-invalid] {
/* styles for label invalid state */
}

Methods and Properties

Machine Context

The switch machine exposes the following context properties:

ids
Partial<{ root: string; hiddenInput: string; control: string; label: string; thumb: string; }>
The ids of the elements in the switch. Useful for composition.
label
string
Specifies the localized strings that identifies the accessibility elements and their states
disabled
boolean
Whether the switch is disabled.
invalid
boolean
If `true`, the switch is marked as invalid.
required
boolean
If `true`, the switch input is marked as required,
readOnly
boolean
Whether the switch is read-only
onCheckedChange
(details: CheckedChangeDetails) => void
Function to call when the switch is clicked.
checked
boolean
Whether the switch is checked.
name
string
The name of the input field in a switch (Useful for form submission).
form
string
The id of the form that the switch belongs to
value
string | number
The value of switch input. Useful for form submission.
dir
"ltr" | "rtl"
The document's text/writing direction.
id
string
The unique identifier of the machine.
getRootNode
() => ShadowRoot | Node | Document
A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.

Machine API

The switch api exposes the following methods:

checked
boolean
Whether the switch is checked
disabled
boolean
Whether the switch is disabled
focused
boolean
Whether the switch is focused
setChecked
(checked: boolean) => void
Function to set the checked state of the switch
toggleChecked
() => void
Function to toggle the checked state of the switch

Data Attributes

Root

name
desc
data-active
Present when active or pressed
data-focus
Present when focused
data-focus-visible
Present when focused with keyboard
data-readonly
Present when read-only
data-hover
Present when hovered
data-disabled
Present when disabled
data-state
"checked" | "unchecked"
data-invalid
Present when invalid

Label

name
desc
data-active
Present when active or pressed
data-focus
Present when focused
data-focus-visible
Present when focused with keyboard
data-readonly
Present when read-only
data-hover
Present when hovered
data-disabled
Present when disabled
data-state
"checked" | "unchecked"
data-invalid
Present when invalid

Thumb

name
desc
data-active
Present when active or pressed
data-focus
Present when focused
data-focus-visible
Present when focused with keyboard
data-readonly
Present when read-only
data-hover
Present when hovered
data-disabled
Present when disabled
data-state
"checked" | "unchecked"
data-invalid
Present when invalid

Control

name
desc
data-active
Present when active or pressed
data-focus
Present when focused
data-focus-visible
Present when focused with keyboard
data-readonly
Present when read-only
data-hover
Present when hovered
data-disabled
Present when disabled
data-state
"checked" | "unchecked"
data-invalid
Present when invalid

Accessibility

Keyboard Interaction

name
desc
Space Enter
Toggle the switch