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

@thaparoyal/calendar-react

v2.0.0

Published

React components for AD and BS (Bikram Sambat) calendars

Downloads

241

Readme

@thaparoyal/calendar-react

React components and hooks for AD (Gregorian) and BS (Bikram Sambat/Nepali) calendars.

Installation

npm install @thaparoyal/calendar-react @thaparoyal/calendar-core

Features

  • Compound Components — shadcn/ui-style composable API for full layout control
  • React HooksuseCalendar, useDatePicker, useSelection, useDateConverter
  • AD & BS Calendars — Gregorian and Bikram Sambat support
  • Locale Support — English and Nepali (Devanagari numerals and month names)
  • Date Range — Single, range, and multiple selection
  • Multi-Calendar — Display multiple months simultaneously
  • Customisable — CSS variables, class overrides, and custom components
  • TypeScript — Complete type definitions

Components

| Component | Description | |-----------|-------------| | Calendar | Full calendar with compound sub-components | | DatePicker | Date picker with input and dropdown | | RangeCalendar | Calendar with range selection | | MultiCalendar | Multiple month calendar |

Usage

Basic Calendar

import { useState } from 'react';
import { Calendar, type CalendarDate } from '@thaparoyal/calendar-react';
import '@thaparoyal/calendar-react/styles.css';
import '@thaparoyal/calendar-core/themes/themes.css';

function MyCalendar() {
  const [date, setDate] = useState<CalendarDate | null>(null);

  return (
    <div data-theme="default">
      <Calendar.Root
        config={{ calendarType: 'BS', locale: 'en' }}
        value={date}
        onValueChange={setDate}
      >
        <Calendar.Header>
          <Calendar.PrevButton />
          <Calendar.Title />
          <Calendar.NextButton />
        </Calendar.Header>
        <Calendar.Grid>
          <Calendar.GridHead />
          <Calendar.GridBody />
        </Calendar.Grid>
      </Calendar.Root>
    </div>
  );
}

Nepali Locale

<Calendar.Root
  config={{ calendarType: 'BS', locale: 'ne' }}
  value={date}
  onValueChange={setDate}
>
  {/* Same sub-components — outputs Devanagari numerals and month names */}
</Calendar.Root>

DatePicker

import { DatePicker, type CalendarDate } from '@thaparoyal/calendar-react';
import '@thaparoyal/calendar-react/styles.css';

function MyDatePicker() {
  const [date, setDate] = useState<CalendarDate | null>(null);

  return (
    <DatePicker.Root
      config={{ calendarType: 'BS', locale: 'en' }}
      value={date}
      onValueChange={setDate}
    >
      <DatePicker.Input />
      <DatePicker.Trigger />
      <DatePicker.ClearButton />
      <DatePicker.Content>
        <DatePicker.Calendar />
      </DatePicker.Content>
    </DatePicker.Root>
  );
}

Range Calendar

import { RangeCalendar, type DateRangeValue } from '@thaparoyal/calendar-react';

function MyRangePicker() {
  const [range, setRange] = useState<DateRangeValue | null>(null);

  return (
    <RangeCalendar.Root
      config={{ calendarType: 'BS', locale: 'en' }}
      value={range}
      onValueChange={setRange}
    >
      <RangeCalendar.Header>
        <RangeCalendar.PrevButton />
        <RangeCalendar.Title />
        <RangeCalendar.NextButton />
      </RangeCalendar.Header>
      <RangeCalendar.Grid>
        <RangeCalendar.GridHead />
        <RangeCalendar.GridBody />
      </RangeCalendar.Grid>
    </RangeCalendar.Root>
  );
}

Multi-Calendar

import { MultiCalendar } from '@thaparoyal/calendar-react';

function MyMultiCalendar() {
  return (
    <MultiCalendar.Root
      config={{ calendarType: 'BS', locale: 'en' }}
      numberOfMonths={2}
    >
      <MultiCalendar.Header>
        <MultiCalendar.PrevButton />
        <MultiCalendar.Title />
        <MultiCalendar.NextButton />
      </MultiCalendar.Header>
      <MultiCalendar.Calendars />
    </MultiCalendar.Root>
  );
}

Hooks

useCalendar

import { useCalendar } from '@thaparoyal/calendar-react';

function MyCustomCalendar() {
  const { state, actions, weeks, title, weekdayNames } = useCalendar({
    config: { calendarType: 'BS', locale: 'en' },
    onValueChange: (date) => console.log('Selected:', date),
  });

  return (
    <div>
      <div>
        <button onClick={actions.prevMonth}>‹</button>
        <span>{title}</span>
        <button onClick={actions.nextMonth}>›</button>
      </div>
      {weeks.map((week, wi) => (
        <div key={wi}>
          {week.map((day, di) => (
            <button
              key={di}
              onClick={() => actions.selectDate(day.date)}
              disabled={day.isDisabled}
              style={{ fontWeight: day.isToday ? 'bold' : 'normal' }}
            >
              {day.date.day}
            </button>
          ))}
        </div>
      ))}
    </div>
  );
}

useDateConverter

import { useDateConverter } from '@thaparoyal/calendar-react';

function DateConverterExample() {
  const { adToBs, bsToAd, format } = useDateConverter();

  const bs = adToBs(new Date());
  const formatted = format(bs, 'YYYY MMMM DD', 'ne');

  return <p>आज: {formatted}</p>;
}

useSelection

import { useSelection } from '@thaparoyal/calendar-react';

function MultiSelectCalendar() {
  const { state, actions, weeks } = useSelection({
    config: { calendarType: 'BS', locale: 'en' },
    selectionMode: 'range',
    onValueChange: (value) => console.log('Range:', value),
  });

  return (/* render weeks */);
}

Month & Weekday Name Exports

import {
  BS_MONTHS_EN,        // ['Baisakh', 'Jestha', ...]
  BS_MONTHS_NP,        // ['बैशाख', 'जेठ', ...]
  BS_MONTHS_SHORT_EN,
  BS_MONTHS_SHORT_NP,
  WEEKDAYS_EN,         // ['Sunday', 'Monday', ...]
  WEEKDAYS_NP,         // ['आइतबार', 'सोमबार', ...]
  WEEKDAYS_SHORT_EN,
  WEEKDAYS_SHORT_NP,
  WEEKDAYS_MIN_EN,
  WEEKDAYS_MIN_NP,
  NEPALI_DIGITS,
  toNepaliNumeral,
  fromNepaliNumeral,
  getMonthName,
  getWeekdayName,
} from '@thaparoyal/calendar-react';

getMonthName(1, 'BS', 'ne');  // "बैशाख"
getWeekdayName(0, 'ne');      // "आइतबार"
toNepaliNumeral(2081);        // "२०८१"

Calendar Sub-Components

Calendar.*

| Sub-component | Description | |---------------|-------------| | Calendar.Root | Context root — provides state to all children | | Calendar.Header | Wrapper for navigation controls | | Calendar.Title | Displays current month and year | | Calendar.PrevButton | Navigate to previous month | | Calendar.NextButton | Navigate to next month | | Calendar.Grid | Table container for the calendar | | Calendar.GridHead | Weekday header row | | Calendar.GridBody | Calendar days grid | | Calendar.Row | Custom row slot | | Calendar.DayCell | Custom day cell slot | | Calendar.MonthPicker | Month selection picker | | Calendar.YearPicker | Year selection picker | | Calendar.MonthDropdown | Month dropdown selector | | Calendar.YearDropdown | Year dropdown selector |

DatePicker.*

| Sub-component | Description | |---------------|-------------| | DatePicker.Root | Context root with picker state | | DatePicker.Input | Text input for date entry | | DatePicker.Trigger | Button to open the calendar | | DatePicker.Content | Dropdown container | | DatePicker.Calendar | Embedded calendar | | DatePicker.ClearButton | Clear the selected date |


Props

Calendar.Root Props

interface CalendarRootProps {
  config?: Partial<CalendarConfig>;
  value?: CalendarDate | null;
  defaultValue?: CalendarDate;
  onValueChange?: (date: CalendarDate) => void;
  disabledDates?: CalendarDate[];
  className?: string;
}

CalendarConfig

interface CalendarConfig {
  calendarType: 'AD' | 'BS';
  locale: 'en' | 'ne';
  weekStartsOn: 0 | 1;       // 0 = Sunday, 1 = Monday
  minDate?: CalendarDate;
  maxDate?: CalendarDate;
}

CalendarDate

interface CalendarDate {
  year: number;
  month: number;   // 1-12
  day: number;     // 1-32 (BS months can be up to 32 days)
  calendarType: 'AD' | 'BS';
}

Styling

Default Styles

import '@thaparoyal/calendar-react/styles.css';

Themes

import '@thaparoyal/calendar-core/themes/themes.css';

Then set data-theme on a parent element:

<div data-theme="dark">
  <Calendar.Root ...>...</Calendar.Root>
</div>

Available themes: default, dark, forest, ocean, sunset, royal.

CSS Variables

Customise the look by overriding CSS variables:

:root {
  --trc-primary: #2563eb;
  --trc-primary-foreground: #ffffff;
  --trc-background: #ffffff;
  --trc-foreground: #1f2937;
  --trc-muted: #f3f4f6;
  --trc-muted-foreground: #6b7280;
  --trc-border: #e5e7eb;
  --trc-ring: #3b82f6;
  --trc-radius: 0.375rem;
}

Class Overrides

Pass classNames to override individual component classes:

<Calendar.Root
  classNames={{
    root: 'my-calendar',
    header: 'my-header',
    title: 'my-title font-bold text-lg',
    dayCell: (day) => day.isSelected ? 'bg-blue-500 text-white' : '',
  }}
>
  ...
</Calendar.Root>

Date Utilities

import {
  adToBs, bsToAd, formatDate, parseDate,
  getTodayBs, getTodayAd, isValidBsDate, isValidAdDate,
} from '@thaparoyal/calendar-react';

// All core utilities are re-exported for convenience
const today = getTodayBs();
const formatted = formatDate(today, 'YYYY MMMM DD', 'ne');

Supported Date Range

  • BS Calendar: 1970–2100 BS (1913–2043 AD)
  • AD Calendar: Full Gregorian calendar support

License

MIT