Components

Date Picker

Dates are typed when people know them (a birthday, a document), picked from a calendar when they browse for a day, ranges come with presets, and time has its own input. In Arabic the fields and the grid mirror, and the week starts from the locale.

Figmashadcn equivalentdate-picker

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 date-picker

Also works with shadcn: npx shadcn@latest add @ritla/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 { DateInput } from "@/components/ui/date-picker";
const [date, setDate] = useState<Date | null>(null);

<DateInput label="Transfer date" value={date} onValueChange={setDate} />

Examples

A date people know

A date of birth is typed, not browsed: picker={false} removes the calendar button, and showAge shows the age so people can check the year. The segments follow the region's order (day first in Arabic) and accept Arabic-Indic digits when typed.

Get the code ›

Time

TimeInput: hour and minute, then AM / PM, and the time zone when it matters. The clock keeps its order in Arabic: hour, then minute, from the left.

Get the code ›

A range with presets

DateRangePicker: the presets people actually use, two months on desktop and one on phones, and the chosen range written out in the field ("March 1 – 15, 2026").

Get the code ›

Date picker menu

DatePickerMenu on its own: the month and year buttons open their lists, then Cancel and Apply. Put it in a Popover, a Dialog or a Drawer as the screen needs.

Get the code ›

API reference

DateInput

PropTypeDefaultDescription
value / onValueChangeDate | null / (value: Date | null) => voidNoneA complete date, or null while it is empty or not real (31 February is not a date).
label / required / helperText / errorReactNode / booleanNoneAs in Input. Say the format in the helper text when it could be misread.
showAgebooleanfalseFigma's age badge, for a date of birth.
pickerbooleantrueThe calendar button that opens the Date picker menu.
min / maxDateNoneThe first and last dates the menu offers.
order("day" | "month" | "year")[]NoneDefault: the region's order. Day first in Arabic, month first in en-US.
disabled / readOnlybooleanNoneFigma's State.

TimeInput

PropTypeDefaultDescription
value / onValueChange{ hours, minutes } | nullNoneHours from 0 to 23.
hourCycle"h12" | "h23""h12"12 hours with AM / PM, or 24 hours.
timeZoneReactNodeNoneThe time zone at the end of the field when it matters ("UTC +03:00").

DatePicker / DatePickerMenu

PropTypeDefaultDescription
trigger (DatePicker)ReactElementNoneThe control that opens the menu in a Popover.
value / onApply / onCancel (Menu)Date / (value: Date) => void / () => voidNoneThe day the menu opens on, and Apply and Cancel.
fromYear / toYear (Menu)numberNoneThe year list's range.

DateRangePicker / DateRangeMenu

PropTypeDefaultDescription
value / onValueChangeDateRangeNoneThe range { from, to }.
presets{ label, range }[]NoneDefault: Figma's eight. Today, Yesterday, This week, Last week, This month, Last month, This year, Last year.
numberOfMonths (Menu)1 | 22Two months on desktop, one on phones.

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
TabFrom one segment to the next, then the calendar button.
ArrowUpArrowDownSteps the segment up or down; on AM / PM, switches it.
BackspaceIn an empty segment, goes back to the previous one.
EnterOn the calendar button, opens the menu; in the grid, chooses the day (see Calendar).
EscapeCloses the menu without a change.

ARIA

  • The field is a group named by its label, and each segment a numeric field with its name ("Day", "Month", "Year").
  • Typing is always the accessible way in; never make the calendar the only one.
  • AM / PM is a spinbutton that reads its value. The age badge reads "Age 34".
  • The calendar, month and year buttons are named in the page language, and the month and year lists are listboxes.

Arabic and RTL notes

Mirrors

  • The date segments: the day on the right, then the month, then the year on the left; the calendar button and the age badge on the left.
  • The presets at the menu's inline start (the right), and Apply at the end of the buttons.

Does not mirror

  • The clock: hour, then minute, from the left, as on a clock.
  • Each segment's digits, and the UTC time zone.
Numerals
Segments, the grid and the age badge follow numerals, and typing accepts both systems.
Arabic typography
Segments are label-16, the month and year buttons body-16 Semibold.
Mixed-direction text
Never mix Hijri and Gregorian in one field: Hijri has its own picker.