From 9fc78405fe9b9b328533d464b2750f6a53e727d3 Mon Sep 17 00:00:00 2001 From: 1amageek Date: Sat, 23 Nov 2024 18:00:26 +0900 Subject: [PATCH] feat(calendar): implement custom cell content rendering --- .../components/calendar/src/calendar-cell.tsx | 6 +- packages/components/calendar/src/calendar.tsx | 2 +- .../calendar/src/range-calendar.tsx | 2 +- .../calendar/src/use-calendar-base.ts | 4 +- .../calendar/stories/calendar.stories.tsx | 61 +++++++++++-------- .../stories/range-calendar.stories.tsx | 60 ++++++++++-------- 6 files changed, 81 insertions(+), 54 deletions(-) diff --git a/packages/components/calendar/src/calendar-cell.tsx b/packages/components/calendar/src/calendar-cell.tsx index 256da657a5..f1313a1df3 100644 --- a/packages/components/calendar/src/calendar-cell.tsx +++ b/packages/components/calendar/src/calendar-cell.tsx @@ -20,7 +20,7 @@ export interface CalendarCellProps extends CalendarCellBaseProps, AriaCalendarCe slots?: CalendarReturnType; classNames?: SlotsToClasses; currentMonth: CalendarDate; - cellContent?: (date: CalendarDate) => React.ReactNode; + cellContent?: ((date: CalendarDate) => React.ReactNode) | React.ReactNode; } export const CalendarCell = ({ @@ -95,7 +95,9 @@ export const CalendarCell = ({ return ( - {cellContent ? cellContent(date) : } + {typeof cellContent === "function" + ? cellContent(date) + : cellContent ?? } ); diff --git a/packages/components/calendar/src/calendar.tsx b/packages/components/calendar/src/calendar.tsx index d39ba986e7..c70bae2c52 100644 --- a/packages/components/calendar/src/calendar.tsx +++ b/packages/components/calendar/src/calendar.tsx @@ -13,7 +13,7 @@ interface Props /** * The calendar cell render function */ - children?: (date: CalendarDate) => React.ReactNode; + children?: ((date: CalendarDate) => React.ReactNode) | React.ReactNode; } function Calendar(props: Props, ref: ForwardedRef) { diff --git a/packages/components/calendar/src/range-calendar.tsx b/packages/components/calendar/src/range-calendar.tsx index 0ab7d5de37..31f55ec2b4 100644 --- a/packages/components/calendar/src/range-calendar.tsx +++ b/packages/components/calendar/src/range-calendar.tsx @@ -20,7 +20,7 @@ interface Props /** * The calendar cell render function */ - children?: (date: CalendarDate) => React.ReactNode; + children?: ((date: CalendarDate) => React.ReactNode) | React.ReactNode; } function RangeCalendar(props: Props, ref: ForwardedRef) { diff --git a/packages/components/calendar/src/use-calendar-base.ts b/packages/components/calendar/src/use-calendar-base.ts index bae77afb42..26d3e12f2c 100644 --- a/packages/components/calendar/src/use-calendar-base.ts +++ b/packages/components/calendar/src/use-calendar-base.ts @@ -87,7 +87,7 @@ interface Props extends NextUIBaseProps { * @param cellState The state of the calendar cell * @returns ReactNode */ - cellContent?: (date: CalendarDate) => React.ReactNode; + cellContent?: ((date: CalendarDate) => React.ReactNode) | React.ReactNode; /** * This function helps to reduce the bundle size by providing a custom calendar system. * @@ -183,7 +183,7 @@ export type ContextType = { setIsHeaderExpanded?: (isExpanded: boolean) => void; classNames?: SlotsToClasses; disableAnimation?: boolean; - cellContent?: (date: CalendarDate) => React.ReactNode; + cellContent?: ((date: CalendarDate) => React.ReactNode) | React.ReactNode; }; export function useCalendarBase(originalProps: UseCalendarBasePropsComplete) { diff --git a/packages/components/calendar/stories/calendar.stories.tsx b/packages/components/calendar/stories/calendar.stories.tsx index 55aa0934a4..d89fcc80fd 100644 --- a/packages/components/calendar/stories/calendar.stories.tsx +++ b/packages/components/calendar/stories/calendar.stories.tsx @@ -8,13 +8,21 @@ import { isWeekend, startOfWeek, startOfMonth, + getDayOfWeek, } from "@internationalized/date"; import {I18nProvider, useLocale} from "@react-aria/i18n"; import {Button, ButtonGroup} from "@nextui-org/button"; import {Radio, RadioGroup} from "@nextui-org/radio"; import {cn} from "@nextui-org/theme"; -import {Calendar, CalendarProps, DateValue} from "../src"; +import { + Calendar, + CalendarProps, + DateValue, + CalendarCellContent, + CalendarCellButton, + CalendarCellBody, +} from "../src"; export default { title: "Components/Calendar", @@ -258,29 +266,40 @@ const CalendarWidthTemplate = (args: CalendarProps) => { }; const CustomCellTemplate = (args: CalendarProps) => { + const {locale} = useLocale(); + return (
- + + + + +
+ + + +
+
+
+
- + {(date) => { + const dayOfWeek = getDayOfWeek(date, locale); + const style = + dayOfWeek === 0 ? "text-red-500" : dayOfWeek === 6 ? "text-blue-500" : "inherit"; + + return ( + + + {date.day} + + + ); }} - /> +
); @@ -409,11 +428,5 @@ export const CustomCellContent = { render: CustomCellTemplate, args: { ...defaultProps, - renderCellContent: (date) => ( -
- {date.day} - -
- ), }, }; diff --git a/packages/components/calendar/stories/range-calendar.stories.tsx b/packages/components/calendar/stories/range-calendar.stories.tsx index acd6fcd20f..f00d155b3a 100644 --- a/packages/components/calendar/stories/range-calendar.stories.tsx +++ b/packages/components/calendar/stories/range-calendar.stories.tsx @@ -12,13 +12,20 @@ import { startOfWeek, endOfMonth, endOfWeek, + getDayOfWeek, } from "@internationalized/date"; import {I18nProvider, useLocale} from "@react-aria/i18n"; import {Button, ButtonGroup} from "@nextui-org/button"; import {Radio, RadioGroup} from "@nextui-org/radio"; import {cn} from "@nextui-org/theme"; -import {RangeCalendar, RangeCalendarProps} from "../src"; +import { + RangeCalendar, + RangeCalendarProps, + CalendarCellContent, + CalendarCellButton, + CalendarCellBody, +} from "../src"; export default { title: "Components/RangeCalendar", @@ -289,29 +296,40 @@ const PresetsTemplate = (args: RangeCalendarProps) => { }; const CustomCellTemplate = (args: RangeCalendarProps) => { + const {locale} = useLocale(); + return (
- + + + + +
+ + + +
+
+
+
- + {(date) => { + const dayOfWeek = getDayOfWeek(date, locale); + const style = + dayOfWeek === 0 ? "text-red-500" : dayOfWeek === 6 ? "text-blue-500" : "inherit"; + + return ( + + + {date.day} + + + ); }} - /> +
); @@ -442,11 +460,5 @@ export const CustomCellContent = { render: CustomCellTemplate, args: { ...defaultProps, - renderCellContent: (date) => ( -
- {date.day} - -
- ), }, };