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

bohra-datepicker

v0.1.1

Published

A Hijri date picker for the Dawoodi Bohra Fatimi calendar — supports React and vanilla JS/HTML

Readme

bohra-datepicker

A Hijri date picker for the Dawoodi Bohra Fatimi calendar — works with React and plain HTML/CSS/JS.

The Dawoodi Bohra community uses a Fatimi Hijri calendar that differs by 1 day from the standard Islamic calendar on certain years. This package uses exact 30-year lookup tables (not the floating-point Kuwait Algorithm) to get those dates right.

License TypeScript

Install

npm install bohra-datepicker

Usage

React

import { useState } from "react";
import {
    DatePicker,
    injectStyles,
    gregorianToFatimi,
    fatimiToGregorian,
    formatHijri,
} from "bohra-datepicker/react";

// Inject CSS once at the root of your app
injectStyles();

function MyForm() {
    // 1. Setup State
    const [date, setDate] = useState(new Date()); // Defaults to Today
    const [hijri, setHijri] = useState(gregorianToFatimi(new Date()));

    // 2. Setting values programmatically
    const setSpecificDate = () => {
        // To set a date using Hijri numbers:
        const newGregorian = fatimiToGregorian({
            day: 1,
            month: 9,
            year: 1447,
        });
        setDate(newGregorian);
        setHijri({ day: 1, month: 9, year: 1447 });
    };

    return (
        <div className="p-4">
            <DatePicker
                value={date}
                onChange={(gregDate, hijriDate) => {
                    // Update both state variables
                    setDate(gregDate);
                    setHijri(hijriDate);
                }}
            />

            <button onClick={setSpecificDate}>Set to 1 Ramadaan</button>

            {/* 3. Using Utility Functions */}
            <div className="mt-4">
                <p>
                    Selected Hijri: {hijri.day}/{hijri.month}/{hijri.year}
                </p>
                <p>Formatted: {formatHijri(hijri, "long")}</p>
            </div>
        </div>
    );
}

React Props

| Prop | Type | Default | Description | | ------------------- | ------------------------------------------- | --------------------------------- | ---------------------------------------------- | | value | Date \| null | — | Controlled selected date (Gregorian) | | onChange | (date: Date, hijri: HijriDate) => void | — | Called on date selection | | placeholder | string | "Select Hijri date" | Input placeholder | | weekStartsOn | 0 \| 1 \| 2 | 0 | 0=Sun, 1=Mon, 2=Sat | | monthNameStyle | "long" \| "short" | "long" | Month name format | | showGregorianDate | boolean | false | Show Gregorian day number in each cell | | isDateDisabled | (date: Date, hijri: HijriDate) => boolean | — | Disable specific dates | | className | string | "" | Extra class on root element | | longMonthNames | string[12] | MONTH_NAMES_LONG | Array of 12 strings for full form month names | | shortMonthNames | string[12] | MONTH_NAMES_SHORT | Array of 12 strings for short form month names |


Vanilla HTML / JS

Drop the IIFE bundle in a <script> tag — no build step needed.

<!DOCTYPE html>
<html>
    <head>
        <script src="https://unpkg.com/bohra-datepicker/dist/vanilla/bohra-datepicker.global.js"></script>
    </head>
    <body>
        <input id="my-date-input" type="text" placeholder="Pick a date..." />

        <script>
            const picker = new BohraDatepicker.Picker("#my-date-input", {
                onChange: function (gregorianDate, hijriDate) {
                    console.log("Gregorian:", gregorianDate);
                    console.log("Hijri:", hijriDate);
                    // hijriDate = { day: 14, month: 10, year: 1447 }
                },
                placeholder: "Select Hijri date",
                monthNameStyle: "long", // "long" | "short"
                showGregorianDate: false,
                weekStartsOn: 0, // 0=Sun, 1=Mon, 2=Sat
            });

            // Programmatic API
            picker.setValue(new Date()); // set a date
            picker.getValue(); // returns Date | null
            picker.getHijriValue(); // returns HijriDate | null
            picker.destroy(); // cleanup
        </script>
    </body>
</html>

Core utilities only (no UI)

If you just need the date conversion logic:

import {
    gregorianToFatimi,
    fatimiToGregorian,
    formatHijri,
    todayFatimi,
    isKabisa,
    daysInHijriMonth,
} from "bohra-datepicker";

// Convert Gregorian → Fatimi Hijri
const hijri = gregorianToFatimi(new Date(2005, 1, 9)); // Input → 9th February 2005
// → { day: 1, month: 1, year: 1426 }

// Format it
formatHijri(hijri, "long"); // "1 Shehre Moharramul Haram 1426 AH"
formatHijri(hijri, "short"); // "1 Moharram 1426 AH"

// Convert back
const greg = fatimiToGregorian({ day: 1, month: 1, year: 1426 });
// → Date: Feb 9, 2005

// Today's Hijri date
const today = todayFatimi();

// Is a year a Kabisa (leap) year?
isKabisa(1426); // → true

// Days in a specific month
daysInHijriMonth(1426, 12); // → 30 (Zilhaj in a Kabisa year)

Theming

The component uses CSS custom properties. Override them to match your brand:

.bdp-root {
    --bdp-accent: #8b1a1a !important; /* your brand colour */
    --bdp-accent-light: #fdf0f0 !important;
    --bdp-radius: 4px !important; /* sharper corners */
    --bdp-day-size: 38px !important; /* larger cells */
}

Custom Month Names

You can override the default month names (e.g., for different transliterations or languages). Note: You must provide an array of exactly 12 strings. See Default Month Names for reference.

React

const customLong = ["Moharram", "Safar", ...]; // must have 12 items

<DatePicker
  longMonthNames={customLong}
  monthNameStyle="long"
/>

Vanilla

const picker = new BohraDatepicker.Picker("#input", {
  longMonthNames: ["Moharram", "Safar", ...], // 12 items
  shortMonthNames: ["Moh", "Saf", ...],      // 12 items
});

Month Names

| # | Long | Short | | --- | ------------------------ | ------------- | | 1 | Shehre Moharramul Haram | Moharram | | 2 | Safarul Muzaffar | Safar | | 3 | Rabiul Awwal | Rabiul Awwal | | 4 | Rabiul Akhar | Rabiul Akhar | | 5 | Jamadal Ula | Jamadal Ula | | 6 | Jamadal Ukhra | Jamadal Ukhra | | 7 | Shehre Rajabul Asab | Rajab | | 8 | Shabanul Karim | Shabaan | | 9 | Shehre Ramazanul Moazzam | Ramadaan | | 10 | Shawwalul Mukarram | Shawwal | | 11 | Zilqadatil Haram | Zilqadah | | 12 | Zilhijjatil Haram | Zilhaj |


Why not the Kuwait Algorithm?

The Kuwait Algorithm uses a floating-point average of 10631/30 ≈ 354.366 days per year. On Kabisa (leap) years that actually have 355 days, this average drifts and places the month boundary 1 day too late.

This package uses exact 30-year lookup tables (the same epoch as the Fatimi Hijri calendar: AJD 1948083.5 = 1 Moharram 1 AH), which correctly handles every Kabisa year boundary.

Verified against the official Fatimi Dawat calendar.


License

MIT — see LICENSE for details. © Burhanuddin Nasikwala