Component slots
Replace the built-in components with custom implementation
month-year
Create and use a custom component implementation in the header for month/year select
Info
When using this slot, the overlays will not be available, it is up to you to create them if you want
Warning
Depending on the used mode, slot will provide a different set of props
Exposed props:
Date picker
interface DefaultSelect {
value: number;
text: string;
className?: Record<string, boolean>;
}
interface Props {
month: number; // Selected month value
year: number; // Selected year value
months: DefaultSelect[]; // Generated array of months
years: DefaultSelect[]; // Generated array of years
updateMonthYear: (month: number, year: number, fromNav: boolean) => void; // Exposed function to update month and year
handleMonthYearChange: (isNext: boolean, fromNav?: boolean) => void; // Exposed function to auto handle next/previous month
instance: number; // In case of multi-calendars, instance is the order of the calendar
}
interface DefaultSelect {
value: number;
text: string;
className?: Record<string, boolean>;
}
interface Props {
month: number; // Selected month value
year: number; // Selected year value
months: DefaultSelect[]; // Generated array of months
years: DefaultSelect[]; // Generated array of years
updateMonthYear: (month: number, year: number, fromNav: boolean) => void; // Exposed function to update month and year
handleMonthYearChange: (isNext: boolean, fromNav?: boolean) => void; // Exposed function to auto handle next/previous month
instance: number; // In case of multi-calendars, instance is the order of the calendar
}
Month picker
interface Props {
year: ComputedRef<(instance: number) => number>; // Selected year on a given instance
months: OverlayGridItem[][]; // Groupped array of months (by 3)
years: OverlayGridItem[][]; // Groupped array of years (by 3)
selectMonth: (month: number, instance: number) => void; // Exposed function to update month value
selectYear: (year: number, instance: number) => void; // Exposed function to update year value
instance: number; // In case of multi-calendars, instance is the order of the calendar
}
interface Props {
year: ComputedRef<(instance: number) => number>; // Selected year on a given instance
months: OverlayGridItem[][]; // Groupped array of months (by 3)
years: OverlayGridItem[][]; // Groupped array of years (by 3)
selectMonth: (month: number, instance: number) => void; // Exposed function to update month value
selectYear: (year: number, instance: number) => void; // Exposed function to update year value
instance: number; // In case of multi-calendars, instance is the order of the calendar
}
Year picker
interface Props {
years: OverlayGridItem[][]; // Groupped array of months (by 3)
selectYear: (year: number) => void; // Exposed function to update year value
}
interface Props {
years: OverlayGridItem[][]; // Groupped array of months (by 3)
selectYear: (year: number) => void; // Exposed function to update year value
}
Shared type
interface OverlayGridItem {
value: number; // Value in the overlay cell
text: string; // Text displayed in the overlay cell
active: boolean; // If the selection is active
disabled: boolean; // If the selection is disabled
className: Record<string, boolean>; // Applied classes on a given cell
}
interface OverlayGridItem {
value: number; // Value in the overlay cell
text: string; // Text displayed in the overlay cell
active: boolean; // If the selection is active
disabled: boolean; // If the selection is disabled
className: Record<string, boolean>; // Applied classes on a given cell
}
Code Example
<template>
<VueDatePicker v-model="date">
<template
#month-year="{
month,
year,
months,
years,
updateMonthYear,
handleMonthYearChange
}">
<div class="custom-month-year-component">
<select
class="select-input"
:value="month"
@change="updateMonth($event, updateMonthYear, year)">
<option v-for="m in months" :key="m.value" :value="m.value">{{ m.text }}</option>
</select>
<select
class="select-input"
:value="year"
@change="updateYear($event, updateMonthYear, month)">
<option v-for="y in years" :key="y.value" :value="y.value">{{ y.text }}</option>
</select>
</div>
<div class="icons">
<span
class="custom-icon"
@click="handleMonthYearChange(false)">
<ChevronLeftIcon />
</span>
<span
class="custom-icon"
@click="handleMonthYearChange(true)">
<ChevronRightIcon />
</span>
</div>
</template>
</VueDatePicker>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import ChevronLeftIcon from './Icons/ChevronLeftIcon.vue';
import ChevronRightIcon from './Icons/ChevronRightIcon.vue';
const date = ref(new Date());
type UpdateMonthYear = (month: number, year: number) => void;
const updateMonth = (event: InputEvent, updateMonthYear: UpdateMonthYear, year: number) => {
updateMonthYear(+(event.target as HTMLSelectElement).value, year);
};
const updateYear = (event: InputEvent, updateMonthYear: UpdateMonthYear, month: number) => {
updateMonthYear(month, +(event.target as HTMLSelectElement).value);
};
</script>
<style lang="scss">
.custom-month-year-component {
display: flex;
align-items: center;
margin: 0 auto;
}
.select-input {
margin: 5px 3px;
padding: 5px;
width: auto;
border-radius: 4px;
border-color: var(--dp-border-color);
outline: none;
-webkit-appearance: menulist;
}
.icons {
display: flex;
box-sizing: border-box;
}
.custom-icon {
padding: 5px;
display: flex;
height: 25px;
align-items: center;
justify-content: center;
cursor: pointer;
width: 25px;
color: var(--dp-icon-color);
text-align: center;
border-radius: 50%;
svg {
height: 20px;
width: 20px;
}
&:hover {
background: var(--dp-hover-color);
}
}
</style>
<template>
<VueDatePicker v-model="date">
<template
#month-year="{
month,
year,
months,
years,
updateMonthYear,
handleMonthYearChange
}">
<div class="custom-month-year-component">
<select
class="select-input"
:value="month"
@change="updateMonth($event, updateMonthYear, year)">
<option v-for="m in months" :key="m.value" :value="m.value">{{ m.text }}</option>
</select>
<select
class="select-input"
:value="year"
@change="updateYear($event, updateMonthYear, month)">
<option v-for="y in years" :key="y.value" :value="y.value">{{ y.text }}</option>
</select>
</div>
<div class="icons">
<span
class="custom-icon"
@click="handleMonthYearChange(false)">
<ChevronLeftIcon />
</span>
<span
class="custom-icon"
@click="handleMonthYearChange(true)">
<ChevronRightIcon />
</span>
</div>
</template>
</VueDatePicker>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import ChevronLeftIcon from './Icons/ChevronLeftIcon.vue';
import ChevronRightIcon from './Icons/ChevronRightIcon.vue';
const date = ref(new Date());
type UpdateMonthYear = (month: number, year: number) => void;
const updateMonth = (event: InputEvent, updateMonthYear: UpdateMonthYear, year: number) => {
updateMonthYear(+(event.target as HTMLSelectElement).value, year);
};
const updateYear = (event: InputEvent, updateMonthYear: UpdateMonthYear, month: number) => {
updateMonthYear(month, +(event.target as HTMLSelectElement).value);
};
</script>
<style lang="scss">
.custom-month-year-component {
display: flex;
align-items: center;
margin: 0 auto;
}
.select-input {
margin: 5px 3px;
padding: 5px;
width: auto;
border-radius: 4px;
border-color: var(--dp-border-color);
outline: none;
-webkit-appearance: menulist;
}
.icons {
display: flex;
box-sizing: border-box;
}
.custom-icon {
padding: 5px;
display: flex;
height: 25px;
align-items: center;
justify-content: center;
cursor: pointer;
width: 25px;
color: var(--dp-icon-color);
text-align: center;
border-radius: 50%;
svg {
height: 20px;
width: 20px;
}
&:hover {
background: var(--dp-hover-color);
}
}
</style>
time-picker
Create and use a custom component for the time picker
This slot exposes the following:
time
(Time
)- Reactive time object with hours, minutes and seconds
updateTime
(UpdateTime
)- Exposed function to update time
// Array values are used if range is enabled
interface Time {
hours: number | number[];
minutes: number | number[];
seconds: number | number[]
}
type UpdateTime = (value: number | number[], isHours: boolean, isSeconds: boolean) => void;
// Array values are used if range is enabled
interface Time {
hours: number | number[];
minutes: number | number[];
seconds: number | number[]
}
type UpdateTime = (value: number | number[], isHours: boolean, isSeconds: boolean) => void;
Info
Keep in mind that when you are using the range picker, both values for the time must be emitted. For example if you want to update the second date hours, you will call a function something like this updateTime([firstValueSaved, newSecondValue])
Code Example
<template>
<VueDatePicker v-model="date">
<template #time-picker="{ time, updateTime }">
<div class="custom-time-picker-component">
<select
class="select-input"
:value="time.hours"
@change="updateTime(+$event.target.value)"
>
<option
v-for="h in hoursArray"
:key="h.value"
:value="h.value">{{ h.text }}</option>
</select>
<select
class="select-input"
:value="time.minutes"
@change="updateTime(+$event.target.value, false)"
>
<option
v-for="m in minutesArray"
:key="m.value"
:value="m.value">{{ m.text }}</option>
</select>
</div>
</template>
</VueDatePicker>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
const date = ref(new Date());
const hoursArray = computed(() => {
const arr = [];
for (let i = 0; i < 24; i++) {
arr.push({ text: i < 10 ? `0${i}` : i, value: i });
}
return arr;
});
const minutesArray = computed(() => {
const arr = [];
for (let i = 0; i < 60; i++) {
arr.push({ text: i < 10 ? `0${i}` : i, value: i });
}
return arr;
});
</script>
<style lang="scss">
.custom-time-picker-component {
display: flex;
align-items: center;
justify-content: center;
}
.select-input {
margin: 5px 3px;
padding: 5px;
width: 100px;
border-radius: 4px;
border-color: var(--dp-border-color);
outline: none;
-webkit-appearance: menulist;
}
</style>
<template>
<VueDatePicker v-model="date">
<template #time-picker="{ time, updateTime }">
<div class="custom-time-picker-component">
<select
class="select-input"
:value="time.hours"
@change="updateTime(+$event.target.value)"
>
<option
v-for="h in hoursArray"
:key="h.value"
:value="h.value">{{ h.text }}</option>
</select>
<select
class="select-input"
:value="time.minutes"
@change="updateTime(+$event.target.value, false)"
>
<option
v-for="m in minutesArray"
:key="m.value"
:value="m.value">{{ m.text }}</option>
</select>
</div>
</template>
</VueDatePicker>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
const date = ref(new Date());
const hoursArray = computed(() => {
const arr = [];
for (let i = 0; i < 24; i++) {
arr.push({ text: i < 10 ? `0${i}` : i, value: i });
}
return arr;
});
const minutesArray = computed(() => {
const arr = [];
for (let i = 0; i < 60; i++) {
arr.push({ text: i < 10 ? `0${i}` : i, value: i });
}
return arr;
});
</script>
<style lang="scss">
.custom-time-picker-component {
display: flex;
align-items: center;
justify-content: center;
}
.select-input {
margin: 5px 3px;
padding: 5px;
width: 100px;
border-radius: 4px;
border-color: var(--dp-border-color);
outline: none;
-webkit-appearance: menulist;
}
</style>
action-row
Create and use a custom component for action row
This slot exposes the following:
internalModelValue
(Date | Date[] | null
)- Current selected value in the datepicker
selectDate
(() => void
)- Select the current
internalModelValue
value
- Select the current
closePicker
(() = void
)- Close the datepicker menu
disabled
(boolean
)- If the value is invalid based on the provided configuration
Code Example
<template>
<VueDatePicker v-model="date">
<template #action-row="{ internalModelValue, selectDate }">
<div class="action-row">
<p class="current-selection">{{ formatDate(internalModelValue) }}</p>
<button class="select-button" @click="selectDate">Select Date</button>
</div>
</template>
</VueDatePicker>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { format } from 'date-fns'
const date = ref(new Date());
const formatDate = (date: Date) => {
return format(date, 'dd.MM.yyyy, HH:mm');
};
</script>
<style lang="scss">
.action-row {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
</style>
<template>
<VueDatePicker v-model="date">
<template #action-row="{ internalModelValue, selectDate }">
<div class="action-row">
<p class="current-selection">{{ formatDate(internalModelValue) }}</p>
<button class="select-button" @click="selectDate">Select Date</button>
</div>
</template>
</VueDatePicker>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { format } from 'date-fns'
const date = ref(new Date());
const formatDate = (date: Date) => {
return format(date, 'dd.MM.yyyy, HH:mm');
};
</script>
<style lang="scss">
.action-row {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
}
</style>