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
<template>
<AppTimePicker v-model="model" placeholder="Select time" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const model = ref(null);
</script>
<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.
<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>
<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.
<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>
<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)
<template>
<AppTimePicker v-model="model" timezone="America/New_York" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const model = ref(null);
</script>
<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:
<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>
<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
<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>
<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
Name | Description | Type | Default |
---|---|---|---|
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 more"HH:mm:ss - HH:mm:ss" ["HH:mm:ss - HH:mm:ss","HH:mm:ss - HH:mm:ss"] . | 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 | 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
Name | Description | Type |
---|---|---|
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
Name | Description |
---|---|
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
Name | Description | Type |
---|---|---|
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 |
<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>
<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
Name | Description | Type |
---|---|---|
popoverVisible | returns whether the popover is currently open or not | object |
focus | focus the picker component | Function |
blur | blur the picker component | Function |