Uecko_ERP/packages/rdx-ui/src/components/form/TextField.tsx

84 lines
2.2 KiB
TypeScript
Raw Normal View History

2025-07-09 17:56:15 +00:00
import {
2025-10-14 17:57:02 +00:00
Field,
FieldDescription,
FieldError,
FieldLabel,
Input
2025-07-09 17:56:15 +00:00
} from "@repo/shadcn-ui/components";
import { cn } from "@repo/shadcn-ui/lib/utils";
2025-10-14 17:57:02 +00:00
import { Control, Controller, FieldPath, FieldValues, useFormState } from "react-hook-form";
2025-10-02 16:30:46 +00:00
import { CommonInputProps } from "./types.js";
2025-07-09 17:56:15 +00:00
2025-09-20 11:25:07 +00:00
type Normalizer = (value: string) => string;
type TextFieldProps<TFormValues extends FieldValues> = CommonInputProps & {
2025-07-09 17:56:15 +00:00
control: Control<TFormValues>;
name: FieldPath<TFormValues>;
2025-10-14 17:57:02 +00:00
2025-07-09 17:56:15 +00:00
label?: string;
description?: string;
2025-09-20 11:25:07 +00:00
2025-10-14 17:57:02 +00:00
orientation?: "vertical" | "horizontal" | "responsive",
2025-09-20 11:25:07 +00:00
2025-10-14 17:57:02 +00:00
inputClassName?: string;
2025-07-09 17:56:15 +00:00
};
export function TextField<TFormValues extends FieldValues>({
control,
name,
label,
description,
2025-10-14 17:57:02 +00:00
required = false,
readOnly = false,
2025-09-20 11:25:07 +00:00
2025-10-14 17:57:02 +00:00
orientation = 'vertical',
2025-09-20 11:25:07 +00:00
2025-10-14 17:57:02 +00:00
className,
inputClassName,
2025-09-20 11:25:07 +00:00
2025-10-14 17:57:02 +00:00
...inputRest
2025-07-09 17:56:15 +00:00
}: TextFieldProps<TFormValues>) {
2025-09-20 11:25:07 +00:00
const { isSubmitting, isValidating } = useFormState({ control, name });
2025-10-14 17:57:02 +00:00
const disabled = isSubmitting || inputRest.disabled;
2025-09-20 11:25:07 +00:00
function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
2025-10-14 17:57:02 +00:00
if (e.key === "Enter") {
2025-09-20 11:25:07 +00:00
const form = (e.currentTarget as HTMLInputElement).form;
if (form) form.requestSubmit();
}
}
2025-07-09 17:56:15 +00:00
return (
2025-10-14 17:57:02 +00:00
<Controller
2025-07-09 17:56:15 +00:00
control={control}
name={name}
2025-10-14 17:57:02 +00:00
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>
);
}}
2025-07-09 17:56:15 +00:00
/>
);
}