Switch
Two-state toggle built on top of a native <input type='checkbox'> with role='switch'.
Overview
The Switch component is a core building block of the Byteion design system, providing a robust, accessibility-compliant interface for its specific UI capabilities.
Why this exists
Switches communicate immediate state changes — especially for settings and preferences where the effect is instant and reversible.
Mental model
A switch is a visual toggle: on or off. It is built on a native checkbox input, so it inherits full keyboard and screen-reader support.
When to use
When not to use
Basic example
The following example demonstrates standard usage, fully compliant with Byteion's token-first approach.
Sizes
Color variants
With icons
Loading and disabled
Settings list
import { useState } from 'react';
import { Switch } from '@byteion/react';
export default function SwitchDemo() {
const [notifications, setNotifications] = useState(true);
return (
<div className="space-y-3 p-6">
<Switch label="Email notifications" checked={notifications} onChange={setNotifications} />
<Switch label="Marketing updates" defaultChecked={false} />
<Switch label="Beta features" defaultChecked size="lg" />
<Switch label="Locked setting" defaultChecked disabled />
</div>
);
}
<script setup lang="ts">
import { ref } from 'vue';
import { Switch } from '@byteion/vue';
const notifications = ref(true);
</script>
<template>
<div class="space-y-3 p-6">
<Switch v-model="notifications" label="Email notifications" />
<Switch label="Marketing updates" :model-value="false" />
<Switch label="Beta features" model-value size="lg" />
<Switch label="Locked setting" model-value disabled />
</div>
</template>
Variants
Each variant communicates a different meaning. Choose based on priority, not aesthetics.
Single default variant.
Sizes
Size should match the importance and context of the component.
- sm — sm size.
- md — md size.
- lg — lg size.
States
This component reacts seamlessly to the following interaction and data states:
- off — off state.
- on — on state.
- disabled — Non-interactive — grayed out, cursor not-allowed.
- default — Resting appearance before interaction.
- hover — Pointer is over the element — visual feedback via color or shadow.
- focus — Keyboard or tab focus — shows ring indicator for accessibility.
- active — Currently selected or in use.
Anatomy
Usage guidelines
- Apply changes immediately — do not require a submit button.
- Add a label that describes the ON state.
- Use for reversible changes only.
Do and Don't
Do
- Apply changes immediately.
- Label describes the ON state.
- Use for reversible toggles.
Don't
- Do not require form submission after toggling.
- Do not use for destructive actions without confirmation.
- Do not use instead of a submit button.
Accessibility
Built on <input type="checkbox" role="switch">. Activated by Enter and Space. State communicated via color and position.
Role:switch
ARIA Attributes
aria-checked
Keyboard Navigation
- Space: Toggles selection or activates the element
- Enter: Activates or submits the element
Customization
Track color uses --primary for ON, --border for OFF.
Compose with React cva()
Use the exportedcva() +cn() utilities to compose your own variant on top of the Byteion tokens.
import { cva, cn, type VariantProps } from '@byteion/react';
const mySwitch = cva('base classes…', {
variants: {
accent: { soft:'border-primary-200', loud:'border-primary-500' },
},
defaultVariants: { accent:'soft' },
});
type Props = React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof mySwitch>;
Compose with Vue cva()
Use the exportedcva() +cn() utilities inside standard Vue setup blocks.
<script setup lang="ts">
import { computed, useAttrs } from 'vue';
import { cva, type VariantProps } from '@byteion/vue';
interface Props { accent?:'soft' |'loud' }
const props = withDefaults(defineProps<Props>(), { accent:'soft' });
const attrs = useAttrs();
const mySwitch = cva('base classes…', {
variants: { accent: { soft:'border-primary-200', loud:'border-primary-500' } },
});
const cls = computed(() => mySwitch({ accent: props.accent, class: attrs.class as string | undefined }));
</script>
Runtime events
Byteion keeps framework APIs idiomatic: HTML uses DOM custom events, React uses callback props, and Vue uses emitted events / v-model updates.
HTML / JS events
No HTML runtime events are declared by this adapter.
React callbacks
No React callback events are declared by this adapter.
Vue emits
update:modelValue[value: boolean]
Remote / AJAX
This component does not implement Byteion JS remote loading. Use normal HTML form submission, framework state, or your application data layer around it.
API Reference
Native checkbox with role="switch".
HTML Data Attributes
No custom data attributes required.
React Props · SwitchProps
Extracted directly fromreact/src/components/Switch.tsx.
export interface SwitchProps
extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'size'> {
label?: ReactNode;
description?: ReactNode;
size?: Size;
tone?: Tone;
loading?: boolean;
}
React Variant Schema
Internal variant composition defined viacva().
cva(
'block rounded-full border border-border bg-muted shadow-inner-sm transition-colors duration-200 ease-out-soft peer-focus-visible:ring-2 peer-focus-visible:ring-primary-500/30 peer-focus-visible:ring-offset-2 peer-focus-visible:ring-offset-background peer-disabled:opacity-60 dark:border-border',
{
variants: {
size: {
sm: 'h-4 w-7',
md: 'h-5 w-9',
lg: 'h-6 w-11',
},
tone: {
primary: 'peer-checked:bg-primary-600',
secondary: 'peer-checked:bg-secondary-foreground',
accent: 'peer-checked:bg-accent-foreground',
success: 'peer-checked:bg-success-600',
danger: 'peer-checked:bg-danger-600',
violet: 'peer-checked:bg-secondary-foreground',
},
},
defaultVariants: { size: 'md', tone: 'primary' },
},
)
Vue Props · SwitchProps
Extracted directly fromvue/src/components/Switch.vue.
export interface SwitchProps {
modelValue?: boolean;
defaultChecked?: boolean;
tone?: 'primary' | 'secondary' | 'accent' | 'success' | 'danger' | 'violet';
size?: 'sm' | 'md' | 'lg';
label?: string;
description?: string;
disabled?: boolean;
loading?: boolean;
id?: string;
}
Developer tips
Common mistakes
Production usage tips
data-bi-* attributes instead of styling hooks.
Premium examples
Advanced patterns available in Byteion Pro:
Related components
Unlock Premium Patterns
Get access to copy-paste ready Pro blocks, SaaS templates, and advanced data-tables built with this component.
Explore Pro Components