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

@armin-eslami/persian-calendar

v1.0.16

Published

Big persian calendar component made by react.

Readme

Persian Calendar

Big Persian Calendar component built with React, Typescript and Tailwindcss.

Features

  • Supports year and month view
  • Customizable theme
  • Supports events
  • Supports custom off dates
  • Supports controlled vs uncontrolled mode

Installation

npm install @armin-eslami/persian-calendar

Example Usage

1. Uncontrolled component

Basic

import PersianCalendar from '@armin-eslami/persian-calendar';

function App() {
  return (
    PersianCalendar
        year={year}
    />
  );
}

Advanced

import PersianCalendar, {
  PersianCalendarTheme,
  PersianCalendarEvent,
  Day,
} from "@armin-eslami/persian-calendar";

function App() {
  // Override the default theme
  const theme: PersianCalendarTheme = {
    fontFamily: "Vazir",
    background: "#fff",
  };

 // Set which days of week are off
  const offDaysOfWeek: number[] = [6]; // 6 is friday

  // Set off dates of the year
  const offDates: string[] = [
    "1404/01/01",
    "1404/01/02",
    "1404/01/03",
    "1404/01/04",
    "1404/01/12",
    "1404/01/13",
    ...
  ];

  // Set events
  const events: PersianCalendarEvent[] = [
    { title: "بدون عنوان", date: "1404/02/05", color: "#ef4444" },
    { title: "بدون عنوان", date: "1404/02/13", color: "#10b981" },
    { title: "بدون عنوان", date: "1404/02/20", color: "#d946ef" },
  ];

  // Gets called when a day is clicked
  const onDayClick = (day: Day) => {
    console.log(day);
  };

  return (
    <PersianCalendar
      className="w-full h-full p-4"
      year="1404"
      month={2}
      theme={theme}
      events={events}
      offDates={offDates}
      offDaysOfWeek={offDaysOfWeek}
      onDayClick={onDayClick}
    />
  );
}

export default App;

2. Controlled component

import PersianCalendar, {
  PersianCalendarMode,
  Day,
  getCurrentYear
  getCurrentMonthIndex,
} from "@armin-eslami/persian-calendar";

function App() {
  // Track the active mode
  const [activeMode, setActiveMode] = useState<PersianCalendarMode>(
    PersianCalendarMode.YEAR
  );

  // Track the active year
  const [year, setYear] = useState<string>("1404");

  // Track active month
  const [month, setMonth] = useState<number | undefined>(
    getCurrentMonthIndex()
  );

  // Gets called when a day is clicked
  const onDayClick = (day: Day) => {
    console.log(day);
  };

  const onNext = () => {
    if (activeMode === PersianCalendarMode.YEAR) {
      setYear((prev) => String(Number(prev) + 1));
    } else {
      const curretnMonth = month ?? getCurrentMonthIndex();
      if (curretnMonth + 1 > 12) {
        setMonth(() => 1);
        setYear((prev) => String(Number(prev) + 1));
      } else {
        setMonth((prev) => Number(prev) + 1);
      }
    }
  };

  const onPrevious = () => {
    if (activeMode === PersianCalendarMode.YEAR) {
      setYear((prev) => String(Number(prev) - 1));
    } else {
      const curretnMonth = month ?? getCurrentMonthIndex();
      if (curretnMonth - 1 < 1) {
        setMonth(() => 12);
        setYear((prev) => String(Number(prev) - 1));
      } else {
        setMonth((prev) => Number(prev) - 1);
      }
    }
  };

  const onToday = () => {
    setJYear(getCurrentYear());
    setMonth(getCurrentMonthIndex());
  };

  const onModeChange = (mode: PersianCalendarMode) => {
    setActiveMode(mode);
  };

  return (
    <PersianCalendar
      className="w-full h-full p-4"
      year={year}
      month={month}
      theme={theme}
      events={events}
      offDates={offDates}
      offDaysOfWeek={offDaysOfWeek}
      onDayClick={onDayClick}
      mode={activeMode}
      onModeChange={onModeChange}
      onNext={onNext}
      onPrevious={onPrevious}
      onToday={onToday}
    />
  );
}

export default App;

PersianCalendar Props

| Name | Type | Default | Required | Description | | ----------------------- | ------------------------------------- | ------------------------ | -------- | --------------------------------------------------------------------------- | | year | string | getCurrentYear() | Yes | Initial year to render. | | month | number | getCurrentMonthIndex() | No | Initial month index. | | mode | PersianCalendarMode | 'year' | No | Display mode of the calendar. | | theme | PersianCalendarTheme | defaultTheme | No | Custom theme object for styling the calendar. | | className | string | — | No | Custom class names for the root container. | | events | PersianCalendarEvent[] | [] | No | List of event objects to mark on the calendar. | | offDates | string[] | [] | No | List of off-day date strings. The format must be jYYYY/jMM/jDD (1404/02/01) | | offDaysOfWeek | number[] | [6] | No | Array of weekday indices to mark as off days (0 = Saturday, 6 = Friday). | | monthTitleFormat | string | "jMMMM" | No | Format string for month title display. | | hasNavbar | boolean | true | No | Whether to show the navbar header. | | hasModeSwitch | boolean | true | No | Whether to show the mode switch. | | gridColumnCount | 112 | 4 | No | Number of columns used in year view grid. | | showEventsOnDay | boolean | false | No | Whether to show the day events on day iteself or below it on year mode. | | multiEventsInDayColor | string | #f43f5e (accent) | No | The Color to use if a day has more than one event on year mode. | | onNext | () => void | — | No | Callback when navigating forward. | | onPrevious | () => void | — | No | Callback when navigating backward. | | onToday | () => void | — | No | Callback for jumping to current date. | | onModeChange | (mode: PersianCalendarMode) => void | — | No | Callback when view mode is toggled. | | onDayClick | (day: Day) => void | — | No | Callback when a day is clicked. |

PersianCalendarTheme

| Property | Type | Default Value | Required | | ------------------------- | ------ | -------------------- | -------- | | primary | string | "#6366f1" | No | | secondary | string | "#818cf8" | No | | accent | string | "#f43f5e" | No | | background | string | "#ffffff" | No | | textPrimary | string | "#1f2937" | No | | textSecondary | string | "#6b7280" | No | | borderColor | string | "#f3f4f6" | No | | disabledMonthBackground | string | "#e5e7eb" | No | | fontSize.header | string | "4rem" | No | | fontSize.subHeader | string | "3rem" | No | | fontSize.title | string | "1rem" | No | | fontSize.body | string | "0.875rem" | No | | fontSize.footer | string | "0.75rem" | No | | fontFamily | string | "monospace, Arial" | No | | colors.monthTitleColor | string | "#6366f1" | No | | colors.offDayColor | string | "#ef4444" | No | | colors.hoverColor | string | "#6366f1" | No |

PersianCalendarEvent

| Property | Type | Required | Description | | -------- | ------ | -------- | -------------------------------------- | | id | number | No | Optional unique ID of the event. | | title | string | No | Optional title of the event. | | date | string | Yes | Date of the event (e.g. "1404/02/05"). | | color | string | No | Optional hex color for the event dot. |

Day

| Property | Type | Required | Description | | ---------- | ---------------------- | -------- | ---------------------------------------------- | | id | string | Yes | Unique identifier, usually the formatted date. | | title | string | Yes | Display title for the day (e.g. "۱", "۲"). | | active | boolean | No | Whether this day is today. | | enabled | boolean | No | Whether this day is selectable. | | isOffDay | boolean | No | Whether this day is an off day. | | event | PersianCalendarEvent[] | No | Array of events assigned to this day. | | month | number | No | The month number this day belongs to. |

PersianCalendarMode

enum PersianCalendarMode {
  YEAR = "1",
  MONTH = "2",
}

License

The MIT License (MIT). Please see License File for more information.