Calendar Units Package
The @usetemporal/calendar-units package provides specialized time units designed for calendar user interfaces, following useTemporal's philosophy of keeping the core minimal while offering powerful extensions.
Overview
While useTemporal's core provides fundamental time operations, calendar UIs often need specialized behavior. The calendar-units package addresses these needs without bloating the core library.
Installation
npm install @usetemporal/calendar-units @usetemporal/coreAvailable Units
stableMonth
The stableMonth unit always returns a 42-day (6-week) period, ensuring calendar grids maintain consistent height regardless of the actual month length.
import { createTemporal, period, divide } from '@usetemporal/core';
import { createNativeAdapter } from '@usetemporal/core/native';
import '@usetemporal/calendar-units'; // Registers units
const temporal = createTemporal({
adapter: createNativeAdapter({ weekStartsOn: 1 }), // Monday
});
const stableMonth = period(temporal, 'stableMonth', temporal.browsing.value);
const days = divide(temporal, stableMonth, 'day');
console.log(days.length); // Always 42Why Use Calendar Units?
Consistent Layouts
Regular months vary from 28-31 days and can span 4-6 weeks when displayed in a grid. This causes:
- Layout shifts when navigating between months
- Complex CSS calculations
- Poor user experience with jumping content
Better Performance
With a fixed 42-day grid:
- Predictable memory allocation
- Cacheable layouts
- Optimized rendering
Simplified Development
- No edge case handling for different month lengths
- Consistent styling rules
- Easier responsive design
Integration with Core
Calendar units integrate seamlessly with all useTemporal operations:
// Navigation
const nextMonth = next(temporal, temporal.browsing.value);
const nextStable = period(temporal, 'stableMonth', nextMonth);
// Division
const weeks = divide(temporal, stableMonth, 'week'); // Always 6 weeks
const days = divide(temporal, stableMonth, 'day'); // Always 42 days
// Comparison
const isInGrid = contains(stableMonth, someDayPeriod);Examples
Basic Calendar Grid
function createCalendarGrid(date: Date) {
const temporal = createTemporal({
adapter: createNativeAdapter(),
weekStartsOn: 1,
date,
});
const stableMonth = period(temporal, 'stableMonth', temporal.browsing.value);
const weeks = divide(temporal, stableMonth, 'week');
return weeks.map(week => divide(temporal, week, 'day'));
}Identifying Current Month Days
const currentMonth = temporal.browsing.value.date.getMonth();
const days = divide(temporal, stableMonth, 'day');
const currentMonthDays = days.filter(day =>
day.date.getMonth() === currentMonth
);
const paddingDays = days.filter(day =>
day.date.getMonth() !== currentMonth
);Migration Guide
If you're currently using manual stable month implementations, see our migration guide for step-by-step instructions.
Performance Considerations
- Generation: O(1) - Fixed 42 iterations
- Memory: ~8.4KB for full day grid
- Caching: Results are cacheable by month/year key
See the performance guide for optimization strategies.
TypeScript Support
Full TypeScript support with automatic type augmentation:
// Automatically registered when imported
import '@usetemporal/calendar-units';
// TypeScript knows about the new unit
const period = period(temporal, 'stableMonth', browsing);Future Units
The calendar-units package sets the foundation for additional calendar-specific units:
businessWeek- 5-day business weeksfiscalQuarter- Company fiscal quartersacademicSemester- School calendar periods