npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-multicalendar-picker

v0.1.0-beta.1

Published

React Native single-date and range picker with 13 calendars, Persian/Arabic/English localization, RTL, themes and custom fonts

Downloads

376

Readme

react-native-multicalendar-picker

A controlled React Native date and date-range picker with 13 calendar systems, configurable calendar segments, Persian/English/Arabic UI, RTL, light/dark themes, and custom typography. Values stay in Gregorian ISO format when the visible calendar changes.

راهنمای فارسی · API reference · Release notes

Features

  • Single-date, optional-date and inclusive start/end range selection.
  • Calendar segments generated from your calendars list.
  • Month/year menus, descending years and persistent browsing highlights.
  • Date limits, whole-year limits and optional future-date restrictions.
  • Range highlighting and built-in date/range shortcuts.
  • Locale-aware labels, digits, week starts and RTL/LTR layout.
  • System/light/dark themes, semantic colors, custom fonts and proportional sizing.
  • Optional descriptions supplied by your own cultural-event data.
  • TypeScript definitions; no network calls, Moment dependency or required provider.

Installation

The first release is available on the beta channel:

npm install react-native-multicalendar-picker@beta react-native-svg

For a bare React Native iOS app, install pods after adding react-native-svg:

cd ios
pod install

The picker adds no native module of its own. Its included chevrons use react-native-svg; no SVG transformer is needed. If your app already has that peer installed and linked, no extra native setup is required for this picker.

| Requirement | Supported range | | ---------------- | ---------------------------------------------------------- | | React | >=18.2.0 <20 | | React Native | >=0.77.0 <1 | | react-native-svg | >=15.0.0 <16 | | Intl | DateTimeFormat data for the selected calendar and locale |

The tested baseline is React 18.3.1 / React Native 0.77.3. Runtime results include Android API 36 and iOS 26.2 simulators. These checks do not establish compatibility with every version in the peer ranges or with every physical device.

Select a date

import {useState} from 'react';
import {ScrollView} from 'react-native';
import {
  MultiCalendarPicker,
  localToday,
} from 'react-native-multicalendar-picker';

export default function DateExample() {
  const [date, setDate] = useState(localToday);

  return (
    <ScrollView>
      <MultiCalendarPicker
        value={date}
        onChange={setDate}
        calendars={['persian', 'gregory']}
        locale="fa-IR"
        theme="system"
        allowFutureDates={false}
      />
    </ScrollView>
  );
}

date and onChange always use a Gregorian ISO date-only string such as 2026-10-17, even when the UI displays ۱۴۰۵/۰۷/۲۵. Do not convert date-only values through new Date(iso) and UTC/local timestamp arithmetic. Use the exported calendarDate helper to read a value in a different calendar.

The component is inline. Place it in your own screen, modal or bottom sheet. For confirm/cancel behavior, keep a draft value in the host and commit it only when the user confirms. Allow vertical scrolling, especially with large text or ranges.

Select a range

import {useState} from 'react';
import {ScrollView, Text} from 'react-native';
import {MultiCalendarPicker} from 'react-native-multicalendar-picker';
import type {DateRange} from 'react-native-multicalendar-picker';

export default function RangeExample() {
  const [range, setRange] = useState<DateRange | null>(null);
  const complete = range !== null && range.end !== null;

  return (
    <ScrollView>
      <MultiCalendarPicker
        selectionMode="range"
        value={range}
        onChange={setRange}
        clearable
        calendars={['persian', 'gregory']}
        locale="fa-IR"
        allowFutureDates={false}
      />
      <Text>{complete ? 'Range ready' : 'Choose both dates'}</Text>
    </ScrollView>
  );
}

The first tap emits {start: '2026-10-12', end: null}. The second tap emits the complete inclusive range, for example {start: '2026-10-12', end: '2026-10-17'}. Update the controlled state after each callback, including the pending start. Earlier second taps are sorted; tapping the same day twice creates a one-day range. A tap after completion starts a new range. Clearing emits null.

Both endpoints and the day band survive calendar switches. Range shortcuts select Today, Last 7 days, Last 30 days, or the active calendar's month through today.

Optional dates

const [date, setDate] = useState<string | null>(null);

<MultiCalendarPicker
  clearable
  value={date}
  onChange={setDate}
  locale="fa-IR"
/>;

Single-date null values require clearable. Required fields retain a string-only setter. In range mode, an empty null range is always valid; clearable controls whether the clear button is shown.

Limit dates and years

<MultiCalendarPicker
  value={date}
  onChange={setDate}
  calendars={['persian', 'gregory']}
  locale="fa-IR"
  yearCalendar="persian"
  minYear={1391}
  maxYear={1405}
  allowFutureDates={false}
/>

minDate/maxDate are inclusive Gregorian ISO bounds. minYear/maxYear use complete years in yearCalendar (Gregorian by default). Reference bounds stay fixed when switching segments. For a rolling 15-year interval, derive the current year with calendarDate(localToday(), 'persian').year, then use currentYear - 14 and currentYear.

Future dates are allowed by default; set allowFutureDates={false} to cap selection at today. All date/year/future limits intersect. An empty intersection throws RangeError. Navigation stays within overlapping periods. See the bound semantics for partial years and eras.

Fonts, sizing and themes

<MultiCalendarPicker
  value={date}
  onChange={setDate}
  fontFamily="Vazirmatn-Regular"
  fontSize={14}
  theme="dark"
  colors={{accent: '#24cbbb', rangeBackground: '#194d47'}}
/>

Register custom fonts in the host app first. fontSize defaults to 14 dp and scales text roles, icons and spacing proportionally; it overrides textStyle.fontSize. Native text scaling remains enabled. Day circles and range bands fit the measured seven-column grid. Theme colors and font assets belong to the consuming app; no font is bundled or downloaded.

Supported calendars

| Identifier | Calendar | | ------------------ | ------------------------------------- | | gregory | Gregorian | | persian | Persian / Solar Hijri | | islamic-civil | Islamic civil | | islamic-tbla | Islamic tabular | | islamic-umalqura | Umm al-Qura | | hebrew | Hebrew, including 13-month leap years | | buddhist | Buddhist | | japanese | Japanese imperial eras | | roc | Taiwan / Republic of China | | indian | Indian national / Saka | | coptic | Coptic | | ethiopic | Ethiopic | | ethioaa | Ethiopic Amete Alem |

Calendar arithmetic is provided by @internationalized/date. This list does not include every historical calendar. Islamic calculation variants may differ from local moon-sighting announcements. Engine ranges and era restrictions apply; Japanese dates before 1868 are unsupported. The runtime must provide matching Intl calendar data; unsupported formatting throws instead of silently showing Gregorian labels. All engine implementations are bundled, regardless of visible segments.

Localization and events

UI messages ship in Persian, English and Arabic. Other locales use Intl-formatted dates with English UI messages until you supply overrides:

messages={{today: 'Aujourd’hui', calendars: {gregory: 'Grégorien'}}}

Optional event descriptions come from a synchronous getEvents(iso, locale) callback. Fetch/cache data in the host app. No official holiday feed or remote service is bundled. See the event example.

Documentation

The package includes source, compiled JavaScript and TypeScript declarations. Native button labels/selected states and simulator flows have been checked; spoken VoiceOver/TalkBack output and physical-device coverage remain incomplete in this beta.

License

MIT, Copyright 2026 Mohammad Kasiri.