Overview
The WeeklyCalendar component displays events in a week-long view with hourly time slots from 12 AM to 11 PM. It automatically handles overlapping events, displays a current time indicator, and supports custom scroll positioning. Perfect for applications requiring detailed time-based scheduling.
Import
import { WeeklyCalendar } from '@newtonschool/grauity' ;
import type { WeeklyCalendarProps , CalendarEvent } from '@newtonschool/grauity' ;
Basic Usage
import { WeeklyCalendar } from '@newtonschool/grauity' ;
import { useState } from 'react' ;
function MyWeeklyCalendar () {
const [ date , setDate ] = useState ( new Date ());
const events = [
{
title: 'Team Meeting' ,
start: new Date ( 2024 , 2 , 18 , 10 , 0 ),
end: new Date ( 2024 , 2 , 18 , 11 , 0 ),
},
{
title: 'Client Call' ,
start: new Date ( 2024 , 2 , 19 , 14 , 0 ),
end: new Date ( 2024 , 2 , 19 , 15 , 30 ),
},
];
return (
< WeeklyCalendar
events = { events }
date = { date }
onDateChange = { setDate }
/>
);
}
Props
events
CalendarEvent<T>[]
default: "[]"
Array of events to display in the calendar. Each event must have start and end dates.
eventRenderer
(item: CalendarEvent<T>) => React.ReactNode
Function to render each event. If not provided, events use the default rendering.
The date to show in the calendar. The calendar will display the week containing this date.
Callback fired when the date changes through week navigation controls. Receives the first day of the new week.
Whether to show week navigation controls (previous/next arrows and Today button).
Custom header content to display above the calendar.
Whether the calendar is in a loading state. Shows placeholder UI when true.
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. Takes precedence over defaultScrollHour.
Additional class name for the calendar wrapper element.
Deprecated Props
The following props are deprecated and will be removed in a future version. Use the recommended alternatives instead.
weekOffset
number
default: "undefined"
Deprecated: Use date prop instead.The offset for the week relative to the current week, where 0 represents the current week.
onWeekChange
(weekOffset: number) => void
Deprecated: Use onDateChange instead.Callback function called when the week changes.
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
}
Overlapping Events
The WeeklyCalendar automatically handles overlapping events by:
Detecting time conflicts between events
Calculating optimal width and positioning
Stacking events side-by-side when they overlap
const overlappingEvents = [
{
title: 'Event 1' ,
start: new Date ( 2024 , 2 , 18 , 11 , 0 ),
end: new Date ( 2024 , 2 , 18 , 13 , 0 ),
},
{
title: 'Event 2' ,
start: new Date ( 2024 , 2 , 18 , 12 , 0 ),
end: new Date ( 2024 , 2 , 18 , 14 , 0 ),
},
{
title: 'Event 3' ,
start: new Date ( 2024 , 2 , 18 , 13 , 0 ),
end: new Date ( 2024 , 2 , 18 , 15 , 0 ),
},
];
< WeeklyCalendar events = { overlappingEvents } />
Events that overlap will be displayed side-by-side with appropriate widths calculated automatically.
Custom Event Rendering
import { WeeklyCalendar , CalendarEvent } from '@newtonschool/grauity' ;
import CalendarEvent from '@newtonschool/grauity' ;
function CustomWeeklyCalendar () {
const events = [
{
title: 'Design Review' ,
start: new Date ( 2024 , 2 , 18 , 14 , 0 ),
end: new Date ( 2024 , 2 , 18 , 15 , 30 ),
focused: true ,
},
];
return (
< WeeklyCalendar
events = { events }
eventRenderer = { ( event ) => (
< CalendarEvent
title = { event . title }
start = { event . start }
end = { event . end }
focused = { event . focused }
chipContent = "Important"
backgroundColor = "var(--bg-emphasis-brand-default, #0673f9)"
textColor = "var(--text-emphasis-invert-primary-default, #ffffff)"
/>
) }
/>
);
}
Scroll Control
Scroll to specific hour
Scroll to first event
< WeeklyCalendar
defaultScrollHour = { 9 } // Scroll to 9:00 AM
shouldScrollToFirstEvent = { false }
events = { events }
/>
Week Navigation
Previous Week
Click the left arrow to navigate to the previous week. The calendar updates to show events for that week.
Next Week
Click the right arrow to navigate to the next week.
Today Button
Click “Today” to quickly return to the current week.
Current Time Indicator
The calendar displays a horizontal line showing the current time position. This indicator:
Updates every 5 minutes
Only appears on today’s date
Provides visual context for scheduling
Complete Example
import { WeeklyCalendar , CalendarEvent } from '@newtonschool/grauity' ;
import { useState } from 'react' ;
function ScheduleApp () {
const [ date , setDate ] = useState ( new Date ());
const currentYear = new Date (). getFullYear ();
const currentMonth = new Date (). getMonth ();
const currentDate = new Date (). getDate ();
const currentDay = new Date (). getDay ();
const weekStartDate = currentDate - currentDay ;
const events = [
{
title: 'Morning Standup' ,
start: new Date ( currentYear , currentMonth , weekStartDate + 1 , 9 , 0 ),
end: new Date ( currentYear , currentMonth , weekStartDate + 1 , 9 , 30 ),
},
{
title: 'Development Work' ,
start: new Date ( currentYear , currentMonth , weekStartDate + 1 , 10 , 0 ),
end: new Date ( currentYear , currentMonth , weekStartDate + 1 , 12 , 0 ),
},
{
title: 'Lunch Break' ,
start: new Date ( currentYear , currentMonth , weekStartDate + 1 , 12 , 0 ),
end: new Date ( currentYear , currentMonth , weekStartDate + 1 , 13 , 0 ),
},
{
title: 'Code Review' ,
start: new Date ( currentYear , currentMonth , weekStartDate + 3 , 14 , 0 ),
end: new Date ( currentYear , currentMonth , weekStartDate + 3 , 15 , 30 ),
},
];
return (
< div style = { { height: '100vh' } } >
< WeeklyCalendar
events = { events }
date = { date }
onDateChange = { ( newDate ) => {
console . log ( 'Week changed to:' , newDate );
setDate ( newDate );
} }
shouldShowWeekControls
defaultScrollHour = { 8 }
shouldScrollToFirstEvent
header = {
< div style = { { padding: '16px' , borderBottom: '1px solid #e1e5ea' } } >
< h2 > Weekly Schedule </ h2 >
</ div >
}
/>
</ div >
);
}
Multi-day Events
Events spanning multiple days are automatically handled:
const multiDayEvent = {
title: 'Conference' ,
start: new Date ( 2024 , 2 , 18 , 9 , 0 ),
end: new Date ( 2024 , 2 , 20 , 17 , 0 ), // Ends 2 days later
};
The calendar will:
Display the event on the start date
Truncate it at 11:59 PM of the start date
Store information about the full event duration
Accessibility
Full keyboard navigation support
ARIA labels on all interactive elements
Screen reader announcements for week changes
Focus management for events
Semantic HTML structure
The calendar uses tabIndex={0} on the timeline to enable keyboard scrolling for accessibility.
Performance Considerations
The calendar processes overlapping events efficiently using async operations. For weeks with hundreds of events, this ensures the UI remains responsive.
Scroll positioning uses scrollTo with behavior: 'auto' for instant positioning on mount, improving perceived performance.
The current time indicator updates every 5 minutes instead of every minute to reduce unnecessary re-renders.
TypeScript
The component supports generic typing for custom event data:
interface MeetingData {
attendees : string [];
room : string ;
isVirtual : boolean ;
}
const meetings : CalendarEvent < MeetingData >[] = [
{
title: 'Team Sync' ,
start: new Date ( 2024 , 2 , 18 , 10 , 0 ),
end: new Date ( 2024 , 2 , 18 , 11 , 0 ),
attendees: [ '[email protected] ' , '[email protected] ' ],
room: 'Conference Room A' ,
isVirtual: false ,
},
];
< WeeklyCalendar < MeetingData >
events = { meetings }
eventRenderer = { ( event ) => (
< div >
< div > { event . title } </ div >
< div > { event . room } </ div >
< div > { event . attendees . length } attendees </ div >
</ div >
) }
/>
Related Components
UnifiedCalendar Combined monthly and weekly calendar with view switching
MonthlyCalendar Traditional month grid view calendar