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

whensday-calendar-lib

v1.0.1

Published

A flexible calendar library with Whensday/Gregorian calendar systems, event management, and customizable UI components

Readme

Whensday Calendar Library

A flexible React calendar library with support for both Whensday and Gregorian calendar systems, featuring event management, schedule tracking, and customizable UI components.

Features

  • Dual Calendar Systems: Switch between Whensday and Gregorian calendars
  • Multiple Views: Month, Week, and Day views
  • Event Management: Add, edit, move, and delete events with drag-and-drop support
  • Schedule Management: Create recurring schedules with on/off patterns
  • Holiday Booking: Built-in holiday tracking and booking system
  • Layer Organization: Organize events and schedules into color-coded layers
  • Customizable Themes: Fully customizable styling with CSS variables
  • TypeScript Support: Full TypeScript definitions included

Installation

npm install whensday-calendar-lib

Quick Start

import React from 'react';
import { Calendar } from '@whensday/calendar-lib';

function App() {
  const [events, setEvents] = React.useState([]);
  const [layers, setLayers] = React.useState([]);
  const [schedules, setSchedules] = React.useState([]);

  const handleEventClick = (event) => {
    console.log('Event clicked:', event);
  };

  const handleEventAdd = (date, time) => {
    console.log('Add event on:', date, 'at:', time);
  };

  return (
    <Calendar
      events={events}
      layers={layers}
      schedules={schedules}
      onEventClick={handleEventClick}
      onEventAdd={handleEventAdd}
      theme={{
        colors: {
          primary: '#3b82f6',
          accent: '#f59e0b',
          background: '#111827',
          surface: '#1f2937',
          text: '#f9fafb',
        }
      }}
    />
  );
}

API Reference

Calendar Component

The main Calendar component accepts the following props:

Data Props

  • events?: Event[] - Array of calendar events
  • layers?: Layer[] - Array of organizational layers
  • schedules?: Schedule[] - Array of recurring schedules

State Props

  • view?: CalendarView - Current view ('month' | 'week' | 'day')
  • system?: CalendarSystem - Calendar system ('whensday' | 'gregorian')
  • displayDate?: DayInGrid - Currently displayed date

Event Handlers

  • onEventClick?: (event: Event) => void - Called when an event is clicked
  • onEventAdd?: (date: DayInGrid, time?: string) => void - Called when adding a new event
  • onEventUpdate?: (event: Event) => void - Called when an event is updated
  • onEventDelete?: (eventId: string) => void - Called when an event is deleted
  • onEventMove?: (eventId: string, newDayTimestamp: number, newStartTime?: string) => void - Called when an event is moved
  • onDateClick?: (date: DayInGrid) => void - Called when a date is clicked
  • onViewChange?: (view: CalendarView) => void - Called when the view changes
  • onSystemChange?: (system: CalendarSystem) => void - Called when the calendar system changes

Customization Props

  • theme?: Partial<CalendarTheme> - Custom theme configuration
  • className?: string - Additional CSS classes
  • style?: React.CSSProperties - Additional inline styles

Feature Flags

  • enableDragAndDrop?: boolean - Enable drag-and-drop functionality (default: true)
  • enableScheduleManagement?: boolean - Enable schedule features (default: true)
  • enableHolidayBooking?: boolean - Enable holiday booking (default: true)
  • enableTravelTime?: boolean - Enable travel time calculations (default: true)
  • enableRecurringEvents?: boolean - Enable recurring events (default: true)

Display Options

  • showWeekNumbers?: boolean - Show week numbers (default: false)
  • showTodayIndicator?: boolean - Show today indicator (default: true)
  • showHolidayIndicators?: boolean - Show holiday indicators (default: true)
  • showScheduleIndicators?: boolean - Show schedule indicators (default: true)

Types

Event

interface Event {
  id: string;
  name: string;
  layerId: string | null;
  color?: string;
  startDate: number; // UTC timestamp
  endDate?: number; // UTC timestamp
  eventType: 'event' | 'deadline' | 'task' | 'birthday';
  isAllDay: boolean;
  location?: LocationDetails | null;
  startLocation?: LocationDetails | null;
  endLocation?: LocationDetails | null;
  isCompleted?: boolean;
  tags?: string[];
  startTime?: string; // "HH:MM" format
  endTime?: string; // "HH:MM" format
  travelTimeBefore?: number; // minutes
  travelTimeAfter?: number; // minutes
  doByDate?: number; // UTC timestamp
  doByTime?: string; // "HH:MM" format
  dueTime?: string; // "HH:MM" format
  duePeriod?: 'morning' | 'afternoon' | 'evening';
  isRecurring?: boolean;
  naturalLanguageRule?: string;
  recurrenceRule?: string;
}

Layer

interface Layer {
  id: string;
  name: string;
  color: string; // Hex color
  isVisible: boolean;
  parentId?: string;
}

Schedule

interface Schedule {
  id: string;
  name: string;
  layerId: string | null;
  color: string | null;
  startDate: number; // UTC timestamp
  endDate?: number; // UTC timestamp
  pattern: {
    on: number;
    off: number;
  };
  isVisible: boolean;
  initialHolidayBalance?: number;
  bookedHolidays?: number[]; // UTC timestamps
  completedDays?: number[]; // UTC timestamps
  holidaySettings?: HolidaySettings;
  exemptions?: ScheduleExemption[];
  bonusDays?: number[]; // UTC timestamps
}

Utilities

The library provides several utility functions for working with dates:

import {
  gregorianToWhensday,
  whensdayToGregorian,
  dayInGridToDate,
  areUniversalDaysEqual,
  formatUniversalDate,
} from '@whensday/calendar-lib';

// Convert between calendar systems
const whensdayDate = gregorianToWhensday(new Date());
const gregorianDate = whensdayToGregorian(whensdayDate);

// Work with universal dates
const dayInGrid = { year: 2024, month: 0, day: 1, monthName: 'January' };
const date = dayInGridToDate(dayInGrid, 'gregorian');
const formatted = formatUniversalDate(date.getTime(), 'gregorian');

Hooks

useCalendar

A custom hook for managing calendar state:

import { useCalendar } from '@whensday/calendar-lib';

const {
  view,
  system,
  displayDate,
  calendarGrid,
  currentMonthName,
  currentYear,
  goToNextPeriod,
  goToPrevPeriod,
  goToToday,
  goToDate,
  toggleSystem,
  useScheduleCalculations,
} = useCalendar('month', 'gregorian');

Styling

The library uses CSS variables for theming. You can customize the appearance by overriding these variables:

.whensday-calendar {
  --calendar-primary: #3b82f6;
  --calendar-secondary: #6b7280;
  --calendar-accent: #f59e0b;
  --calendar-background: #111827;
  --calendar-surface: #1f2937;
  --calendar-text: #f9fafb;
  --calendar-text-secondary: #9ca3af;
  --calendar-border: #374151;
  --calendar-today: #f59e0b;
  --calendar-whensday-leap: #ec4899;
  
  --calendar-font-primary: 'Inter, system-ui, sans-serif';
  --calendar-font-secondary: 'Bangers, cursive';
  
  --calendar-spacing-xs: 0.25rem;
  --calendar-spacing-sm: 0.5rem;
  --calendar-spacing-md: 1rem;
  --calendar-spacing-lg: 1.5rem;
  --calendar-spacing-xl: 2rem;
  
  --calendar-border-radius-sm: 0.25rem;
  --calendar-border-radius-md: 0.5rem;
  --calendar-border-radius-lg: 0.75rem;
}

Whensday Calendar System

The Whensday calendar is an alternative calendar system with the following characteristics:

  • 13 months: 12 regular months of 28 days each, plus a 13th month (Sol) of 14-15 days
  • Leap day: The 15th day of Sol month in leap years is called "Whensday"
  • Year start: The Whensday year begins on March 1st of the Gregorian calendar
  • Consistent weeks: Each month starts on the same day of the week

Examples

Basic Calendar

<Calendar
  events={[
    {
      id: '1',
      name: 'Team Meeting',
      layerId: 'work',
      startDate: new Date('2024-01-15T10:00:00Z').getTime(),
      endDate: new Date('2024-01-15T11:00:00Z').getTime(),
      eventType: 'event',
      isAllDay: false,
      startTime: '10:00',
      endTime: '11:00',
    }
  ]}
  layers={[
    {
      id: 'work',
      name: 'Work',
      color: '#3b82f6',
      isVisible: true,
    }
  ]}
  onEventClick={(event) => console.log('Event clicked:', event)}
/>

Custom Theme

<Calendar
  theme={{
    colors: {
      primary: '#8b5cf6',
      accent: '#f59e0b',
      background: '#0f172a',
      surface: '#1e293b',
      text: '#f8fafc',
      textSecondary: '#cbd5e1',
      border: '#334155',
      today: '#f59e0b',
      whensdayLeap: '#ec4899',
    },
    fonts: {
      primary: 'Inter, system-ui, sans-serif',
      secondary: 'Bangers, cursive',
    },
    spacing: {
      xs: '0.25rem',
      sm: '0.5rem',
      md: '1rem',
      lg: '1.5rem',
      xl: '2rem',
    },
    borderRadius: {
      sm: '0.25rem',
      md: '0.5rem',
      lg: '0.75rem',
    },
  }}
/>

Schedule Management

<Calendar
  schedules={[
    {
      id: 'work-schedule',
      name: 'Work Schedule',
      layerId: 'work',
      startDate: new Date('2024-01-01T00:00:00Z').getTime(),
      pattern: { on: 5, off: 2 }, // 5 days on, 2 days off
      isVisible: true,
      holidaySettings: {
        enabled: true,
        onDays: 5,
        holidays: 25,
        bonusDayRate: 0.2,
      },
    }
  ]}
  enableScheduleManagement={true}
  enableHolidayBooking={true}
/>

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details.