Components

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.

Preview

Mirrored is the same English content laid out right to left: it separates a mirroring bug from a translation one.

Installation

SoonInstalling from the registry is coming soon. Until then, these are the commands you will run.
npx ritla add hijri-date-picker

Also works with shadcn: npx shadcn@latest add @ritla/hijri-date-picker

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

Installing by hand copies the component's source into your project. The source comes with a Ritla UI license, so the CLI is the short way to the same files.

Usage

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.

Get the code ›

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.").

Get the code ›

API reference

HijriDateInput

PropTypeDefaultDescription
value / onValueChangeDate | null / (value: Date | null) => voidNoneThe 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 / errorReactNode / booleanNoneAs in Input. Say it is Hijri in the label ("Date of birth (Hijri)").
helperTextReactNodeNoneDefault: the Hijri day and month, then the full Gregorian date ("17 Rabiʻ II, Monday, September 28, 2026").
pickerbooleantrueThe calendar button with the Hijri menu.
disabledbooleanNoneState = Disabled.

HijriDatePickerMenu / HijriCalendar

PropTypeDefaultDescription
value / onApply / onCancel (Menu)Date / (value: Date) => void / () => voidNoneThe day it opens on, and Apply and Cancel.
HijriCalendarDayPickerPropsNoneThe Hijri grid on its own, with every react-day-picker prop, as Calendar.
toHijri / fromHijri / hijriDateLibfunctionsNoneConversion between the Gregorian day and the Umm al-Qura date through Intl, and the date library that runs the grid.

Accessibility

Keyboard

Keys are written for left-to-right. In right-to-left the arrow keys swap: the one pointing toward the reading direction moves forward.

KeyAction
TabDay, then month, then year, then the calendar button.
ArrowLeftArrowRightArrowUpArrowDownIn the grid: a day or a week; in Arabic ArrowLeft is the next day.
PageUpPageDownOne 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.