Datepicker
The datepicker attaches a calendar popup to any text input. Supports custom date formats, min/max date constraints, and month/year navigation — all driven by data attributes and wired with useDatepicker.
Basic Datepicker
Minimal setup: add data-vd-datepicker to a text input (these demos use readonly so typing is off). With no format attribute, picked dates are written as YYYY-MM-DD. Focus the field to open the calendar and choose a day.
<input type="text"
class="vd-input"
placeholder="YYYY-MM-DD"
data-vd-datepicker
readonly>Pre-selected Value & Custom Format
Beyond basic: set value and data-vd-datepicker-format so the initial string is parsed and new picks match that pattern. Tokens: YYYY, MM, DD (case-insensitive).
<input type="text"
class="vd-input"
value="01/15/2026"
data-vd-datepicker
data-vd-datepicker-format="MM/DD/YYYY"
readonly>Min / Max Date Constraints
Use data-vd-datepicker-min and data-vd-datepicker-max with YYYY-MM-DD bounds. Out-of-range days are disabled; the view snaps to a month that contains selectable dates.
<input type="text"
class="vd-input"
data-vd-datepicker
data-vd-datepicker-min="2026-05-01"
data-vd-datepicker-max="2026-05-31"
readonly>API Reference
Wiring
// Vue 3 — the useDatepicker composable wires every
// [data-vd-datepicker] input inside the root ref.
import { ref } from 'vue';
import { useDatepicker } from "@vanduo-oss/vd3";
const root = ref<HTMLElement | null>(null);
useDatepicker(root); // cleanup is automatic on unmount
// listen for picks
root.value?.addEventListener('datepicker:select', (e) => {
console.log(e.detail.date, e.detail.formatted);
});CSS Classes
| Class | Description |
|---|---|
.vd-datepicker-popup | The floating calendar container positioned below the input |
.vd-datepicker-header | Header row with month/year label and navigation arrows |
.vd-datepicker-grid | Wraps the weekday row and week rows (role="grid") |
.vd-datepicker-days | Legacy 7-column grid class (week rows use .vd-datepicker-row) |
.vd-datepicker-day | Individual day cell button |
.vd-datepicker-day.is-today | Highlights today's date with a ring indicator |
.vd-datepicker-day.is-selected | The currently selected date (filled primary color) |
.vd-datepicker-day.is-disabled | Dates outside the min/max range (greyed out, not clickable) |
.vd-datepicker-day.is-outside | Days from the previous/next month shown for grid continuity |
Data Attributes
| Attribute | Description |
|---|---|
data-vd-datepicker | Activates the datepicker on the input |
data-vd-datepicker-format | Date format string. Tokens: YYYY, MM, DD (matched case-insensitively). Default: "YYYY-MM-DD" |
data-vd-datepicker-min | Earliest selectable date in YYYY-MM-DD format |
data-vd-datepicker-max | Latest selectable date in YYYY-MM-DD format |
Composable API
| Symbol | Description |
|---|---|
useDatepicker(root) | Composable — attaches a calendar to every [data-vd-datepicker] input inside the root ref. Call once in setup(). |
(automatic cleanup) | The popup and listeners are removed on component unmount via onUnmounted — there is no manual destroy step. |
Events
| Event | Description |
|---|---|
datepicker:select | Fired on the input when a date is picked. event.detail contains { date: Date, formatted: string } |
Accessibility
- The popup has
role="dialog"andaria-label="Choose date" - Calendar uses
role="grid"; weekday labels userole="columnheader"; in-month days userole="gridcell" - ← / → move by day; ↑ / ↓ move by week
- Home / End jump to start/end of the current week
- Page Up / Page Down navigate by month
- Enter selects the focused date; Escape closes the popup and returns focus to the input
- Disabled dates have
aria-disabled="true"and are skipped during keyboard navigation