Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Calendar): Add firstDayOfWeek prop #7363

Merged
merged 41 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
8ecbca1
add firstDayOfWeek prop
reidbarber Nov 13, 2024
3819daa
pass to DatePicker/DateRangePicker
reidbarber Nov 13, 2024
4675901
add storybook controls
reidbarber Nov 13, 2024
b84969e
add to RAC
reidbarber Nov 13, 2024
afa1c0f
add docs
reidbarber Nov 13, 2024
509257c
add v3 tests
reidbarber Nov 13, 2024
b03d491
add hook tests
reidbarber Nov 13, 2024
68b9f48
lint
reidbarber Nov 13, 2024
c9f80eb
add chromatic stories
reidbarber Nov 13, 2024
15a047a
update v3 RangeCalendar styles for first and last day of week
reidbarber Nov 14, 2024
c4f7e5f
Merge remote-tracking branch 'origin/main' into calendar-firstDayOfWeek
reidbarber Nov 14, 2024
4020fb2
lint
reidbarber Nov 14, 2024
ab374a8
lint
reidbarber Nov 14, 2024
b554178
use number instead of enum for type
reidbarber Nov 14, 2024
237cdfb
update type to enum
reidbarber Nov 15, 2024
11c86e3
update tests
reidbarber Nov 15, 2024
c16d42e
fix v3 cell style
reidbarber Nov 15, 2024
b7f7185
use lowercase and update docs
reidbarber Nov 16, 2024
e4a342b
Merge remote-tracking branch 'origin/main' into calendar-firstDayOfWeek
reidbarber Nov 16, 2024
158341e
update to use firstDayOfWeek day regardless of locale
reidbarber Nov 27, 2024
363b9be
lint
reidbarber Nov 27, 2024
94241a4
fix cell style
reidbarber Nov 27, 2024
37b329a
more tests
reidbarber Nov 27, 2024
0f48109
update test
reidbarber Dec 6, 2024
60b00a3
update getDatesInWeek logic
reidbarber Dec 6, 2024
4e373d7
Merge remote-tracking branch 'origin/main' into calendar-firstDayOfWeek
reidbarber Dec 6, 2024
6d255c0
Merge remote-tracking branch 'origin/main' into calendar-firstDayOfWeek
reidbarber Dec 18, 2024
932fac8
fix test
reidbarber Dec 20, 2024
cdfc45d
fix null dates
reidbarber Dec 20, 2024
48c3dc0
fix minimum dates case
reidbarber Dec 20, 2024
d9f6bd1
Merge remote-tracking branch 'origin/main' into calendar-firstDayOfWeek
reidbarber Dec 20, 2024
80409f7
add offset logic to startOfWeek
reidbarber Dec 23, 2024
38c0ed2
lint
reidbarber Dec 23, 2024
a6bf5a1
pass firstDayOfWeek into getWeeksInMonth
reidbarber Jan 6, 2025
ad1a352
Merge remote-tracking branch 'origin/main' into calendar-firstDayOfWeek
reidbarber Jan 6, 2025
22d398f
add firstDayOfWeek param to endOfWeek
reidbarber Jan 8, 2025
779505b
Merge remote-tracking branch 'origin/main' into calendar-firstDayOfWeek
reidbarber Jan 8, 2025
6d061df
add firstDayOfWeek to getDayOfWeek
reidbarber Jan 8, 2025
34a3442
pass firstDayOfWeek to getDayOfWeek
reidbarber Jan 8, 2025
e631c51
slight simplification and add tests
devongovett Jan 9, 2025
32f9e25
add docs
devongovett Jan 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/@internationalized/date/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ export {
minDate,
maxDate,
isWeekend,
isWeekday
isWeekday,
getWeekStart
} from './queries';
export {
parseDate,
Expand Down
39 changes: 30 additions & 9 deletions packages/@internationalized/date/src/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,13 +180,30 @@ export function getMinimumDayInMonth(date: AnyCalendarDate) {
return 1;
}

const DAY_MAP = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't think it was worth exporting since they're different packages and it would be public. Open to changing this if we think that's better though.

sun: 0,
mon: 1,
tue: 2,
wed: 3,
thu: 4,
fri: 5,
sat: 6
};

type DayOfWeek = 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be in the @react-types package?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the above, I didn't think it was worth exporting, but open to changing if that would be better.


/** Returns the first date of the week for the given date and locale. */
export function startOfWeek(date: ZonedDateTime, locale: string): ZonedDateTime;
export function startOfWeek(date: CalendarDateTime, locale: string): CalendarDateTime;
export function startOfWeek(date: CalendarDate, locale: string): CalendarDate;
export function startOfWeek(date: DateValue, locale: string): DateValue;
export function startOfWeek(date: DateValue, locale: string): DateValue {
export function startOfWeek(date: ZonedDateTime, locale: string, firstDayOfWeek?: DayOfWeek): ZonedDateTime;
export function startOfWeek(date: CalendarDateTime, locale: string, firstDayOfWeek?: DayOfWeek): CalendarDateTime;
export function startOfWeek(date: CalendarDate, locale: string, firstDayOfWeek?: DayOfWeek): CalendarDate;
export function startOfWeek(date: DateValue, locale: string, firstDayOfWeek?: DayOfWeek): DateValue;
export function startOfWeek(date: DateValue, locale: string, firstDayOfWeek?: DayOfWeek): DateValue {
let dayOfWeek = getDayOfWeek(date, locale);
if (firstDayOfWeek) {
let offset = (DAY_MAP[firstDayOfWeek] - getWeekStart(locale) + 7) % 7;
let diff = (7 + dayOfWeek - offset) % 7;
return date.subtract({days: diff});
}
return date.subtract({days: dayOfWeek});
}

Expand Down Expand Up @@ -225,17 +242,21 @@ function getRegion(locale: string): string | undefined {
return part === 'u' ? undefined : part;
}

function getWeekStart(locale: string): number {
export function getWeekStart(locale: string): number {
// TODO: use Intl.Locale for this once browsers support the weekInfo property
// https://github.com/tc39/proposal-intl-locale-info
let region = getRegion(locale);
return region ? weekStartData[region] || 0 : 0;
}

/** Returns the number of weeks in the given month and locale. */
export function getWeeksInMonth(date: DateValue, locale: string): number {
let days = date.calendar.getDaysInMonth(date);
return Math.ceil((getDayOfWeek(startOfMonth(date), locale) + days) / 7);
export function getWeeksInMonth(date: DateValue, locale: string, firstDayOfWeek?: DayOfWeek): number {
let monthStart = startOfMonth(date);
let firstVisibleDay = startOfWeek(monthStart, locale, firstDayOfWeek);
let monthEnd = endOfMonth(date);
let lastVisibleDay = startOfWeek(monthEnd, locale, firstDayOfWeek).add({days: 6});
reidbarber marked this conversation as resolved.
Show resolved Hide resolved
let totalDays = lastVisibleDay.calendar.toJulianDay(lastVisibleDay) - firstVisibleDay.calendar.toJulianDay(firstVisibleDay) + 1;
return Math.ceil(totalDays / 7);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same logic as before should work if you pass firstDayOfWeek through to getDayOfWeek I think

}

/** Returns the lesser of the two provider dates. */
Expand Down
12 changes: 10 additions & 2 deletions packages/@react-aria/calendar/docs/useCalendar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ function Calendar(props) {
<Button {...prevButtonProps}>&lt;</Button>
<Button {...nextButtonProps}>&gt;</Button>
</div>
<CalendarGrid state={state} />
<CalendarGrid state={state} firstDayOfWeek={props.firstDayOfWeek} />
</div>
);
}
Expand All @@ -152,7 +152,7 @@ function CalendarGrid({state, ...props}) {
let {gridProps, headerProps, weekDays} = useCalendarGrid(props, state);

// Get the number of weeks in the month so we can render the proper number of rows.
let weeksInMonth = getWeeksInMonth(state.visibleRange.start, locale);
let weeksInMonth = getWeeksInMonth(state.visibleRange.start, locale, props.firstDayOfWeek);

return (
<table {...gridProps}>
Expand Down Expand Up @@ -458,6 +458,14 @@ The `isReadOnly` boolean prop makes the Calendar's value immutable. Unlike `isDi
<Calendar aria-label="Event date" value={today(getLocalTimeZone())} isReadOnly />
```

### 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'`.

```tsx example
<Calendar aria-label="Event date" value={today(getLocalTimeZone())} firstDayOfWeek="mon" />
```

### Labeling

An aria-label must be provided to the `Calendar` for accessibility. If it is labeled by a separate element, an `aria-labelledby` prop must be provided using the `id` of the labeling element instead.
Expand Down
12 changes: 10 additions & 2 deletions packages/@react-aria/calendar/docs/useRangeCalendar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ function RangeCalendar(props) {
<Button {...prevButtonProps}>&lt;</Button>
<Button {...nextButtonProps}>&gt;</Button>
</div>
<CalendarGrid state={state} />
<CalendarGrid state={state} firstDayOfWeek={props.firstDayOfWeek} />
</div>
);
}
Expand All @@ -152,7 +152,7 @@ function CalendarGrid({state, ...props}) {
let {gridProps, headerProps, weekDays} = useCalendarGrid(props, state);

// Get the number of weeks in the month so we can render the proper number of rows.
let weeksInMonth = getWeeksInMonth(state.visibleRange.start, locale);
let weeksInMonth = getWeeksInMonth(state.visibleRange.start, locale, props.firstDayOfWeek);

return (
<table {...gridProps}>
Expand Down Expand Up @@ -477,6 +477,14 @@ The `isReadOnly` boolean prop makes the RangeCalendar's value immutable. Unlike
<RangeCalendar aria-label="Trip dates" value={{start: today(getLocalTimeZone()), end: today(getLocalTimeZone()).add({ weeks: 1 })}} isReadOnly />
```

### 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'`.

```tsx example
<RangeCalendar aria-label="Trip dates" firstDayOfWeek="mon" />
```

### Labeling

An aria-label must be provided to the `RangeCalendar` for accessibility. If it is labeled by a separate element, an `aria-labelledby` prop must be provided using the `id` of the labeling element instead.
Expand Down
13 changes: 9 additions & 4 deletions packages/@react-aria/calendar/src/useCalendarGrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ export interface AriaCalendarGridProps {
* e.g. single letter, abbreviation, or full day name.
* @default "narrow"
*/
weekdayStyle?: 'narrow' | 'short' | 'long'
weekdayStyle?: 'narrow' | 'short' | 'long',
/**
* The day that starts the week.
*/
firstDayOfWeek?: 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'
}

export interface CalendarGridAria {
Expand All @@ -56,7 +60,8 @@ export interface CalendarGridAria {
export function useCalendarGrid(props: AriaCalendarGridProps, state: CalendarState | RangeCalendarState): CalendarGridAria {
let {
startDate = state.visibleRange.start,
endDate = state.visibleRange.end
endDate = state.visibleRange.end,
firstDayOfWeek
} = props;

let {direction} = useLocale();
Expand Down Expand Up @@ -137,13 +142,13 @@ export function useCalendarGrid(props: AriaCalendarGridProps, state: CalendarSta
let dayFormatter = useDateFormatter({weekday: props.weekdayStyle || 'narrow', timeZone: state.timeZone});
let {locale} = useLocale();
let weekDays = useMemo(() => {
let weekStart = startOfWeek(today(state.timeZone), locale);
let weekStart = startOfWeek(today(state.timeZone), locale, firstDayOfWeek);
return [...new Array(7).keys()].map((index) => {
let date = weekStart.add({days: index});
let dateDay = date.toDate(state.timeZone);
return dayFormatter.format(dateDay);
});
}, [locale, state.timeZone, dayFormatter]);
}, [locale, state.timeZone, dayFormatter, firstDayOfWeek]);

return {
gridProps: mergeProps(labelProps, {
Expand Down
46 changes: 46 additions & 0 deletions packages/@react-aria/calendar/stories/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,49 @@ function Cell(props) {
</div>
);
}

export function ExampleCustomFirstDay(props) {
let {locale} = useLocale();
const {firstDayOfWeek} = props;

let state = useCalendarState({
...props,
locale,
createCalendar
});

let {calendarProps, prevButtonProps, nextButtonProps} = useCalendar(props, state);

return (
<div {...calendarProps}>
<div style={{textAlign: 'center'}} data-testid={'range'}>
{calendarProps['aria-label']}
</div>
<div style={{display: 'grid', gridTemplateColumns: 'repeat(1, 1fr)', gap: '1em'}}>
<ExampleFirstDayCalendarGrid state={state} firstDayOfWeek={firstDayOfWeek} />
</div>
<div>
<Button variant={'secondary'} {...prevButtonProps}>prev</Button>
<Button variant={'secondary'} {...nextButtonProps}>next</Button>
</div>
</div>
);
}

function ExampleFirstDayCalendarGrid({state, firstDayOfWeek}: {state: CalendarState | RangeCalendarState, firstDayOfWeek?: 'sun' | 'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat'}) {
let {locale} = useLocale();
let {gridProps} = useCalendarGrid({firstDayOfWeek}, state);
let startDate = state.visibleRange.start;
let weeksInMonth = getWeeksInMonth(startDate, locale, firstDayOfWeek);
return (
<div {...gridProps}>
{[...new Array(weeksInMonth).keys()].map(weekIndex => (
<div key={weekIndex} role="row">
{state.getDatesInWeek(weekIndex, startDate).map((date, i) => (
<Cell key={i} state={state} date={date} />
))}
</div>
))}
</div>
);
}
38 changes: 37 additions & 1 deletion packages/@react-aria/calendar/test/useCalendar.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@

import {act, pointerMap, render} from '@react-spectrum/test-utils-internal';
import {CalendarDate} from '@internationalized/date';
import {Example} from '../stories/Example';
import {Example, ExampleCustomFirstDay} from '../stories/Example';
import {I18nProvider} from '@react-aria/i18n';
import React from 'react';
import userEvent from '@testing-library/user-event';

Expand Down Expand Up @@ -63,6 +64,17 @@ describe('useCalendar', () => {
unmount();
}

async function testFirstDayOfWeek(defaultValue, firstDayOfWeek, expectedFirstDay, locale = 'en-US') {
let {getAllByRole, unmount} = render(
<I18nProvider locale={locale}>
<ExampleCustomFirstDay defaultValue={defaultValue} firstDayOfWeek={firstDayOfWeek} />
</I18nProvider>
);
let cells = getAllByRole('gridcell');
expect(cells[0].children[0]).toHaveAttribute('aria-label', expectedFirstDay);
unmount();
}

describe('visibleDuration: 3 days', () => {
it('should move the focused date by one day with the left/right arrows', async () => {
await testKeyboard(new CalendarDate(2019, 6, 5), 'June 4 to 6, 2019', 'ArrowLeft', 1, 'Tuesday, June 4, 2019', 'June 4 to 6, 2019', {visibleDuration: {days: 3}});
Expand Down Expand Up @@ -227,4 +239,28 @@ describe('useCalendar', () => {
await testPagination(defaultValue, rangeBefore, rangeAfter, rel, count, visibleDuration, pageBehavior);
});
});

describe('firstDayOfWeek', () => {
it.each`
Name | defaultValue | firstDayOfWeek | expectedFirstDay | locale
${'default'} | ${new CalendarDate(2024, 1, 1)} | ${undefined} | ${'Sunday, December 31, 2023'} | ${'en-US'}
${'Sunday'} | ${new CalendarDate(2024, 1, 1)} | ${'sun'} | ${'Sunday, December 31, 2023'} | ${'en-US'}
${'Monday'} | ${new CalendarDate(2024, 1, 1)} | ${'mon'} | ${'Monday, January 1, 2024 selected'} | ${'en-US'}
${'Tuesday'} | ${new CalendarDate(2024, 1, 1)} | ${'tue'} | ${'Tuesday, December 26, 2023'} | ${'en-US'}
${'Wednesday'} | ${new CalendarDate(2024, 1, 1)} | ${'wed'} | ${'Wednesday, December 27, 2023'} | ${'en-US'}
${'Thursday'} | ${new CalendarDate(2024, 1, 1)} | ${'thu'} | ${'Thursday, December 28, 2023'} | ${'en-US'}
${'Friday'} | ${new CalendarDate(2024, 1, 1)} | ${'fri'} | ${'Friday, December 29, 2023'} | ${'en-US'}
${'Saturday'} | ${new CalendarDate(2024, 1, 1)} | ${'sat'} | ${'Saturday, December 30, 2023'} | ${'en-US'}
${'default (fr-FR)'} | ${new CalendarDate(2024, 1, 1)} | ${undefined} | ${'lundi 1 janvier 2024 sélectionné'} | ${'fr-FR'}
${'Sunday (fr-FR)'} | ${new CalendarDate(2024, 1, 1)} | ${'sun'} | ${'dimanche 31 décembre 2023'} | ${'fr-FR'}
${'Monday (fr-FR)'} | ${new CalendarDate(2024, 1, 1)} | ${'mon'} | ${'lundi 1 janvier 2024 sélectionné'} | ${'fr-FR'}
${'Tuesday (fr-FR)'} | ${new CalendarDate(2024, 1, 1)} | ${'tue'} | ${'mardi 26 décembre 2023'} | ${'fr-FR'}
${'Wednesday (fr-FR)'} | ${new CalendarDate(2024, 1, 1)} | ${'wed'} | ${'mercredi 27 décembre 2023'} | ${'fr-FR'}
${'Thursday (fr-FR)'} | ${new CalendarDate(2024, 1, 1)} | ${'thu'} | ${'jeudi 28 décembre 2023'} | ${'fr-FR'}
${'Friday (fr-FR)'} | ${new CalendarDate(2024, 1, 1)} | ${'fri'} | ${'vendredi 29 décembre 2023'} | ${'fr-FR'}
${'Saturday (fr-FR)'} | ${new CalendarDate(2024, 1, 1)} | ${'sat'} | ${'samedi 30 décembre 2023'} | ${'fr-FR'}
`('should use firstDayOfWeek $Name', async ({defaultValue, firstDayOfWeek, expectedFirstDay, locale}) => {
await testFirstDayOfWeek(defaultValue, firstDayOfWeek, expectedFirstDay, locale);
});
});
});
12 changes: 10 additions & 2 deletions packages/@react-aria/datepicker/docs/useDatePicker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function DatePicker(props) {
{state.isOpen &&
<Popover state={state} triggerRef={ref} placement="bottom start">
<Dialog {...dialogProps}>
<Calendar {...calendarProps} />
<Calendar {...calendarProps} firstDayOfWeek={props.firstDayOfWeek} />
</Dialog>
</Popover>
}
Expand Down Expand Up @@ -346,7 +346,7 @@ function Calendar(props) {
<Button {...prevButtonProps}>&lt;</Button>
<Button {...nextButtonProps}>&gt;</Button>
</div>
<CalendarGrid state={state} />
<CalendarGrid state={state} firstDayOfWeek={props.firstDayOfWeek} />
</div>
);
}
Expand Down Expand Up @@ -690,3 +690,11 @@ By default, `useDatePicker` displays times in either 12 or 24 hour hour format d
granularity="minute"
hourCycle={24} />
```

### 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'`.

```tsx example
<DatePicker label="Appointment time" firstDayOfWeek="mon" />
```
14 changes: 11 additions & 3 deletions packages/@react-aria/datepicker/docs/useDateRangePicker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ function DateRangePicker(props) {
{state.isOpen &&
<Popover state={state} triggerRef={ref} placement="bottom start">
<Dialog {...dialogProps}>
<RangeCalendar {...calendarProps} />
<RangeCalendar {...calendarProps} firstDayOfWeek={props.firstDayOfWeek} />
</Dialog>
</Popover>
}
Expand Down Expand Up @@ -359,7 +359,7 @@ function RangeCalendar(props) {
<Button {...prevButtonProps}>&lt;</Button>
<Button {...nextButtonProps}>&gt;</Button>
</div>
<CalendarGrid state={state} />
<CalendarGrid state={state} firstDayOfWeek={props.firstDayOfWeek} />
</div>
);
}
Expand All @@ -369,7 +369,7 @@ function CalendarGrid({state, ...props}) {
let {gridProps, headerProps, weekDays} = useCalendarGrid(props, state);

// Get the number of weeks in the month so we can render the proper number of rows.
let weeksInMonth = getWeeksInMonth(state.visibleRange.start, locale);
let weeksInMonth = getWeeksInMonth(state.visibleRange.start, locale, props.firstDayOfWeek);

return (
<table {...gridProps}>
Expand Down Expand Up @@ -755,3 +755,11 @@ By default, `useDateRangePicker` displays times in either 12 or 24 hour hour for
granularity="minute"
hourCycle={24} />
```

### 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'`.

```tsx example
<DateRangePicker label="Date range" firstDayOfWeek="mon" />
```
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,5 @@ export const Invalid = () => <Calendar value={date} isInvalid />;
export const ErrorMessage = () => <Calendar value={date} isInvalid errorMessage="Selection invalid." />;
export const UnavailableInvalid = () => <Calendar value={date} isDateUnavailable={d => d.compare(date) === 0} />;
export const DisabledInvalid = () => <Calendar value={date} minValue={new CalendarDate(2022, 2, 5)} />;
export const CustomWeekStartMonday = () => <Calendar value={date} firstDayOfWeek="mon" />;
export const CustomWeekStartSaturday = () => <Calendar value={date} firstDayOfWeek="sat" />;
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,5 @@ export const NonContiguousInvalid = () => {
);
};

export const CustomWeekStartMonday = () => <RangeCalendar value={value} firstDayOfWeek="mon" />;
export const CustomWeekStartSaturday = () => <RangeCalendar value={value} firstDayOfWeek="sat" />;
10 changes: 10 additions & 0 deletions packages/@react-spectrum/calendar/docs/Calendar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,13 @@ By default, when pressing the next or previous buttons, pagination will advance
<Calendar aria-label="Event date" visibleMonths={3} pageBehavior="single" />
</div>
```

### 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'`.

```tsx example
<div style={{maxWidth: '100%', overflow: 'auto'}}>
<Calendar aria-label="Event date" firstDayOfWeek="mon" />
</div>
```
10 changes: 10 additions & 0 deletions packages/@react-spectrum/calendar/docs/RangeCalendar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,13 @@ By default, when pressing the next or previous buttons, pagination will advance
<RangeCalendar aria-label="Trip dates" visibleMonths={3} pageBehavior="single" />
</div>
```

### 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'`.

```tsx example
<div style={{maxWidth: '100%', overflow: 'auto'}}>
<RangeCalendar aria-label="Trip dates" firstDayOfWeek="mon" />
</div>
```
Loading
Loading