Back to components
Components

DatePickerField

A form field to pick dates, either as an input that opens a calendar popup or as an inline calendar, with label, help text and validation.

Component

Help text example

Props

Props Required Default Type
idtrue — string
label — — string
ariaLabel — — string
helpText — — string
helpTextPosition — Position.BOTTOMPosition
type — DatePickerType.DATEDatePickerType
variant — PickerVariant.INPUTPickerVariant
modelValue — nullstring | string[] | CalendarRange | null
mode — CalendarMode.SINGLECalendarMode
placeholder — — string
icon — — string
size — InputSize.MDInputSize
displayFormat — — Intl.DateTimeFormatOptions
closeOnSelect — trueboolean
clearable — trueboolean
calendarPosition — Position.BOTTOMPosition
autoFlip — trueboolean
min — — string
max — — string
isDateDisabled — () => false(date: string) => boolean
locale — 'en-US'string
firstDayOfWeek — 0number
color — ColorAccent.PRIMARY_BRANDColorAccent
hasYearControls — falseboolean
hasOutsideDays — trueboolean
hasWeekNumbers — falseboolean
isRounded — falseboolean
isNavigationLocked — falseboolean
isBoxed — trueboolean
markers — {}Record<string, CalendarMarker[]>
maxMarkers — 3number
dayPopoverTrigger — Trigger.MANUALTrigger
hasDayPopover — — (date: string) => boolean
dayPopoverPosition — Position.BOTTOMPosition
dayPopoverAlign — — Align
dayPopoverAutoFlip — trueboolean
hourFormat — — HourFormat
hasSeconds — falseboolean
minuteStep — 1number
secondStep — 1number
validator — () => null(value: unknown) => string | null
error — ''string
disabled — falseboolean
readonly — falseboolean
required — falseboolean
showOptionalLabel — trueboolean
optionalLabel — — string
transparent — falseboolean
clearAriaLabel — — string
openAriaLabel — — string
doneText — — string
clearText — — string
glowColorMode — GlowColorMode.NONEGlowColorMode
glowTrigger — GlowTrigger.FOCUSGlowTrigger
glowType — GlowType.INNERGlowType
glowOpacity — 40number
glowSize — — number

Slots

Name Description
day-popover

Content of the panel of a day in the calendar, shown according to `dayPopoverTrigger`. Receives `date` (the ISO date), `markers` (the markers of the day) and `close` (a function that closes the panel).

Usage

id

Sets the id of the input (and the for of the label). Required.

 <template>
    <DatePickerField id="birth-date" />
</template>
 
  • Type: string

label

Sets the label shown above the field. In the INLINE variant it also names the calendar.

 <template>
    <DatePickerField id="date" label="Birth date" />
</template>
 
  • Type: string

ariaLabel

Sets the accessible name when there is no visible label.

 <template>
    <DatePickerField id="date" ariaLabel="Birth date" />
</template>
 
  • Type: string

helpText

Sets the help text. When there is an error, the error is shown instead.

 <template>
    <DatePickerField id="date" helpText="Pick your birth date" />
</template>
 
  • Type: string

helpTextPosition

Sets where the help text is shown, via the Position enum.

 <template>
    <DatePickerField id="date" :helpTextPosition="Position.TOP" helpText="Hint" />
</template>
 
  • Type: Position
  • Default: Position.BOTTOM

Options

Value Description
TOP

top

BOTTOM

bottom

type

Sets what the field picks, via the DatePickerType enum. The values are the ones of the native input types they replace, so a v-model keeps the same format.

 <template>
    <DatePickerField id="week" :type="DatePickerType.WEEK" label="Week" />
</template>
 
  • Type: DatePickerType
  • Default: DatePickerType.DATE

Options

Value Description
DATE

date: an ISO date, such as `2026-10-15`

MONTH

month: a month, such as `2026-10`

WEEK

week: an ISO week, such as `2026-W41`

DATETIME_LOCAL

datetime-local: a date and a time, such as `2026-10-15T19:30`

variant

Sets how the calendar is shown via the PickerVariant enum. INPUT shows a field that opens the calendar in a popup, and INLINE shows the calendar itself in place of the field. The label, help text and error are shown in both.

 <template>
    <DatePickerField id="date" :variant="PickerVariant.INLINE" label="Date" />
</template>
 
  • Type: PickerVariant
  • Default: PickerVariant.INPUT

Options

Value Description
INPUT

input

INLINE

inline

modelValue

Sets the selected value. In SINGLE mode it is a string, in MULTIPLE mode an array of strings and in RANGE mode a CalendarRange. The format of each string depends on the type: a date (2026-10-15), a month (2026-10), an ISO week (2026-W41) or a date and time (2026-10-15T19:30). Bind it with v-model.

 <template>
    <DatePickerField v-model="date" id="date" />
</template>
 
  • Type: string | string[] | CalendarRange | null
  • Default: null

TypeScript Interface

 export interface CalendarRange {
    start: string | null
    end: string | null
}
 

mode

Sets how many selections can be made, via the CalendarMode enum. See the Calendar for how each mode behaves. It combines with the type: a range of months, several weeks... The DATETIME_LOCAL type always takes one.

 <template>
    <DatePickerField v-model="range" id="range" :mode="CalendarMode.RANGE" />
</template>
 
  • Type: CalendarMode
  • Default: CalendarMode.SINGLE

Options

Value Description
SINGLE

single

MULTIPLE

multiple

RANGE

range

placeholder

Sets the placeholder of the input. Falls back to a text for the type in useDSConfig().calendar. Only applies to the INPUT variant.

 <template>
    <DatePickerField id="date" placeholder="Choose a day" />
</template>
 
  • Type: string

icon

Sets an icon shown at the start of the input. Only applies to the INPUT variant.

 <template>
    <DatePickerField id="date" icon="mdi:cake-variant-outline" />
</template>
 
  • Type: string

size

Sets the height of the input via the InputSize enum. Only applies to the INPUT variant.

 <template>
    <DatePickerField id="date" :size="InputSize.LG" />
</template>
 
  • Type: InputSize
  • Default: InputSize.MD

Options

Value Description
MD

md

LG

lg

displayFormat

Sets how dates are written in the input, using Intl.DateTimeFormat options. Defaults to a numeric day/month/year order that follows the locale, and to the month name and year for the MONTH type. It does not apply to the WEEK type or to the time of DATETIME_LOCAL.

 <template>
    <DatePickerField id="date" :displayFormat="{ dateStyle: 'long' }" />
</template>
 
  • Type: Intl.DateTimeFormatOptions

closeOnSelect

Closes the popup once the selection is complete: after one date, month or week, and after the end date of a range. MULTIPLE mode and the DATETIME_LOCAL type never close on their own, since they take more than one pick: close them with Escape or by clicking outside.

 <template>
    <DatePickerField id="date" :closeOnSelect="false" />
</template>
 
  • Type: boolean
  • Default: true

clearable

Shows a button to clear the value while there is one.

 <template>
    <DatePickerField id="date" :clearable="false" />
</template>
 
  • Type: boolean
  • Default: true

calendarPosition

Sets whether the popup opens below or above the input, via the Position enum.

 <template>
    <DatePickerField id="date" :calendarPosition="Position.TOP" />
</template>
 
  • Type: Position
  • Default: Position.BOTTOM

Options

Value Description
TOP

top

BOTTOM

bottom

autoFlip

Moves the calendar to the other side when it does not fit in the window. If it would be cut off at the bottom or the top edge of the screen and there is more room on the other side, it opens there instead. The position is checked when it opens, and calendarPosition is only the starting point. Set it to false to always keep the position as given.

 <template>
    <DatePickerField v-model="date" id="date" :autoFlip="false" />
</template>
 
  • Type: boolean
  • Default: true

min

Sets the earliest selectable value, in the format of the type: a date, a month (2026-10), a week (2026-W41) or a date and time (2026-10-15T09:00). In date and time, the time limit only applies on the day of the date limit.

 <template>
    <DatePickerField id="date" min="2026-10-10" />
</template>
 
  • Type: string

max

Sets the latest selectable value, in the same formats as min.

 <template>
    <DatePickerField id="date" max="2026-10-20" />
</template>
 
  • Type: string

isDateDisabled

Receives each day as an ISO string and returns true to disable it.

 <template>
    <DatePickerField id="date" :isDateDisabled="isWeekend" />
</template>
 
  • Type: (date: string) => boolean
  • Default: () => false

locale

Sets the BCP 47 locale used for the text in the input and the calendar.

 <template>
    <DatePickerField id="date" locale="es-ES" :firstDayOfWeek="1" />
</template>
 
  • Type: string
  • Default: 'en-US'

firstDayOfWeek

Sets the first column of the calendar, from 0 (Sunday) to 6 (Saturday). The WEEK type always starts on Monday.

 <template>
    <DatePickerField id="date" :firstDayOfWeek="1" />
</template>
 
  • Type: number
  • Default: 0

color

Sets the accent color of the calendar. Supports PRIMARY_BRAND and SECONDARY_BRAND.

 <template>
    <DatePickerField id="date" :color="ColorAccent.SECONDARY_BRAND" />
</template>
 
  • Type: ColorAccent
  • Default: ColorAccent.PRIMARY_BRAND

Options

Value Description
PRIMARY_BRAND

primary-brand

SECONDARY_BRAND

secondary-brand

hasYearControls

Shows buttons to jump a year in the calendar header.

 <template>
    <DatePickerField id="date" :hasYearControls="true" />
</template>
 
  • Type: boolean
  • Default: false

hasOutsideDays

Shows the days of the adjacent months in the calendar.

 <template>
    <DatePickerField id="date" :hasOutsideDays="false" />
</template>
 
  • Type: boolean
  • Default: true

hasWeekNumbers

Shows the ISO week number of each row in the calendar. The WEEK type always shows them.

 <template>
    <DatePickerField id="date" :hasWeekNumbers="true" :firstDayOfWeek="1" />
</template>
 
  • Type: boolean
  • Default: false

isRounded

Makes the calendar cells fully round.

 <template>
    <DatePickerField id="date" :isRounded="true" />
</template>
 
  • Type: boolean
  • Default: false

isNavigationLocked

Locks the calendar to the visible month. See the Calendar.

 <template>
    <DatePickerField id="date" :isNavigationLocked="true" />
</template>
 
  • Type: boolean
  • Default: false

isBoxed

Adds the border and background to the calendar. Only applies to the INLINE variant, since the popup is always boxed.

 <template>
    <DatePickerField id="date" :variant="PickerVariant.INLINE" :isBoxed="false" />
</template>
 
  • Type: boolean
  • Default: true

markers

Shows dots under the days of the calendar, such as events or tasks. It is passed to the Calendar. It maps ISO dates to a list of markers. A marker can have a color, from the ColorAccent enum (PRIMARY_BRAND by default), and a label, which is added to the aria-label of the day so screen readers get it too. The dots follow the design system colors, and on a selected day they use the color of the text on filled backgrounds so they stay visible.

 <template>
    <DatePickerField v-model="date" id="date" :markers="events" />
</template>

<script setup lang="ts">
const events = {
    '2026-10-15': [{ color: ColorAccent.DANGER, label: 'Deploy' }],
    '2026-10-20': [{ label: 'Review' }, { color: ColorAccent.SUCCESS, label: 'Release' }],
}
</script>
 
  • Type: Record<string, CalendarMarker[]>
  • Default: {}

TypeScript Interface

 export interface CalendarMarker {
    color?: ColorAccent
    label?: string
}
 

maxMarkers

Sets how many dots are drawn under a day. The labels of all its markers are still part of the aria-label.

 <template>
    <DatePickerField v-model="date" id="date" :markers="events" :maxMarkers="2" />
</template>
 
  • Type: number
  • Default: 3

dayPopoverTrigger

Sets when the panel of a day opens, via the Trigger enum. See the Calendar for the details. The CLICK trigger selects the day too, which closes the popup unless closeOnSelect is off or the selection takes more picks, so HOVER is usually the better fit for a date field. The content of the panel is the day-popover slot, which receives the date, its markers and a close function. By default the panel opens only for days with markers, and hasDayPopover changes that. It also closes with Escape, with a click outside, and when the visible month changes. Without the slot, or with MANUAL, no panel is shown.

 <template>
    <DatePickerField v-model="date" id="date" :markers="events" :dayPopoverTrigger="Trigger.HOVER">
        <template #day-popover="{ date, markers, close }">
            <p v-for="marker in markers" :key="marker.label">{{ marker.label }}</p>
        </template>
    </DatePickerField id="date">
</template>
 
  • Type: Trigger
  • Default: Trigger.MANUAL

Options

Value Description
CLICK

click: a click opens the panel (and a second click closes it). The click still selects the day.

HOVER

hover: the panel opens while the pointer or the keyboard focus is on the day, and stays open while the pointer is over it.

MANUAL

manual: the panel never opens. This is the default.

The panel opens below the day, towards the inside of the calendar for the first and last columns. It is not repositioned near the edge of the screen and can be clipped by a parent with overflow: hidden.

hasDayPopover

Receives each day as an ISO string and returns true when it has a panel. It replaces the default rule of opening only for days with markers, so you can show a panel on any day, such as an empty state with an add button.

 <template>
    <DatePickerField v-model="date" id="date" :dayPopoverTrigger="Trigger.CLICK" :hasDayPopover="isWorkday">
        <template #day-popover="{ date }">
            <ActionButton text="Add task" @click="addTask(date)" />
        </template>
    </DatePickerField id="date">
</template>
 
  • Type: (date: string) => boolean

dayPopoverPosition

Sets whether the panel of a day opens below or above it, via the Position enum. See the Calendar for the details. It is not the position of the calendar popup, which is calendarPosition. With dayPopoverAutoFlip, it goes to the other side when it does not fit.

 <template>
    <DatePickerField v-model="date" id="date" :markers="events" :dayPopoverTrigger="Trigger.HOVER" :dayPopoverPosition="Position.TOP">
        <template #day-popover="{ date }">{{ date }}</template>
    </DatePickerField v-model="date" id="date">
</template>
 
  • Type: Position
  • Default: Position.BOTTOM

Options

Value Description
BOTTOM

bottom

TOP

top

dayPopoverAlign

Sets how the panel is aligned with its day, via the Align enum. Without it, the panel is centered under the day, and the first two and last two columns align it inwards (LEFT and RIGHT) so it stays inside the calendar.

 <template>
    <DatePickerField v-model="date" id="date" :markers="events" :dayPopoverTrigger="Trigger.HOVER" :dayPopoverAlign="Align.LEFT">
        <template #day-popover="{ date }">{{ date }}</template>
    </DatePickerField v-model="date" id="date">
</template>
 
  • Type: Align

Options

Value Description
LEFT

left: the left edge of the panel is aligned with the left edge of the day

CENTER

center: the panel is centered on the day

RIGHT

right: the right edge of the panel is aligned with the right edge of the day

dayPopoverAutoFlip

Moves the panel when it does not fit in the window. It goes to the other side, above or below, when it would be cut off and there is more room there, and it aligns to the right or the left when it would overflow horizontally. The position is checked when the panel opens, and a position or align that you set is only the starting point. Set it to false to always keep the placement as given.

 <template>
    <DatePickerField v-model="date" id="date" :markers="events" :dayPopoverTrigger="Trigger.HOVER" :dayPopoverAutoFlip="false">
        <template #day-popover="{ date }">{{ date }}</template>
    </DatePickerField v-model="date" id="date">
</template>
 
  • Type: boolean
  • Default: true

hourFormat

Sets the 12 or 24 hour clock of the time picker via the HourFormat enum. Defaults to the one of the locale. Only applies to the DATETIME_LOCAL type.

 <template>
    <DatePickerField id="date" :type="DatePickerType.DATETIME_LOCAL" :hourFormat="HourFormat.HOURS_12" />
</template>
 
  • Type: HourFormat

Options

Value Description
HOURS_12

12

HOURS_24

24

hasSeconds

Adds a seconds column to the time picker and to the value (YYYY-MM-DDTHH:mm:ss). Only applies to the DATETIME_LOCAL type.

 <template>
    <DatePickerField id="date" :type="DatePickerType.DATETIME_LOCAL" :hasSeconds="true" />
</template>
 
  • Type: boolean
  • Default: false

minuteStep

Sets the interval between the minutes of the time picker. Only applies to the DATETIME_LOCAL type.

 <template>
    <DatePickerField id="date" :type="DatePickerType.DATETIME_LOCAL" :minuteStep="15" />
</template>
 
  • Type: number
  • Default: 1

secondStep

Sets the interval between the seconds of the time picker. Only applies to the DATETIME_LOCAL type.

 <template>
    <DatePickerField id="date" :type="DatePickerType.DATETIME_LOCAL" :hasSeconds="true" :secondStep="15" />
</template>
 
  • Type: number
  • Default: 1

validator

Validates the value and returns an error message, or null. It runs only when the field is required, whenever the value changes and when the popup closes.

 <template>
    <DatePickerField id="date" required :validator="validateField" />
</template>
 
  • Type: (value: unknown) => string | null
  • Default: () => null

error

Sets the error message. The field and the help text switch to the error style.

 <template>
    <DatePickerField id="date" error="Required field" />
</template>
 
  • Type: string
  • Default: ''

disabled

Disables the field and the calendar.

 <template>
    <DatePickerField id="date" :disabled="true" />
</template>
 
  • Type: boolean
  • Default: false

readonly

Shows the value without letting the user change it. The popup does not open, and an inline calendar can be browsed but not selected.

 <template>
    <DatePickerField id="date" :readonly="true" />
</template>
 
  • Type: boolean
  • Default: false

required

Marks the field as required: hides the optional label and enables the validator.

 <template>
    <DatePickerField id="date" label="Date" :required="true" />
</template>
 
  • Type: boolean
  • Default: false

showOptionalLabel

Shows the optional text next to the label when the field is not required.

 <template>
    <DatePickerField id="date" label="Date" :showOptionalLabel="false" />
</template>
 
  • Type: boolean
  • Default: true

optionalLabel

Sets the optional text. Falls back to useDSConfig().forms.optionalLabelText().

 <template>
    <DatePickerField id="date" label="Fecha" optionalLabel="(opcional)" />
</template>
 
  • Type: string

transparent

Removes the background of the input.

 <template>
    <DatePickerField id="date" :transparent="true" />
</template>
 
  • Type: boolean
  • Default: false

clearAriaLabel

Sets the aria-label of the clear button. Falls back to useDSConfig().forms.clearSelectionText().

 <template>
    <DatePickerField id="date" clearAriaLabel="Borrar fecha" />
</template>
 
  • Type: string

openAriaLabel

Sets the aria-label of the calendar button. Falls back to useDSConfig().calendar.openText().

 <template>
    <DatePickerField id="date" openAriaLabel="Abrir calendario" />
</template>
 
  • Type: string

doneText

Sets the text of the button that closes the calendar in CalendarMode.MULTIPLE and in the date and time type, where no pick completes the selection. Falls back to useDSConfig().calendar.doneText().

 <template>
    <DatePickerField id="date" :mode="CalendarMode.MULTIPLE" doneText="Listo" />
</template>
 
  • Type: string

clearText

Sets the text of the button that clears the selected value in CalendarMode.MULTIPLE and in the date and time type. It sits next to the done button and keeps the calendar open. Falls back to useDSConfig().calendar.clearText().

 <template>
    <DatePickerField id="date" :mode="CalendarMode.MULTIPLE" clearText="Limpiar" />
</template>
 
  • Type: string

glowColorMode

Draws a glow around the date input box only. The label and the help text do not glow. It is shown in light mode, dark mode, both or none, and it uses the GlowColorMode enum. It is GlowColorMode.NONE by default, so the field has no glow until you turn it on.

The glow uses the brand color and turns to the error color when the field has an error.

 <template>
    <DatePickerField :glowColorMode="GlowColorMode.DARK" />
</template>
 
  • Type: GlowColorMode
  • Default: GlowColorMode.NONE (set by the DS config, see Configuration)

Options

Value Description
NONE

No glow.

BOTH

Glow in light and dark mode.

LIGHT

Glow in light mode only.

DARK

Glow in dark mode only.

glowTrigger

Sets when the glow appears. It uses the GlowTrigger enum and works together with glowColorMode, which decides in which theme the glow shows. It is GlowTrigger.FOCUS by default.

FOCUS shows the glow while the field has focus. On touch screens there is no hover, so with HOVER the glow never shows.

 <template>
    <DatePickerField :glowColorMode="GlowColorMode.BOTH" :glowTrigger="GlowTrigger.FOCUS" />
</template>
 
  • Type: GlowTrigger
  • Default: GlowTrigger.FOCUS (set by the DS config, see Configuration)

Options

Value Description
ALWAYS

The glow is always visible.

HOVER

The glow shows while the pointer is over the field.

FOCUS

The glow shows while the field has focus.

HOVER_FOCUS

The glow shows on hover and on focus.

glowType

Sets where the glow is drawn. It uses the GlowType enum and works together with glowColorMode. It is GlowType.INNER by default.

 <template>
    <DatePickerField :glowColorMode="GlowColorMode.BOTH" :glowType="GlowType.INNER" />
</template>
 
  • Type: GlowType
  • Default: GlowType.INNER (set by the DS config, see Configuration)

Options

Value Description
OUTER

The glow spreads around the outside of the element.

INNER

The glow is drawn inside the element, along its edges.

glowOpacity

Sets how strong the glow is, from 0 (invisible) to 100 (full color). The default is 40. Values move in steps of 5, so 42 is rounded to 40. It has no effect while glowColorMode is GlowColorMode.NONE.

 <template>
    <DatePickerField :glowColorMode="GlowColorMode.BOTH" :glowOpacity="30" />
</template>
 
  • Type: number
  • Default: 40 (set by the DS config, see Configuration)

glowSize

Sets how far the glow spreads, in pixels. It is null by default, so each component keeps its own size (for example, buttons follow their size). Values move in steps of 2 from 0 to 64, so 13 is rounded to 14. It has no effect while glowColorMode is GlowColorMode.NONE.

 <template>
    <DatePickerField :glowColorMode="GlowColorMode.BOTH" :glowSize="32" />
</template>
 
  • Type: number
  • Default: null (set by the DS config, see Configuration)

Accessibility

For every type, in the INPUT variant the field is a read-only text input with aria-haspopup="dialog" and aria-expanded. Focus moves into the calendar when it opens and returns to the input when it closes.

Value Description
Enter / Space / ArrowDown

Opens the calendar from the input.

Escape

Closes the calendar and returns the focus to the input.

Inside the calendar, the arrow keys, Home, End and PageUp / PageDown move between days. See the Calendar accessibility notes for the full list.

Emits

Value Description
@update:modelValue

Emitted with the new value when it changes: a string, an array of strings or a `CalendarRange`, depending on the mode. Clearing emits `null`, `[]` or `{ start: null, end: null }`.

@day-click

Emitted with `{ date, key, isDisabled }` when a day of the calendar is clicked, also for disabled days and when the calendar is readonly. `key` is what the click would select: the date, its ISO week or its month, depending on the `unit`.

@day-hover

Emitted with `{ date, key, isDisabled }` when the pointer enters a day.

@day-hover-end

Emitted when the pointer leaves the grid of days.

@month-change

Emitted with `{ year, month, from, to }` when the visible month changes, by the buttons, the month and year pickers or the keyboard. `month` goes from 1 to 12, and `from` and `to` are the first and last day of the month as ISO dates, so you can load its events.

@update:error

Emitted with the validation message, or an empty string, when the validator runs.

Example

 <template>
    <DatePickerField :modelValue="date" id="date" @update:modelValue="handleChange" />
</template>

<script setup lang="ts">
const date = ref<string | null>(null)

const handleChange = (value: string | null) => {
    date.value = value
}
</script>
 

Methods

Value Description
open()

Opens the popup. Does nothing when the field is disabled, readonly or inline.

close()

Closes the popup and returns the focus to the input.