Skip to content

WeekCalendar

A weekly calendar view with hourly time slots for displaying and scheduling events.

import { WeekCalendar, type CalendarEvent, type CalendarLocale } from 'asterui'

Basic Calendar

Simple week calendar showing hourly time slots.

Sun
21
Mon
22
Tue
23
Wed
24
Thu
25
Fri
26
Sat
27
9am
10am
11am
12pm
1pm
2pm
3pm
4pm
5pm
import { WeekCalendar, Card } from 'asterui'

function App() {
  return (
      <Card className="h-[500px]" bodyClassName="overflow-hidden">
        <WeekCalendar date={new Date()} />
      </Card>
    )
}

export default App

With Events

Calendar displaying events at their scheduled times.

Sun
21
Mon
22
Tue
23
Wed
24
Thu
25
Fri
26
Sat
27
9am
Standup
10am
Sprint Planning
11am
12pm
Lunch Meeting
1pm
2pm
Design Review
3pm
Demo
4pm
Team Sync
5pm
import { WeekCalendar, Card, message, type CalendarEvent } from 'asterui'
import { useState } from 'react'

function App() {
  const [date] = useState(new Date())
  
  // Create events for this week
  const weekStart = new Date(date)
  weekStart.setDate(date.getDate() - date.getDay())
  
  const events: CalendarEvent[] = [
    { date: new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 1, 9, 0), title: 'Standup', color: '#3b82f6' },
    { date: new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 1, 14, 0), title: 'Design Review', color: '#8b5cf6' },
    { date: new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 2, 10, 0), title: 'Sprint Planning', color: '#10b981' },
    { date: new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 3, 12, 0), title: 'Lunch Meeting', color: '#f59e0b' },
    { date: new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 4, 15, 0), title: 'Demo', color: '#ef4444' },
    { date: new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 5, 16, 0), title: 'Team Sync', color: '#06b6d4' },
  ]
  
  return (
      <Card className="h-[500px]" bodyClassName="overflow-hidden">
        <WeekCalendar
          date={date}
          events={events}
          onEventClick={(event) => message.info(`Clicked: ${event.title}`)}
        />
      </Card>
    )
}

export default App

Slot Selection

Click on empty time slots to select them.

Sun
21
Mon
22
Tue
23
Wed
24
Thu
25
Fri
26
Sat
27
9am
10am
11am
12pm
1pm
2pm
3pm
4pm
5pm
import { WeekCalendar, Card, message } from 'asterui'
import { useState } from 'react'

function App() {
  const [date] = useState(new Date())
  
  return (
      <Card className="h-[500px]" bodyClassName="overflow-hidden">
        <WeekCalendar
          date={date}
          onSelectSlot={(slot) => message.info(`Selected: ${slot.start.toLocaleString()} - ${slot.end.toLocaleTimeString()}`)}
        />
      </Card>
    )
}

export default App

Strikethrough Events

Show cancelled events with strikethrough styling.

Sun
21
Mon
22
Tue
23
Wed
24
Thu
25
Fri
26
Sat
27
9am
10am
Cancelled Meeting
11am
12pm
Postponed
1pm
2pm
Active Event
3pm
4pm
5pm
import { WeekCalendar, Card, type CalendarEvent } from 'asterui'
import { useState } from 'react'

function App() {
  const [date] = useState(new Date())
  
  const weekStart = new Date(date)
  weekStart.setDate(date.getDate() - date.getDay())
  
  const events: CalendarEvent[] = [
    { date: new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 2, 10, 0), title: 'Cancelled Meeting', color: '#ef4444', strikethrough: true },
    { date: new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 2, 14, 0), title: 'Active Event', color: '#10b981' },
    { date: new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 4, 12, 0), title: 'Postponed', color: '#f59e0b', strikethrough: true },
  ]
  
  return (
      <Card className="h-[500px]" bodyClassName="overflow-hidden">
        <WeekCalendar
          date={date}
          events={events}
        />
      </Card>
    )
}

export default App

Custom Hours

Show only morning hours (6am-12pm) using startHour and endHour.

Sun
21
Mon
22
Tue
23
Wed
24
Thu
25
Fri
26
Sat
27
6am
Morning Run
7am
Early Sync
8am
Team Breakfast
9am
Standup
10am
Code Review
11am
12pm
import { WeekCalendar, Card, type CalendarEvent } from 'asterui'
import { useState } from 'react'

function App() {
  const [date] = useState(new Date())
  
  const weekStart = new Date(date)
  weekStart.setDate(date.getDate() - date.getDay())
  
  const events: CalendarEvent[] = [
    { date: new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 1, 6, 0), title: 'Morning Run', color: '#10b981' },
    { date: new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 2, 7, 0), title: 'Early Sync', color: '#8b5cf6' },
    { date: new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 3, 8, 0), title: 'Team Breakfast', color: '#f59e0b' },
    { date: new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 4, 9, 0), title: 'Standup', color: '#3b82f6' },
    { date: new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 5, 10, 0), title: 'Code Review', color: '#ef4444' },
  ]
  
  return (
      <Card className="h-[400px]" bodyClassName="overflow-hidden">
        <WeekCalendar
          date={date}
          events={events}
          startHour={6}
          endHour={12}
        />
      </Card>
    )
}

export default App

Allow Past Interaction

Enable clicking on past time slots.

Sun
21
Mon
22
Tue
23
Wed
24
Thu
25
Fri
26
Sat
27
9am
10am
11am
12pm
1pm
2pm
3pm
4pm
5pm
import { WeekCalendar, Card, message } from 'asterui'
import { useState } from 'react'

function App() {
  const [date] = useState(new Date())
  
  return (
      <Card className="h-[500px]" bodyClassName="overflow-hidden">
        <WeekCalendar
          date={date}
          allowPastInteraction
          onDayClick={(date) => message.info(`Day clicked: ${date.toLocaleDateString()}`)}
          onSelectSlot={(slot) => message.info(`Slot: ${slot.start.toLocaleTimeString()}`)}
        />
      </Card>
    )
}

export default App
PropertyDescriptionTypeDefault
dateThe date to display (determines which week is shown)Datenew Date()
eventsArray of calendar events to displayCalendarEvent[][]
startHourStart hour for the time grid (0-23)number9
endHourEnd hour for the time grid (0-23)number17
allowPastInteractionAllow clicking on past time slotsbooleanfalse
fitContainerFit rows to container height instead of scrollingbooleanfalse
localeLocale configuration for day names and time formatCalendarLocale-
onDayClickHandler when a day header is clicked(date: Date) => void-
onEventClickHandler when an event is clicked(event: CalendarEvent) => void-
onSelectSlotHandler when a time slot is clicked(slotInfo: { start: Date; end: Date }) => void-
data-testidTest ID for testingstring-
PropertyDescriptionTypeDefault
dateEvent date and time (hour determines which row)Date-
titleEvent titlestring-
colorEvent dot colorstring-
strikethroughShow event with strikethrough (cancelled)boolean-
styleCustom inline styles for the eventCSSProperties-
data-testidTest ID for testingstring-