mirror of
https://github.com/nextui-org/nextui.git
synced 2025-12-08 19:26:11 +00:00
feat(calendar): add firstDayOfWeek (#4852)
* feat(calendar): add firstDayOfWeek * feat(docs): add firstDayOfWeek in Calendar docs * feat(calendar): add firstDayOfWeek to range calendar * feat(docs): add firstDayOfWeek to API table * feat: add firstDayOfWeek to date picker & date range picker * feat(docs): add firstDayOfWeek * feat(changeset): add changeset * feat: add firstDayOfWeek option in storybook * feat(docs): export firstDayOfWeek * chore(docs): update title
This commit is contained in:
parent
80f6c77bae
commit
446dd0bfde
6
.changeset/itchy-monkeys-run.md
Normal file
6
.changeset/itchy-monkeys-run.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"@heroui/date-picker": patch
|
||||
"@heroui/calendar": patch
|
||||
---
|
||||
|
||||
add `firstDayOfWeek`
|
||||
@ -0,0 +1,5 @@
|
||||
import {Calendar} from "@heroui/react";
|
||||
|
||||
export default function App() {
|
||||
return <Calendar aria-label="Date (firstDayOfWeek)" firstDayOfWeek="mon" />;
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
import App from "./first-day-of-week.raw.jsx?raw";
|
||||
|
||||
const react = {
|
||||
"/App.jsx": App,
|
||||
};
|
||||
|
||||
export default {
|
||||
...react,
|
||||
};
|
||||
@ -10,6 +10,7 @@ import invalidDate from "./invalid-date";
|
||||
import withMonthAndYearPicker from "./with-month-and-year-picker";
|
||||
import internationalCalendars from "./international-calendars";
|
||||
import visibleMonths from "./visible-months";
|
||||
import firstDayOfWeek from "./first-day-of-week";
|
||||
import pageBehaviour from "./page-behaviour";
|
||||
import presets from "./presets";
|
||||
|
||||
@ -26,6 +27,7 @@ export const calendarContent = {
|
||||
withMonthAndYearPicker,
|
||||
internationalCalendars,
|
||||
visibleMonths,
|
||||
firstDayOfWeek,
|
||||
pageBehaviour,
|
||||
presets,
|
||||
};
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
import {DatePicker} from "@heroui/react";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<div className="flex w-full flex-wrap md:flex-nowrap gap-4">
|
||||
<DatePicker
|
||||
className="max-w-[284px]"
|
||||
description={"This is my birth date."}
|
||||
firstDayOfWeek="mon"
|
||||
label="Birth date"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
import App from "./first-day-of-week.raw.jsx?raw";
|
||||
|
||||
const react = {
|
||||
"/App.jsx": App,
|
||||
};
|
||||
|
||||
export default {
|
||||
...react,
|
||||
};
|
||||
@ -18,6 +18,7 @@ import minAndMaxDate from "./min-and-max-date";
|
||||
import internationalCalendar from "./international-calendar";
|
||||
import unavailableDates from "./unavailable-dates";
|
||||
import visibleMonth from "./visible-month";
|
||||
import firstDayOfWeek from "./first-day-of-week";
|
||||
import pageBehavior from "./page-behavior";
|
||||
import preset from "./preset";
|
||||
|
||||
@ -42,6 +43,7 @@ export const datePickerContent = {
|
||||
internationalCalendar,
|
||||
unavailableDates,
|
||||
visibleMonth,
|
||||
firstDayOfWeek,
|
||||
pageBehavior,
|
||||
preset,
|
||||
};
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
import {DateRangePicker} from "@heroui/react";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<DateRangePicker
|
||||
className="max-w-xs"
|
||||
description="Please enter your stay duration"
|
||||
firstDayOfWeek="mon"
|
||||
label="Stay duration"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
import App from "./first-day-of-week.raw.jsx?raw";
|
||||
|
||||
const react = {
|
||||
"/App.jsx": App,
|
||||
};
|
||||
|
||||
export default {
|
||||
...react,
|
||||
};
|
||||
@ -17,6 +17,7 @@ import minAndMaxDate from "./min-and-max-date";
|
||||
import internationalCalendar from "./international-calendar";
|
||||
import unavailableDates from "./unavailable-dates";
|
||||
import visibleMonth from "./visible-month";
|
||||
import firstDayOfWeek from "./first-day-of-week";
|
||||
import pageBehavior from "./page-behavior";
|
||||
import nonContigous from "./non-contiguous";
|
||||
import presets from "./presets";
|
||||
@ -43,6 +44,7 @@ export const dateRangePickerContent = {
|
||||
internationalCalendar,
|
||||
unavailableDates,
|
||||
visibleMonth,
|
||||
firstDayOfWeek,
|
||||
pageBehavior,
|
||||
nonContigous,
|
||||
presets,
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
import {RangeCalendar} from "@heroui/react";
|
||||
|
||||
export default function App() {
|
||||
return <RangeCalendar aria-label="Date (firstDayOfWeek)" firstDayOfWeek="mon" />;
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
import App from "./first-day-of-week.raw.jsx?raw";
|
||||
|
||||
const react = {
|
||||
"/App.jsx": App,
|
||||
};
|
||||
|
||||
export default {
|
||||
...react,
|
||||
};
|
||||
@ -10,6 +10,7 @@ import invalidDate from "./invalid-date";
|
||||
import nonContiguousRanges from "./non-contiguous-ranges";
|
||||
import internationalCalendars from "./international-calendars";
|
||||
import visibleMonths from "./visible-months";
|
||||
import firstDayOfWeek from "./first-day-of-week";
|
||||
import pageBehaviour from "./page-behaviour";
|
||||
import presets from "./presets";
|
||||
import withMonthAndYearPicker from "./with-month-and-year-picker";
|
||||
@ -27,6 +28,7 @@ export const rangeCalendarContent = {
|
||||
nonContiguousRanges,
|
||||
internationalCalendars,
|
||||
visibleMonths,
|
||||
firstDayOfWeek,
|
||||
pageBehaviour,
|
||||
presets,
|
||||
withMonthAndYearPicker,
|
||||
|
||||
@ -117,6 +117,12 @@ By default, the Calendar displays a single month. The `visibleMonths` prop allow
|
||||
|
||||
<CodeDemo title="Visible Months" files={calendarContent.visibleMonths} />
|
||||
|
||||
### Custom first day of week
|
||||
|
||||
By default, the first day of the week is automatically set based on the current locale. This can be changed by setting the `firstDayOfWeek` prop to `'sun'`, `'mon'`, `'tue'`, `'wed'`, `'thu'`, `'fri'`, or `'sat'`.
|
||||
|
||||
<CodeDemo title="Custom first day of week" files={calendarContent.firstDayOfWeek} />
|
||||
|
||||
### Page Behaviour
|
||||
|
||||
By default, when pressing the next or previous buttons, pagination will advance by the `visibleMonths` value. This behavior can be changed to page by single months instead, by setting `pageBehavior` to `single`.
|
||||
@ -237,6 +243,12 @@ Here's the example to customize `topContent` and `bottomContent` to have some pr
|
||||
description: "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.",
|
||||
default: "1"
|
||||
},
|
||||
{
|
||||
attribute: "firstDayOfWeek",
|
||||
type: "sun | mon | tue | wed | thu | fri | sat",
|
||||
description: "The day that starts the week.",
|
||||
default: "-"
|
||||
},
|
||||
{
|
||||
attribute: "focusedValue",
|
||||
type: "DateValue",
|
||||
|
||||
@ -233,6 +233,12 @@ By default, the calendar popover displays a single month. The `visibleMonths` pr
|
||||
|
||||
<CodeDemo title="Visible Months" files={datePickerContent.visibleMonth} />
|
||||
|
||||
### Custom first day of week
|
||||
|
||||
By default, the first day of the week is automatically set based on the current locale. This can be changed by setting the `firstDayOfWeek` prop to `'sun'`, `'mon'`, `'tue'`, `'wed'`, `'thu'`, `'fri'`, or `'sat'`.
|
||||
|
||||
<CodeDemo title="Custom first day of week" files={datePickerContent.firstDayOfWeek} />
|
||||
|
||||
### Page Behavior
|
||||
|
||||
By default, when pressing the next or previous buttons, pagination will advance by the `visibleMonths` value. This behavior can be changed to page by single months instead, by setting `pageBehavior` to `single`.
|
||||
@ -435,6 +441,12 @@ import {I18nProvider} from "@react-aria/i18n";
|
||||
description: "The number of months to display at once. Up to 3 months are supported.",
|
||||
default: "1"
|
||||
},
|
||||
{
|
||||
attribute: "firstDayOfWeek",
|
||||
type: "sun | mon | tue | wed | thu | fri | sat",
|
||||
description: "The day that starts the week.",
|
||||
default: "-"
|
||||
},
|
||||
{
|
||||
attribute: "selectorIcon",
|
||||
type: "ReactNode",
|
||||
|
||||
@ -66,6 +66,12 @@ By default, the calendar popover displays a single month. The `visibleMonths` pr
|
||||
|
||||
<CodeDemo title="Visible Months" files={dateRangePickerContent.visibleMonth} />
|
||||
|
||||
### Custom first day of week
|
||||
|
||||
By default, the first day of the week is automatically set based on the current locale. This can be changed by setting the `firstDayOfWeek` prop to `'sun'`, `'mon'`, `'tue'`, `'wed'`, `'thu'`, `'fri'`, or `'sat'`.
|
||||
|
||||
<CodeDemo title="Custom first day of week" files={dateRangePickerContent.firstDayOfWeek} />
|
||||
|
||||
### Page Behavior
|
||||
|
||||
By default, when pressing the next or previous buttons, pagination will advance by the `visibleMonths` value. This behavior can be changed to page by single months instead, by setting `pageBehavior` to `single`.
|
||||
@ -530,6 +536,12 @@ You can customize the `DateRangePicker` component by passing custom Tailwind CSS
|
||||
description: "The number of months to display at once. Up to 3 months are supported.",
|
||||
default: "1"
|
||||
},
|
||||
{
|
||||
attribute: "firstDayOfWeek",
|
||||
type: "sun | mon | tue | wed | thu | fri | sat",
|
||||
description: "The day that starts the week.",
|
||||
default: "-"
|
||||
},
|
||||
{
|
||||
attribute: "autoFocus",
|
||||
type: "boolean",
|
||||
|
||||
@ -125,6 +125,12 @@ By default, the Calendar displays a single month. The `visibleMonths` prop allow
|
||||
|
||||
<CodeDemo title="Visible Months" files={rangeCalendarContent.visibleMonths} />
|
||||
|
||||
### Custom first day of week
|
||||
|
||||
By default, the first day of the week is automatically set based on the current locale. This can be changed by setting the `firstDayOfWeek` prop to `'sun'`, `'mon'`, `'tue'`, `'wed'`, `'thu'`, `'fri'`, or `'sat'`.
|
||||
|
||||
<CodeDemo title="Custom first day of week" files={rangeCalendarContent.firstDayOfWeek} />
|
||||
|
||||
### Page Behaviour
|
||||
|
||||
By default, when pressing the next or previous buttons, pagination will advance by the `visibleMonths` value. This behavior can be changed to page by single months instead, by setting `pageBehavior` to `single`.
|
||||
@ -245,6 +251,12 @@ Here's the example to customize `topContent` and `bottomContent` to have some pr
|
||||
description: "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.",
|
||||
default: "1"
|
||||
},
|
||||
{
|
||||
attribute: "firstDayOfWeek",
|
||||
type: "sun | mon | tue | wed | thu | fri | sat",
|
||||
description: "The day that starts the week.",
|
||||
default: "-"
|
||||
},
|
||||
{
|
||||
attribute: "focusedValue",
|
||||
type: "DateValue",
|
||||
|
||||
@ -33,6 +33,7 @@ export interface CalendarBaseProps extends HTMLHeroUIProps<"div"> {
|
||||
errorMessageProps: HTMLAttributes<HTMLElement>;
|
||||
calendarRef: RefObject<HTMLDivElement>;
|
||||
errorMessage?: ReactNode;
|
||||
firstDayOfWeek?: "sun" | "mon" | "tue" | "wed" | "thu" | "fri" | "sat";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,6 +64,7 @@ export function CalendarBase(props: CalendarBaseProps) {
|
||||
errorMessageProps,
|
||||
calendarRef: ref,
|
||||
errorMessage,
|
||||
firstDayOfWeek,
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
@ -120,6 +122,7 @@ export function CalendarBase(props: CalendarBaseProps) {
|
||||
key={`calendar-month-${i}`}
|
||||
currentMonth={currentMonth.month}
|
||||
direction={direction}
|
||||
firstDayOfWeek={firstDayOfWeek}
|
||||
startDate={d}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -17,10 +17,12 @@ export interface CalendarCellProps extends HTMLHeroUIProps<"td">, AriaCalendarCe
|
||||
slots?: CalendarReturnType;
|
||||
classNames?: SlotsToClasses<CalendarSlots>;
|
||||
currentMonth: CalendarDate;
|
||||
firstDayOfWeek?: "sun" | "mon" | "tue" | "wed" | "thu" | "fri" | "sat";
|
||||
}
|
||||
|
||||
export function CalendarCell(originalProps: CalendarCellProps) {
|
||||
const {state, slots, isPickerVisible, currentMonth, classNames, ...props} = originalProps;
|
||||
const {state, slots, isPickerVisible, currentMonth, classNames, firstDayOfWeek, ...props} =
|
||||
originalProps;
|
||||
|
||||
const ref = useRef<HTMLButtonElement>(null);
|
||||
|
||||
@ -53,7 +55,8 @@ export function CalendarCell(originalProps: CalendarCellProps) {
|
||||
const isSelectionEnd =
|
||||
isSelected && highlightedRange ? isSameDay(props.date, highlightedRange.end) : false;
|
||||
const {locale} = useLocale();
|
||||
const dayOfWeek = getDayOfWeek(props.date, locale);
|
||||
|
||||
const dayOfWeek = getDayOfWeek(props.date, locale, firstDayOfWeek);
|
||||
const isRangeStart =
|
||||
isSelected && (isFirstSelectedAfterDisabled || dayOfWeek === 0 || props.date.day === 1);
|
||||
const isRangeEnd =
|
||||
|
||||
@ -17,10 +17,11 @@ export interface CalendarMonthProps extends HTMLHeroUIProps<"table">, CalendarPr
|
||||
}
|
||||
|
||||
export function CalendarMonth(props: CalendarMonthProps) {
|
||||
const {startDate, direction, currentMonth} = props;
|
||||
const {startDate, direction, currentMonth, firstDayOfWeek} = props;
|
||||
|
||||
const {locale} = useLocale();
|
||||
const weeksInMonth = getWeeksInMonth(startDate, locale);
|
||||
|
||||
const weeksInMonth = getWeeksInMonth(startDate, locale, firstDayOfWeek);
|
||||
|
||||
const {state, slots, weekdayStyle, isHeaderExpanded, disableAnimation, classNames} =
|
||||
useCalendarContext();
|
||||
@ -30,6 +31,7 @@ export function CalendarMonth(props: CalendarMonthProps) {
|
||||
...props,
|
||||
weekdayStyle,
|
||||
endDate: endOfMonth(startDate),
|
||||
firstDayOfWeek,
|
||||
},
|
||||
state,
|
||||
);
|
||||
@ -52,6 +54,7 @@ export function CalendarMonth(props: CalendarMonthProps) {
|
||||
classNames={classNames}
|
||||
currentMonth={startDate}
|
||||
date={date}
|
||||
firstDayOfWeek={firstDayOfWeek}
|
||||
isPickerVisible={isHeaderExpanded}
|
||||
slots={slots}
|
||||
state={state}
|
||||
|
||||
@ -65,6 +65,10 @@ interface Props extends HeroUIBaseProps {
|
||||
* @default true
|
||||
*/
|
||||
showHelper?: boolean;
|
||||
/**
|
||||
* The day that starts the week.
|
||||
*/
|
||||
firstDayOfWeek?: "sun" | "mon" | "tue" | "wed" | "thu" | "fri" | "sat";
|
||||
/**
|
||||
* Whether the calendar header is expanded. This is only available if the `showMonthAndYearPickers` prop is set to `true`.
|
||||
* @default false
|
||||
@ -207,6 +211,7 @@ export function useCalendarBase(originalProps: UseCalendarBasePropsComplete) {
|
||||
topContent,
|
||||
bottomContent,
|
||||
showHelper = true,
|
||||
firstDayOfWeek,
|
||||
calendarWidth = 256,
|
||||
visibleMonths: visibleMonthsProp = 1,
|
||||
weekdayStyle = "narrow",
|
||||
@ -326,6 +331,7 @@ export function useCalendarBase(originalProps: UseCalendarBasePropsComplete) {
|
||||
maxValue,
|
||||
baseProps,
|
||||
showHelper,
|
||||
firstDayOfWeek,
|
||||
weekdayStyle,
|
||||
visibleMonths,
|
||||
visibleDuration,
|
||||
|
||||
@ -29,6 +29,7 @@ export function useCalendar<T extends DateValue>({
|
||||
minValue,
|
||||
maxValue,
|
||||
showHelper,
|
||||
firstDayOfWeek,
|
||||
weekdayStyle,
|
||||
visibleDuration,
|
||||
baseProps,
|
||||
@ -78,6 +79,7 @@ export function useCalendar<T extends DateValue>({
|
||||
...baseProps,
|
||||
Component,
|
||||
showHelper,
|
||||
firstDayOfWeek,
|
||||
topContent,
|
||||
bottomContent,
|
||||
buttonPickerProps,
|
||||
|
||||
@ -35,6 +35,7 @@ export function useRangeCalendar<T extends DateValue>({
|
||||
domRef,
|
||||
locale,
|
||||
showHelper,
|
||||
firstDayOfWeek,
|
||||
minValue,
|
||||
maxValue,
|
||||
weekdayStyle,
|
||||
@ -86,6 +87,7 @@ export function useRangeCalendar<T extends DateValue>({
|
||||
...baseProps,
|
||||
Component,
|
||||
showHelper,
|
||||
firstDayOfWeek,
|
||||
topContent,
|
||||
bottomContent,
|
||||
buttonPickerProps,
|
||||
|
||||
@ -44,6 +44,10 @@ export default {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
firstDayOfWeek: {
|
||||
control: "select",
|
||||
options: [undefined, "sun", "mon", "tue", "wed", "thu", "fri", "sat"],
|
||||
},
|
||||
},
|
||||
} as Meta<typeof Calendar>;
|
||||
|
||||
@ -412,3 +416,11 @@ export const ReducedMotion = {
|
||||
...defaultProps,
|
||||
},
|
||||
};
|
||||
|
||||
export const FirstDayOfWeek = {
|
||||
render: Template,
|
||||
args: {
|
||||
...defaultProps,
|
||||
firstDayOfWeek: "mon",
|
||||
},
|
||||
};
|
||||
|
||||
@ -42,6 +42,10 @@ export default {
|
||||
},
|
||||
options: ["narrow", "short", "long"],
|
||||
},
|
||||
firstDayOfWeek: {
|
||||
control: "select",
|
||||
options: [undefined, "sun", "mon", "tue", "wed", "thu", "fri", "sat"],
|
||||
},
|
||||
},
|
||||
} as Meta<typeof RangeCalendar>;
|
||||
|
||||
@ -414,3 +418,11 @@ export const Presets = {
|
||||
...defaultProps,
|
||||
},
|
||||
};
|
||||
|
||||
export const FirstDayOfWeek = {
|
||||
render: Template,
|
||||
args: {
|
||||
...defaultProps,
|
||||
firstDayOfWeek: "mon",
|
||||
},
|
||||
};
|
||||
|
||||
@ -131,6 +131,7 @@ export function useDatePickerBase<T extends DateValue>(originalProps: UseDatePic
|
||||
validationState,
|
||||
validationBehavior,
|
||||
visibleMonths = 1,
|
||||
firstDayOfWeek,
|
||||
pageBehavior = "visible",
|
||||
calendarWidth = 256,
|
||||
isDateUnavailable,
|
||||
@ -215,6 +216,7 @@ export function useDatePickerBase<T extends DateValue>(originalProps: UseDatePic
|
||||
onHeaderExpandedChange: setIsCalendarHeaderExpanded,
|
||||
color: isDefaultColor ? "primary" : originalProps.color,
|
||||
disableAnimation,
|
||||
firstDayOfWeek,
|
||||
},
|
||||
restUserCalendarProps,
|
||||
),
|
||||
|
||||
@ -70,6 +70,10 @@ export default {
|
||||
},
|
||||
options: ["aria", "native"],
|
||||
},
|
||||
firstDayOfWeek: {
|
||||
control: "select",
|
||||
options: [undefined, "sun", "mon", "tue", "wed", "thu", "fri", "sat"],
|
||||
},
|
||||
},
|
||||
decorators: [
|
||||
(Story) => (
|
||||
@ -693,3 +697,11 @@ export const WithDateInputClassNames = {
|
||||
description: "Please enter your birth date",
|
||||
},
|
||||
};
|
||||
|
||||
export const FirstDayOfWeek = {
|
||||
render: Template,
|
||||
args: {
|
||||
...defaultProps,
|
||||
firstDayOfWeek: "mon",
|
||||
},
|
||||
};
|
||||
|
||||
@ -71,6 +71,10 @@ export default {
|
||||
},
|
||||
options: ["aria", "native"],
|
||||
},
|
||||
firstDayOfWeek: {
|
||||
control: "select",
|
||||
options: [undefined, "sun", "mon", "tue", "wed", "thu", "fri", "sat"],
|
||||
},
|
||||
},
|
||||
decorators: [
|
||||
(Story) => (
|
||||
@ -799,3 +803,11 @@ export const CustomStyles = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const FirstDayOfWeek = {
|
||||
render: Template,
|
||||
args: {
|
||||
...defaultProps,
|
||||
firstDayOfWeek: "mon",
|
||||
},
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user