Uecko_ERP/packages/rdx-ui/src/components/form/text-area-field.tsx
2026-04-04 00:09:05 +02:00

91 lines
2.5 KiB
TypeScript

import { Field, FieldDescription, FieldError, Textarea } from "@repo/shadcn-ui/components";
import { cn } from "@repo/shadcn-ui/lib/utils";
import * as React from "react";
import { type FieldPath, type FieldValues, useFormContext } from "react-hook-form";
import { FormFieldLabel } from "./form-field-label.tsx";
import type { NativeTextareaProps } from "./types.ts";
type TextAreaFieldProps<TFormValues extends FieldValues> = Omit<NativeTextareaProps, "name"> & {
name: FieldPath<TFormValues>;
label?: string;
description?: string;
orientation?: "vertical" | "horizontal" | "responsive";
inputClassName?: string;
};
export function TextAreaField<TFormValues extends FieldValues>({
name,
label,
description,
required = false,
readOnly = false,
orientation = "vertical",
className,
inputClassName,
...inputRest
}: TextAreaFieldProps<TFormValues>) {
const { register, formState, getFieldState } = useFormContext<TFormValues>();
const inputId = React.useId();
const disabled = formState.isSubmitting || inputRest.disabled;
// Obtener error del campo (tipado seguro)
const fieldError = getFieldState(name, formState).error;
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
inputRest.onKeyDown?.(e);
if (e.defaultPrevented) return;
// Cmd/Ctrl + Enter para submit
if ((e.metaKey || e.ctrlKey) && e.key === "Enter" && !e.nativeEvent.isComposing) {
e.preventDefault();
e.currentTarget.form?.requestSubmit();
}
};
return (
<Field className={cn("gap-1", className)} data-invalid={!!fieldError} orientation={orientation}>
{label ? (
<FormFieldLabel htmlFor={inputId} required={required}>
{label}
</FormFieldLabel>
) : null}
<Textarea
{...inputRest}
{...register(name)}
aria-invalid={!!fieldError}
className={cn(
"bg-muted/50 font-medium",
"hover:border-ring/60",
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
"placeholder:text-muted-foreground/50",
inputClassName
)}
disabled={disabled}
id={inputId}
onKeyDown={handleKeyDown}
readOnly={readOnly}
required={required}
/>
{description ? (
<FieldDescription>{description}</FieldDescription>
) : (
<div aria-hidden="true" className="min-h-5" />
)}
<FieldError errors={[fieldError]} />
</Field>
);
}