import { createSignal } from 'solid-js';
import { cn } from '../utils/cn';
export interface SwitchProps {
/** Controlled checked state. When set, the component defers state to the
* parent; drive it from `onChange`. Omit for uncontrolled (internal) state. */
checked?: boolean;
/** Initial checked state when uncontrolled. */
defaultChecked?: boolean;
/** Disable interaction. */
disabled?: boolean;
/** Accessible label for the control. */
label?: string;
/** Form-control name. When set (paired with `value`), a hidden checkbox carries
* the on/off value for serialization. */
name?: string;
/** Submitted value when checked (paired with `name`). Defaults to `'on'`. */
value?: string;
/** Fires with the next checked state on toggle. */
onChange?: (checked: boolean) => void;
/** Receives the inner `role="switch"` button so a parent can focus it. */
buttonRef?: (el: HTMLButtonElement) => void;
class?: string;
}
/**
* A toggle switch (`role="switch"`). Controlled via `checked`, or uncontrolled
* from `defaultChecked`. Keyboard-operable (Space/Enter) and theme-tokened.
*/
export function Switch(props: SwitchProps) {
const [internal, setInternal] = createSignal(props.defaultChecked ?? false);
const isControlled = () => props.checked !== undefined;
const isOn = () => (isControlled() ? !!props.checked : internal());
const toggle = () => {
if (props.disabled) return;
const next = !isOn();
if (!isControlled()) setInternal(next);
props.onChange?.(next);
};
return (
<>
{props.name != null && (
{ /* driven by the button; keep the input in sync only */ }}
/>
)}
>
);
}