Uecko_ERP/packages/rdx-ui/src/components/form/date-picker-field.tsx

107 lines
2.7 KiB
TypeScript
Raw Normal View History

2026-04-03 16:15:25 +00:00
import {
Field,
FieldDescription,
FieldError,
2026-04-09 18:39:54 +00:00
InputGroup,
InputGroupAddon,
InputGroupInput,
2026-04-03 16:15:25 +00:00
} from "@repo/shadcn-ui/components";
import { cn } from "@repo/shadcn-ui/lib/utils";
2026-04-09 18:39:54 +00:00
import * as React from "react";
2026-04-03 16:15:25 +00:00
import { type FieldPath, type FieldValues, useFormContext } from "react-hook-form";
import { FormFieldLabel } from "./form-field-label.tsx";
2026-04-09 18:39:54 +00:00
import type { NativeInputProps } from "./types.ts";
2026-04-03 16:15:25 +00:00
2026-04-09 18:39:54 +00:00
type DatePickerFieldProps<TFormValues extends FieldValues> = Omit<NativeInputProps, "name"> & {
2026-04-03 16:15:25 +00:00
name: FieldPath<TFormValues>;
label?: string;
description?: string;
2026-04-29 15:02:08 +00:00
reserveDescriptionSpace?: boolean;
2026-04-03 16:15:25 +00:00
orientation?: "vertical" | "horizontal" | "responsive";
inputClassName?: string;
};
2026-04-09 18:39:54 +00:00
export const DatePickerField = <TFormValues extends FieldValues>({
2026-04-03 16:15:25 +00:00
name,
2026-04-09 18:39:54 +00:00
2026-04-03 16:15:25 +00:00
label,
description,
2026-04-29 15:02:08 +00:00
reserveDescriptionSpace = false,
2026-04-09 18:39:54 +00:00
2026-04-03 16:15:25 +00:00
required = false,
readOnly = false,
2026-04-09 18:39:54 +00:00
2026-04-03 16:15:25 +00:00
orientation = "vertical",
2026-04-09 18:39:54 +00:00
2026-04-03 16:15:25 +00:00
className,
inputClassName,
2026-04-09 18:39:54 +00:00
...inputRest
}: DatePickerFieldProps<TFormValues>) => {
const { register, formState, getFieldState } = useFormContext<TFormValues>();
const inputId = React.useId();
const disabled = formState.isSubmitting || inputRest.disabled;
const presetProps = {
type: "date",
autoComplete: "off",
spellCheck: false,
};
2026-06-01 18:48:12 +00:00
const rightIcon = null; //<CalendarX2Icon />;
2026-04-09 18:39:54 +00:00
// Obtener error del campo (tipado seguro)
const fieldError = getFieldState(name, formState).error;
2026-04-03 16:15:25 +00:00
return (
2026-04-09 18:39:54 +00:00
<Field className={cn("gap-1", className)} data-invalid={!!fieldError} orientation={orientation}>
{label ? (
<FormFieldLabel htmlFor={inputId} required={required}>
{label}
</FormFieldLabel>
) : null}
<InputGroup
className={cn(
"bg-muted/50 font-medium",
"hover:border-ring hover:ring-ring/20 hover:ring-[3px]",
"focus-visible:border-ring focus-visible:ring-ring/60 focus-visible:ring-[3px]",
"placeholder:text-muted-foreground/50",
inputClassName
)}
>
<InputGroupInput
{...presetProps}
{...inputRest}
{...register(name)}
aria-invalid={!!fieldError}
className="placeholder:text-muted-foreground/50"
disabled={disabled}
id={inputId}
readOnly={readOnly}
required={required}
/>
2026-05-18 16:41:19 +00:00
{rightIcon && (
<InputGroupAddon align="inline-end" aria-hidden="true">
{rightIcon}
</InputGroupAddon>
)}
2026-04-09 18:39:54 +00:00
</InputGroup>
{description ? (
<FieldDescription>{description}</FieldDescription>
2026-04-29 15:02:08 +00:00
) : reserveDescriptionSpace ? (
2026-04-09 18:39:54 +00:00
<div aria-hidden="true" className="min-h-5" />
2026-04-29 15:02:08 +00:00
) : null}
2026-04-09 18:39:54 +00:00
<FieldError errors={[fieldError]} />
</Field>
2026-04-03 16:15:25 +00:00
);
2026-04-09 18:39:54 +00:00
};