import { type ChangeEvent, useMemo, useState } from "react"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; export function Field({ label, value = "", onChange = () => {}, validate, hidden = false, submitAttempted, placeholder, error, tabIndex, spellcheck, maxLength, showCounter = true, }: { label: string; value?: string; onChange?: (e: ChangeEvent) => void; validate?: (value: string) => string | undefined; hidden?: boolean; submitAttempted?: boolean; placeholder?: string; error?: string; tabIndex?: number; spellcheck?: boolean; maxLength?: number; showCounter?: boolean; }) { const [internalTouched, setInternalTouched] = useState(false); const isTouched = submitAttempted || internalTouched; const invalidMessage = useMemo(() => { if (!isTouched && value === "") { return ""; } return validate?.(value) ?? ""; }, [isTouched, validate, value]); return (
{ onChange(e); setInternalTouched(true); }} onBlur={() => setInternalTouched(true)} name={label} aria-invalid={error !== undefined || invalidMessage !== ""} type={hidden ? "password" : "text"} tabIndex={tabIndex} spellCheck={spellcheck} maxLength={maxLength} showCounter={showCounter} />
{error || invalidMessage !== "" ? ( ) : ( )}
); }