Overview
The UnifiedCalendar component provides a complete calendar solution that combines both monthly and weekly views in a single interface. It includes built-in view switching controls, navigation, and event rendering capabilities, making it ideal for applications that need to display events in multiple calendar formats.
Import
import { UnifiedCalendar } from '@newtonschool/grauity' ;
import type { UnifiedCalendarProps , CalendarEvent } from '@newtonschool/grauity' ;
Basic Usage
import { UnifiedCalendar } from '@newtonschool/grauity' ;
import { useState } from 'react' ;
function MyCalendar () {
const [ date , setDate ] = useState ( new Date ());
const [ view , setView ] = useState ( 'monthly' );
const events = [
{
id: '1' ,
title: 'Team Meeting' ,
start: new Date ( 2024 , 2 , 15 , 10 , 0 ),
end: new Date ( 2024 , 2 , 15 , 11 , 0 ),
},
{
id: '2' ,
title: 'Project Review' ,
start: new Date ( 2024 , 2 , 20 , 14 , 0 ),
end: new Date ( 2024 , 2 , 20 , 15 , 30 ),
},
];
return (
< UnifiedCalendar
date = { date }
onDateChange = { setDate }
view = { view }
onViewChange = { setView }
events = { events }
eventRenderer = { ( event , view ) => (
< div >
{ event . title }
</ div >
) }
/>
);
}
Props
events
CalendarEvent<T>[]
required
Array of events to display in the calendar. Each event must have start and end dates.
eventRenderer
(item: CalendarEvent<T>, view: CalendarView) => React.ReactNode
required
Function to render each event. Receives the event data and current view type (‘monthly’ or ‘weekly’) as parameters.
The date for which the calendar should render events.
view
'monthly' | 'weekly'
default: "'weekly'"
Calendar view to display. Controls whether the calendar shows the monthly or weekly layout.
onViewChange
(viewType: CalendarView) => void
Callback fired when the user switches between monthly and weekly views.
Callback fired when the date changes through navigation controls.
Whether to show view switching tabs and navigation controls in the header.
Custom header content to display above the calendar controls.
Whether the calendar is in a loading state. Shows placeholder UI when true.
Additional class name for the calendar wrapper element.
Weekly Calendar Props
Configuration options specific to the weekly calendar view. The time in hours (24-hour format) to show at the top initially. Default is 8.5 (8:30 AM).
Whether to automatically scroll to the first event when the calendar loads.
Monthly Calendar Props
Configuration options specific to the monthly calendar view. renderDayItem
(item: CalendarEvent<T>, view: CalendarView) => React.ReactNode
Optional alternative render function for day items in the monthly view.
Callback to run when the overflow events popover closes.
Event Data Structure
The CalendarEvent interface defines the structure for calendar events:
interface CalendarEvent < T = {}> {
id ?: string | number ;
title ?: string ;
start : Date ; // Required: Event start time
end : Date ; // Required: Event end time
allDay ?: boolean ;
render ?: ( event : CalendarEvent < T >) => React . ReactNode ;
focused ?: boolean ; // Highlights the event
}
Complete Example with Custom Event Rendering
import { UnifiedCalendar } from '@newtonschool/grauity' ;
import MonthlyCalendarEventItem from '@newtonschool/grauity' ;
import { useState } from 'react' ;
function CalendarApp () {
const [ date , setDate ] = useState ( new Date ());
const [ view , setView ] = useState ( 'monthly' );
const events = [
{
id: '1' ,
title: 'Morning Meeting' ,
start: new Date ( 2024 , 2 , 7 , 9 , 0 ),
end: new Date ( 2024 , 2 , 7 , 10 , 30 ),
},
{
id: '2' ,
title: 'Team Lunch' ,
start: new Date ( 2024 , 2 , 7 , 12 , 0 ),
end: new Date ( 2024 , 2 , 7 , 13 , 0 ),
},
{
id: '3' ,
title: 'Project Review' ,
start: new Date ( 2024 , 2 , 10 , 11 , 0 ),
end: new Date ( 2024 , 2 , 10 , 12 , 30 ),
},
];
return (
< div style = { { height: '100vh' } } >
< UnifiedCalendar
date = { date }
onDateChange = { setDate }
view = { view }
onViewChange = { setView }
events = { events }
eventRenderer = { ( event , viewType ) => (
< MonthlyCalendarEventItem
key = { event . id }
eventTime = { event . start }
eventTitle = { event . title }
eventTitleColor = "var(--text-emphasis-invert-primary-default, #ffffff)"
eventTimeColor = "var(--text-emphasis-invert-primary-default, #ffffff)"
backgroundColor = "var(--bg-emphasis-brand-default, #0673f9)"
height = "50px"
/>
) }
shouldShowControls
weeklyCalendarProps = { {
defaultScrollHour: 8 ,
shouldScrollToFirstEvent: true ,
} }
monthlyCalendarProps = { {
onPopOverClose : () => console . log ( 'Popover closed' ),
} }
/>
</ div >
);
}
View Switching
The UnifiedCalendar automatically handles view transitions:
User clicks view tab
The header displays “Monthly” and “Weekly” tabs when shouldShowControls is true.
View state updates
The onViewChange callback fires with the new view type.
Calendar re-renders
The appropriate calendar component (Monthly or Weekly) renders with the same events and date.
You can add custom content above the calendar controls:
< UnifiedCalendar
header = {
< div style = { { padding: '16px' } } >
< h2 > Team Schedule </ h2 >
< p > View and manage team events </ p >
</ div >
}
// ... other props
/>
Loading State
< UnifiedCalendar
loading = { true }
events = { [] }
// ... other props
/>
When loading is true, the calendar displays placeholder elements instead of actual events.
Accessibility
The calendar wrapper has appropriate ARIA labels describing the current view
Navigation buttons include descriptive aria-label attributes
Keyboard navigation is fully supported
All interactive elements are keyboard accessible
Best Practices
Keep event data in a state management solution when dealing with large datasets. The calendar efficiently handles hundreds of events, but consider pagination for very large collections.
Store the user’s preferred view in localStorage or your backend to maintain consistency across sessions.
Always keep the date prop synchronized with your application state to ensure the calendar displays the correct time period.
Event Renderer Performance
Memoize your event renderer function if it performs expensive computations to avoid unnecessary re-renders.
TypeScript
The component is fully typed with generic support for custom event data:
interface CustomEventData {
priority : 'high' | 'medium' | 'low' ;
attendees : string [];
}
const events : CalendarEvent < CustomEventData >[] = [
{
id: '1' ,
title: 'Meeting' ,
start: new Date (),
end: new Date (),
priority: 'high' ,
attendees: [ '[email protected] ' , '[email protected] ' ],
},
];
< UnifiedCalendar < CustomEventData >
events = { events }
eventRenderer = { ( event ) => (
< div >
{ event . title } - Priority: { event . priority }
</ div >
) }
// ... other props
/>
Related Components
WeeklyCalendar Week-based calendar view with time slots
MonthlyCalendar Month-based calendar grid view