Forms / React + CSS
Preference switch
A compact setting that clearly shows whether it is on or off.
Email updates are on in this demo.
"use client";
import styles from "./PreferenceSwitch.module.css";
export default function PreferenceSwitch({
label = "Email updates",
checked = false,
onChange,
}) {
return (
<button
type="button"
role="switch"
aria-checked={checked}
className={styles.switch}
onClick={() => onChange?.(!checked)}
>
<span>{label}</span>
<span className={styles.track} aria-hidden="true">
<span />
</span>
</button>
);
}
Make it yours
Use for a setting that takes effect immediately. Keep checked in parent state and persist it in your application when needed.
- Use a React project with CSS Modules support, such as Next.js or Vite.
- Save the JSX as
PreferenceSwitch.jsxand the CSS asPreferenceSwitch.module.cssin the same folder. - Import
PreferenceSwitchand connect its props to your application. Controlled components need parent state and change handlers.
No third-party component or animation package is required. Use the theme controls to adjust accent, corners, spacing, and type. Copy the Theme CSS into your stylesheet and wrap your components in <div className="tdp-components">. The theme applies to every component inside that wrapper. TDP defaults work without a theme file.
Props
| Prop | Type | Use |
|---|---|---|
label | string | Visible setting name. |
checked | boolean | Current state, owned by the parent. |
onChange | function | Receives the next boolean value. |
Accessibility & behavior
The switch exposes aria-checked and a visible label. Native button behavior supports Enter and Space; the thumb position conveys state without relying on color.
Visible focus styles and reduced-motion support are included. Check labels, contrast, keyboard behavior, and screen-reader output again after adapting the component to your product.