From 44be8c6537d125cc060e924848da17e85e6f6171 Mon Sep 17 00:00:00 2001 From: Colin Guthrie Date: Tue, 2 Aug 2022 23:12:58 +0100 Subject: [PATCH 1/2] feat: add ability to add custom classes to each day. This will allow custom functionality such as differentiating what kind of 'invalid' a day might be. e.g. when used as a booking calendar, you might not be allowed to select a given day to check in because it's sold out, or it may simply not be a valid check-in day. Differentiating this is key to user experience. --- src/constant/types.ts | 2 ++ src/datePicker/DatePicker.tsx | 2 ++ src/datePicker/Day.tsx | 8 +++++++- src/datePicker/Months.tsx | 3 +++ src/rangePicker/Day.tsx | 8 +++++++- src/rangePicker/Months.tsx | 3 +++ src/rangePicker/RangePicker.tsx | 2 ++ src/stories/DatePicker.stories.tsx | 17 +++++++++++++++++ src/stories/RangePicker.stories.tsx | 17 +++++++++++++++++ 9 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/constant/types.ts b/src/constant/types.ts index 5639837..2ac536f 100644 --- a/src/constant/types.ts +++ b/src/constant/types.ts @@ -1,5 +1,6 @@ import { DefaultTheme } from "styled-components"; import { ElementType, ReactNode } from "react"; +import { Dayjs } from "dayjs"; type HeaderIconsPosition = { right: ReactNode; @@ -35,6 +36,7 @@ export interface InitialProps { numberOfMonths?: number; initialMonthAndYear?: string; onRangeDateInScreen?: DatePickerWindowUpdated; + dayClasses?: (day: Dayjs) => string[]; } type DatePickerWindow = { start: string; end: string }; diff --git a/src/datePicker/DatePicker.tsx b/src/datePicker/DatePicker.tsx index 9795253..8a7654a 100644 --- a/src/datePicker/DatePicker.tsx +++ b/src/datePicker/DatePicker.tsx @@ -27,6 +27,7 @@ export const DatePicker = ({ onChange, initialMonthAndYear, onRangeDateInScreen, + dayClasses, }: DatePickerProps) => { const [selectedDays, setSelectedDays] = useState(selectedDaysProps || []); const [numberOfMonths, setNumberOfMonths] = useState(numberOfMonthsProps); @@ -129,6 +130,7 @@ export const DatePicker = ({ disabledBeforeDate={disabledBeforeDate} disabledBeforeToday={disabledBeforeToday} numberOfSelectableDays={numberOfSelectableDays} + dayClasses={dayClasses} /> )} diff --git a/src/datePicker/Day.tsx b/src/datePicker/Day.tsx index a4c48b7..6f4b202 100644 --- a/src/datePicker/Day.tsx +++ b/src/datePicker/Day.tsx @@ -23,6 +23,7 @@ type Props = { components?: DatePickerComponents; onChange: DatePickerOnChange; setSelectedDays: Dispatch>; + dayClasses?: (day: Dayjs) => string[]; }; export const Day: React.FC = ({ @@ -40,6 +41,7 @@ export const Day: React.FC = ({ numberOfSelectableDays, disabledBeforeDate, disabledAfterDate, + dayClasses, }) => { if (disabledBeforeToday) { const today = dayjs().format(FORMAT_DATE); @@ -134,6 +136,10 @@ export const Day: React.FC = ({ }; const DayComponent = components?.days; + let extraDayClasses = ""; + if (dayClasses) { + extraDayClasses = dayClasses(day).join(" "); + } return ( = ({ dayjs() .calendar(jalali ? "jalali" : "gregory") .format(FORMAT_DATE) === day.format(FORMAT_DATE), - })} + }, extraDayClasses)} > {DayComponent && ( diff --git a/src/datePicker/Months.tsx b/src/datePicker/Months.tsx index a155cd2..05eb4e3 100644 --- a/src/datePicker/Months.tsx +++ b/src/datePicker/Months.tsx @@ -24,6 +24,7 @@ interface Props { components?: DatePickerComponents; setSource: Dispatch>; setSelectedDays: Dispatch>; + dayClasses?: (day: Dayjs) => string[]; } export const Months = ({ @@ -41,6 +42,7 @@ export const Months = ({ disabled, onChange, source: sourceProp, + dayClasses, }: Props) => { const renderMonths = () => { let months = []; @@ -90,6 +92,7 @@ export const Months = ({ disabledBeforeDate={disabledBeforeDate} disabledAfterDate={disabledAfterDate} numberOfSelectableDays={numberOfSelectableDays} + dayClasses={dayClasses} /> ))} diff --git a/src/rangePicker/Day.tsx b/src/rangePicker/Day.tsx index aeb8416..141f814 100644 --- a/src/rangePicker/Day.tsx +++ b/src/rangePicker/Day.tsx @@ -33,6 +33,7 @@ interface Props { setSelectedDays: Dispatch< SetStateAction >; + dayClasses?: (day: Dayjs) => string[]; } export const Day = ({ @@ -52,6 +53,7 @@ export const Day = ({ disabledBeforeToday, disabledBeforeDate, disabledAfterDate, + dayClasses, }: Props) => { if (disabledBeforeToday) { const today = dayjs().format(FORMAT_DATE); @@ -199,6 +201,10 @@ export const Day = ({ }; const DayComponent = components?.days; + let extraDayClasses = ""; + if (dayClasses) { + extraDayClasses = dayClasses(day).join(" "); + } return ( {DayComponent && ( diff --git a/src/rangePicker/Months.tsx b/src/rangePicker/Months.tsx index 356ff7d..00d6857 100644 --- a/src/rangePicker/Months.tsx +++ b/src/rangePicker/Months.tsx @@ -33,6 +33,7 @@ interface Props { setSelectedDays: Dispatch< SetStateAction >; + dayClasses?: (day: Dayjs) => string[]; } export const Months = ({ @@ -52,6 +53,7 @@ export const Months = ({ disabled, onChange, source: sourceProp, + dayClasses, }: Props) => { const renderMonths = () => { let months = []; @@ -103,6 +105,7 @@ export const Months = ({ allowDisabledDaysSpan={allowDisabledDaysSpan} disabledBeforeDate={disabledBeforeDate} disabledAfterDate={disabledAfterDate} + dayClasses={dayClasses} /> ))} diff --git a/src/rangePicker/RangePicker.tsx b/src/rangePicker/RangePicker.tsx index 22bca72..5b0e8f5 100644 --- a/src/rangePicker/RangePicker.tsx +++ b/src/rangePicker/RangePicker.tsx @@ -27,6 +27,7 @@ export const RangePicker = ({ onChange, initialMonthAndYear, onRangeDateInScreen, + dayClasses, }: RangePickerProps) => { const [selectedDays, setSelectedDays] = useState(selectedDaysProps); const [hoverDay, setHoverDay] = useState(); @@ -130,6 +131,7 @@ export const RangePicker = ({ disabledBeforeDate={disabledBeforeDate} disabledAfterDate={disabledAfterDate} allowDisabledDaysSpan={allowDisabledDaysSpan} + dayClasses={dayClasses} /> )} diff --git a/src/stories/DatePicker.stories.tsx b/src/stories/DatePicker.stories.tsx index 7a9ac4a..e1acc9e 100644 --- a/src/stories/DatePicker.stories.tsx +++ b/src/stories/DatePicker.stories.tsx @@ -183,6 +183,23 @@ stories.add("Selected Days", () => { ); }); +stories.add("Custom Day Classes", () => { + return ( + <> + + window.console.log(dates)} + dayClasses={day => [parseInt(day.format('D')) % 2 == 1 ? 'odd' : 'even' ]} + /> + + ); +}); + stories.add("Number of Selectable Days", () => { return ( { ); }); +stories.add("Custom Day Classes", () => { + return ( + <> + + window.console.log(dates)} + dayClasses={day => [parseInt(day.format('D')) % 2 == 1 ? 'odd' : 'even' ]} + /> + + ); +}); + stories.add("Custom components - Title of weeks Component", () => { return ( Date: Wed, 3 Aug 2022 10:43:35 +0100 Subject: [PATCH 2/2] feat: sprinkle some class names around This just gives a bit of control over downstream styling that can't always be achieved via styled component overrides (that I can work out anyway) --- src/components/DisplayMonths.tsx | 2 +- src/components/DisplayYears.tsx | 2 +- src/components/Header.tsx | 1 + src/components/TitleOfWeek.tsx | 2 +- src/datePicker/Day.tsx | 2 +- src/datePicker/Months.tsx | 4 +++- src/rangePicker/Day.tsx | 2 +- src/rangePicker/Months.tsx | 4 +++- 8 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/components/DisplayMonths.tsx b/src/components/DisplayMonths.tsx index f18dbed..11993c0 100644 --- a/src/components/DisplayMonths.tsx +++ b/src/components/DisplayMonths.tsx @@ -37,7 +37,7 @@ export const DisplayMonths = ({ ); }); }; - return {renderMonths()}; + return {renderMonths()}; }; type StyleProps = { diff --git a/src/components/DisplayYears.tsx b/src/components/DisplayYears.tsx index a06d24f..dd911a4 100644 --- a/src/components/DisplayYears.tsx +++ b/src/components/DisplayYears.tsx @@ -27,7 +27,7 @@ export const DisplayYears = ({ setDisplayYears, setSource }: Props) => { ); } - return {years} ; + return {years} ; }; const Wrapper = styled.div` diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 50e50ad..dc80c74 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -96,6 +96,7 @@ export const Header = ({ return ( = ({ } return ( - + {titles.map(item => (

{item}

))} diff --git a/src/datePicker/Day.tsx b/src/datePicker/Day.tsx index 6f4b202..99125fd 100644 --- a/src/datePicker/Day.tsx +++ b/src/datePicker/Day.tsx @@ -153,7 +153,7 @@ export const Day: React.FC = ({ dayjs() .calendar(jalali ? "jalali" : "gregory") .format(FORMAT_DATE) === day.format(FORMAT_DATE), - }, extraDayClasses)} + }, extraDayClasses, "tp-calendar-day")} > {DayComponent && ( diff --git a/src/datePicker/Months.tsx b/src/datePicker/Months.tsx index 05eb4e3..5253449 100644 --- a/src/datePicker/Months.tsx +++ b/src/datePicker/Months.tsx @@ -57,6 +57,7 @@ export const Months = ({ ); months.push( {weeksDays.map(week => ( {renderMonths()}
; + return {renderMonths()}; }; diff --git a/src/rangePicker/Day.tsx b/src/rangePicker/Day.tsx index 141f814..2749218 100644 --- a/src/rangePicker/Day.tsx +++ b/src/rangePicker/Day.tsx @@ -234,7 +234,7 @@ export const Day = ({ dayjs() .calendar(jalali ? "jalali" : "gregory") .format(FORMAT_DATE) === day.format(FORMAT_DATE), - }, extraDayClasses)} + }, extraDayClasses, "tp-calendar-day")} > {DayComponent && ( diff --git a/src/rangePicker/Months.tsx b/src/rangePicker/Months.tsx index 00d6857..ca4a02e 100644 --- a/src/rangePicker/Months.tsx +++ b/src/rangePicker/Months.tsx @@ -68,6 +68,7 @@ export const Months = ({ ); months.push( {weeksDays.map(week => ( {renderMonths()}
; + return {renderMonths()}; };