COMPONENTS/INPUTS
Switch.
An immediate change, clearly expressed.
In practice
Compose SwitchThumb inside Switch. Label the control. Use checked/onCheckedChange for controlled state.
Installation
Install Coal once. Components and TypeScript declarations are included. React 19 and React DOM 19 are peer dependencies.
Terminal · local package
npm install http://localhost:3100/downloads/chlohal-coal-ui-0.5.0.tgzThis installs the local package. It is not yet published on npm. See installation for stylesheet setup and integration.
Usage
example.tsx
"use client";
import * as React from "react";
import "@chlohal/coal-ui/styles.css";
import { Switch, SwitchThumb } from "@chlohal/coal-ui";
export default function Example() {
return (<div>
<label>
Quiet mode
<Switch defaultChecked>
<SwitchThumb />
</Switch>
</label>
<label>
Email updates
<Switch>
<SwitchThumb />
</Switch>
</label>
</div>);
}
Source
The original Coal implementation. Use the package export to integrate it.
packages/react/src/switch.tsx
"use client";
import * as React from "react";
import { cn } from "./internal.js";
export type SwitchProps = Omit<
React.ComponentPropsWithRef<"input">,
"type" | "size"
> & { onCheckedChange?: (checked: boolean) => void };
export function Switch({
checked,
defaultChecked = false,
onCheckedChange,
onChange,
children,
className,
...props
}: SwitchProps) {
return (
<span
className={cn("coal-switch", className)}
data-disabled={props.disabled || undefined}
>
<input
{...props}
type="checkbox"
role="switch"
checked={checked}
defaultChecked={checked === undefined ? defaultChecked : undefined}
onChange={(e) => {
onChange?.(e);
if (!e.defaultPrevented) onCheckedChange?.(e.target.checked);
}}
/>
{children ?? <SwitchThumb />}
</span>
);
}
export function SwitchThumb({
className,
...props
}: React.ComponentPropsWithRef<"span">) {
return (
<span
aria-hidden="true"
className={cn("coal-switch-thumb", className)}
{...props}
/>
);
}
Accessibility checklist
- Provide an accessible name for controls, including icon-only buttons.
- Check keyboard navigation, visible focus and disabled states in your application.
- Do not rely on color alone to communicate status.