-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDatePicker.tsx
More file actions
88 lines (79 loc) · 2.56 KB
/
DatePicker.tsx
File metadata and controls
88 lines (79 loc) · 2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
'use client';
import { Calendar } from './calendar';
import { Button } from './button';
import { Popover, PopoverContent, PopoverTrigger } from './popover';
import { Icon } from '@/shared/icons';
import { cn } from '@/shared/lib';
import { useEffect, useState } from 'react';
interface DatePickerProps {
value?: Date;
onChange?: (date: Date) => void;
defaultValue?: Date;
className?: string;
}
const toFirstOfMonth = (d: Date) => new Date(d.getFullYear(), d.getMonth(), 1);
export function DatePicker({
value,
onChange,
defaultValue,
className,
...calendarProps
}: DatePickerProps) {
const [open, setOpen] = useState(false);
const [innerDate, setInnerDate] = useState<Date | undefined>(defaultValue);
const [displayMonth, setDisplayMonth] = useState<Date>(
toFirstOfMonth(value ?? innerDate ?? new Date()),
);
useEffect(() => {
if (value !== undefined) {
setInnerDate(value);
setDisplayMonth(toFirstOfMonth(value));
}
}, [value]);
useEffect(() => {
if (open) {
const base = value ?? innerDate ?? new Date();
setDisplayMonth(toFirstOfMonth(base));
}
}, [open, value, innerDate]);
const selected = value ?? innerDate;
const handleSelect = (d?: Date) => {
if (!d) return;
onChange ? onChange(d) : setInnerDate(d);
setDisplayMonth(toFirstOfMonth(d));
setOpen(false);
};
const today = new Date();
const startOfToday = new Date(
today.getFullYear(),
today.getMonth(),
today.getDate(),
);
return (
<div className={cn('flex flex-col gap-3', className)}>
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button className='w-[16rem] h-[4rem] justify-between rounded-[500px] text-label-lg text-pink-300 bg-pink-50 border border-pink-100'>
{selected ? selected.toLocaleDateString() : 'Select date'}
<Icon name='CalendarBlank' color='pink-400' size={14} />
</Button>
</PopoverTrigger>
<PopoverContent className='w-[24rem] p-0' align='start'>
<Calendar
mode='single'
className='w-[24rem] h-auto p-3 [--cell-size:2.8rem]'
selected={selected}
onSelect={handleSelect}
month={displayMonth}
onMonthChange={setDisplayMonth}
captionLayout='dropdown'
disabled={{ before: startOfToday }}
fromDate={startOfToday}
toYear={new Date(new Date().getFullYear() + 5, 0, 1).getFullYear()}
{...calendarProps}
/>
</PopoverContent>
</Popover>
</div>
);
}