Skip to content

Calendar ​

te-calendar shows events in a month grid or a week grid with hour lanes. Month and weekday names come from Intl, so there are no monthNames or days props to translate by hand — pass a locale and the header, the weekday row and the clock all follow it.

Usage ​

September 2026

Sun
Mon
Tue
Wed
Thu
Fri
Sat
30
31
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
1
2
3
vue
<te-calendar :events="events" />

An event is { start, end?, title?, type?, allDay? }. start and end take a Date or anything new Date() parses; end defaults to 30 minutes after start, and type is one of the shared variants, so an event chip is coloured like a te-badge.

js
const events = [
  { start: new Date(2024, 0, 15, 9), end: new Date(2024, 0, 15, 10), title: 'Standup' },
  { start: '2024-01-16T14:00', title: 'Retro', type: 'danger' },
  { start: new Date(2024, 0, 17), title: 'Offsite', allDay: true },
];

Week view ​

v-model:view switches between month and week, and the built-in toolbar already does it. The week body only draws the hours between dayStart and dayEnd; anything outside that window is clipped, so a calendar of working hours does not scroll through an empty night.

Aug 30 – Sep 5, 2026

Sun30
Mon31
Tue1
Wed2
Thu3
Fri4
Sat5
8 AM
9 AM
10 AM
11 AM
12 PM
1 PM
2 PM
3 PM
4 PM
5 PM
vue
<te-calendar v-model:view="view" :events="events" :day-start="8" :day-end="18" />

Events that share a time range split the column between them, and the split resets after a gap — three overlapping meetings are three thirds, and the next free hour goes back to full width. Events marked allDay move out of the hour grid into a row above it.

Moving events ​

editable turns on drag-and-drop. The component never mutates the events array: it emits move-event with the new start and end, and you decide whether to apply it, ask the server first, or refuse.

September 2026

Sun
Mon
Tue
Wed
Thu
Fri
Sat
30
31
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
1
2
3

Drag an event to another day or hour.

vue
<te-calendar :events="events" editable @move-event="onMove" />
js
function onMove({ event, index, start, end }) {
  events.value[index] = { ...events.value[index], start, end };
}

Dropping on a month cell keeps the time and changes only the date. Dropping in the week body sets the time too, snapped to snapMinutes (15 by default).

v-model is the date the grid is looking at — the month it shows in month view, the week containing it in week view. Leave it unbound and the calendar starts on today and manages its own position.

vue
<te-calendar v-model="focus" v-model:view="view" :events="events" />

Props ​

PropTypeDefaultDescription
modelValueDate | nullnullThe visible month or week. null means today.
view'month' | 'week''month'Use with v-model:view.
eventsCalendarEvent[][]
localestringbrowserPassed to Intl.
weekStartsOn0-600 is Sunday, 1 Monday.
dayStart / dayEndnumber7 / 21First and last hour of the week body.
hourHeightnumber48Pixel height of one hour.
bodyHeightstring'32rem'Max height before the week body scrolls.
maxPerDaynumber3Events per month cell before +N more.
snapMinutesnumber15Drop granularity in the week body.
hour12booleanlocaleForces 12- or 24-hour times.
editablebooleanfalseEnables drag-and-drop.
labelToday, labelMonth, labelWeek, labelAllDay, labelMore, labelPrev, labelNextstringEnglishToolbar and chrome copy.

Events ​

EventPayload
select-dateThe clicked Date. In the week body it carries the clicked time.
select-event(event, index) — the original object you passed in.
move-event{ event, index, start, end }

Slots ​

SlotPropsDescription
event{ event, view }Replaces an event chip.
day-header{ date, view }Replaces a weekday heading.
toolbar{ label, view, prev, next, today, showsToday, setView }Replaces the whole toolbar. showsToday is true while the visible range already contains today — the built-in toolbar uses it to disable its Today button.
September 2026
Sun
Mon
Tue
Wed
Thu
Fri
Sat
30
31
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
1
2
3

What it does not do ​

No resizing, no recurrence rules, no timezone conversion, and no day or year view. A multi-day event repeats in each day it covers rather than drawing one bar across the row. If you need those, use a dedicated calendar library — this one is a component, not a scheduling engine.