whensday-calendar-lib
v1.0.1
Published
A flexible calendar library with Whensday/Gregorian calendar systems, event management, and customizable UI components
Maintainers
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-libQuick 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 eventslayers?: Layer[]- Array of organizational layersschedules?: 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 clickedonEventAdd?: (date: DayInGrid, time?: string) => void- Called when adding a new eventonEventUpdate?: (event: Event) => void- Called when an event is updatedonEventDelete?: (eventId: string) => void- Called when an event is deletedonEventMove?: (eventId: string, newDayTimestamp: number, newStartTime?: string) => void- Called when an event is movedonDateClick?: (date: DayInGrid) => void- Called when a date is clickedonViewChange?: (view: CalendarView) => void- Called when the view changesonSystemChange?: (system: CalendarSystem) => void- Called when the calendar system changes
Customization Props
theme?: Partial<CalendarTheme>- Custom theme configurationclassName?: string- Additional CSS classesstyle?: 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.
