Skip to main content

Calendar

A responsive calendar component with container query support, hexagonal architecture, and seamless event management

Tags:
calendarinteractivecontainer-queriesresponsivehexagonal-architecture
Last updated: 2025-01-25T00:00:00.000Z

Calendar

The Calendar component provides a modern, responsive calendar interface with Month and Week views, event management capabilities, and viewport-based responsive behavior. Built with clean hexagonal architecture, it automatically adapts to different screen sizes - from mobile devices to desktop displays.

Full Calendar Display

Complete calendar interface with all features enabled and responsive container query behavior

December 2025
Sun
Mon
Tue
Wed
Thu
Fri
Sat
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
Today
Selected
Has Events
Usage Tips:
  • Navigate: Use header arrows or Month/Week toggle
  • Select dates: Click any date to trigger selection event
  • Manage events: Toggle events by clicking dates with indicators
  • View console: All interactions logged for development

Code

<Calendar
  initialEvents=Sun Sep 15 2024 00:00:00 GMT+0000 (Coordinated Universal Time)
  initialView="Month"
  ondateselect=function handleDateSelect(date) {
      logEvent("Date Selected", date);
    }
  oneventtoggle=function handleEventToggle(date) {
      logEvent("Event Toggled", date);
    }
/>

Core Features

Automatic Responsive Design

The calendar automatically adapts to different screen sizes using viewport-based responsive design. The interface seamlessly scales from mobile phones (320px) to large desktop displays (1200px+), with text sizes, spacing, and button dimensions adjusting proportionally.

Hexagonal Architecture

Built with domain-driven design principles:

  • Domain Layer: Pure business logic for date calculations and validations
  • Service Layer: Orchestrates calendar operations and state management
  • Repository Layer: Handles data persistence and retrieval
  • Component Layer: Presentation logic with clean separation of concerns

Dual View Support

  • Month View: Traditional calendar grid with full month visibility
  • Week View: Focused weekly layout for detailed scheduling

API Reference

Props

PropTypeDefaultDescription
initialDateDatenew Date()Starting date for calendar display
initialEventsDate[][]Array of dates with existing events
initialViewCalendarView'Month'Starting view mode (‘Month’ | ‘Week’)

Event Callbacks

EventTypeDescription
ondateselect(date: Date) => voidFired when a date is selected
oneventadd(date: Date) => voidFired when an event is added to a date
oneventremove(date: Date) => voidFired when an event is removed from date
oneventtoggle(date: Date) => voidFired when an event is toggled on date
onmonthchange(date: Date) => voidFired when month navigation occurs
onviewchange(view: CalendarView) => voidFired when view mode changes

Design Philosophy

Responsive Design Benefits

The viewport-based responsive design ensures the calendar:

  • Works consistently across all devices and screen sizes
  • Scales intelligently with fluid text sizing using clamp() functions
  • Maintains readability with appropriate text sizes for each breakpoint
  • Adapts automatically without requiring manual configuration

Event-Driven Architecture

All calendar interactions emit events rather than managing state internally:

  • Flexible integration with any state management solution
  • Predictable behavior through explicit event handling
  • Easy testing via event mocking and verification
  • Clean separation between UI and business logic

Usage Examples

Basic Implementation

<script>
import Calendar from '$lib/calendar/components/Calendar.svelte';

function handleDateSelect(date) {
  console.log('Selected:', date);
}

function handleEventToggle(date) {
  // Add your event logic here
}
</script>

<Calendar
  initialEvents={[new Date(2024, 8, 15)]}
  ondateselect={handleDateSelect}
  oneventtoggle={handleEventToggle}
/>

Full Event Handling

<script>
import Calendar from '$lib/calendar/components/Calendar.svelte';

let events = [
  new Date(2024, 8, 15),
  new Date(2024, 8, 22)
];

function handleEventAdd(date) {
  events = [...events, date];
}

function handleEventRemove(date) {
  events = events.filter(e => e.getTime() !== date.getTime());
}

function handleMonthChange(date) {
  console.log('Navigated to:', date.toLocaleDateString());
}

function handleViewChange(view) {
  console.log('Changed to:', view);
}
</script>

<Calendar
  initialEvents={events}
  oneventadd={handleEventAdd}
  oneventremove={handleEventRemove}
  onmonthchange={handleMonthChange}
  onviewchange={handleViewChange}
/>

Constrained Container

<div style="max-width: 400px; margin: 0 auto;">
  <Calendar initialView="Week" />
</div>

Best Practices

When to Use

  • Event scheduling interfaces requiring date selection
  • Dashboard widgets showing calendar data in constrained spaces
  • Booking systems with availability visualization
  • Content management with publication date selection
  • Any interface requiring responsive calendar behavior

Integration Patterns

  1. State Management: Use event callbacks to integrate with your state solution
  2. Data Persistence: Connect event handlers to your backend API
  3. Styling: Calendar inherits design system tokens automatically
  4. Accessibility: Built-in keyboard navigation and ARIA support

Performance Considerations

  • Lightweight rendering: Only visible dates are rendered
  • Efficient calculations: Domain layer uses optimized date algorithms
  • Memory management: Repository pattern handles data lifecycle
  • Container queries: No JavaScript resize listeners needed

Accessibility

  • Keyboard Navigation: Full arrow key and tab navigation support
  • Screen Reader Support: Proper ARIA labels and announcements
  • Focus Management: Visible focus indicators and logical tab order
  • Date Formatting: Localized date display and announcements

Architecture Benefits

The hexagonal architecture provides several advantages:

  • Testability: Pure domain functions are easily unit tested
  • Flexibility: Easy to swap data sources via repository pattern
  • Maintainability: Clear separation of concerns reduces complexity
  • Extensibility: New features can be added without breaking existing code

Performance

  • Bundle Size: Minimal JavaScript footprint with tree-shaking support
  • Runtime Performance: Optimized date calculations and DOM updates
  • CSS Performance: Container queries provide native responsive behavior
  • Memory Usage: Efficient data structures prevent memory leaks