init
This commit is contained in:
83
src/components/forms/fields/date-picker-field.tsx
Normal file
83
src/components/forms/fields/date-picker-field.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
'use client';
|
||||
|
||||
import { useStore } from '@tanstack/react-form';
|
||||
import { format } from 'date-fns';
|
||||
import { Calendar } from '@/components/ui/calendar';
|
||||
import { FieldDescription, FieldLabel } from '@/components/ui/field';
|
||||
import { Icons } from '@/components/icons';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
|
||||
import {
|
||||
FormField,
|
||||
FormFieldError,
|
||||
FormFieldSet,
|
||||
createFormField,
|
||||
useFieldContext
|
||||
} from '@/components/ui/form-context';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
interface DatePickerFieldProps {
|
||||
label: string;
|
||||
description?: string;
|
||||
required?: boolean;
|
||||
placeholder?: string;
|
||||
disabled?: (date: Date) => boolean;
|
||||
}
|
||||
|
||||
export function DatePickerField({
|
||||
label,
|
||||
description,
|
||||
required,
|
||||
placeholder = 'Pick a date',
|
||||
disabled
|
||||
}: DatePickerFieldProps) {
|
||||
const field = useFieldContext();
|
||||
const value = useStore(field.store, (s) => s.value) as string | null | undefined;
|
||||
const isTouched = useStore(field.store, (s) => s.meta.isTouched);
|
||||
const isValid = useStore(field.store, (s) => s.meta.isValid);
|
||||
const selectedDate = value ? new Date(value) : undefined;
|
||||
|
||||
return (
|
||||
<FormFieldSet>
|
||||
<FormField>
|
||||
<FieldLabel>
|
||||
{label}
|
||||
{required && ' *'}
|
||||
</FieldLabel>
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
type='button'
|
||||
variant='outline'
|
||||
className={cn(
|
||||
'w-full justify-start text-left font-normal',
|
||||
!value && 'text-muted-foreground'
|
||||
)}
|
||||
aria-invalid={isTouched && !isValid}
|
||||
onBlur={field.handleBlur}
|
||||
>
|
||||
<Icons.calendar className='mr-2 h-4 w-4' />
|
||||
{selectedDate ? format(selectedDate, 'PPP') : <span>{placeholder}</span>}
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className='w-auto p-0' align='start'>
|
||||
<Calendar
|
||||
mode='single'
|
||||
selected={selectedDate}
|
||||
onSelect={(date) => {
|
||||
field.handleChange(date ? date.toISOString() : '');
|
||||
field.handleBlur();
|
||||
}}
|
||||
disabled={disabled}
|
||||
initialFocus
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
{description && <FieldDescription>{description}</FieldDescription>}
|
||||
</FormField>
|
||||
<FormFieldError />
|
||||
</FormFieldSet>
|
||||
);
|
||||
}
|
||||
|
||||
export const FormDatePickerField = createFormField(DatePickerField);
|
||||
Reference in New Issue
Block a user