From b312788310dc2df4e48b7d2d778e70a9f44bd97c Mon Sep 17 00:00:00 2001 From: Ryo Matsukawa <76232929+ryo-manba@users.noreply.github.com> Date: Tue, 5 Nov 2024 03:27:24 +0900 Subject: [PATCH] feat: add month and year pickers to DateRangePicker and RangeCalendar (#3302) * feat: add month and year pickers to DateRangePicker and RangeCalendar * chore: update docs * Update .changeset/kind-cobras-travel.md * chore: react package version --------- Co-authored-by: Junior Garcia --- .changeset/few-jars-flow.md | 2 +- .changeset/kind-cobras-travel.md | 6 ++++++ .../components/date-range-picker/index.ts | 2 ++ .../with-month-and-year-pickers.ts | 21 +++++++++++++++++++ .../components/range-calendar/index.ts | 2 ++ .../with-month-and-year-picker.ts | 18 ++++++++++++++++ .../docs/content/docs/components/calendar.mdx | 4 ++-- .../content/docs/components/date-picker.mdx | 11 +++++----- .../docs/components/date-range-picker.mdx | 17 ++++++++++----- .../docs/components/range-calendar.mdx | 9 +++++++- .../calendar/src/calendar-header.tsx | 1 + .../calendar/src/range-calendar.tsx | 5 +---- .../calendar/src/use-calendar-base.ts | 13 +++++++----- .../components/calendar/src/use-calendar.ts | 9 +------- .../calendar/src/use-range-calendar.ts | 12 +++++++++++ .../stories/range-calendar.stories.tsx | 10 +++++++-- .../stories/date-range-picker.stories.tsx | 8 +++++++ 17 files changed, 117 insertions(+), 33 deletions(-) create mode 100644 .changeset/kind-cobras-travel.md create mode 100644 apps/docs/content/components/date-range-picker/with-month-and-year-pickers.ts create mode 100644 apps/docs/content/components/range-calendar/with-month-and-year-picker.ts diff --git a/.changeset/few-jars-flow.md b/.changeset/few-jars-flow.md index 99d6c3ae1a..61eecc890c 100644 --- a/.changeset/few-jars-flow.md +++ b/.changeset/few-jars-flow.md @@ -31,7 +31,7 @@ "@nextui-org/tabs": patch "@nextui-org/tooltip": patch "@nextui-org/user": patch -"@nextui-org/react": patch +"@nextui-org/react": minor "@nextui-org/system": patch "@nextui-org/system-rsc": patch "@nextui-org/use-aria-accordion": patch diff --git a/.changeset/kind-cobras-travel.md b/.changeset/kind-cobras-travel.md new file mode 100644 index 0000000000..75b552cfe7 --- /dev/null +++ b/.changeset/kind-cobras-travel.md @@ -0,0 +1,6 @@ +--- +"@nextui-org/calendar": patch +"@nextui-org/date-picker": patch +--- + +Add month and year picker to DateRangePicker and RangeCalendar (#3089, #3090) diff --git a/apps/docs/content/components/date-range-picker/index.ts b/apps/docs/content/components/date-range-picker/index.ts index 695a486145..2f64826bed 100644 --- a/apps/docs/content/components/date-range-picker/index.ts +++ b/apps/docs/content/components/date-range-picker/index.ts @@ -20,6 +20,7 @@ import visibleMonth from "./visible-month"; import pageBehavior from "./page-behavior"; import nonContigous from "./non-contiguous"; import presets from "./presets"; +import withMonthAndYearPickers from "./with-month-and-year-pickers"; import customStyles from "./custom-styles"; export const dateRangePickerContent = { @@ -45,5 +46,6 @@ export const dateRangePickerContent = { pageBehavior, nonContigous, presets, + withMonthAndYearPickers, customStyles, }; diff --git a/apps/docs/content/components/date-range-picker/with-month-and-year-pickers.ts b/apps/docs/content/components/date-range-picker/with-month-and-year-pickers.ts new file mode 100644 index 0000000000..5e5d03a2fd --- /dev/null +++ b/apps/docs/content/components/date-range-picker/with-month-and-year-pickers.ts @@ -0,0 +1,21 @@ +const App = `import {DateRangePicker} from "@nextui-org/react"; + +export default function App() { + return ( +
+ +
+ ); +}`; + +const react = { + "/App.jsx": App, +}; + +export default { + ...react, +}; diff --git a/apps/docs/content/components/range-calendar/index.ts b/apps/docs/content/components/range-calendar/index.ts index 9b92f64465..37396dac6d 100644 --- a/apps/docs/content/components/range-calendar/index.ts +++ b/apps/docs/content/components/range-calendar/index.ts @@ -12,6 +12,7 @@ import internationalCalendars from "./international-calendars"; import visibleMonths from "./visible-months"; import pageBehaviour from "./page-behaviour"; import presets from "./presets"; +import withMonthAndYearPicker from "./with-month-and-year-picker"; export const rangeCalendarContent = { usage, @@ -28,4 +29,5 @@ export const rangeCalendarContent = { visibleMonths, pageBehaviour, presets, + withMonthAndYearPicker, }; diff --git a/apps/docs/content/components/range-calendar/with-month-and-year-picker.ts b/apps/docs/content/components/range-calendar/with-month-and-year-picker.ts new file mode 100644 index 0000000000..05581f78a1 --- /dev/null +++ b/apps/docs/content/components/range-calendar/with-month-and-year-picker.ts @@ -0,0 +1,18 @@ +const App = `import {RangeCalendar} from "@nextui-org/react"; + +export default function App() { + return ( + + ); +}`; + +const react = { + "/App.jsx": App, +}; + +export default { + ...react, +}; diff --git a/apps/docs/content/docs/components/calendar.mdx b/apps/docs/content/docs/components/calendar.mdx index 44b416a83d..56312766af 100644 --- a/apps/docs/content/docs/components/calendar.mdx +++ b/apps/docs/content/docs/components/calendar.mdx @@ -101,7 +101,7 @@ This example validates that the selected date is a weekday and not a weekend acc ### With Month And Year Picker -Calendar supports month and year picker for rapid selection. +Calendar supports month and year picker for rapid selection. You can enable this feature by setting `showMonthAndYearPickers` to `true`. However, if `visibleMonths` is set to a number greater than 1, this feature will be disabled. @@ -206,7 +206,7 @@ Here's the example to customize `topContent` and `bottomContent` to have some pr | minValue | `DateValue` | The minimum allowed date that a user may select. | - | | maxValue | `DateValue` | The maximum allowed date that a user may select. | - | | color | `default` \| `primary` \| `secondary` \| `success` \| `warning` \| `danger` | The color of the time input. | `default` | -| visibleMonths | `number` | The number of months to display at once. Up to 3 months are supported. Passing a number greater than 1 will disable the `showMonthAndYearPickers` prop | `1` | +| visibleMonths | `number` | The number of months to display at once. Up to 3 months are supported. Passing a number greater than 1 will disable the `showMonthAndYearPickers` prop. | `1` | | focusedValue | `DateValue` | Controls the currently focused date within the calendar. | - | | defaultFocusedValue | `DateValue` | The date that is focused when the calendar first mounts (uncountrolled). | - | | calendarWidth | `number` \| `string` | The width to be applied to the calendar component. This value is multiplied by the `visibleMonths` number to determine the total width of the calendar. | `256` | diff --git a/apps/docs/content/docs/components/date-picker.mdx b/apps/docs/content/docs/components/date-picker.mdx index 735b52fbdb..8b387403f6 100644 --- a/apps/docs/content/docs/components/date-picker.mdx +++ b/apps/docs/content/docs/components/date-picker.mdx @@ -83,6 +83,8 @@ You can also pass an error message as a function. This allows for dynamic error ### With Month and Year Pickers +You can show month and year pickers in the calendar popover by setting the `showMonthAndYearPickers` property to `true`. However, passing a number greater than 1 to the `visibleMonths` prop will disable this feature. + ### With Time Fields @@ -319,7 +321,7 @@ import {I18nProvider} from "@react-aria/i18n"; | color | `default` \| `primary` \| `secondary` \| `success` \| `warning` \| `danger` | The color of the date input. | `default` | | size | `sm` \| `md` \| `lg` | The size of the date input. | `md` | | radius | `none` \| `sm` \| `md` \| `lg` \| `full` | The radius of the date input. | - | -| defaultValue | `string` \| undefined | The default value of the date-picker (uncontrolled). | - | +| defaultValue | `string` | The default value of the date-picker (uncontrolled). | - | | placeholderValue | `ZonedDateTime` \| `CalendarDate` \| `CalendarDateTime` \| `undefined` \| `null` | The placeholder of the date-picker. | - | | description | `ReactNode` | A description for the date-picker. Provides a hint such as specific requirements for what to choose. | - | | errorMessage | `ReactNode \| (v: ValidationResult) => ReactNode` | An error message for the date input. | - | @@ -332,13 +334,12 @@ import {I18nProvider} from "@react-aria/i18n"; | isReadOnly | `boolean` | Whether the date-picker can be selected but not changed by the user. | | | isDisabled | `boolean` | Whether the date-picker is disabled. | `false` | | isInvalid | `boolean` | Whether the date-picker is invalid. | `false` | -| visibleMonths | `number` \| `undefined` | The number of months to display at once. Up to 3 months are supported. Passing a number greater than 1 will disable the `showMonthAndYearPickers` prop. | `1` | +| visibleMonths | `number` | The number of months to display at once. Up to 3 months are supported. Passing a number greater than 1 will disable the `showMonthAndYearPickers` prop. | `1` | | selectorIcon | `ReactNode` | The icon to toggle the date picker popover. Usually a calendar icon. | | -| pageBehavior | `PageBehavior` \| `undefined` | Controls the behavior of paging. Pagination either works by advancing the visible page by visibleDuration (default) or one unit of visibleDuration. | `visible` | -| visibleMonths | `number` \| `undefined` | The number of months to display at once. Up to 3 months are supported. Passing a number greater than 1 will disable the `showMonthAndYearPickers` prop. | `1` | +| pageBehavior | `PageBehavior` | Controls the behavior of paging. Pagination either works by advancing the visible page by visibleDuration (default) or one unit of visibleDuration. | `visible` | | calendarWidth | `number` | The width to be applied to the calendar component. | `256` | | CalendarTopContent | `ReactNode` | Top content to be rendered in the calendar component. | | -| isDateUnavailable | `((date: DateValue) => boolean)` \| `undefined` | Callback that is called for each date of the calendar. If it returns true, then the date is unavailable. | +| isDateUnavailable | `((date: DateValue) => boolean)` | Callback that is called for each date of the calendar. If it returns true, then the date is unavailable. | | | autoFocus | `boolean` | Whether the element should receive focus on render. | `false` | | hourCycle | `12` \| `24` | Whether to display the time in 12 or 24 hour format. This is determined by the user's locale. | - | | granularity | `day` \| `hour` \| `minute` \| `second` | Determines the smallest unit that is displayed in the date picker. Typically "day" for dates. | - | diff --git a/apps/docs/content/docs/components/date-range-picker.mdx b/apps/docs/content/docs/components/date-range-picker.mdx index dbe671500d..40557e7634 100644 --- a/apps/docs/content/docs/components/date-range-picker.mdx +++ b/apps/docs/content/docs/components/date-range-picker.mdx @@ -96,6 +96,12 @@ You can also pass an error message as a function. This allows for dynamic error +### With Month and Year Pickers + +You can show month and year pickers in the calendar popover by setting the `showMonthAndYearPickers` property to `true`. However, passing a number greater than 1 to the `visibleMonths` prop will disable this feature. + + + ### With Time Fields DateRangePicker automatically includes time fields when a `CalendarDateTime` or `ZonedDateTime` object is provided as the value. @@ -364,7 +370,7 @@ You can customize the `DateRangePicker` component by passing custom Tailwind CSS | radius | `none` \| `sm` \| `md` \| `lg` \| `full` | The radius of the date input. | - | | minValue | `RangeValue` \| `undefined` \| `null` | The minimum value of the date-range-picker. | - | | maxValue | `RangeValue` \| `undefined` \| `null` | The maximum value of the date-range-picker. | - | -| defaultValue | `string` \| undefined | The default value of the date-range-picker (uncontrolled). | - | +| defaultValue | `string` | The default value of the date-range-picker (uncontrolled). | - | | placeholderValue | `ZonedDateTime` \| `CalendarDate` \| `CalendarDateTime` \| `undefined` \| `null` | The placeholder of the date-range-picker. | - | | description | `ReactNode` | A description for the date-range-picker. Provides a hint such as specific requirements for what to choose. | - | | errorMessage | `ReactNode \| (v: ValidationResult) => ReactNode` | An error message for the date input. | - | @@ -383,18 +389,19 @@ You can customize the `DateRangePicker` component by passing custom Tailwind CSS | isInvalid | `boolean` | Whether the date-range-picker is invalid. | `false` | | selectorIcon | `ReactNode` | The icon to toggle the date picker popover. Usually a calendar icon. | | | pageBehavior | `single` \| `visible` | Controls the behavior of paging. Pagination either works by advancing the visible page by visibleDuration (default) or one unit of visibleDuration. | `visible` | -| visibleMonths | `number` | The number of months to display at once. Up to 3 months are supported. | `1` | +| visibleMonths | `number` | The number of months to display at once. Up to 3 months are supported. Passing a number greater than 1 will disable the `showMonthAndYearPickers` prop. | `1` | | autoFocus | `boolean` | Whether the element should receive focus on render. | `false` | | hourCycle | `12` \| `24` | Whether to display the time in 12 or 24 hour format. This is determined by the user's locale. | - | | granularity | `day` \| `hour` \| `minute` \| `second` | Determines the smallest unit that is displayed in the date picker. Typically "day" for dates. | - | | hideTimeZone | `boolean` | Whether to hide the time zone abbreviation. | `false` | -| allowsNonContiguousRanges | `boolean` | When combined with `isDateUnavailable`, determines whether non-contiguous ranges, i.e. ranges containing unavailable dates, may be selected. | false | +| allowsNonContiguousRanges | `boolean` | When combined with `isDateUnavailable`, determines whether non-contiguous ranges, i.e. ranges containing unavailable dates, may be selected. | `false` | | shouldForceLeadingZeros | `boolean` | Whether to always show leading zeros in the month, day, and hour fields. | `true` | | calendarWidth | `number` | The width to be applied to the calendar component. | `256` | | CalendarTopContent | `ReactNode` | Top content to be rendered in the calendar component. | | | CalendarBottomContent | `ReactNode` | Bottom content to be rendered in the calendar component. | | -| allowsNonContiguousRanges | `boolean` | enables a range to be selected even if there are unavailable dates in the middle | false | -| popoverProps | `PopoverProps` | Props to be passed to the popover component. | `{ placement: "bottom", triggerScaleOnOpen: false, offset: 13 }` | +| showMonthAndYearPickers | `boolean` | Whether the calendar should show month and year pickers. | `false` | +| allowsNonContiguousRanges | `boolean` | enables a range to be selected even if there are unavailable dates in the middle | `false` | +| popoverProps | [PopoverProps](/docs/components/popover#api) | Props to be passed to the popover component. | `{ placement: "bottom", triggerScaleOnOpen: false, offset: 13 }` | | selectorButtonProps | `ButtonProps` | Props to be passed to the selector button component. | `{ size: "sm", variant: "light", radius: "full", isIconOnly: true }` | | selectorButtonPlacement | `start` \| `end` | The position of the selector button. | `end` | | calendarProps | `CalendarProps` | Props to be passed to the selector button component. | `{ size: "sm", variant: "light", radius: "full", isIconOnly: true }` | diff --git a/apps/docs/content/docs/components/range-calendar.mdx b/apps/docs/content/docs/components/range-calendar.mdx index 170ca67651..292a4b8f36 100644 --- a/apps/docs/content/docs/components/range-calendar.mdx +++ b/apps/docs/content/docs/components/range-calendar.mdx @@ -107,6 +107,12 @@ This example validates that the selected date is a weekday and not a weekend acc +### With Month And Year Picker + +Calendar supports month and year picker for rapid selection. You can enable this feature by setting `showMonthAndYearPickers` to `true`. However, if `visibleMonths` is set to a number greater than 1, this feature will be disabled. + + + ### International Calendars Calendar supports selecting dates in many calendar systems used around the world, including Gregorian, Hebrew, Indian, Islamic, Buddhist, and more. Dates are automatically displayed in the appropriate calendar system for the user's locale. The calendar system can be overridden using the [Unicode calendar locale extension](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/calendar#adding_a_calendar_in_the_locale_string), passed to the `Provider` component. @@ -208,12 +214,13 @@ Here's the example to customize `topContent` and `bottomContent` to have some pr | minValue | `DateValue` | The minimum allowed date that a user may select. | - | | | maxValue | `DateValue` | The maximum allowed date that a user may select. | - | | | color | `default` \| `primary` \| `secondary` \| `success` \| `warning` \| `danger` | The color of the time input. | `default` | | -| visibleMonths | `number` | The number of months to display at once. Up to 3 months are supported. | `1` | | +| visibleMonths | `number` | The number of months to display at once. Up to 3 months are supported. Passing a number greater than 1 will disable the `showMonthAndYearPickers` prop. | `1` | | | focusedValue | `DateValue` | Controls the currently focused date within the calendar. | - | | | defaultFocusedValue | `DateValue` | The date that is focused when the calendar first mounts (uncountrolled). | - | | | calendarWidth | `number` \| `string` | The width to be applied to the calendar component. This value is multiplied by the `visibleMonths` number to determine the total width of the calendar. | `256` | | | pageBehavior | `PageBehavior` | Controls the behavior of paging. Pagination either works by advancing the visible page by visibleDuration (default) or one unit of visibleDuration. | `visible` | | | weekdayStyle | `"narrow" \|"short" \| "long" \| undefined` | The style of weekday names to display in the calendar grid header, e.g. single letter, abbreviation, or full day name. | `narrow` | | +| showMonthAndYearPickers | `boolean` | Whether the label should be crossed out. | `false` | | allowsNonContiguousRanges | `boolean` | When combined with `isDateUnavailable`, determines whether non-contiguous ranges, i.e. ranges containing unavailable dates, may be selected. | `false` | | | isDisabled | `boolean` | Whether the calendar is disabled. | `false` | | | isReadOnly | `boolean` | Whether the calendar value is immutable. | `false` | | diff --git a/packages/components/calendar/src/calendar-header.tsx b/packages/components/calendar/src/calendar-header.tsx index 7e04926dd1..400104f4bd 100644 --- a/packages/components/calendar/src/calendar-header.tsx +++ b/packages/components/calendar/src/calendar-header.tsx @@ -99,6 +99,7 @@ export function CalendarHeader(props: CalendarHeaderProps) { return showMonthAndYearPickers ? (