84 lines
2.2 KiB
TypeScript
84 lines
2.2 KiB
TypeScript
import {
|
|
Field,
|
|
FieldDescription,
|
|
FieldError,
|
|
FieldLabel,
|
|
Input
|
|
} from "@repo/shadcn-ui/components";
|
|
|
|
import { cn } from "@repo/shadcn-ui/lib/utils";
|
|
import { Control, Controller, FieldPath, FieldValues, useFormState } from "react-hook-form";
|
|
import { CommonInputProps } from "./types.js";
|
|
|
|
|
|
type Normalizer = (value: string) => string;
|
|
|
|
type TextFieldProps<TFormValues extends FieldValues> = CommonInputProps & {
|
|
control: Control<TFormValues>;
|
|
name: FieldPath<TFormValues>;
|
|
|
|
label?: string;
|
|
description?: string;
|
|
|
|
orientation?: "vertical" | "horizontal" | "responsive",
|
|
|
|
inputClassName?: string;
|
|
};
|
|
|
|
export function TextField<TFormValues extends FieldValues>({
|
|
control,
|
|
name,
|
|
label,
|
|
description,
|
|
required = false,
|
|
readOnly = false,
|
|
|
|
orientation = 'vertical',
|
|
|
|
className,
|
|
inputClassName,
|
|
|
|
...inputRest
|
|
}: TextFieldProps<TFormValues>) {
|
|
const { isSubmitting, isValidating } = useFormState({ control, name });
|
|
const disabled = isSubmitting || inputRest.disabled;
|
|
|
|
function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
|
|
if (e.key === "Enter") {
|
|
const form = (e.currentTarget as HTMLInputElement).form;
|
|
if (form) form.requestSubmit();
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Controller
|
|
control={control}
|
|
name={name}
|
|
render={({ field, fieldState }) => {
|
|
return (
|
|
<Field data-invalid={fieldState.invalid} orientation={orientation} className={className}>
|
|
{label && <FieldLabel className='text-xs text-muted-foreground text-nowrap' htmlFor={name}>{label}</FieldLabel>}
|
|
|
|
<Input
|
|
ref={field.ref}
|
|
id={name}
|
|
value={field.value ?? ""}
|
|
onChange={field.onChange}
|
|
onBlur={field.onBlur}
|
|
onKeyDown={handleKeyDown}
|
|
aria-invalid={fieldState.invalid}
|
|
aria-busy={isValidating}
|
|
{...inputRest}
|
|
disabled={disabled}
|
|
aria-disabled={disabled}
|
|
className={cn(inputClassName)}
|
|
/>
|
|
{false && <FieldDescription className='text-xs'>{description || "\u00A0"}</FieldDescription>}
|
|
<FieldError errors={[fieldState.error]} />
|
|
</Field>
|
|
);
|
|
}}
|
|
/>
|
|
);
|
|
}
|