@comperio/vue2-multi-select-calendar
v1.17.0
Published
A Vue2 calendar with event support and multiple selection
Readme
Vue2 Multi Select Calendar
Vue2 calendar with event support and multiple selection.
Table of Contents
- Installation
- Basic Usage
- Props
- Slots
- Events
- Lazy Loading Event Details
- CSS Variables
- Types
- Available Scripts
Installation
npm install @comperio/vue2-multi-select-calendarBasic Usage
/* Import both variables and styles */
import '@comperio/vue2-multi-select-calendar/dist/style.css';
/* Or define your own variables and import only the styles */
:root {
/* your custom variables here */
}
import '@comperio/vue2-multi-select-calendar/dist/styles.css';import { MultiDatePicker } from "@comperio/vue2-multi-select-calendar";
// As a component
export default {
components: {
MultiDatePicker,
},
};
// As a plugin
import { VueCalendarPlugin } from "@comperio/vue2-multi-select-calendar";
Vue.use(VueCalendarPlugin);
// Usage Example
<template>
<multi-date-picker
:events="events"
:pre-selected-dates="preSelectedDates"
@update:busy="onBusyUpdate"
@update:selected="onSelectionUpdate"
@event-hover="onEventHover"
@event-leave="onEventLeave"
>
<template #tooltip="{ data }">
<div class="custom-tooltip">
<strong>{{ data?.note }}</strong>
</div>
</template>
</multi-date-picker>
</template>
<script>
export default {
data() {
return {
events: [
{
date: new Date("2024-02-22"),
data: { note: "Important meeting" },
},
],
preSelectedDates: [new Date("2024-02-22")],
hoveredEvent: null,
};
},
methods: {
onBusyUpdate(selectedBusyDates) {
console.log("Selected busy dates:", selectedBusyDates);
},
onSelectionUpdate(selectedFreeDates) {
console.log("Selected free dates:", selectedFreeDates);
},
onEventHover(event) {
this.hoveredEvent = event;
// Lazy load additional data
setTimeout(() => {
if (this.hoveredEvent && this.hoveredEvent.date.getTime() === event.date.getTime()) {
this.hoveredEvent.data.additionalInfo = "Lazy loaded data";
this.hoveredEvent = { ...this.hoveredEvent };
}
}, 500);
},
onEventLeave() {
this.hoveredEvent = null;
},
},
};
</script>Props
Core Props
events: CalendarDate[]- Array of events to display in the calendar. Each event contains:date: Date- Event datedata: any- Additional data associated with the event (e.g., notes, title) Events are displayed as "busy" days with a distinctive style.
preSelectedDates: Date[]- Array of pre-selected dates. Behavior varies based on the number of dates:- Single date: always selected
- Multiple dates: only dates matching busy days (present in
events) are selected - Empty array: no dates selected Note: setting this prop overrides any current selection.
Display Props
year: number | null- The year to initialize the calendar with. If provided, the calendar will start from January 1st of this year. Ifnull, the calendar will start from the current date. (default:null)years: number[]- An array of years to allow navigation between. If provided, the year navigator will only allow switching between these years. If empty, navigation is unrestricted. (default:[])numberOfMonths: number- Number of months to display (default: 1). Valid values are between 1 and 12.showNavigator: boolean- Show month navigator (default: true)showYearNavigator: boolean- Show year navigator (default: true)showMonthLabels: boolean- Show month labels (default: true)showNextMonthDays: boolean- Show days from next month (default: true)showPreviousMonthDays: boolean- Show days from previous month (default: true)
Internationalization (i18n) Props
i18n: I18n | null- An object containing translations for month names and weekday abbreviations. Ifnull, default (Italian) translations are used. (default:null) The structure of theI18nobject should be:interface I18n { months?: { [monthKey: string]: { [langKey: string]: string }; // e.g., january: { en: "January", it: "Gennaio" } }; weekDaysShort?: { [dayKey: string]: { [langKey: string]: string }; // e.g., monday: { en: "Mon", it: "Lun" } }; }language: Language- A string specifying the current language (e.g., "en", "it", "de"). This key is used to pick the correct translation from thei18nobject. (default:"it")
Move Restriction Props
enableMoveRestriction: boolean- Enables the move restriction feature (default:false). Whentrue, and an event (a busy day) is selected, attempting to move it to a day outside the definedminMovableDateandmaxMovableDatewill be prevented.minMovableDate: Date | null- The earliest date an event can be moved to (default:null). Ifnull, there is no minimum date restriction for moving.maxMovableDate: Date | null- The latest date an event can be moved to (default:null). Ifnull, there is no maximum date restriction for moving.
Slots
tooltip- Custom tooltip content
<multi-date-picker>
<template #tooltip="event">
<div class="custom-tooltip">
<strong>custom tooltip</strong>
<p>
<strong>{{ event?.data?.note }}</strong>
</p>
</div>
</template>
</multi-date-picker>year-navigator- Provides a custom UI for year navigation, replacing the default navigator. The slot is provided with the following properties:currentYear(number): The currently displayed year.previousYear(function): A function to navigate to the previous year.nextYear(function): A function to navigate to the next year.
<multi-date-picker> <template #year-navigator="{ currentYear, previousYear, nextYear }"> <div class="custom-year-nav"> <button @click="previousYear"><<</button> <span>Year: {{ currentYear }}</span> <button @click="nextYear">>></button> </div> </template> </multi-date-picker>
Events
@update:busy- Emitted when busy days are selected@update:selected- Emitted when free days are selected@event-hover- Emitted when the mouse enters an event@event-leave- Emitted when the mouse leaves an event@month-change- Emitted when the visible month is changed via the navigator. The payload is the name of the new month (string).@year-change- Emitted when the visible year is changed via the navigator. The payload is the new year (number).@move-restricted- Emitted whenenableMoveRestrictionistrueand an attempt is made to move an event to a date outside theminMovableDateormaxMovableDate. The payload includes{ date: Date, day: CalendarDay }corresponding to the restricted target date.@click-outside- Emitted when a click occurs outside the calendar component. The payload is the nativeMouseEvent.
Lazy Loading Event Details
The calendar provides hover events that allow you to implement lazy loading of event details:
<template>
<div>
<multi-date-picker
:events="events"
@event-hover="onEventHover"
@event-leave="onEventLeave"
/>
<div v-if="hoveredEvent" class="event-details">
<h3>{{ hoveredEvent.data.note }}</h3>
<p v-if="hoveredEvent.data.additionalInfo">
{{ hoveredEvent.data.additionalInfo }}
</p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
events: [...],
hoveredEvent: null
}
},
methods: {
onEventHover(event) {
this.hoveredEvent = event;
// Simulate API call to load additional data
setTimeout(() => {
if (this.hoveredEvent && this.hoveredEvent.date.getTime() === event.date.getTime()) {
this.hoveredEvent.data.additionalInfo = "Loaded from API";
// Force reactivity update
this.hoveredEvent = { ...this.hoveredEvent };
}
}, 500);
},
onEventLeave() {
this.hoveredEvent = null;
}
}
}
</script>CSS Variables
--v-cal-font-family: Arial, sans-serif;
--v-cal-border-color: #ddd;
--v-cal-background: white;
--v-cal-text-color: #2c3e50;
--v-cal-past-color: #ddd;
--v-cal-other-month-color: #999;
--v-cal-selected-background: #4caf50;
--v-cal-selected-color: white;
--v-cal-selected-border-color: #81c784;
--v-cal-hover-background: #f0f0f0;
--v-cal-header-background: #f0f0f0;
--v-cal-year-nav-background: #e8e8e8;
--v-cal-weekday-background: #f8f8f8;
--v-cal-month-label-color: #666;
--v-cal-grid-gap: 1px;
--v-cal-padding: 10px;
--v-cal-month-width: 300px;
--v-cal-font-size: 0.9em;
--v-cal-button-hover: rgba(0, 0, 0, 0.05);
--v-cal-tooltip-background: rgba(0, 0, 0, 0.8);
--v-cal-tooltip-color: white;
--v-cal-unmovable-target-background: #eeeeee; /* Background color for days that are not valid move targets when move restriction is active. Applied to free days via the .v-cal-is-unmovable-target class. */Types
interface CalendarDate<T = any> {
date: Date;
data: T;
}
interface CalendarDay {
date: Date;
dayNumber: number;
isCurrentMonth: boolean;
}
interface I18n {
months?: {
[monthKey: string]: { [langKey: string]: string };
};
weekDaysShort?: {
[dayKey: string]: { [langKey: string]: string };
};
}
type Language = "it" | "en" | "de" | string; // Allow for other language codesThe CalendarDate interface is used for both the events prop and the emitted events. The generic type T allows you to specify the type of the data property.
The I18n interface defines the structure for providing translations.
The Language type is a string union for supported languages, but can also be any string if you provide corresponding translations in the i18n object.
Available Scripts
In the project directory, you can run the following scripts:
pnpm devornpm run devRuns the app in development mode using Vite. Open http://localhost:5173 (or the port shown in your terminal) to view it in the browser.pnpm testornpm run testExecutes the Playwright tests for the application.pnpm type-checkornpm run type-checkRuns the TypeScript compiler (vue-tsc) to check for type errors in the project without emitting JavaScript files.pnpm buildornpm run buildBuilds the app for production to thedistfolder. It first runstype-checkand then uses Vite to bundle the library.pnpm build:devornpm run build:devCreates a development build with source maps enabled for easier debugging. It setsKEEP_SOURCE_MAP=truebefore running the standard build process.pnpm bump-version:patchornpm run bump-version:patchIncrements the patch version of the package (e.g., 1.0.0 -> 1.0.1).pnpm bump-version:minorornpm run bump-version:minorIncrements the minor version of the package (e.g., 1.0.0 -> 1.1.0).pnpm bump-version:majorornpm run bump-version:majorIncrements the major version of the package (e.g., 1.0.0 -> 2.0.0).pnpm serveornpm run serveServes the production build locally using Vite's preview mode. This is useful for checking the production build before deployment.pnpm publish:dry-runornpm run publish:dry-runPerforms a dry run of the publishing process. It builds the project and then simulates publishing to npm without actually making changes to the registry.pnpm publish:prodornpm run publish:prodBuilds the project and then publishes it to npm.pnpm release:patchornpm run release:patchAutomates a patch release: bumps the patch version, commits, pushes the commit, and pushes the new tag.pnpm release:minorornpm run release:minorAutomates a minor release: bumps the minor version, commits, pushes the commit, and pushes the new tag.pnpm release:majorornpm run release:majorAutomates a major release: bumps the major version, commits, pushes the commit, and pushes the new tag.
(Note: The _commit-and-push-tag script is an internal helper for the release scripts and is not typically run directly.)
