Skip to content

Installing

npm install time-blocks-vue

Basic usage

vue
<template>
    <EventCalendar :events="events" />
</template>

<script setup lang='ts'>
import { EventCalendar } from 'time-blocks-vue'
import { ref } from 'vue';

let startDate = new Date();
let endDate = new Date();
endDate.setMinutes(startDate.getMinutes() + 15);

const events = ref([{
    id: "1234",
    description: "Event description",
    color: "blue",
    startDate: startDate,
    endDate: endDate,
}]);
</script>

<style>
@import "time-blocks-vue/style.css";
</style>

TIP

The event calendar will try to fill it's parent's dimensions, so best practice is to put it in a wrapper element with a fixed height.

Props

NameTypeRequiredDefaultPurpose
eventsCalendarEvent[]YesArray of events to be displayed.
dateDateNoThe current date displayed by the calendar.
mode"week" | "day"NoDisplay mode of the calendar (week or day view).
interval-heightnumberNo20Height of each time interval in pixels.
interval-minutesnumberNo15Duration in minutes of each interval.
hide-weekendsbooleanNofalseWhether to hide weekends on the calendar.
no-headerbooleanNofalseIf true, the calendar header will be hidden.
dark-modebooleanNotrueEnables dark mode for the calendar.
scroll-to-hournumberNo5.5Default hour to scroll to on calendar load.
concurrency-mode"stack" | "split"No"stack"How overlapping events are displayed.
hours-past-midnightnumberNo4Number of hours past midnight shown.
default-event-propertiesPartial<CalendarEvent>NoDefault properties for new events.

Intervals

IntervalMinutes will define the granularity of where an event's date properties will snap to when interacting with the calendar.

Mode

In 'day' mode, only the current date prop will be shown. In 'week' mode, the start and end of the week will be determined from the current date prop, and a column for each day of the week will be shown.

Concurrency Mode

Currently both 'stack' and 'split' modes are a WIP, but decent enough to work with for now.

CalendarEvent Properties

NameTypeRequiredPurpose
idstring | numberYesUnique identifier for the event.
descriptionstring | nullNoDescriptive text about the event.
startDateDateYesThe starting date and time of the event.
endDateDateYesThe ending date and time of the event.
colorstringNoColor used to represent the event visually. (CSS color name or hex value)

TIP

The color property will have no affect when implementing a custom CalendarEvent Slot. In this case, the property can be used however you like: CSS color name, hex value, class name, etc.

Events

Event NamePayloadPurpose
event-createdCalendarEventEmitted when a new event is created.
event-clickedCalendarEventEmitted when an event is clicked.
event-updatedCalendarEventEmitted when an existing event is updated.

INFO

Event calendar will allow the user to draw out a new event that is populated with a unique id, and the appropriate start and end dates. However it does nothing with this info other than emit the event-created event, this is where you would want to process what should actually happen.

Examples would be: validate or manipulate the incoming payload, and push directly to the events prop, or another array if the events prop is a computed buffer.

Slots

One of the main goals is to open up as much custom styling as possible, and for now where possible, exposing slots are leaned towards over providing custom classes.

CalendarEvent Slot

PropsProp Type
eventCalendarEvent
vue
<template #calendarEvent="{ event }">
    <div
    class="calendar-event-card"
    :style="{ 
        backgroundColor: event.color, 
        width: '100%', 
        height: '100%' }">
    <div>{{ event.startDate }} - {{ event.endDate }}</div>
    <div>{{ event.description }}</div>
    </div>
</template>

TIP

When using this slot, it's better to avoid handling click events on the root element, in favor of the event-clicked event, as EventCalendar needs to consume click events and may end up in odd/unexpected behavior. As long as nested elements stop propagation, they should be safe to implement them.

SIZING

When using this slot, your root element will automatically receive the following:

box-sizing: border-box
overflow: hidden
width: 100% (of value determined by concurrencyMode)
height: 100% (of height calculated by difference in minutes)

You are free to override these, but take special care.

DayHeader Slot

This slot is the header above each day column.

PropsProp Type
dateDate
vue
<template #dayHeader="{ date }">
    <div class="day-header">
    <!-- Format the date as needed -->
    <span>{{ date.toDateString() }}</span>
    </div>
</template>

TimeInterval Slot

The time display for each horizontal hour line. These will be centered vertically with each hour line.

PropsProp Type
hournumber
vue
<template #timeInterval="{ hour }">
    <div class="time-interval">
    <!-- Display the hour or format as needed -->
    <span>{{ hour }}:00</span>
    </div>
</template>