Binary on/off control.
<label class="switch-row" for="sw-1">
<span class="switch-row__label">Marketing emails</span>
<span class="switch switch--md" style="--accent:#A8E6C1;">
<input type="checkbox" role="switch" id="sw-1" class="switch__input" checked aria-checked="true">
<span class="switch__track"><span class="switch__thumb"></span></span>
<span class="switch__caption">On</span>
</span>
</label>
<style>
.switch-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; font: 14px system-ui, sans-serif; color: #241430; max-width: 300px; cursor: pointer; }
.switch { display: inline-flex; align-items: center; gap: 8px; position: relative; }
.switch__input { position: absolute; opacity: 0; width: 40px; height: 24px; margin: 0; cursor: pointer; }
.switch__track { width: 40px; height: 24px; border-radius: 12px; background: #24143030; flex: none; }
.switch--sm .switch__track { width: 32px; height: 19px; border-radius: 10px; }
.switch__thumb { display: block; width: 18px; height: 18px; margin: 3px; border-radius: 50%; background: #FAF7F2; }
@media (prefers-reduced-motion: no-preference) {
.switch__track { transition: background .15s; }
.switch__thumb { transition: transform .15s; }
}
.switch--sm .switch__thumb { width: 13px; height: 13px; margin: 3px; }
.switch__input:checked + .switch__track { background: var(--accent); }
.switch__input:checked + .switch__track .switch__thumb { transform: translateX(16px); }
.switch--sm .switch__input:checked + .switch__track .switch__thumb { transform: translateX(13px); }
.switch__input:focus-visible + .switch__track { outline: 2px solid #241430; outline-offset: 2px; }
.switch__input:disabled + .switch__track { opacity: .5; cursor: not-allowed; }
.switch__caption { font-size: 12px; opacity: .7; width: 20px; }
</style><label for="sw-1-tw" class="flex items-center justify-between gap-4 font-sans text-sm text-[#241430] max-w-[300px] cursor-pointer">
<span>Marketing emails</span>
<span class="switch-tw switch-tw--md inline-flex items-center gap-2 relative" style="--accent:#A8E6C1;">
<input type="checkbox" role="switch" id="sw-1-tw" class="switch-input-tw absolute opacity-0 w-10 h-6 m-0 cursor-pointer" checked aria-checked="true">
<span class="switch-track-tw w-10 h-6 rounded-full bg-[#24143030] flex-none block"><span class="switch-thumb-tw block w-[18px] h-[18px] m-[3px] rounded-full bg-[#FAF7F2]"></span></span>
<span class="text-xs opacity-70 w-5">On</span>
</span>
</label>
<style>
.switch-tw--sm .switch-track-tw { width: 32px; height: 19px; border-radius: 10px; }
.switch-tw--sm .switch-thumb-tw { width: 13px; height: 13px; }
.switch-input-tw:checked + .switch-track-tw { background: #A8E6C1; }
.switch-input-tw:checked + .switch-track-tw .switch-thumb-tw { transform: translateX(16px); }
.switch-tw--sm .switch-input-tw:checked + .switch-track-tw .switch-thumb-tw { transform: translateX(13px); }
.switch-input-tw:focus-visible + .switch-track-tw { outline: 2px solid #241430; outline-offset: 2px; }
.switch-input-tw:disabled + .switch-track-tw { opacity: .5; }
@media (prefers-reduced-motion: no-preference) {
.switch-input-tw:checked + .switch-track-tw .switch-thumb-tw { transition: transform .15s; }
}
</style>export function Switch({
label = "Marketing emails",
on = true,
size = "md",
accent = "#A8E6C1",
disabled = false,
}) {
const sm = size === "sm";
const trackW = sm ? 32 : 40, trackH = sm ? 19 : 24, thumb = sm ? 13 : 18;
return (
<>
<label style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, fontFamily: "system-ui, sans-serif", fontSize: 14, color: "#241430", maxWidth: 300, cursor: disabled ? "not-allowed" : "pointer" }}>
<span>{label}</span>
<span style={{ display: "inline-flex", alignItems: "center", gap: 8 }}>
<span role="switch" aria-checked={on} style={{
width: trackW, height: trackH, borderRadius: trackH / 2,
background: on ? accent : "#24143030", position: "relative", display: "inline-block",
opacity: disabled ? 0.5 : 1,
}}>
<span className="switch-thumb" style={{
display: "block", width: thumb, height: thumb, margin: 3, borderRadius: "50%", background: "#FAF7F2",
transform: on ? `translateX(${trackW - thumb - 6}px)` : "translateX(0)",
}} />
</span>
<span style={{ fontSize: 12, opacity: .7, width: 20 }}>{on ? "On" : "Off"}</span>
</span>
</label>
<style>{`
@media (prefers-reduced-motion: no-preference) {
.switch-thumb { transition: transform .15s; }
}
`}</style>
</>
);
}