Skip to content
On this page

Component slots

Replace the built-in components with custom implementation

Info

These slots are introduced as a replacement for custom components, old documentation can be found here, but the feature is deprecated and will be removed on next major release

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

This slot exposes the following:

  • month (number)
    • Selected month value
  • year (number)
    • Selected year value
  • months ( { text: string; value: number }[])
    • Generated array of months
  • years ( { text: string; value: number }[])
    • Generated array of years
  • updateMonthYear ((month: number, year: number) => void)
    • Exposed function to update month and year
  • handleMonthYearChange ((isNext: boolean) => void)
    • Exposed function to auto handle next/previous month
  • instance (number)
    • In case of multi-calendars, instance is the order of the calendar
Code Example
vue
<template>
    <Datepicker 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>
    </Datepicker>
</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
ts
// 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
vue
<template>
    <Datepicker 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>
    </Datepicker>
</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
  • closeMenu (() = void)
    • Close the datepicker menu
  • disabled (boolean)
    • If the value is invalid based on the provided configuration
Code Example
vue
<template>
    <Datepicker 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>
    </Datepicker>
</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>

Released under the MIT License.