@boemjay/pax-calendar
v1.2.2
Published
Modern responsive React Calendar with editable weekview
Readme
React Calendar Views
A modern React calendar component library that provides flexible week and day views with drag-and-drop event management.

Features
- 🗓️ Multiple Views: Choose between
WeekViewandDayViewcomponents - 🖱️ Drag & Drop: Intuitive drag-and-drop interface for event management
- ⚡ Responsive: Fully responsive design that works across all device sizes
- 💪 TypeScript: Built with TypeScript for enhanced code reliability
- 🌐 i18n Ready: Supports multiple languages through simple translation objects
Installation
- Install the package (using your favorite package manager):
npm install @boemjay/pax-calendar- Import the calendar styles in your main JavaScript file:
import "@boemjay/pax-calendar/dist/style.css";Usage
Week View Example:
import { CalendarWeekView } from "@boemjay/pax-calendar";
function App() {
return (
<CalendarWeekView
onChange={(events) => console.log("Calendar events:", events)}
/>
);
}Day View Example:
import { CalendarDayView } from "@boemjay/pax-calendar";
function App() {
return <CalendarDayView labels={{ clearSchedule: "Remove everything" }} />;
}Configuring Time Step Intervals
You can customize how events snap to time intervals using the dragStepMinutes prop:
import { CalendarWeekView } from "@boemjay/pax-calendar";
function App() {
// Events will snap to 5-minute intervals
return (
<CalendarWeekView
dragStepMinutes={5}
onChange={(events) => console.log(events)}
/>
);
}Examples:
dragStepMinutes={1}- 1-minute precision (highly granular)dragStepMinutes={5}- 5-minute intervalsdragStepMinutes={15}- 15-minute intervals (default)dragStepMinutes={30}- 30-minute intervalsdragStepMinutes={60}- 1-hour intervals
Component Props
Common Props
Both CalendarWeekView and CalendarDayView share these props:
| Name | Type | Default | Description |
| ------------------- | --------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| onChange | (events: Event[]) => void | - | Callback fired when calendar events change |
| value | Event[] | [] | Array of calendar events to display |
| labels | Partial<Translations> | - | Translations object for customizing text |
| dragStepMinutes | number | 15 | Time interval in minutes for snapping/magnetizing events when dragging. Supported values: 1, 5, 10, 15, 20, 30, 60 |
| modalPortalTarget | HTMLElement | document.body | DOM element where internal UI overlays (event edit modal and context menu) will be portaled. Useful when rendering the calendar inside UI frameworks that isolate or hide subtrees (e.g. Mantine Modal). Ensures nested modals remain visible and focusable. |
| modalZIndex | number | 101 | Optional z-index to control stacking of the event edit modal. Useful when calendar is inside another modal (e.g., Mantine Modal). |
Translations Interface
type Translations = {
clearSchedule: string;
defaultEventTitle: string;
editEventTitle: string;
editEventStartTime: string;
editEventEndTime: string;
cancel: string;
save: string;
edit: string;
delete: string;
// WeekView only
weekdays?: [string, string, string, string, string, string, string];
applyScheduleForWeek?: string;
tip?: string;
// DayView only
dayname?: string;
};Calendar Event Data Structure
Events use a minute-based time system for maximum flexibility:
type CalendarEvent = {
id: string;
title: string;
day: DayOfWeek; // "Monday" | "Tuesday" | ... | "Sunday"
start: number; // Minutes from midnight (0-1440)
end: number; // Minutes from midnight (0-1440)
draft: boolean;
};Time Format Examples:
start: 0= 12:00 AM (midnight)start: 480= 8:00 AMstart: 720= 12:00 PM (noon)start: 1080= 6:00 PMend: 1440= 12:00 AM next day (24:00)
Helper Functions:
import { formatTime, MIN_MINUTE, MAX_MINUTE } from "@boemjay/pax-calendar";
// Convert minutes to "HH:MM" format
formatTime(480); // "8:00"
formatTime(1080); // "18:00"
formatTime(1440, true); // "24:00"
// Valid time range
console.log(MIN_MINUTE); // 0
console.log(MAX_MINUTE); // 1440Migration Guide
Migrating from Quarter-Based to Minute-Based System
If you're upgrading from a version that used the quarter-based system (96 15-minute intervals per day), here's how to migrate:
Old System (Deprecated):
// Events were stored as quarters (0-96)
const event = {
start: 32, // 8:00 AM (32 quarters × 15 min)
end: 40, // 10:00 AM (40 quarters × 15 min)
};New System:
// Events are now stored as minutes (0-1440)
const event = {
start: 480, // 8:00 AM (480 minutes)
end: 600, // 10:00 AM (600 minutes)
};Conversion:
// Convert quarter values to minutes
const minutesFromQuarters = quarters * 15;
// Example:
const oldStart = 32; // quarters
const newStart = oldStart * 15; // 480 minutes (8:00 AM)Backwards Compatibility:
The library still exports deprecated MIN_QUARTER and MAX_QUARTER constants for compatibility, but these should not be used in new code. Use MIN_MINUTE and MAX_MINUTE instead.
🤝 Contributing
We welcome contributions! If you find a bug or have an idea for improvement, please open an issue or submit a pull request.
- Fork it
- Create your feature branch (
git checkout -b new-feature) - Commit your changes (
git commit -am 'Add feature') - Push to the branch (
git push origin new-feature) - Create a new Pull Request
📦 Publishing
For maintainers publishing new versions:
# 1. Update version in package.json
npm version patch # or minor/major
# 2. Build and publish to npm
npm run release
# Note: The 'release' script runs tsc, vite build, and npm publish automaticallyLicense
This project is licensed under the MIT License.
