diff --git a/.jest/with-theme.tsx b/.jest/with-theme.tsx index 03a1c4d..77f76b0 100644 --- a/.jest/with-theme.tsx +++ b/.jest/with-theme.tsx @@ -1,11 +1,11 @@ +import * as React from 'react' import { render, RenderOptions } from '@testing-library/react' import { ChakraProvider } from '@chakra-ui/react' import { theme } from '../src/theme' -import { PropsWithChildren, ReactElement } from 'react' -const Providers = ({ children }: PropsWithChildren) => {children} +const Providers = ({ children }: React.PropsWithChildren) => {children} -const renderer = (ui: ReactElement, options?: RenderOptions) => { +const renderer = (ui: React.ReactElement, options?: RenderOptions) => { return render(ui, { wrapper: Providers, ...options }) } diff --git a/src/calendar.stories.tsx b/src/calendar.stories.tsx index 2556e15..c005dc3 100644 --- a/src/calendar.stories.tsx +++ b/src/calendar.stories.tsx @@ -1,5 +1,5 @@ +import * as React from 'react' import { ComponentStory, ComponentMeta } from '@storybook/react' -import { ChangeEvent, useRef, useState, useEffect } from 'react' import { addDays, format, isAfter, isBefore, isValid, subDays } from 'date-fns' import { Box, @@ -33,7 +33,7 @@ export default { } as ComponentMeta export const Basic: ComponentStory = () => { - const [dates, setDates] = useState({}) + const [dates, setDates] = React.useState({}) const handleSelectDate = (dates: CalendarValues) => setDates(dates) @@ -56,7 +56,7 @@ export const Basic: ComponentStory = () => { } export const CustomLocale: ComponentStory = ({ locale }) => { - const [dates, setDates] = useState({}) + const [dates, setDates] = React.useState({}) const handleSelectDate = (dates: CalendarValues) => setDates(dates) @@ -97,7 +97,7 @@ CustomLocale.args = { } export const DisablePastDates: ComponentStory = () => { - const [dates, setDates] = useState({}) + const [dates, setDates] = React.useState({}) const handleSelectDate = (dates: CalendarValues) => setDates(dates) @@ -120,7 +120,7 @@ export const DisablePastDates: ComponentStory = () => { } export const DisablePastDatesFrom: ComponentStory = () => { - const [dates, setDates] = useState({}) + const [dates, setDates] = React.useState({}) const handleSelectDate = (dates: CalendarValues) => setDates(dates) @@ -147,7 +147,7 @@ export const DisablePastDatesFrom: ComponentStory = () => { } export const DisableFutureDates: ComponentStory = () => { - const [dates, setDates] = useState({}) + const [dates, setDates] = React.useState({}) const handleSelectDate = (dates: CalendarValues) => setDates(dates) @@ -170,7 +170,7 @@ export const DisableFutureDates: ComponentStory = () => { } export const DisableFutureDatesFrom: ComponentStory = () => { - const [dates, setDates] = useState({}) + const [dates, setDates] = React.useState({}) const handleSelectDate = (dates: CalendarValues) => setDates(dates) @@ -197,7 +197,7 @@ export const DisableFutureDatesFrom: ComponentStory = () => { } export const DisableDates: ComponentStory = () => { - const [dates, setDates] = useState({}) + const [dates, setDates] = React.useState({}) const handleSelectDate = (dates: CalendarValues) => setDates(dates) @@ -233,7 +233,7 @@ export const DisableDates: ComponentStory = () => { } export const DisableWeekends: ComponentStory = () => { - const [dates, setDates] = useState({}) + const [dates, setDates] = React.useState({}) const handleSelectDate = (dates: CalendarValues) => setDates(dates) @@ -256,7 +256,7 @@ export const DisableWeekends: ComponentStory = () => { } export const AllowOutsideDays: ComponentStory = () => { - const [dates, setDates] = useState({}) + const [dates, setDates] = React.useState({}) const handleSelectDate = (dates: CalendarValues) => setDates(dates) @@ -279,7 +279,7 @@ export const AllowOutsideDays: ComponentStory = () => { } export const SingleDateSelection: ComponentStory = () => { - const [date, setDate] = useState() + const [date, setDate] = React.useState() const handleSelectDate = (date: CalendarDate) => setDate(date) @@ -306,7 +306,7 @@ export const SingleDateSelection: ComponentStory = () => { } export const CustomControlButtons: ComponentStory = () => { - const [date, setDate] = useState() + const [date, setDate] = React.useState() const handleSelectDate = (date: CalendarDate) => setDate(date) @@ -345,7 +345,7 @@ export const CustomControlButtons: ComponentStory = () => { } export const WithMultipleMonths: ComponentStory = () => { - const [dates, setDates] = useState({}) + const [dates, setDates] = React.useState({}) const MONTHS = 2 const handleSelectDate = (dates: CalendarValues) => setDates(dates) @@ -371,13 +371,13 @@ export const WithMultipleMonths: ComponentStory = () => { } export const WithInputPopover: ComponentStory = () => { - const [date, setDate] = useState() - const [value, setValue] = useState('') + const [date, setDate] = React.useState() + const [value, setValue] = React.useState('') const { isOpen, onOpen, onClose } = useDisclosure() - const initialRef = useRef(null) - const calendarRef = useRef(null) + const initialRef = React.useRef(null) + const calendarRef = React.useRef(null) const handleSelectDate = (date: CalendarDate) => { setDate(date) @@ -387,7 +387,9 @@ export const WithInputPopover: ComponentStory = () => { const match = (value: string) => value.match(/(\d{2})\/(\d{2})\/(\d{4})/) - const handleInputChange = ({ target }: ChangeEvent) => { + const handleInputChange = ({ + target, + }: React.ChangeEvent) => { setValue(target.value) if (match(target.value)) { @@ -401,7 +403,7 @@ export const WithInputPopover: ComponentStory = () => { enabled: isOpen, }) - useEffect(() => { + React.useEffect(() => { if (match(value)) { const date = new Date(value) @@ -462,167 +464,172 @@ export const WithInputPopover: ComponentStory = () => { ) } -export const WithInputPopoverStartEndDates: ComponentStory< - typeof Calendar -> = () => { - const [dates, setDates] = useState({}) - const [values, setValues] = useState({ - start: '', - end: '', - }) +export const WithInputPopoverStartEndDates: ComponentStory = + () => { + const [dates, setDates] = React.useState({}) + const [values, setValues] = React.useState({ + start: '', + end: '', + }) - const { isOpen, onOpen, onClose } = useDisclosure() + const { isOpen, onOpen, onClose } = useDisclosure() - const initialRef = useRef(null) - const calendarRef = useRef(null) - const startInputRef = useRef(null) - const endInputRef = useRef(null) + const initialRef = React.useRef(null) + const calendarRef = React.useRef(null) + const startInputRef = React.useRef(null) + const endInputRef = React.useRef(null) - const MONTHS = 2 + const MONTHS = 2 - const handleSelectDate = (dates: CalendarValues) => { - setDates(dates) + const handleSelectDate = (dates: CalendarValues) => { + setDates(dates) - setValues({ - start: isValid(dates.start) - ? format(dates.start as Date, 'MM/dd/yyyy') - : '', - end: isValid(dates.end) ? format(dates.end as Date, 'MM/dd/yyyy') : '', - }) + setValues({ + start: isValid(dates.start) + ? format(dates.start as Date, 'MM/dd/yyyy') + : '', + end: isValid(dates.end) ? format(dates.end as Date, 'MM/dd/yyyy') : '', + }) - if (dates.end) { - onClose() + if (dates.end) { + onClose() + } } - } - const match = (value: string) => value.match(/(\d{2})\/(\d{2})\/(\d{4})/) + const match = (value: string) => value.match(/(\d{2})\/(\d{2})\/(\d{4})/) + + const handleInputChange = ({ + target, + }: React.ChangeEvent) => { + setValues({ + ...values, + [target.name]: target.value, + }) + + if ( + target.name === 'start' && + match(target.value) && + endInputRef.current + ) { + endInputRef.current.focus() + } + } - const handleInputChange = ({ target }: ChangeEvent) => { - setValues({ - ...values, - [target.name]: target.value, + useOutsideClick({ + ref: calendarRef, + handler: onClose, + enabled: isOpen, }) - if (target.name === 'start' && match(target.value) && endInputRef.current) { - endInputRef.current.focus() - } - } - - useOutsideClick({ - ref: calendarRef, - handler: onClose, - enabled: isOpen, - }) + React.useEffect(() => { + if (match(values.start)) { + const startDate = new Date(values.start) + const isValidStartDate = isValid(startDate) + const isAfterEndDate = dates.end && isAfter(startDate, dates.end) - useEffect(() => { - if (match(values.start)) { - const startDate = new Date(values.start) - const isValidStartDate = isValid(startDate) - const isAfterEndDate = dates.end && isAfter(startDate, dates.end) + if (isValidStartDate && isAfterEndDate) { + setValues({ ...values, end: '' }) + return setDates({ end: undefined, start: startDate }) + } - if (isValidStartDate && isAfterEndDate) { - setValues({ ...values, end: '' }) - return setDates({ end: undefined, start: startDate }) + return setDates({ ...dates, start: startDate }) } + }, [values.start]) - return setDates({ ...dates, start: startDate }) - } - }, [values.start]) + React.useEffect(() => { + if (match(values.end)) { + const endDate = new Date(values.end) + const isValidEndDate = isValid(endDate) + const isBeforeStartDate = dates.start && isBefore(endDate, dates.start) - useEffect(() => { - if (match(values.end)) { - const endDate = new Date(values.end) - const isValidEndDate = isValid(endDate) - const isBeforeStartDate = dates.start && isBefore(endDate, dates.start) + if (isValidEndDate && isBeforeStartDate) { + setValues({ ...values, start: '' }) - if (isValidEndDate && isBeforeStartDate) { - setValues({ ...values, start: '' }) + startInputRef.current?.focus() - startInputRef.current?.focus() + return setDates({ start: undefined, end: endDate }) + } - return setDates({ start: undefined, end: endDate }) + onClose() + return setDates({ ...dates, end: endDate }) } - - onClose() - return setDates({ ...dates, end: endDate }) - } - }, [values.end]) - - return ( - - - - - - - - - - + - + + + + + + + - - - - - - - - {[...Array(MONTHS).keys()].map(m => ( - - - - - - ))} - - - - - - - ) -} + + + + + + + + + {[...Array(MONTHS).keys()].map(m => ( + + + + + + ))} + + + + + + + ) + } export const CustomContent: ComponentStory = () => { - const [dates, setDates] = useState({}) + const [dates, setDates] = React.useState({}) const handleSelectDate = (dates: CalendarValues) => setDates(dates) @@ -678,7 +685,7 @@ export const CustomContent: ComponentStory = () => { } export const StartWeekDay: ComponentStory = () => { - const [dates, setDates] = useState({}) + const [dates, setDates] = React.useState({}) const handleSelectDate = (dates: CalendarValues) => setDates(dates) @@ -701,7 +708,7 @@ export const StartWeekDay: ComponentStory = () => { } export const HighlightToday: ComponentStory = () => { - const [dates, setDates] = useState({}) + const [dates, setDates] = React.useState({}) const handleSelectDate = (dates: CalendarValues) => setDates(dates) return ( @@ -723,7 +730,7 @@ export const HighlightToday: ComponentStory = () => { } export const WeekSelection: ComponentStory = () => { - const [dates, setDates] = useState({}) + const [dates, setDates] = React.useState({}) const handleSelectDate = (dates: CalendarValues) => setDates(dates) diff --git a/src/control-next-button.tsx b/src/control-next-button.tsx index 7b329e1..e66e360 100644 --- a/src/control-next-button.tsx +++ b/src/control-next-button.tsx @@ -1,5 +1,5 @@ +import * as React from 'react' import { Button, useMultiStyleConfig } from '@chakra-ui/react' -import { useContext } from 'react' import { CalendarContext } from './context' import { CalendarControlStyles } from './types' @@ -12,7 +12,7 @@ export function CalendarNextButton({ as }: CalendarNextButton) { 'CalendarControl', {} ) as CalendarControlStyles - const { nextMonth } = useContext(CalendarContext) + const { nextMonth } = React.useContext(CalendarContext) if (as) { return as({ onClick: nextMonth }) diff --git a/src/control-prev-button.tsx b/src/control-prev-button.tsx index 5cf6acc..2c4b107 100644 --- a/src/control-prev-button.tsx +++ b/src/control-prev-button.tsx @@ -1,5 +1,5 @@ +import * as React from 'react' import { Button, useMultiStyleConfig } from '@chakra-ui/react' -import { useContext } from 'react' import { CalendarContext } from './context' import { CalendarControlStyles } from './types' @@ -12,7 +12,7 @@ export function CalendarPrevButton({ as }: CalendarPrevButton) { 'CalendarControl', {} ) as CalendarControlStyles - const { prevMonth } = useContext(CalendarContext) + const { prevMonth } = React.useContext(CalendarContext) if (as) { return as({ onClick: prevMonth }) diff --git a/src/day.tsx b/src/day.tsx index 64c8b8b..367cac7 100644 --- a/src/day.tsx +++ b/src/day.tsx @@ -1,13 +1,14 @@ +import * as React from 'react' import format from 'date-fns/format' import { Button, useStyleConfig } from '@chakra-ui/react' import { CalendarDate } from './types' -export type Day = { +export type Day = React.PropsWithChildren<{ day: CalendarDate variant?: 'selected' | 'range' | 'outside' | 'today' disabled?: boolean onSelectDate: (date: CalendarDate) => void -} +}> export function Day({ day, variant, disabled, onSelectDate }: Day) { const styles = useStyleConfig('CalendarDay', { variant }) diff --git a/src/month-week.tsx b/src/month-week.tsx index aa7f6bc..185bda3 100644 --- a/src/month-week.tsx +++ b/src/month-week.tsx @@ -1,6 +1,6 @@ +import * as React from 'react' import { Grid, Text, useMultiStyleConfig } from '@chakra-ui/react' import { addDays, format, startOfWeek } from 'date-fns' -import { useContext } from 'react' import { CalendarContext } from './context' import { CalendarMonthStyles } from './types' @@ -19,7 +19,8 @@ function weekdays({ weekdayFormat = 'E', locale, weekStartsOn }: Weekdays) { export function CalendarWeek() { const styles = useMultiStyleConfig('CalendarMonth', {}) as CalendarMonthStyles - const { locale, weekdayFormat, weekStartsOn } = useContext(CalendarContext) + const { locale, weekdayFormat, weekStartsOn } = + React.useContext(CalendarContext) const week = weekdays({ weekdayFormat, locale, weekStartsOn }) return ( diff --git a/src/useCalendar.ts b/src/useCalendar.ts index d85538d..e19b76b 100644 --- a/src/useCalendar.ts +++ b/src/useCalendar.ts @@ -1,4 +1,4 @@ -import { useState, useMemo } from 'react' +import * as React from 'react' import { endOfMonth, startOfMonth, @@ -31,9 +31,9 @@ export function useCalendar({ weekStartsOn = 0, }: UseCalendar) { const initialState = blockFuture ? subMonths(start, 1) : start - const [date, setDate] = useState(initialState) + const [date, setDate] = React.useState(initialState) - const actions = useMemo( + const actions = React.useMemo( function actionsFn() { const nextMonth = () => setDate(prevSet => addMonths(prevSet, 1)) const prevMonth = () => setDate(prevSet => subMonths(prevSet, 1))