Vitral 0.2
Form

DatePicker

A date field you can type into or pick from a calendar, read in the locale's format.

Import

main.ts
import { DatePicker } from '@vitral/vue';

Basic

Format from the locale · value: null
<script setup lang="ts">import { DatePicker, Label, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const today = new Date();const start = new Date(today.getFullYear(), today.getMonth(), today.getDate());const plus = (days: number) => new Date(start.getFullYear(), start.getMonth(), start.getDate() + days); const date = ref<Date | null>(null);const iso = ref<Date | null>(plus(3)); const shown = (value: Date | null) => (value ? value.toDateString() : 'null');</script> <template>    <StackPanel orientation="horizontal" spacing="0.75rem" align="start" wrap>        <StackPanel spacing="0.375rem" style="min-width: 16rem">            <Label for="dp-basic">Date</Label>            <DatePicker id="dp-basic" v-model="date" placeholder="Pick a date" aria-describedby="dp-basic-hint" />            <small id="dp-basic-hint" style="color: var(--vt-text-muted-color)">Format from the locale · value: {{ shown(date) }}</small>        </StackPanel>        <StackPanel spacing="0.375rem" style="min-width: 16rem">            <Label for="dp-iso">ISO format, weeks from Monday</Label>            <DatePicker id="dp-iso" v-model="iso" date-format="yyyy-MM-dd" :first-day-of-week="1" />        </StackPanel>    </StackPanel></template>

Constraints

Only the next 30 days, no weekends, and two blocked days. Unselectable days are skipped by the keys and cannot be clicked or typed.

<script setup lang="ts">import { DatePicker, Label, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const today = new Date();const start = new Date(today.getFullYear(), today.getMonth(), today.getDate());const plus = (days: number) => new Date(start.getFullYear(), start.getMonth(), start.getDate() + days); const booking = ref<Date | null>(null);const holidays = [plus(4), plus(5)];</script> <template>    <StackPanel spacing="0.375rem" style="min-width: 16rem">        <Label for="dp-booking">Delivery</Label>        <DatePicker id="dp-booking" v-model="booking" :min-date="start" :max-date="plus(30)" :disabled-days="[0, 6]" :disabled-dates="holidays" placeholder="Choose a weekday" />    </StackPanel></template>

Inline

The calendar on its own, without the field.

Pick-up day
September 2026
SuMoTuWeThFrSa
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910
Value: Sun Sep 27 2026
Disabled
September 2026
SuMoTuWeThFrSa
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910
<script setup lang="ts">import { DatePicker, StackPanel } from '@vitral/vue';import { ref } from 'vue'; const today = new Date();const start = new Date(today.getFullYear(), today.getMonth(), today.getDate());const plus = (days: number) => new Date(start.getFullYear(), start.getMonth(), start.getDate() + days); const inline = ref<Date | null>(plus(2));</script> <template>    <StackPanel orientation="horizontal" spacing="0.75rem" align="start" wrap>        <StackPanel spacing="0.375rem" style="min-width: 16rem">            <span id="dp-inline-label">Pick-up day</span>            <DatePicker v-model="inline" inline show-today-button show-clear-button aria-labelledby="dp-inline-label" />            <small style="color: var(--vt-text-muted-color)">Value: {{ inline ? inline.toDateString() : 'null' }}</small>        </StackPanel>        <StackPanel spacing="0.375rem" style="min-width: 16rem">            <span id="dp-inline-disabled">Disabled</span>            <DatePicker :model-value="plus(1)" inline disabled aria-labelledby="dp-inline-disabled" />        </StackPanel>    </StackPanel></template>

Sizes, variants and states

<script setup lang="ts">import { DatePicker } from '@vitral/vue'; const today = new Date();const start = new Date(today.getFullYear(), today.getMonth(), today.getDate());</script> <template>    <DatePicker size="small" placeholder="Small" aria-label="Small" />    <DatePicker placeholder="Normal" aria-label="Normal" />    <DatePicker size="large" placeholder="Large" aria-label="Large" />    <DatePicker variant="filled" placeholder="Filled" aria-label="Filled" />    <DatePicker invalid placeholder="Invalid" aria-label="Invalid" />    <DatePicker :model-value="start" disabled aria-label="Disabled" />    <DatePicker :model-value="start" readonly aria-label="Read only" /></template>

Fluid

<script setup lang="ts">import { DatePicker } from '@vitral/vue';</script> <template>    <DatePicker fluid placeholder="Fills its container" aria-label="Fluid" /></template>

API

Read from packages/vue/src/components/DatePicker/types.ts, so it says what the component actually accepts.

Props

NameTypeDescription
dateFormatstringA `formatDate` pattern (`yyyy yy MMMM MMM MM M dd d`); defaults to the locale's `dateFormat`.
minDateDate | nullThe earliest selectable day.
maxDateDate | nullThe latest selectable day.
disabledDatesDate[]Days that cannot be chosen.
disabledDaysnumber[]Weekdays that cannot be chosen, 0 = Sunday.
showTodayButtonbooleanA footer button that selects today.
showClearButtonbooleanA footer button that empties the value.
firstDayOfWeeknumber0 = Sunday; defaults to the locale's `firstDayOfWeek`.
placeholderstring—
inlinebooleanShow the calendar in place, without a text box or popup.
sizeSize—
variantInputVariantDefaults to the plugin's `inputVariant`.
invalidboolean—
disabledboolean—
readonlyboolean—
fluidboolean—
placementOverlayPlacement—
appendTostring`'body'` (the default), `'self'` to render in place, or a selector.

Plus pt, dt and unstyled from BaseProps, see pass-through and unstyled mode.

Emits

EventPayloadDescription
dateSelectdate: DateA day was chosen in the calendar, or typed and committed.
clear——
show——
hide——
monthChangeevent: DatePickerMonthChangeEvent—
focusevent: FocusEvent—
blurevent: FocusEvent—

Slots

NameSlot propsDescription
date(props: DatePickerDateSlotProps)The content of one day cell.
footer—Extra content in the calendar's footer.
dropdownicon—The calendar button's icon.