Files
spsays-training/components/settings/setting-row.tsx
T
2026-06-11 00:32:04 +05:30

66 lines
1.7 KiB
TypeScript

"use client";
/**
* Shared building blocks for /settings rows: SettingRow lays out a
* label + description with a control on the right, and ToggleSwitch is the
* pill switch every boolean preference uses. Keeps the notification toggles
* (push, reminders, like emails) from each carrying a copy of this markup.
*/
export function SettingRow({
label,
description,
control,
}: {
label: string;
description: React.ReactNode;
control: React.ReactNode;
}) {
return (
<ul className="divide-y divide-border">
<li className="flex items-center justify-between gap-4 py-3">
<div className="min-w-0">
<span className="text-sm text-foreground">{label}</span>
<p className="text-xs text-muted-foreground mt-0.5">{description}</p>
</div>
<div className="shrink-0">{control}</div>
</li>
</ul>
);
}
export function ToggleSwitch({
checked,
disabled,
onToggle,
label,
}: {
checked: boolean;
disabled?: boolean;
onToggle: () => void;
/** Accessible name — the row label isn't programmatically associated. */
label: string;
}) {
return (
<button
type="button"
role="switch"
aria-checked={checked}
aria-label={label}
onClick={onToggle}
disabled={disabled}
className={[
"relative inline-flex h-6 w-11 items-center rounded-full transition-colors disabled:opacity-60",
checked ? "bg-primary" : "bg-muted-foreground/30",
].join(" ")}
>
<span
className={[
"inline-block size-5 transform rounded-full bg-white shadow transition-transform",
checked ? "translate-x-5" : "translate-x-0.5",
].join(" ")}
/>
</button>
);
}