54 lines
1.7 KiB
TypeScript
54 lines
1.7 KiB
TypeScript
import { Controller, useFormContext } from 'react-hook-form';
|
|
import { FieldError } from './FieldError';
|
|
|
|
type Props = {
|
|
name: string;
|
|
label: string;
|
|
hint?: string;
|
|
};
|
|
|
|
export function ToggleField({ name, label, hint }: Props) {
|
|
const { control } = useFormContext();
|
|
return (
|
|
<Controller
|
|
name={name}
|
|
control={control}
|
|
render={({ field }) => {
|
|
const on = !!field.value;
|
|
return (
|
|
<div>
|
|
<button
|
|
type="button"
|
|
role="switch"
|
|
aria-checked={on}
|
|
onClick={() => field.onChange(!on)}
|
|
className={`flex items-center gap-3 px-3 py-2 rounded border bg-[color:var(--color-surface-2)] transition-colors ${
|
|
on
|
|
? 'border-[color:var(--color-acid)] text-[color:var(--color-acid)]'
|
|
: 'border-[color:var(--color-border)] text-[color:var(--color-text-muted)]'
|
|
}`}
|
|
>
|
|
<span
|
|
className={`led ${on ? 'led-acid animate-led-green' : ''}`}
|
|
style={!on ? { background: 'var(--color-text-dim)', boxShadow: 'none' } : undefined}
|
|
/>
|
|
<span className="font-mono text-xs uppercase tracking-widest">
|
|
{label}
|
|
</span>
|
|
<span className="ml-auto font-mono text-[10px] opacity-70">
|
|
{on ? 'ON' : 'OFF'}
|
|
</span>
|
|
</button>
|
|
{hint && (
|
|
<span className="block font-mono text-[10px] text-[color:var(--color-text-dim)] mt-1">
|
|
{hint}
|
|
</span>
|
|
)}
|
|
<FieldError name={name} />
|
|
</div>
|
|
);
|
|
}}
|
|
/>
|
|
);
|
|
}
|