import { assignInlineVars } from '@vanilla-extract/dynamic'; import dayjs from 'dayjs'; import { useCallback, useState } from 'react'; import * as styles from './calendar.css'; import { DATE_MAX, DATE_MIN } from './constants'; import { DayPicker } from './day-picker'; import { MonthPicker } from './month-picker'; import type { DatePickerProps, SelectMode } from './types'; import { defaultDatePickerProps } from './types'; import { YearPicker } from './year-picker'; export type { DatePickerProps } from './types'; /** * Inline DatePicker * @returns */ export const DatePicker = (props: DatePickerProps) => { const finalProps = { ...defaultDatePickerProps, ...props }; const { value, gapX, gapY, onChange } = finalProps; const [mode, setMode] = useState<SelectMode>('day'); const [cursor, setCursor] = useState(dayjs(value)); const variables = assignInlineVars({ [styles.vars.gapX]: `${gapX}px`, [styles.vars.gapY]: `${gapY}px`, }); const Component = mode === 'day' ? DayPicker : mode === 'month' ? MonthPicker : YearPicker; const onPreChange = useCallback( (v: string) => { setMode('day'); setCursor(dayjs(v)); onChange?.(v); }, [onChange] ); const onCursorChange = useCallback((newCursor: dayjs.Dayjs) => { // validate range if (newCursor.isBefore(DATE_MIN)) newCursor = dayjs(DATE_MIN); else if (newCursor.isAfter(DATE_MAX)) newCursor = dayjs(DATE_MAX); setCursor(newCursor); }, []); return ( <div className={styles.calendarRoot} style={variables}> <Component cursor={cursor} {...finalProps} onChange={onPreChange} onCursorChange={onCursorChange} onModeChange={setMode} /> </div> ); };