From f1458aec589ec76d2da5fab3f2146d2122abd9ca Mon Sep 17 00:00:00 2001 From: Thomas Josso Date: Mon, 25 Mar 2024 14:14:43 +0400 Subject: [PATCH 1/2] feat(weekdays): add weekdayContent prop --- packages/react-calendar/README.md | 1 + packages/react-calendar/src/Calendar.tsx | 10 ++++++++++ packages/react-calendar/src/MonthView.tsx | 2 ++ .../src/MonthView/Weekdays.spec.tsx | 11 +++++++++++ .../react-calendar/src/MonthView/Weekdays.tsx | 16 +++++++++++++++- packages/react-calendar/src/shared/types.ts | 7 +++++++ 6 files changed, 46 insertions(+), 1 deletion(-) diff --git a/packages/react-calendar/README.md b/packages/react-calendar/README.md index f0acae92..cdfde0a6 100644 --- a/packages/react-calendar/README.md +++ b/packages/react-calendar/README.md @@ -168,6 +168,7 @@ Displays a given month, year, decade and a century, respectively. | tileClassName | Class name(s) that will be applied to a given calendar item (day on month view, month on year view and so on). | n/a | | | tileContent | Allows to render custom content within a given item (day on month view, month on year view and so on). **Note**: For tiles with custom content you might want to set fixed height of `react-calendar__tile` to ensure consistent layout. | n/a | `({ date, view }) => view === 'month' && date.getDay() === 0 ?

It's Sunday!

: null` | | value | Calendar value. Can be either one value or an array of two values. | n/a | | +| weekdayContent | Allows to render custom content within a given weekday container on month view. | n/a | `({ locale, date }) =>

{formatDate(date, 'dd')}

: null` | ## Useful links diff --git a/packages/react-calendar/src/Calendar.tsx b/packages/react-calendar/src/Calendar.tsx index eec48ddf..4bda820d 100644 --- a/packages/react-calendar/src/Calendar.tsx +++ b/packages/react-calendar/src/Calendar.tsx @@ -39,6 +39,7 @@ import type { TileDisabledFunc, Value, View, + WeekdayContentFunc, } from './shared/types.js'; import type { @@ -430,6 +431,13 @@ export type CalendarProps = { * @example 'year' */ view?: View; + /** + * Allows to render custom content within a given weekday container on month view. + * + * @example 'Sample' + * @example ({ locale, date }) =>

{formatDate(date, 'dd')}

: null + */ + weekdayContent?: WeekdayContentFunc | React.ReactNode; }; function toDate(value: Date | string): Date { @@ -666,6 +674,7 @@ const Calendar = forwardRef(function Calendar(props: CalendarProps, ref) { tileDisabled, value: valueProps, view: viewProps, + weekdayContent, } = props; const [activeStartDateState, setActiveStartDateState] = useState( @@ -1077,6 +1086,7 @@ const Calendar = forwardRef(function Calendar(props: CalendarProps, ref) { } showNeighboringMonth={showNeighboringMonth} showWeekNumbers={showWeekNumbers} + weekdayContent={weekdayContent} {...commonProps} /> ); diff --git a/packages/react-calendar/src/MonthView.tsx b/packages/react-calendar/src/MonthView.tsx index ae514623..e802f764 100644 --- a/packages/react-calendar/src/MonthView.tsx +++ b/packages/react-calendar/src/MonthView.tsx @@ -55,6 +55,7 @@ const MonthView: React.FC = function MonthView(props) { formatWeekday, onClickWeekNumber, showWeekNumbers, + weekdayContent, ...childProps } = props; @@ -66,6 +67,7 @@ const MonthView: React.FC = function MonthView(props) { formatWeekday={formatWeekday} locale={locale} onMouseLeave={onMouseLeave} + weekdayContent={weekdayContent} /> ); } diff --git a/packages/react-calendar/src/MonthView/Weekdays.spec.tsx b/packages/react-calendar/src/MonthView/Weekdays.spec.tsx index 2e2ddaa0..67d47281 100644 --- a/packages/react-calendar/src/MonthView/Weekdays.spec.tsx +++ b/packages/react-calendar/src/MonthView/Weekdays.spec.tsx @@ -51,4 +51,15 @@ describe('Weekdays', () => { expect(firstWeekdayAbbr).toHaveAccessibleName('Weekday'); }); + + it('applies weekdayContent to button properly given function', () => { + const content = 'content'; + const weekdayContent = () => content; + + const { container } = render(); + + const firstWeekday = container.querySelector('.react-calendar__month-view__weekdays__weekday'); + + expect(firstWeekday).toHaveTextContent('content'); + }); }); diff --git a/packages/react-calendar/src/MonthView/Weekdays.tsx b/packages/react-calendar/src/MonthView/Weekdays.tsx index 9a26af42..2e6b1588 100644 --- a/packages/react-calendar/src/MonthView/Weekdays.tsx +++ b/packages/react-calendar/src/MonthView/Weekdays.tsx @@ -11,7 +11,7 @@ import { } from '../shared/dateFormatter.js'; import { mapCalendarType } from '../shared/utils.js'; -import type { CalendarType, DeprecatedCalendarType } from '../shared/types.js'; +import type { CalendarType, DeprecatedCalendarType, WeekdayContentFunc } from '../shared/types.js'; const className = 'react-calendar__month-view__weekdays'; const weekdayClassName = `${className}__weekday`; @@ -35,6 +35,13 @@ type WeekdaysProps = { * @example (locale, date) => formatDate(date, 'dd') */ formatWeekday?: typeof defaultFormatWeekday; + /** + * Allows to render custom content within a given weekday container on month view. + * + * @example 'Sample' + * @example ({ locale, date }) =>

{formatDate(date, 'dd')}

: null + */ + weekdayContent?: WeekdayContentFunc | React.ReactNode; /** * Locale that should be used by the calendar. Can be any [IETF language tag](https://en.wikipedia.org/wiki/IETF_language_tag). **Note**: When using SSR, setting this prop may help resolving hydration errors caused by locale mismatch between server and client. * @@ -51,6 +58,7 @@ export default function Weekdays(props: WeekdaysProps) { formatWeekday = defaultFormatWeekday, locale, onMouseLeave, + weekdayContent: weekdayContentProps, } = props; const calendarType = mapCalendarType(calendarTypeOrDeprecatedCalendarType); @@ -70,6 +78,11 @@ export default function Weekdays(props: WeekdaysProps) { const abbr = formatWeekday(locale, weekdayDate); + const weekdayContent = + typeof weekdayContentProps === 'function' + ? weekdayContentProps({ locale, date: weekdayDate }) + : weekdayContentProps; + weekdays.push(
{formatShortWeekday(locale, weekdayDate).replace('.', '')} + {weekdayContent}
, ); } diff --git a/packages/react-calendar/src/shared/types.ts b/packages/react-calendar/src/shared/types.ts index 4d5fb24d..6a6a1b0b 100644 --- a/packages/react-calendar/src/shared/types.ts +++ b/packages/react-calendar/src/shared/types.ts @@ -65,3 +65,10 @@ export type TileClassNameFunc = (args: TileArgs) => ClassName; export type TileContentFunc = (args: TileArgs) => React.ReactNode; export type TileDisabledFunc = (args: TileArgs) => boolean; + +export type WeekdayArgs = { + date: Date; + locale: string | undefined; +}; + +export type WeekdayContentFunc = (args: WeekdayArgs) => React.ReactNode; From 64427fbc324821c3b368d417a544049e9547eac3 Mon Sep 17 00:00:00 2001 From: Thomas Josso Date: Mon, 25 Mar 2024 14:24:21 +0400 Subject: [PATCH 2/2] chore(weekdays): add string test --- .../react-calendar/src/MonthView/Weekdays.spec.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/react-calendar/src/MonthView/Weekdays.spec.tsx b/packages/react-calendar/src/MonthView/Weekdays.spec.tsx index 67d47281..6c77b1d7 100644 --- a/packages/react-calendar/src/MonthView/Weekdays.spec.tsx +++ b/packages/react-calendar/src/MonthView/Weekdays.spec.tsx @@ -52,7 +52,7 @@ describe('Weekdays', () => { expect(firstWeekdayAbbr).toHaveAccessibleName('Weekday'); }); - it('applies weekdayContent to button properly given function', () => { + it('applies weekdayContent properly given function', () => { const content = 'content'; const weekdayContent = () => content; @@ -60,6 +60,16 @@ describe('Weekdays', () => { const firstWeekday = container.querySelector('.react-calendar__month-view__weekdays__weekday'); - expect(firstWeekday).toHaveTextContent('content'); + expect(firstWeekday).toHaveTextContent(content); + }); + + it('applies weekdayContent properly given string', () => { + const content = 'content'; + + const { container } = render(); + + const firstWeekday = container.querySelector('.react-calendar__month-view__weekdays__weekday'); + + expect(firstWeekday).toHaveTextContent(content); }); });