Skip to content

DatePicker

Three components over one implementation: WxDatePicker (a date), WxDateTimePicker (a date and a time) and WxTimePicker (a time). They wrap @vuepic/vue-datepicker — calendars are a lot of behaviour to get right, and that library already has.

Date

Model: 2026-03-14

Date and time

Model: 2026-03-14 09:30

Time

Model: 09:00

In a form item, with an error and a bound range
In another language — open the calendar
Русский
Disabled

The model is a string, in the backend's format

By default the model holds exactly what a Laravel column expects, so the value can go to the API and come back without a conversion step anywhere:

ComponentModelField shows
WxDatePicker2026-03-1414.03.2026
WxDateTimePicker2026-03-14 09:3014.03.2026 09:30
WxTimePicker09:3009:30

Add seconds and both the stored and the shown value gain :ss. An empty field is null, never an empty string.

vue
<script setup lang="ts">
import { ref } from 'vue'

const publishedAt = ref('2026-03-14')
</script>

<template>
  <wx-date-picker v-model="publishedAt" placeholder="Pick a date" />
</template>

Override either side when the backend disagrees, or opt out of strings entirely:

vue
<template>
  <!-- stored as 14/03/2026, shown as 2026.03.14 -->
  <wx-date-picker v-model="value" value-format="dd/MM/yyyy" format="yyyy.MM.dd" />

  <!-- the model holds a Date object -->
  <wx-date-picker v-model="date" value-format="date" />
</template>

Props

All three take the same props; WxDateTimePicker and WxTimePicker simply fix type.

PropTypeDefaultDescription
modelValuestring | Date | nullnullCurrent value
type'date' | 'datetime' | 'time''date'What is being picked
valueFormatstringper typeFormat the value is stored in; 'date' keeps a Date
formatstringper typeFormat the field shows
placeholderstringPlaceholder text
clearablebooleantrueShow the clear button
minDatestring | DateEarliest selectable date
maxDatestring | DateLatest selectable date
secondsbooleanfalseInclude seconds
minutesIncrementnumber1Step of the minutes column
is24booleantrue24-hour clock
localestring | Localethe browserLanguage of the calendar
weekStartnumber10 is Sunday, 1 is Monday
autoApplybooleantrueApply on pick, with no confirm button
textInputbooleanfalseAllow typing as well as picking
teleportboolean | stringtrueRender the menu in a portal
size'sm' | 'md' | 'lg''md'Control height
status'default' | 'success' | 'warning' | 'error''default'Validation state
disabledbooleanfalseDisables the field
readonlybooleanfalseRead-only field
idstringgeneratedOverrides the id the label points at; WxFormItem supplies one
namestringname of the underlying input
ariaLabelstringLabel when there is no visible one

Events: update:modelValue, change, clear, open, close.

teleport is on by default on purpose: a picker inside a WxCard or a scrolling table would otherwise be clipped by overflow: hidden.

Language

The library underneath carries exactly one language, en-US, so a calendar left alone heads a Russian screen with "Sep 2026" over a "Mo Tu We" row. locale takes a BCP-47 tag and the month and weekday names come from the browser's own Intl data — no language packs to import, and any tag the browser knows works:

vue
<template>
  <wx-date-picker v-model="publishedAt" locale="ru" />
</template>

An application in one language throughout says it once, and every picker under it follows — that is what an admin panel wants, because the calendar has to follow the language the user picked in the interface rather than the one their browser is set to:

ts
import { dateLocaleKey } from '@webx-ui/core'

app.provide(
  dateLocaleKey,
  computed(() => i18n.state.locale),
)

provideDateLocale(locale) does the same from inside a component. A locale prop on a field still wins over both, and with neither the browser's own language is used.

The library's own convention — a date-fns locale object — is still accepted, for a language the browser does not carry or a calendar that needs wording of its own. date-fns comes along with the picker, so it is importable without installing anything else:

vue
<script setup lang="ts">
import { uk } from 'date-fns/locale'
</script>

<template>
  <wx-date-picker v-model="value" :locale="uk" />
</template>

Anything else the library takes

Unknown attributes are passed straight through to the underlying picker, so its whole prop surface stays reachable without us re-declaring it:

vue
<template>
  <wx-date-picker v-model="value" :disabled-week-days="[6, 0]" range />
</template>

Theming

The library's --dp-* variables are mapped onto WebX tokens, so the calendar follows the theme, dark mode included, without its dark prop. Restyling the picker means overriding the same tokens as everything else — see Theming.

Accessibility

  • Inside a WxFormItem, the generated id reaches the real <input>, so the label's for works and the error message is linked by aria-describedby.
  • The error state is passed to the library the way it expects, so the field is marked invalid rather than merely coloured.
  • Keyboard navigation inside the calendar comes from the library: arrows move, Enter picks, Escape closes.

Bundle size

@vuepic/vue-datepicker is a real dependency of @webx-ui/core, installed automatically. It is not bundled into our output — your app resolves and de-duplicates it — but its stylesheet is part of @webx-ui/core/style.css, about 4 kB gzipped, whether or not you use a picker.

Released under the MIT License.