Skip to content

TimePicker

TimePicker component for entering time

Usual time selection

You can select the time by entering data in the input or the time selection panel

vue
<template>
  <AppTimePicker v-model="model" placeholder="Select time" />
</template>

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

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

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

Selecting a time range

Using the is-range attribute, the picker will start working in the time range selection mode

TIP

Please note that if you do not use the selectable-range attribute and if the is-range=‘true’ attribute is set, the picker will automatically determine the valid range based on the selected data.

vue
<template>
  <AppTimePicker
    v-model="model"
    is-range
    start-placeholder="Start time"
    end-placeholder="End time"
  />
</template>

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

const model = ref(null);
</script>
vue
<template>
  <AppTimePicker
    v-model="model"
    is-range
    start-placeholder="Start time"
    end-placeholder="End time"
  />
</template>

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

Default time

In the picker, you can set the time that will be substituted by default when the user opens it for the first time. You can configure both for one picker and for each picker separately.


vue
<template>
  <AppTimePicker
    v-model="modelFirst"
    :default-time="defaultTime"
    placeholder="Select time"
  />

  <AppTimePicker
    v-model="modelLast"
    is-range
    :default-time="defaultTimeRange"
    start-placeholder="Start time"
    end-placeholder="End time"
  />
</template>

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

const modelFirst = ref(null);
const modelLast = ref(null);

const defaultTime = setTime(15, 30, 30);

const defaultTimeRange = [setTime(12, 0, 30), setTime(17, 28, 30)];

function setTime(hours: number, minutes: number, seconds: number): Date {
  const now = new Date();

  now.setHours(hours);
  now.setMinutes(minutes);
  now.setSeconds(seconds);

  return now;
}
</script>
vue
<template>
  <AppTimePicker
    v-model="modelFirst"
    :default-time="defaultTime"
    placeholder="Select time"
  />

  <AppTimePicker
    v-model="modelLast"
    is-range
    :default-time="defaultTimeRange"
    start-placeholder="Start time"
    end-placeholder="End time"
  />
</template>

<script>
export default {
  data() {
    return {
      modelFirst: null,
      modelLast: null,
    };
  },
  computed: {
    defaultTime() {
      return setTime(15, 30, 30);
    },
    defaultTimeRange() {
      return [setTime(12, 0, 30), setTime(17, 28, 30)];
    },
  },
  methods: {
    setTime(hours, minutes, seconds) {
      const now = new Date();

      now.setHours(hours);
      now.setMinutes(minutes);
      now.setSeconds(seconds);

      return now;
    },
  },
};
</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>
  <AppTimePicker v-model="model" timezone="America/New_York" />
</template>

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

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

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

Formats

In this component, you can configure the format in which the date will be displayed in the input. Also, unlike the DateTimePicker, the format affects the display of the panels in the popover.

TIP

To learn more about the available formats, follow this link

Display of hours and minutes only:

Time display with AM\PM:

vue
<template>
  <AppTimePicker v-model="modelFirst" format="HH:mm" placeholder="HH:mm" />

  <AppTimePicker v-model="modelLast" format="hh:mm:ss a" placeholder="HH:mm" />
</template>

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

const modelFirst = ref(null);
const modelLast = ref(null);
</script>
vue
<template>
  <AppTimePicker v-model="modelFirst" format="HH:mm" placeholder="HH:mm" />

  <AppTimePicker v-model="modelLast" format="hh:mm:ss a" placeholder="HH:mm" />
</template>

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

Limit the time range

With the selectable-range attribute, you can limit the time selection for the user. This attribute works for picker in normal mode and in range selection.

WARNING

The attribute has a strict format, namely ‘HH:mm:ss - HH:mm:ss’, and for the range selection mode [‘HH:mm:ss - HH:mm:ss’, ‘HH:mm:ss - HH:mm:ss’].

INFO

If the picker does not have an initial value and the selectable-range attribute is configured, the time that will be selected by default (the current time or the time that was passed in the default-time attribute) will be determined relative to the selectable-range attribute.

  • If the current time is less than the initial time, the initial time will be selected
  • If the current time is greater than the end time, the end time will be selected
  • If the current time is in the range, it will be selected



vue
<template>
  <AppTimePicker
    v-model="modelFirst"
    selectable-range="12:30:30 - 16:00:00"
    placeholder="Select time"
  />

  <AppTimePicker
    v-model="modelLast"
    is-range
    :selectable-range="['12:30:30 - 16:00:00', '12:00:30 - 14:30:00']"
    start-placeholder="Start time"
    end-placeholder="End time"
  />
</template>

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

const modelFirst = ref(null);
const modelLast = ref(null);
</script>
vue
<template>
  <AppTimePicker
    v-model="modelFirst"
    selectable-range="12:30:30 - 16:00:00"
    placeholder="Select time"
  />

  <AppTimePicker
    v-model="modelLast"
    is-range
    :selectable-range="['12:30:30 - 16:00:00', '12:00:30 - 14:30:00']"
    start-placeholder="Start time"
    end-placeholder="End time"
  />
</template>

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

API

Attributes

NameDescriptionTypeDefault
v-model / model-value
binding value, if it is an array, the length should be 2
null / Date / object
null
is-range
whether to display the picker in the time range selection mode
boolean
false
time-format
the format in which the time in the picker will be displayed, as well as the corresponding panels in the popover.
more
string
HH:mm:ss
default-time
the time that will be set by default.
more
object
new Date()
selectable-range
limitation for time selection. The expected format is "HH:mm:ss - HH:mm:ss"
["HH:mm:ss - HH:mm:ss","HH:mm:ss - HH:mm:ss"].
more
string / object
"
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>
  <AppTimePicker v-model="model">
    <template #default="{ value, popoverVisible, input, focus }">
      <input
        :value="dateToStringTime(value)"
        :class="{ 'custom-input--focus': popoverVisible }"
        class="custom-input"
        placeholder="Select time"
        @focus="focus"
        @input="event => stringDateToDate(event, input)"
      />
    </template>
  </AppTimePicker>
</template>

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

const model = ref(null);

const timeFormat = 'HH:ss:mm';

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

  return format(value, timeFormat);
}

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

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

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

  if (value.length === timeFormat.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>
  <AppTimePicker v-model="model">
    <template #default="{ value, popoverVisible, input, focus }">
      <input
        :value="dateToStringTime(value)"
        :class="{ 'custom-input--focus': popoverVisible }"
        class="custom-input"
        placeholder="Select time"
        @focus="focus"
        @input="event => stringDateToDate(event, input)"
      />
    </template>
  </AppTimePicker>
</template>

<script>
export default {
  data() {
    return {
      model: null,
      timeFormat: 'HH:ss:mm',
    };
  },
  methods: {
    dateToStringTime(value) {
      if (!value || !isDate(value)) return '';

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

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

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

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

      if (value.length === this.timeFormat.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