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
| Property | Type | Description |
|---|---|---|
isOpen | ComputedRef<boolean> | Whether the popup is visible |
inputValue | ComputedRef<string> | Current text in the input |
selectedDate | ComputedRef<CalendarDate | null> | Selected date |
formattedValue | ComputedRef<string> | Date formatted with format string |
weeks | ComputedRef<Week[]> | Calendar grid |
title | ComputedRef<string> | Month/year title |
weekdayNames | ComputedRef<string[]> | Weekday labels |
actions | Object | open, close, toggle, selectDate, clear, onInputChange, onInputBlur, prevMonth, nextMonth |
formatDayNumber | (day: number) => string | Locale-aware formatter |
isPrevMonthDisabled | ComputedRef<boolean> | Nav constraint |
isNextMonthDisabled | ComputedRef<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()" >×</button> <button class="trc-date-picker-trigger" @click="dp.actions.toggle()"> 📅 </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">‹</button> <span class="trc-calendar-title">{{ dp.title }}</span> <button class="trc-calendar-nav-button" @click="dp.actions.nextMonth()" :disabled="dp.isNextMonthDisabled">›</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
| Action | Description |
|---|---|
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' |