# Hijri Date Picker

> For government services, Islamic finance, Hajj and Umrah, and any form that asks for a Hijri date. Built on the Umm al-Qura calendar, with the Gregorian date always visible next to it.

Source: https://ritla.app/ui/hijri-date-picker

## Installation

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

```bash
npx ritla add hijri-date-picker
```

With the shadcn CLI instead:

```bash
npx shadcn@latest add @ritla/hijri-date-picker
```

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

## Usage

```tsx
import { HijriDateInput } from "@/components/ui/hijri-date-picker";

// Store the Gregorian day; the field shows and takes it as Umm al-Qura.
const [date, setDate] = useState<Date | null>(null);

<HijriDateInput label="Date of birth (Hijri)" value={date} onValueChange={setDate} />
```

## Examples

### Hijri date menu

Each Hijri day with its Gregorian day small under it, and the month's Gregorian span under the title ("12 September to 11 October 2026"). The Hijri / Gregorian switch keeps the chosen day and only changes the grid. The week starts on Monday in English and Saturday in Arabic, as in Date picker.

Live preview: https://ritla.app/_kanz/preview/ltr/hijri-date-picker-menu

### A date in the future

The error state: the badge turns red and the message says how to fix it ("This date is in the future. Check the year.").

Live preview: https://ritla.app/_kanz/preview/ltr/hijri-date-picker-error

## API reference

### `HijriDateInput`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `value / onValueChange` | `Date \| null / (value: Date \| null) => void` | None | The Gregorian day (store it as an ISO date); the field shows and takes it as Umm al-Qura. `null` while the day doesn't exist (the 30th of a 29-day month). |
| `label / required / error` | `ReactNode / boolean` | None | As in Input. Say it is Hijri in the label ("Date of birth (Hijri)"). |
| `helperText` | `ReactNode` | None | Default: the Hijri day and month, then the full Gregorian date ("17 Rabiʻ II, Monday, September 28, 2026"). |
| `picker` | `boolean` | `true` | The calendar button with the Hijri menu. |
| `disabled` | `boolean` | None | State = Disabled. |

### `HijriDatePickerMenu / HijriCalendar`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `value / onApply / onCancel (Menu)` | `Date / (value: Date) => void / () => void` | None | The day it opens on, and Apply and Cancel. |
| `HijriCalendar` | `DayPickerProps` | None | The Hijri grid on its own, with every react-day-picker prop, as Calendar. |
| `toHijri / fromHijri / hijriDateLib` | `functions` | None | Conversion between the Gregorian day and the Umm al-Qura date through Intl, and the date library that runs the grid. |

## Accessibility

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

- `Tab`: Day, then month, then year, then the calendar button.
- `ArrowLeft` + `ArrowRight` + `ArrowUp` + `ArrowDown`: In the grid: a day or a week; in Arabic ArrowLeft is the next day.
- `PageUp` + `PageDown`: One Hijri month.

ARIA:

- Each day in the grid is a button named with its full Hijri date ("Monday, Rabiʻ II 17, 1448 AH"); the Gregorian day under it is for the eye only.
- The full Gregorian date in the helper is read with the field.
- The Calendar type switch is a named toggle group.

## Arabic and RTL notes

Mirrors:

- The grid runs right to left; the segments run day, month, year from the right, with the badge and the calendar button on the left.

Does not mirror:

- The day numbers themselves.

Numerals: Western digits by default in both languages, asked of Intl explicitly (`-nu-latn`), and Arabic-Indic with `numerals="arab"`.

Arabic typography: The Hijri day is `body-14` and the Gregorian day under it `label-12`, in a 48px cell.

Mixed-direction text: Umm al-Qura through Intl (`islamic-umalqura`). In some countries a month can start a day earlier or later after the moon sighting, and the menu says so. Never mix Hijri and Gregorian in one field.
