# Calendar

> The month grid on its own, inline on a page (bookings, statements, delivery slots) or inside a date picker. One day, or a range between a start and an end. The week starts from the locale, and in Arabic the grid reads right to left.

Source: https://ritla.app/ui/calendar

## Installation

Installing from the registry is coming soon. Until then, these are the commands you will run.

```bash
npx ritla add calendar
```

With the shadcn CLI instead:

```bash
npx shadcn@latest add @ritla/calendar
```

Dependencies: `react-day-picker`, `@phosphor-icons/react`

## Usage

```tsx
import { Calendar } from "@/components/ui/calendar";

const [day, setDay] = useState<Date | undefined>(new Date());

<Calendar mode="single" selected={day} onSelect={setDay} />
```

## Examples

### Range

`mode="range"`: the start, then the end; the days between take a light band. Picking an end before the start swaps them quietly.

Live preview: https://ritla.app/_kanz/preview/ltr/calendar-range

### Unavailable days

`disabled` turns off the days that can't be chosen (before the first slot, Fridays), and `footer` says why under the grid, so the state never rests on color alone.

Live preview: https://ritla.app/_kanz/preview/ltr/calendar-unavailable

## API reference

### `Calendar`

Every react-day-picker prop, as in shadcn's Calendar.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | `"single" \| "range" \| "multiple"` | None | Figma's Mode: one day or a range. |
| `selected / onSelect` | `Date \| DateRange` | None | The chosen day or range. |
| `month / defaultMonth / onMonthChange` | `Date` | None | The month shown. Open on the first available month, never an empty one. |
| `disabled` | `Matcher \| Matcher[]` | None | Days that can't be chosen; say why in `footer`. |
| `weekStartsOn` | `0 to 6` | None | Default: from the locale. Monday in English and Saturday in Arabic; Sunday for ar-SA, Monday for ar-AE. |
| `numberOfMonths` | `number` | `1` | Two months on desktop for ranges. |
| `framed` | `boolean` | `true` | The Figma panel (gray border, radius 12, 16px in). Turn it off inside a menu that has its own. |
| `numerals` | `"latn" \| "arab"` | None | Default: from `KanzProvider`. |

## Accessibility

Keyboard (keys as in left-to-right; arrows swap in right-to-left):

- `ArrowLeft` + `ArrowRight`: One day back or on; in Arabic ArrowLeft is the next day.
- `ArrowUp` + `ArrowDown`: One week.
- `PageUp` + `PageDown`: One month; with Shift, a year.
- `Home` + `End`: The week's edges.
- `Enter` + `Space`: Chooses the day.

ARIA:

- The grid is `role="grid"` named by its month, and each day a button with its full name ("Thursday, September 17, 2026"), with Today and selected when they apply.
- The month name is in a live region (`aria-live="polite"`), so a change is announced.
- Previous and Next month are named in the page language, with a 48px touch target.

## Arabic and RTL notes

Mirrors:

- The grid: the first day of the week on the right.
- Previous month at the inline start (the right), pointing right; Next month on the left.
- A range band runs from right to left.

Does not mirror:

- The day numbers themselves.

Numerals: Day numbers and the year follow `numerals`.

Arabic typography: Days are `body-14` and the title `label-16` Semibold. Arabic weekday names come from Intl without the article («سبت») at `label-12`, to fit a 44px column.

Mixed-direction text: Arabic month names run يناير to ديسمبر, the same set as the rest of the product.
