diff --git a/src/DateTimePicker.tsx b/src/DateTimePicker.tsx index f77c88f..65b8d05 100644 --- a/src/DateTimePicker.tsx +++ b/src/DateTimePicker.tsx @@ -8,10 +8,11 @@ import type { CalendarAction, CalendarState, CalendarTheme, + HeaderProps, } from './types'; import Calendar from './components/Calendar'; -interface PropTypes extends CalendarTheme { +interface PropTypes extends CalendarTheme, HeaderProps { value: DateType; mode?: CalendarModes; locale?: string | ILocale; @@ -46,6 +47,8 @@ const DateTimePicker = ({ selectedItemColor, timePickerContainerStyle, timePickerTextStyle, + buttonLeftIcon, + buttonRightIcon, }: PropTypes) => { const utils = new calendarUtils({ mode, @@ -173,7 +176,10 @@ const DateTimePicker = ({ return ( - + ); }; diff --git a/src/components/Calendar.tsx b/src/components/Calendar.tsx index 0412869..982fdfe 100644 --- a/src/components/Calendar.tsx +++ b/src/components/Calendar.tsx @@ -1,26 +1,34 @@ -import React, { ReactElement } from 'react'; +import React, { ReactNode } from 'react'; import { View, StyleSheet } from 'react-native'; import { useCalendarContext } from '../CalendarContext'; import type { CalendarViews } from '../enums'; +import type { HeaderProps } from '../types'; import Header from './Header'; import YearSelector from './YearSelector'; import MonthSelector from './MonthSelector'; import DaySelector from './DaySelector'; import TimeSelector from './TimeSelector'; -const CalendarView: Record = { +const CalendarView: Record = { year: , month: , day: , time: , }; -const Calendar = () => { +interface PropTypes extends HeaderProps {} + +const Calendar = ({ buttonLeftIcon, buttonRightIcon }: PropTypes) => { const { calendarView, mode } = useCalendarContext(); return ( - {mode !== 'time' ?
: null} + {mode !== 'time' ? ( +
+ ) : null} {CalendarView[calendarView]} ); diff --git a/src/components/DaySelector.tsx b/src/components/DaySelector.tsx index 624e9fb..998cda2 100644 --- a/src/components/DaySelector.tsx +++ b/src/components/DaySelector.tsx @@ -1,11 +1,17 @@ -import React, { memo } from 'react'; +import React, { memo, useMemo } from 'react'; import { Text, View, TouchableOpacity, StyleSheet } from 'react-native'; import { useCalendarContext } from '../CalendarContext'; const DaySelector = () => { const { utils, currentDate, selectedDate, onSelectDate, theme } = useCalendarContext(); - const days = utils.getMonthDays(currentDate); + const month = utils.getDateMonth(currentDate); + const year = utils.getDateYear(currentDate); + const days = useMemo( + () => utils.getMonthDays(currentDate), + // eslint-disable-next-line react-hooks/exhaustive-deps + [month, year] + ); const handleSelectDate = (date: string) => { const newDate = utils diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 38efc25..60eed50 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -3,11 +3,12 @@ import { View, Text, TouchableOpacity, StyleSheet, Image } from 'react-native'; import { useCalendarContext } from '../CalendarContext'; import dayjs from 'dayjs'; import { CalendarViews } from '../enums'; +import type { HeaderProps } from '../types'; const arrow_left = require('../assets/images/arrow_left.png'); const arrow_right = require('../assets/images/arrow_right.png'); -const Header = () => { +const Header = ({ buttonLeftIcon, buttonRightIcon }: HeaderProps) => { const { currentDate, selectedDate, @@ -19,20 +20,20 @@ const Header = () => { theme, } = useCalendarContext(); - const renderPrevButton = () => { - return ( - - calendarView === CalendarViews.day - ? onChangeMonth(-1) - : calendarView === CalendarViews.month - ? onChangeYear(-1) - : calendarView === CalendarViews.year && onChangeYear(-12) - } + const renderPrevButton = ( + + calendarView === CalendarViews.day + ? onChangeMonth(-1) + : calendarView === CalendarViews.month + ? onChangeYear(-1) + : calendarView === CalendarViews.year && onChangeYear(-12) + } + > + - + {buttonLeftIcon || ( { tintColor: theme?.headerButtonColor, }} /> - - - ); - }; + )} + + + ); - const renderNextButton = () => { - return ( - - calendarView === CalendarViews.day - ? onChangeMonth(1) - : calendarView === CalendarViews.month - ? onChangeYear(1) - : calendarView === CalendarViews.year && onChangeYear(12) - } + const renderNextButton = ( + + calendarView === CalendarViews.day + ? onChangeMonth(1) + : calendarView === CalendarViews.month + ? onChangeYear(1) + : calendarView === CalendarViews.year && onChangeYear(12) + } + > + - + {buttonRightIcon || ( { tintColor: theme?.headerButtonColor, }} /> - - - ); - }; + )} + + + ); - const renderSelectors = () => { - return ( - <> - - - setCalendarView( - calendarView === CalendarViews.month - ? CalendarViews.day - : CalendarViews.month - ) - } - > - - - {dayjs(currentDate).format('MMMM')} - - - + const renderSelectors = ( + <> + + + setCalendarView( + calendarView === CalendarViews.month + ? CalendarViews.day + : CalendarViews.month + ) + } + > + + + {dayjs(currentDate).format('MMMM')} + + + - - setCalendarView( - calendarView === CalendarViews.year - ? CalendarViews.day - : CalendarViews.year - ) - } - > - - - {calendarView === CalendarViews.year - ? dayjs(selectedDate).format('YYYY') - : dayjs(currentDate).format('YYYY')} - - - - - {mode === 'datetime' ? ( - - setCalendarView( - calendarView === CalendarViews.time - ? CalendarViews.day - : CalendarViews.time - ) - } - > - - - {dayjs(selectedDate).format('HH:mm')} - - - - ) : null} - - ); - }; + + setCalendarView( + calendarView === CalendarViews.year + ? CalendarViews.day + : CalendarViews.year + ) + } + > + + + {calendarView === CalendarViews.year + ? dayjs(selectedDate).format('YYYY') + : dayjs(currentDate).format('YYYY')} + + + + + {mode === 'datetime' ? ( + + setCalendarView( + calendarView === CalendarViews.time + ? CalendarViews.day + : CalendarViews.time + ) + } + > + + + {dayjs(selectedDate).format('HH:mm')} + + + + ) : null} + + ); return ( {theme?.headerButtonsPosition === 'left' ? ( - {renderPrevButton()} - {renderNextButton()} + {renderPrevButton} + {renderNextButton} - {renderSelectors()} + {renderSelectors} ) : theme?.headerButtonsPosition === 'right' ? ( - {renderSelectors()} + {renderSelectors} - {renderPrevButton()} - {renderNextButton()} + {renderPrevButton} + {renderNextButton} ) : ( - {renderPrevButton()} - {renderSelectors()} - {renderNextButton()} + {renderPrevButton} + {renderSelectors} + {renderNextButton} )} diff --git a/src/types.ts b/src/types.ts index 7e200fd..8c12bda 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,6 +1,7 @@ import type { Dayjs } from 'dayjs'; import type { CalendarActionKind, CalendarViews } from './enums'; import type { TextStyle, ViewStyle } from 'react-native'; +import type { ReactNode } from 'react'; export type DateType = string | number | Date | Dayjs | null; @@ -39,3 +40,8 @@ export type CalendarTheme = { timePickerContainerStyle?: ViewStyle; timePickerTextStyle?: TextStyle; }; + +export type HeaderProps = { + buttonLeftIcon?: ReactNode; + buttonRightIcon?: ReactNode; +};