---
name: Calendar
package: '@wordpress/ui'
category: Calendar
status: stable
canonical: 'https://system.automattic.design/components/calendar/'
storybook: 'https://wordpress.github.io/gutenberg/?path=/docs/design-system-components-calendar-calendar--docs'
github: 'https://github.com/WordPress/gutenberg/tree/trunk/packages/ui/src/calendar'
---

# Calendar

`Calendar` provides a customizable calendar interface for **single date**
selection.

The component is built with accessibility in mind and follows ARIA best
practices for calendar widgets. It provides keyboard navigation, screen reader
support, and customizable labels for internationalization.

```tsx
import { Calendar } from '@wordpress/ui';
```

## Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `role` | `AriaRole \| undefined` | `'application'` | The ARIA role for the calendar's root element.<br>The default `application` role helps assistive technologies pass calendar navigation keys to the component. Its accessible name includes the current month.<br>Changing this role can affect screen-reader keyboard navigation. Only override it for a tested composition. Apply roles that require additional behavior, such as `dialog`, to a wrapper. |
| `required` | `boolean` | `false` | Whether the selection is required. When `true`, there always needs to be a date selected. |
| `defaultMonth` | `Date` | `The current month` | The initial month to show in the calendar view (uncontrolled). |
| `month` | `Date` | — | The month displayed in the calendar view (controlled). Use together with `onMonthChange` to change the month programmatically. |
| `numberOfMonths` | `number` | `1` | The number of months displayed at once. |
| `showOutsideDays` | `boolean` | `false` | When `true`, days from adjacent months are shown in the grid and receive the `outside` modifier and the class. |
| `fixedWeeks` | `boolean` | `false` | When `true`, the calendar always shows a fixed number of weeks (e.g. 6) so the grid height does not change between months. |
| `startMonth` | `Date` | — | The earliest month to start the month navigation. |
| `endMonth` | `Date` | — | The latest month to end the month navigation. |
| `autoFocus` | `boolean` | — | Focus the first selected day (if set) or today's date (if not disabled).<br>Use this prop when the calendar should receive initial focus as it opens, such as in a calendar popover. Do not use it to move focus after updates to an open calendar. |
| `disabled` | `Matcher \| Matcher[] \| undefined` | — | Specify which days are disabled. Using `true` will disable all dates. |
| `disableNavigation` | `boolean` | — | Disable the navigation buttons. |
| `labels` | `{ labelNav?: (() => string) \| undefined; labelGrid?: ((date: Date) => string) \| undefined; labelGridcell?: ((date: Date, modifiers?: Modifiers \| undefined) => string) \| undefined; labelNext?: ((month: Date \| undefined) => string) \| undefined; labelPrevious?: ((month: Date \| undefined) => string) \| undefined; labelDa...` | — | Use custom labels, useful for translating the component.<br>For a correct localized experience, consumers should make sure the locale used for translated labels and date text is consistent. |
| `locale` | `string \| Locale \| undefined` | `The \`enUS\` locale from \`date-fns/locale\`` | A BCP 47 locale code or date-fns locale object used to localize date text, numerals, the default text direction, and the first day of the week.<br>The locale code derives the first day of the week when the browser provides that information, whether passed directly or through a date-fns locale object. Use `weekStartsOn` to override this default.<br>Invalid or unsupported locale codes fall back to `en-US` for date text. A date-fns locale object with an unsupported code retains its own first-day setting.<br>For a correct localized experience, consumers should make sure the locale used for translated labels and date text is consistent.<br>The calendar always uses a Gregorian date grid. The locale does not change the underlying calendar system. |
| `weekStartsOn` | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6` | `Based on the \`locale\` prop when available` | The index of the first day of the week (0 - Sunday). Overrides the locale's one. |
| `onMonthChange` | `(month: Date) => void` | — | Event fired when the user navigates between months. |
| `timeZone` | `string` | — | The time zone (IANA or UTC offset) to use in the calendar.<br>See [Wikipedia](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) for the possible values.<br>When working with time zones, use the `TZDate` object from the [`@date-fns/tz`](https://www.npmjs.com/package/@date-fns/tz) package instead of the native `Date` object. |
| `style` | `CSSProperties` | — | CSS style to apply to the element. |
| `className` | `string` | — | CSS class name to apply to the element. |
| `render` | `ComponentRenderFn<HTMLAttributesWithRef<any>> \| ReactElement<Record<string, unknown>, string \| JSXElementConstructor<any>> \| undefined` | — | Replaces the component's default HTML element using a given React element, or a function that returns a React element. |
| `value` | `Date \| null \| undefined` | — | The selected date (controlled). Use `null` when there is no selection. To render an uncontrolled calendar, use `defaultValue` instead. |
| `onValueChange` | `OnValueChangeHandler<Date \| null>` | — | Event handler called when the selected date changes. |
| `defaultValue` | `Date` | — | The initially selected date (uncontrolled). |


## Examples

### Default

```tsx
const Default = () => <Calendar onMonthChange={fn()} onValueChange={fn()} endMonth={ toDate( endMonth ) } />;
```

### Disabled Dates

```tsx
const DisabledDates = () => <Calendar
    onMonthChange={fn()}
    onValueChange={fn()}
    disabled={DISABLED_DATES_SAMPLE}
    endMonth={ toDate( endMonth ) } />;
```

### With Selected Date And Month

```tsx
const WithSelectedDateAndMonth = () => <Calendar
    onMonthChange={fn()}
    onValueChange={fn()}
    defaultValue={firstDayOfNextMonth}
    defaultMonth={firstDayOfNextMonth}
    endMonth={ toDate( endMonth ) } />;
```

### With Outside Days

Shows days from adjacent months in the grid. Outside days use a lighter style
and are still interactive. Use `fixedWeeks` to keep the grid height constant.

```tsx
const WithOutsideDays = () => <Calendar
    onMonthChange={fn()}
    onValueChange={fn()}
    showOutsideDays
    fixedWeeks
    endMonth={ toDate( endMonth ) } />;
```

### With Time Zone

When working with time zones, use the `TZDate` object from the
[`@date-fns/tz`](https://www.npmjs.com/package/@date-fns/tz) package instead
of the native `Date` object.

```tsx
const WithTimeZone = () => {
    const [ selected, setSelected ] = useState< TZDate | null >( null );

    useEffect( () => {
        setSelected(
            // Select one week from today every time the time zone changes.
            new TZDate(
                new Date().setDate( new Date().getDate() + 7 ),
                args.timeZone
            )
        );
    }, [ args.timeZone ] );

    return (
        <>
            <Calendar
                onMonthChange={fn()}
                timeZone="Pacific/Auckland"
                endMonth={ toDate( endMonth ) }
                value={ selected }
                onValueChange={ ( selectedDate, ...rest ) => {
                    setSelected(
                        selectedDate
                            ? new TZDate( selectedDate, args.timeZone )
                            : null
                    );
                    args.onValueChange?.( selectedDate, ...rest );
                } }
                disabled={ [
                    {
                        // Disable any date before today
                        before: new TZDate( new Date(), args.timeZone ),
                    },
                ] } />
            <p>Calendar set to { args.timeZone ?? 'current' }timezone,
                                    disabling selection for all dates before today, and starting
                                    with a default date of 1 week from today.
                                </p>
        </>
    );
};
```