-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathdate-picker.tsx
88 lines (74 loc) · 2.7 KB
/
date-picker.tsx
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
import type {DateValue} from "@internationalized/date";
import {ForwardedRef, ReactElement, Ref, useMemo} from "react";
import {cloneElement, isValidElement} from "react";
import {forwardRef} from "@nextui-org/system";
import {Button} from "@nextui-org/button";
import {DateInput, TimeInput} from "@nextui-org/date-input";
import {FreeSoloPopover} from "@nextui-org/popover";
import {Calendar} from "@nextui-org/calendar";
import {AnimatePresence} from "framer-motion";
import {CalendarBoldIcon} from "@nextui-org/shared-icons";
import {UseDatePickerProps, useDatePicker} from "./use-date-picker";
export interface Props<T extends DateValue> extends UseDatePickerProps<T> {}
function DatePicker<T extends DateValue>(props: Props<T>, ref: ForwardedRef<HTMLDivElement>) {
const {
state,
endContent,
selectorIcon,
showTimeField,
disableAnimation,
isCalendarHeaderExpanded,
getDateInputProps,
getPopoverProps,
getTimeInputProps,
getSelectorButtonProps,
getSelectorIconProps,
getCalendarProps,
CalendarTopContent,
CalendarBottomContent,
} = useDatePicker<T>({...props, ref});
const selectorContent = isValidElement(selectorIcon) ? (
cloneElement(selectorIcon, getSelectorIconProps())
) : (
<CalendarBoldIcon {...getSelectorIconProps()} />
);
const calendarBottomContent = useMemo(() => {
if (isCalendarHeaderExpanded) return null;
return showTimeField ? (
<>
<TimeInput {...getTimeInputProps()} />
{CalendarBottomContent}
</>
) : (
CalendarBottomContent
);
}, [state, showTimeField, CalendarBottomContent, isCalendarHeaderExpanded]);
const calendarTopContent = useMemo(() => {
if (isCalendarHeaderExpanded) return null;
return CalendarTopContent;
}, [showTimeField, CalendarTopContent, isCalendarHeaderExpanded]);
const popoverContent = state.isOpen ? (
<FreeSoloPopover {...getPopoverProps()}>
<Calendar
{...getCalendarProps()}
bottomContent={calendarBottomContent}
topContent={calendarTopContent}
/>
</FreeSoloPopover>
) : null;
return (
<>
<DateInput
{...getDateInputProps()}
endContent={<Button {...getSelectorButtonProps()}>{endContent || selectorContent}</Button>}
/>
{disableAnimation ? popoverContent : <AnimatePresence>{popoverContent}</AnimatePresence>}
</>
);
}
DatePicker.displayName = "NextUI.DatePicker";
export type DatePickerProps<T extends DateValue = DateValue> = Props<T> & {ref?: Ref<HTMLElement>};
// forwardRef doesn't support generic parameters, so cast the result to the correct type
export default forwardRef(DatePicker) as <T extends DateValue>(
props: DatePickerProps<T>,
) => ReactElement;