Date Calendar Picker
A standalone, Date Calendar Picker component that can be used independently with v-model functionality. This component provides a complete calendar interface with multiple modes and can be attached to any element or used anywhere in your application.
Features
- ✅ v-model Support: Full two-way data binding
- ✅ Multiple Modes: Full, month-year, and year-only modes
- ✅ Custom Formatting: Support for different date formats
- ✅ Disabled Dates: Comprehensive date restriction options
- ✅ Rest Days: Mark specific days as rest days
- ✅ Responsive Design: Works on all screen sizes
- ✅ Accessibility: Full keyboard navigation and screen reader support
- ✅ TypeScript: Complete type safety
- ✅ Event Handling: Rich event system for all interactions
Basic Usage
Selected Date: 2024-01-15
<template>
<spr-date-calendar-picker
v-model="selectedDate"
:min-max-year="{ min: 2024, max: 2025 }"
@update:month="handleMonthUpdate"
@update:year="handleYearUpdate"
@update:day="handleDayUpdate"
/>
</template>
<script setup>
import { ref } from 'vue';
const selectedDate = ref('2024-01-15');
const handleMonthUpdate = (month) => {
console.log('Month updated:', month);
};
const handleYearUpdate = (year) => {
console.log('Year updated:', year);
};
const handleDayUpdate = (day) => {
console.log('Day updated:', day);
};
</script>Modes
The Date Calendar Picker supports three different modes to control what date information is displayed and collected.
Full Mode (Default)
The full mode displays a complete calendar with month, day, and year selection. This is the default mode.
Selected Date: 2024-01-15
<template>
<spr-date-calendar-picker
v-model="selectedDate"
mode="full"
:min-max-year="{ min: 2024, max: 2025 }"
/>
</template>
<script setup>
import { ref } from 'vue';
const selectedDate = ref('2024-01-15');
</script>Month-Year Mode
The month-year mode displays only month and year selection, hiding the day selection.
Selected Value: 2024-06
<template>
<spr-date-calendar-picker
v-model="selectedMonthYear"
mode="month-year"
:selected-month="selectedMonth"
:selected-year="selectedYear"
@update:month="handleMonthUpdate"
@update:year="handleYearUpdate"
/>
</template>
<script setup>
import { ref } from 'vue';
const selectedMonthYear = ref('2024-06');
const selectedMonth = ref(5); // June (0-indexed)
const selectedYear = ref(2024);
const handleMonthUpdate = (month) => {
selectedMonth.value = month;
};
const handleYearUpdate = (year) => {
selectedYear.value = year;
};
</script>Year-Only Mode
The year-only mode displays only year selection, hiding both month and day selection.
Selected Value: 2024
<template>
<spr-date-calendar-picker
v-model="selectedYear"
mode="year-only"
:selected-year="selectedYearValue"
@update:year="handleYearUpdate"
/>
</template>
<script setup>
import { ref } from 'vue';
const selectedYear = ref('2024');
const selectedYearValue = ref(2024);
const handleYearUpdate = (year) => {
selectedYearValue.value = year;
};
</script>Mode Comparison
Compare the different modes side by side:
Full Mode
Month-Year Mode
Year-Only Mode
Custom Format
You can specify the format of the date by passing the format prop. The default format is MM-DD-YYYY.
Selected Date (YYYY-MM-DD): 2024-01-15
<template>
<spr-date-calendar-picker
v-model="selectedDate"
format="YYYY-MM-DD"
:min-max-year="{ min: 2024, max: 2025 }"
/>
</template>
<script setup>
import { ref } from 'vue';
const selectedDate = ref('2024-01-15');
</script>Disabled Dates
You can disable specific dates by passing the disabled-dates prop.
Selected Date: 2024-01-15
<template>
<spr-date-calendar-picker
v-model="selectedDate"
:min-max-year="{ min: 2024, max: 2025 }"
:disabled-dates="disabledDates"
:rest-days="['su', 'sa']"
/>
</template>
<script setup>
import { ref } from 'vue';
const selectedDate = ref('2024-01-15');
const disabledDates = ref({
from: '2024-01-20',
to: '2024-01-25',
selectedDates: ['2024-01-10', '2024-01-11'],
weekends: false,
weekdays: false,
selectedDays: [],
pastDates: false,
futureDates: false
});
</script>Disabled State
Add the disabled prop to disable the calendar.
<template>
<spr-date-calendar-picker
v-model="selectedDate"
:min-max-year="{ min: 2024, max: 2025 }"
disabled
/>
</template>
<script setup>
import { ref } from 'vue';
const selectedDate = ref('2024-01-15');
</script>Read Only
Add the readonly prop to make the calendar read-only.
<template>
<spr-date-calendar-picker
v-model="selectedDate"
:min-max-year="{ min: 2024, max: 2025 }"
readonly
/>
</template>
<script setup>
import { ref } from 'vue';
const selectedDate = ref('2024-01-15');
</script>Min-Max Year
You can manually set the minimum and maximum year to be shown in the calendar.
Selected Date: 2024-01-15
<template>
<spr-date-calendar-picker
v-model="selectedDate"
:min-max-year="{ min: 2020, max: 2030 }"
/>
</template>
<script setup>
import { ref } from 'vue';
const selectedDate = ref('2024-01-15');
</script>Rest Days
You can set the rest days in the week by passing the rest-days prop.
Selected Date: 2024-01-15
<template>
<spr-date-calendar-picker
v-model="selectedDate"
:min-max-year="{ min: 2024, max: 2025 }"
:rest-days="restDays"
/>
</template>
<script setup>
import { ref } from 'vue';
const selectedDate = ref('2024-01-15');
const restDays = ref(['mo', 'we', 'fr', 'sa']);
</script>Event Handling
The component emits events for all interactions:
Selected Date: 2024-01-15
Last Month Update: None
Last Year Update: None
Last Day Update: None
<template>
<spr-date-calendar-picker
v-model="selectedDate"
:min-max-year="{ min: 2024, max: 2025 }"
@update:month="handleMonthUpdate"
@update:year="handleYearUpdate"
@update:day="handleDayUpdate"
/>
<div class="mt-4 p-4 bg-gray-100 rounded">
<p><strong>Selected Date:</strong> {{ selectedDate }}</p>
<p><strong>Last Month Update:</strong> {{ lastMonthUpdate }}</p>
<p><strong>Last Year Update:</strong> {{ lastYearUpdate }}</p>
<p><strong>Last Day Update:</strong> {{ lastDayUpdate }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
const selectedDate = ref('2024-01-15');
const lastMonthUpdate = ref('');
const lastYearUpdate = ref('');
const lastDayUpdate = ref('');
const handleMonthUpdate = (month) => {
lastMonthUpdate.value = `Month ${month + 1} (${new Date(2024, month).toLocaleString('default', { month: 'long' })})`;
};
const handleYearUpdate = (year) => {
lastYearUpdate.value = `Year ${year}`;
};
const handleDayUpdate = (day) => {
lastDayUpdate.value = `Day ${day}`;
};
</script>Integration Examples
In a Modal
<template>
<div>
<button @click="showModal = true">Open Calendar</button>
<Modal v-if="showModal" @close="showModal = false">
<spr-date-calendar-picker
v-model="selectedDate"
:min-max-year="{ min: 2024, max: 2025 }"
@update:modelValue="handleDateSelect"
/>
</Modal>
</div>
</template>
<script setup>
import { ref } from 'vue';
const showModal = ref(false);
const selectedDate = ref('');
const handleDateSelect = (date) => {
console.log('Date selected:', date);
showModal.value = false;
};
</script>In a Form
<template>
<form @submit="handleSubmit">
<div class="form-group">
<label>Select Date:</label>
<spr-date-calendar-picker
v-model="formData.date"
:min-max-year="{ min: 2024, max: 2025 }"
:disabled-dates="disabledDates"
/>
</div>
<button type="submit">Submit</button>
</form>
</template>
<script setup>
import { ref } from 'vue';
const formData = ref({
date: ''
});
const disabledDates = ref({
pastDates: true,
weekends: true
});
const handleSubmit = (e) => {
e.preventDefault();
console.log('Form submitted with date:', formData.value.date);
};
</script>API Reference
Props
| Name | Description | Type | Default |
|---|---|---|---|
| modelValue | The selected date value (v-model) | string | '' |
| selectedMonth | Pre-selected month (0-indexed) | number | undefined |
| selectedYear | Pre-selected year | number | undefined |
| selectedDay | Pre-selected day | number | undefined |
| minMaxYear | Year range constraints | MinMaxYearType | { min: 1900, max: currentYear } |
| restDays | Days to mark as rest days | RestDayType[] | [] |
| disabledDates | Date restrictions | DisabledDatesType | undefined |
| disabled | Disable the calendar | boolean | false |
| readonly | Make the calendar read-only | boolean | false |
| mode | Calendar mode: 'full', 'month-year', 'year-only' | DatePickerMode | 'full' |
| format | Date format for v-model | string | 'MM-DD-YYYY' |
Events
| Name | Description | Parameters |
|---|---|---|
| update:modelValue | Emitted when the selected date changes | (value: string) |
| update:month | Emitted when month changes (0-indexed) | (month: number) |
| update:year | Emitted when year changes | (year: number) |
| update:day | Emitted when day changes | (day: number) |
TypeScript Support
The component is fully typed with TypeScript interfaces:
interface MinMaxYearType {
min: number;
max: number;
}
interface DisabledDatesType {
to: string;
from: string;
pastDates: boolean | string;
futureDates: boolean | string;
selectedDates: Array<string>;
weekends: boolean;
weekdays: boolean;
selectedDays: Array<string>;
}
type RestDayType = 'su' | 'mo' | 'tu' | 'we' | 'th' | 'fr' | 'sa';
type DatePickerMode = 'full' | 'month-year' | 'year-only';Browser Support
- ✅ Chrome 60+
- ✅ Firefox 60+
- ✅ Safari 12+
- ✅ Edge 79+
Dependencies
- Vue 3.x
- @iconify/vue
- dayjs
- Tailwind CSS