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

• Feature toggles (notifications, dark mode) • Settings and preferences • Enable/disable controls • Inline status changes

When not to use

• Do not use for form submission — use a button • Do not use for multi-option selection — use checkboxes or radio • Avoid when the change requires confirmation — use a checkbox + submit button instead

Basic example

The following example demonstrates standard usage, fully compliant with Byteion's token-first approach.

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

• Native checkbox — the actual input (hidden but accessible) • Track — background changes color • Thumb — slides left/right • Label — describes the toggle

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 mistake: using a switch for a setting that requires a"Save" button — switches imply instant effect.

Common mistakes

Avoid hardcoded neutral colors, placeholder-only labels, duplicated primary actions, and missing keyboard states. Keep this component on Byteion tokens so dashboard, admin, POS, ERP, ecommerce back-office, Laravel, React, and Vue starter-kit screens can be rebranded without rewriting markup.

Production usage tips

Use the canonical HTML as the source of truth, keep React and Vue wrappers aligned with the documented variants, test dark mode and branded themes before release, and wire interactive behavior through data-bi-* attributes instead of styling hooks.

Premium examples

Advanced patterns available in Byteion Pro:

• Switch with animated icon (sun/moon for dark mode) • Switch group with summary text

Unlock Premium Patterns

Get access to copy-paste ready Pro blocks, SaaS templates, and advanced data-tables built with this component.

Explore Pro Components