Interactive Demo
Click on any event to view its detailed information including location, attendees, priority, and conference links. All data is type-safe using TypeScript generics.
Immediate updates - drag or resize events for instant changes
Implementation Guide
1. Define Your Data Interface
Create a TypeScript interface for your custom event data. This ensures type safety and autocomplete support throughout your application.
// Define your custom data interface
interface MeetingData {
location: string;
attendees: string[];
description: string;
priority: "low" | "medium" | "high";
conferenceLink?: string;
organizer: string;
}
// Use CalendarEvent with generic type
type CalendarEventWithData = {
title: string;
start: Date;
end: Date;
allDay?: boolean;
variant?: "primary" | "secondary" | "outline";
data: MeetingData; // Type-safe custom data
};2. Create Events with Custom Data
Populate your events array with the custom data. All properties are type-checked by TypeScript.
const events: CalendarEventWithData[] = [
{
title: "Product Review Meeting",
start: new Date(2024, 0, 15, 10, 0),
end: new Date(2024, 0, 15, 11, 0),
variant: "primary",
data: {
location: "Conference Room A",
attendees: ["Sarah Chen", "Mike Johnson"],
description: "Quarterly product review",
priority: "high",
conferenceLink: "https://meet.example.com/review",
organizer: "Sarah Chen",
},
},
];3. Handle Event Selection
Use the onSelectEvent callback to capture when users click on events and display the custom data.
const handleSelectEvent = (event: CalendarEventWithData) => {
setSelectedEvent(event);
setModalOpen(true);
};
<ShadcnBigCalendar
localizer={localizer}
events={events}
onSelectEvent={handleSelectEvent}
// ... other props
/>4. Display Data in Modal
Create a modal dialog to show the event details. Access custom data via the event.data property.
<Dialog open={modalOpen} onOpenChange={setModalOpen}>
<DialogContent className="max-w-2xl">
<DialogHeader>
<DialogTitle>{selectedEvent?.title}</DialogTitle>
<DialogDescription>
{formatDate(selectedEvent?.start)} at {formatTime(selectedEvent?.start)}
</DialogDescription>
</DialogHeader>
<div className="space-y-4">
{/* Location */}
<div className="flex gap-3">
<MapPin className="h-5 w-5 text-muted-foreground" />
<div>
<p className="font-medium">Location</p>
<p className="text-sm text-muted-foreground">
{selectedEvent?.data?.location}
</p>
</div>
</div>
{/* Attendees */}
<div className="flex gap-3">
<Users className="h-5 w-5 text-muted-foreground" />
<div>
<p className="font-medium">Attendees ({selectedEvent?.data?.attendees.length})</p>
<p className="text-sm text-muted-foreground">
{selectedEvent?.data?.attendees.join(", ")}
</p>
</div>
</div>
{/* Conference Link */}
{selectedEvent?.data?.conferenceLink && (
<Button asChild variant="outline" className="w-full">
<a href={selectedEvent.data.conferenceLink} target="_blank" rel="noreferrer">
<Video className="mr-2 h-4 w-4" />
Join Meeting
</a>
</Button>
)}
</div>
</DialogContent>
</Dialog>Benefits
Type Safety
TypeScript generics ensure your custom data is type-safe with autocomplete support.
Flexible Schema
Define any data structure you need - from simple strings to complex nested objects.
Rich Context
Store meeting links, attendees, locations, priorities, and any other metadata.
Maintainable Code
Clear interfaces make it easy to understand and modify your event data structure.
Use Cases
Meeting Scheduler
Store conference links, attendee lists, meeting rooms, and agenda items for each meeting.
Project Management
Track task assignees, priority levels, project IDs, and completion status for project milestones.
Resource Booking
Manage room reservations, equipment bookings, and capacity limits with detailed resource information.
Healthcare Appointments
Store patient information, doctor details, appointment types, and medical notes securely.