Skip to content

DateTimePicker

DateTimePicker component for entering date and time

Usual date selection

You can choose an arbitrary date (By default, the picker works in calendar mode with a choice of the day of the month)

vue
<template>
  <AppDateTimePicker v-model="model" placeholder="Select date" />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const model = ref(null);
</script>
vue
<template>
  <AppDateTimePicker v-model="model" placeholder="Select date" />
</template>

<script>
export default {
  data() {
    return {
      model: null,
    };
  },
};
</script>

Selecting the date and time

By passing the type=‘datetime’ attribute, you will switch the picker to the mode when you can select the date and time

vue
<template>
  <AppDateTimePicker
    v-model="model"
    type="datetime"
    placeholder="Select date"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const model = ref(null);
</script>
vue
<template>
  <AppDateTimePicker
    v-model="model"
    type="datetime"
    placeholder="Select date"
  />
</template>

<script>
export default {
  data() {
    return {
      model: null,
    };
  },
};
</script>

Selecting a date range

By passing the type=‘daterange’ or type=‘datetimerange’ attribute, the picker will switch to the mode of selecting a date range or date and time


vue
<template>
  <AppDateTimePicker
    v-model="dateRange"
    type="daterange"
    start-placeholder="Start date"
    end-placeholder="End date"
  />

  <AppDateTimePicker
    v-model="dateTimeRange"
    type="datetimerange"
    start-placeholder="Start date"
    end-placeholder="End date"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const dateRange = ref(null);

const dateTimeRange = ref(null);
</script>
vue
<template>
  <AppDateTimePicker
    v-model="dateRange"
    type="daterange"
    start-placeholder="Start date"
    end-placeholder="End date"
  />

  <AppDateTimePicker
    v-model="dateTimeRange"
    type="datetimerange"
    start-placeholder="Start date"
    end-placeholder="End date"
  />
</template>

<script>
export default {
  data() {
    return {
      dateRange: null,
      dateTimeRange: null,
    };
  },
};
</script>

Modes ^0.1.0

You can configure the calendar mode you need

  • day - the initial display of the calendar of days of the month (it is also possible to select a month or year)
  • month - the initial display of the calendar of months of the year (it is also possible to select the year)
  • year - start display of the calendar of years of the decade

INFO

Note that the value that will be emitted will be a date, not a number

To correctly display the value in the input, pass the appropriate format using the
date-format attribute


vue
<template>
  <AppDateTimePicker
    v-model="month"
    mode="month"
    date-format="MM"
    placeholder="Select month"
  />

  <AppDateTimePicker
    v-model="yearRange"
    date-format="yyyy"
    type="daterange"
    start-placeholder="Start year"
    end-placeholder="End year"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const month = ref(null);

const yearRange = ref(null);
</script>
vue
<template>
  <AppDateTimePicker
    v-model="month"
    mode="month"
    date-format="MM"
    placeholder="Select month"
  />

  <AppDateTimePicker
    v-model="yearRange"
    date-format="yyyy"
    type="daterange"
    start-placeholder="Start year"
    end-placeholder="End year"
  />
</template>

<script>
export default {
  data() {
    return {
      month: null,
      yearRange: null,
    };
  },
};
</script>

Shortcuts

You can set up shortcuts to quickly select a date

vue
<template>
  <AppDateTimePicker
    v-model="model"
    :shortcuts="shortcuts"
    placeholder="Select date"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const model = ref(null);

const shortcuts = [
  {
    text: 'Today',
    value: new Date(),
  },
  {
    text: 'Next Monday',
    value: (() => {
      const today = new Date();
      const nextMonday = new Date(
        today.setDate(today.getDate() + ((8 - today.getDay()) % 7 || 7))
      );
      return nextMonday;
    })(),
  },
  {
    text: 'A week later',
    value: new Date(new Date().setDate(new Date().getDate() + 7)),
  },
];
</script>
vue
<template>
  <AppDateTimePicker
    v-model="model"
    :shortcuts="shortcuts"
    placeholder="Select date"
  />
</template>

<script>
export default {
  data() {
    return {
      model: null,
    };
  },
  computed: {
    shortcuts: [
      {
        text: 'Today',
        value: new Date(),
      },
      {
        text: 'Next Monday',
        value: (() => {
          const today = new Date();
          const nextMonday = new Date(
            today.setDate(today.getDate() + ((8 - today.getDay()) % 7 || 7))
          );
          return nextMonday;
        })(),
      },
      {
        text: 'A week later',
        value: new Date(new Date().setDate(new Date().getDate() + 7)),
      },
    ],
  },
};
</script>

Default time

You can configure which time will be substituted by default

vue
<template>
  <AppDateTimePicker
    v-model="model"
    type="datetime"
    default-time="15:00:00"
    placeholder="Select date"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const model = ref(null);
</script>
vue
<template>
  <AppDateTimePicker
    v-model="model"
    type="datetime"
    default-time="15:00:00"
    placeholder="Select date"
  />
</template>

<script>
export default {
  data() {
    return {
      model: null,
    };
  },
};
</script>

Timezone

The timezone attribute is used to correct the time in the picker.

WARNING

The Date object always remains in the local time zone

When a date is selected, the component atomically calculates the difference between the user's local time zone and the time zone specified in timezone and adds or subtracts it from the time of the selected date for the final display.

The same thing happens when the user first selects a date, only in this case the date is returned, adjusted to the user's local time

INFO

Selected Timezone: America/New_York

Your local time: Sat Apr 26 2025 16:22:40 GMT+0000 (Coordinated Universal Time)

vue
<template>
  <AppDateTimePicker
    v-model="model"
    type="datetime"
    timezone="America/New_York"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const model = ref(null);
</script>
vue
<template>
  <AppDateTimePicker
    v-model="model"
    type="datetime"
    timezone="America/New_York"
  />
</template>

<script>
export default {
  data() {
    return {
      model: null,
    };
  },
};
</script>

Formats

TIP

To learn more about the available formats, follow this link

In this component, you can configure the format of the date that will be displayed in the inputs.

date-format attribute is responsible for the format that will be displayed in the main input

time-format attribute is responsible for the format that will be displayed in the time selection in the popover

Using the combine-formats (default - true) attribute, you can determine whether it is necessary to combine the date-format & time-format format for the main instep (used when the picker works in the time type)

Example when the attribute has a value of false:

vue
<template>
  <AppDateTimePicker
    v-model="model"
    type="datetime"
    date-format="yyyy-MM-dd"
    time-format="HH-mm-ss"
    placeholder="yyyy-MM-dd HH-mm-ss"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const model = ref(null);
</script>
vue
<template>
  <AppDateTimePicker
    v-model="model"
    type="datetime"
    date-format="yyyy-MM-dd"
    time-format="HH-mm-ss"
    placeholder="yyyy-MM-dd HH-mm-ss"
  />
</template>

<script>
export default {
  data() {
    return {
      model: null,
    };
  },
};
</script>

Disabled date

In order to block the date for selection in a picker or when entering into an input, you need to pass a function to the disabledDate attribute that checks whether the date is blocked

Block a date that is less than the current one:

Range of available dates (2 days before and 2 days after the current date):

vue
<template>
  <p>Block a date that is less than the current one:</p>
  <AppDateTimePicker
    v-model="modelOne"
    :disabled-date="isDateDisabledBeforeToday"
    placeholder="Select date"
  />
  <p>
    Range of available dates (2 days before and 2 days after the current date):
  </p>
  <AppDateTimePicker
    v-model="modelTwo"
    :disabled-date="isDateNotInRange"
    placeholder="Select date"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue';

const modelOne = ref(null);
const modelTwo = ref(null);

function isDateDisabledBeforeToday(date: Date) {
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  return date < today;
}

function isDateNotInRange(date: Date) {
  const today = new Date();
  today.setHours(0, 0, 0, 0);

  const twoDaysBefore = new Date(today);
  twoDaysBefore.setDate(today.getDate() - 2);

  const twoDaysAfter = new Date(today);
  twoDaysAfter.setDate(today.getDate() + 2);

  return date <= twoDaysBefore || date >= twoDaysAfter;
}
</script>
vue
<template>
  <p>Block a date that is less than the current one:</p>
  <AppDateTimePicker
    v-model="modelOne"
    :disabled-date="isDateDisabledBeforeToday"
    placeholder="Select date"
  />
  <p>
    Range of available dates (2 days before and 2 days after the current date):
  </p>
  <AppDateTimePicker
    v-model="modelTwo"
    :disabled-date="isDateNotInRange"
    placeholder="Select date"
  />
</template>

<script>
export default {
  data() {
    return {
      modelOne: null,
      modelTwo: null,
    };
  },
  methods: {
    isDateDisabledBeforeToday(date) {
      const today = new Date();
      today.setHours(0, 0, 0, 0);
      return date < today;
    },
    isDateNotInRange(date) {
      const today = new Date();
      today.setHours(0, 0, 0, 0);

      const twoDaysBefore = new Date(today);
      twoDaysBefore.setDate(today.getDate() - 2);

      const twoDaysAfter = new Date(today);
      twoDaysAfter.setDate(today.getDate() + 2);

      return date <= twoDaysBefore || date >= twoDaysAfter;
    },
  },
};
</script>

API

Attributes

NameDescriptionTypeDefault
v-model / model-value
binding value, if it is an array, the length should be 2
null / Date / object
null
date-format
format is designed to display the date in the input data.
more
string
yyyy/MM/dd
time-format
format is for displaying the time in the time input (ie in datetime, datetimerange modes)
more
string
HH:mm:ss
combine-formats
generate the format for the picker from the date-format & time-format props
boolean
true
type
which type of picker should be displayed
string
date
mode
^0.1.0
in which mode you want to display the calendar.
more
string
day
first-day-of-week
the order of the days of the week in the day calendar
number
1
weekday-format
format of the days of the week displayed in the calendar
string
short
month-cell-format
format of months displayed in the calendar
string
short
month-button-format
the format of the month, which is displayed in the button located in the top panel of the calendar
string
long
shortcuts
list of shortcuts to quickly select a date
more
object
[]
default-time
the time that will be set by default. The expected format is “00:00:00”.
more
string / object
"
locale
the language in which you want to display data in the picker. (Use only if you do not have the vue-i18n package)
string
en
time-options
setting up the time picker
string
{}
disabled-date
the option is used to define blocked dates
Function
hide-offset-day
^0.3.0
hide the days of another month in the calendar
false
false
auto-apply
^0.2.0
applying changes without clicking the "Apply" button
boolean
false
disabled
whether the picker is blocked
boolean
false
readonly
whether the picker is read-only
boolean
false
input-readonly
^0.0.2
switch the inputs to read-only mode, but through the popover it is possible to select the date
boolean
false
clearable
displaying a controller for clearing a data input when it is full
boolean
false
timezone
which time zone will be used for date correction.
more
string
"
placeholder
a placeholder that will be displayed in the inpt when the picker is working in single mode
string
"
start-placeholder
placeholder that will be displayed in the first input when the picker is in range mode
string
"
end-placeholder
placeholder that will be displayed in the last input when the picker is in range mode
string
"
align
the position of the popover display
string
left
start-id
^0.2.0
id for the first native input (also used for the native input when there is only one)
string
"
end-id
^0.2.0
id for the last native input
string
"
start-name
^0.2.0
name attribute for the first native input (also used for the native input when there is only one)
string
"
end-name
^0.2.0
name attribute for the last native input
string
"
apply-text
the text displayed in the apply button in the picker popover
string
"Apply"
cancel-text
the text displayed in the cancel button in the picker popover
string
"Cancel"
invalid
indicates that the picker has an invalid value
boolean
false
z-index
^0.3.0
z-index for popover conent
number
1000
client-only-popover-content
^0.3.0
Render popover content inside component. (Works only in SSR mode)
boolean
false
open-delay
delay in milliseconds before the popover opens after being triggered
number
0
close-delay
delay in milliseconds before the popover closes after being triggered
number
150
append-to-body
determines if the popover content should be appended to the body instead of being nested within the DOM structure of the component
boolean
true
stay-opened
leave the picker open after opening it. Use it for debugging or researching a popover
boolean
false

Events

NameDescriptionType
change
triggered when the value was changed
Function
focus
triggers when picker focuses
Function
blur
triggered when the picker is no longer in focus
Function

Slots

NameDescription
default
custom reference for popover
separator
custom range separator content

Default slot ^0.0.2

This slot is a replacement for the date entry field. Below is a table with the available props for this slot

NameDescriptionType
value
The value that is passed to the input (without formatting)
null / Date / object
popoverVisible
returns whether the popover is currently open or not
boolean
input
setting a new value in the picker
Function
blur
blur the picker component
Function
focus
focus the picker component
Function

vue
<template>
  <AppDateTimePicker v-model="model">
    <template #default="{ value, popoverVisible, input, focus }">
      <input
        :value="dateToStringDate(value)"
        :class="{ 'custom-input--focus': popoverVisible }"
        class="custom-input"
        placeholder="Select date"
        @focus="focus"
        @input="event => stringDateToDate(event, input)"
      />
    </template>
  </AppDateTimePicker>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { format, isDate, parse } from 'date-fns';

const model = ref(null);

const dateFormat = 'yyyy-MM-dd';

function dateToStringDate(value: Date | null) {
  if (!value || !isDate(value)) return '';

  return format(value, dateFormat);
}

function stringDateToDate(event: InputEvent, cb: (value: unknown) => void) {
  const value = (event.target as HTMLInputElement).value;

  const parsed = parse(value, dateFormat, new Date());

  if (!value) {
    cb(null);
  }

  if (value.length === dateFormat.length && isDate(parsed)) {
    cb(parsed);
  }
}
</script>

<style lang="scss" scoped>
.custom-input {
  width: 100%;
  border: 1px solid;

  &:focus,
  &--focus {
    border-color: blue;
  }
}
</style>
vue
<template>
  <AppDateTimePicker v-model="model">
    <template #default="{ value, popoverVisible, input, focus }">
      <input
        :value="dateToStringDate(value)"
        :class="{ 'custom-input--focus': popoverVisible }"
        class="custom-input"
        placeholder="Select date"
        @focus="focus"
        @input="event => stringDateToDate(event, input)"
      />
    </template>
  </AppDateTimePicker>
</template>

<script>
export default {
  data() {
    return {
      model: null,
      dateFormat: 'yyyy-MM-dd',
    };
  },
  methods: {
    dateToStringDate(value) {
      if (!value || !isDate(value)) return '';

      return format(value, this.dateFormat);
    },

    stringDateToDate(event, cb) {
      const value = event.target.value;

      const parsed = parse(value, this.dateFormat, new Date());

      if (!value) {
        cb(null);
      }

      if (value.length === this.dateFormat.length && isDate(parsed)) {
        cb(parsed);
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.custom-input {
  width: 100%;
  border: 1px solid;

  &:focus,
  &--focus {
    border-color: blue;
  }
}
</style>

Exposes

NameDescriptionType
popoverVisible
returns whether the popover is currently open or not
object
focus
focus the picker component
Function
blur
blur the picker component
Function