/** * @file SettingsRow — the settings page's row primitives: a titled card * (`SettingsSection`), a label/description | control row (`SettingsRow`), a * switch row (`SettingsSwitchRow`) and a segmented radio group * (`SettingsSegmented`). Rows divide themselves with a hairline, none after the * last, so a section is just its rows in order. * @author Nguyễn Ngọc Trí Vĩ */ import type { ReactNode } from "react"; export function SettingsSection({ title, description, children, }: { title: ReactNode; description?: ReactNode; children: ReactNode; }) { return (

{title}

{description &&

{description}

}
{children}
); } export function SettingsRow({ label, description, control, alignTop = false, }: { label: ReactNode; description?: ReactNode; control: ReactNode; alignTop?: boolean; }) { return (

{label}

{description &&

{description}

}
{control}
); } export function SettingsSwitchRow({ label, description, checked, onChange, disabled = false, }: { label: string; description?: ReactNode; checked: boolean; onChange: (v: boolean) => void; disabled?: boolean; }) { return ( onChange(!checked)} className={`relative inline-flex h-5 w-9 rounded-full border-2 border-transparent transition-colors disabled:opacity-50 ${ checked ? "bg-accent" : "bg-surface-4" }`} > } /> ); } export function SettingsSegmented({ options, value, onChange, ariaLabel, }: { options: { value: T; label: ReactNode }[]; value: T; onChange: (v: T) => void; ariaLabel?: string; }) { return (
{options.map((o) => ( ))}
); }