Skip to content

Date Picker (useDatePicker)

Date Picker (useDatePicker)

The useDatePicker composable combines calendar selection with an input field and popup management. It tracks open/close state, formats the input value, and auto-closes after selection.

Import

import { useDatePicker } from '@thaparoyal/calendar-vue';
import type { CalendarDate } from '@thaparoyal/calendar-vue';
import '@thaparoyal/calendar-core/themes/themes.css';

Options

interface UseDatePickerOptions {
config?: Partial<CalendarConfig>;
defaultValue?: CalendarDate;
modelValue?: Ref<CalendarDate | null>;
format?: string; // Default: 'YYYY-MM-DD'
disabled?: boolean;
disabledDates?: CalendarDate[];
}

Return Values

PropertyTypeDescription
isOpenComputedRef<boolean>Whether the popup is visible
inputValueComputedRef<string>Current text in the input
selectedDateComputedRef<CalendarDate | null>Selected date
formattedValueComputedRef<string>Date formatted with format string
weeksComputedRef<Week[]>Calendar grid
titleComputedRef<string>Month/year title
weekdayNamesComputedRef<string[]>Weekday labels
actionsObjectopen, close, toggle, selectDate, clear, onInputChange, onInputBlur, prevMonth, nextMonth
formatDayNumber(day: number) => stringLocale-aware formatter
isPrevMonthDisabledComputedRef<boolean>Nav constraint
isNextMonthDisabledComputedRef<boolean>Nav constraint

Basic Usage

<script setup lang="ts">
import { ref } from 'vue';
import { useDatePicker, type CalendarDate } from '@thaparoyal/calendar-vue';
import '@thaparoyal/calendar-core/themes/themes.css';
const selected = ref<CalendarDate | null>(null);
const dp = useDatePicker({
config: { calendarType: 'BS', locale: 'en' },
modelValue: selected,
});
</script>
<template>
<div class="trc-date-picker" data-theme="indigo">
<!-- Input -->
<div class="trc-date-picker-input-wrapper">
<input
class="trc-date-picker-input"
type="text"
placeholder="Select date..."
:value="dp.inputValue"
readonly
@click="dp.actions.toggle()"
/>
<button
v-if="dp.selectedDate"
class="trc-date-picker-clear"
@click="dp.actions.clear()"
>&times;</button>
<button class="trc-date-picker-trigger" @click="dp.actions.toggle()">
&#128197;
</button>
</div>
<!-- Dropdown -->
<div v-if="dp.isOpen" class="trc-date-picker-content">
<div class="trc-date-picker-calendar">
<div class="trc-calendar-header">
<button class="trc-calendar-nav-button" @click="dp.actions.prevMonth()" :disabled="dp.isPrevMonthDisabled">&lsaquo;</button>
<span class="trc-calendar-title">{{ dp.title }}</span>
<button class="trc-calendar-nav-button" @click="dp.actions.nextMonth()" :disabled="dp.isNextMonthDisabled">&rsaquo;</button>
</div>
<table class="trc-calendar-grid">
<thead class="trc-calendar-grid-head">
<tr>
<th v-for="d in dp.weekdayNames" :key="d" class="trc-calendar-weekday">{{ d }}</th>
</tr>
</thead>
<tbody>
<tr v-for="(week, wi) in dp.weeks" :key="wi" class="trc-calendar-week">
<td
v-for="day in week"
:key="`${day.date.year}-${day.date.month}-${day.date.day}`"
class="trc-calendar-cell"
:class="{
'trc-calendar-cell-today': day.isToday,
'trc-calendar-cell-selected': day.isSelected,
'trc-calendar-cell-outside': day.isOutsideMonth,
'trc-calendar-cell-disabled': day.isDisabled,
}"
>
<button
class="trc-calendar-day"
:disabled="day.isDisabled || day.isOutsideMonth"
@click="dp.actions.selectDate(day.date)"
>{{ dp.formatDayNumber(day.date.day) }}</button>
</td>
</tr>
</tbody>
</table>
</div>
<div class="trc-date-picker-footer">
<button class="trc-date-picker-today-button" @click="dp.actions.goToToday()">Today</button>
<button class="trc-date-picker-clear-button" @click="dp.actions.clear()">Clear</button>
</div>
</div>
</div>
<p>Selected: {{ selected ? `${selected.year}-${selected.month}-${selected.day}` : 'None' }}</p>
</template>

Click Outside to Close

Add a click-outside handler to close the dropdown when the user clicks elsewhere:

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { useDatePicker } from '@thaparoyal/calendar-vue';
const dp = useDatePicker({ config: { calendarType: 'BS', locale: 'en' } });
const pickerRef = ref<HTMLElement | null>(null);
function handleClickOutside(e: MouseEvent) {
if (pickerRef.value && !pickerRef.value.contains(e.target as Node)) {
dp.actions.close();
}
}
onMounted(() => document.addEventListener('click', handleClickOutside));
onUnmounted(() => document.removeEventListener('click', handleClickOutside));
</script>
<template>
<div ref="pickerRef" class="trc-date-picker">
<!-- ... same template ... -->
</div>
</template>

Custom Format

const dp = useDatePicker({
config: { calendarType: 'BS', locale: 'en' },
format: 'YYYY/MM/DD',
});

The formattedValue computed ref and inputValue will use the provided format string.

With Min/Max Constraints

const dp = useDatePicker({
config: {
calendarType: 'BS',
locale: 'en',
minDate: { year: 2081, month: 1, day: 1, calendarType: 'BS' },
maxDate: { year: 2081, month: 12, day: 30, calendarType: 'BS' },
},
});

Actions Reference

ActionDescription
open()Open the dropdown
close()Close the dropdown
toggle()Toggle open/close
selectDate(date)Select a date and auto-close
clear()Clear the selection and input
onInputChange(value)Handle manual input text changes
onInputBlur()Handle input blur (validates input)
prevMonth()Navigate to previous month
nextMonth()Navigate to next month
prevYear()Navigate to previous year
nextYear()Navigate to next year
goToToday()Jump to today’s date
setViewMode(mode)Switch between 'day', 'month', 'year'