Raccourci clavier : Ctrl + K
Commencer

Sélecteur de date

Une grille de calendrier en ligne. Chaque date qu'il contient est une simple chaîne YYYY-MM-DD en heure locale et jamais un Date, si bien qu'une valeur ne peut pas glisser d'un jour d'un fuseau à l'autre.

Utilisation

vue
lun.mar.mer.jeu.ven.sam.dim.
<script setup lang="ts">
import { ref } from 'vue'
import { VDatePicker } from 'vectis-ui'

const date = ref('2026-06-10')
</script>

<template>
  <VDatePicker v-model="date" />
</template>

Exemples

Période

selection à range fait de la valeur un début et une fin, la période sous le pointeur étant prévisualisée entre les deux clics.

vue
lun.mar.mer.jeu.ven.sam.dim.
2026-06-19 to 2026-06-26
<script setup lang="ts">
import { ref } from 'vue'
import { VDatePicker, type DatePickerRange } from 'vectis-ui'

const period = ref<DatePickerRange>({ start: '2026-06-19', end: '2026-06-26' })
</script>

<template>
  <div class="column">
    <VDatePicker v-model="period" selection="range" />
    <output class="value" aria-label="Chosen period">
      {{ period.start ?? 'none' }} to {{ period.end ?? 'none' }}
    </output>
  </div>
</template>

<style scoped>
.column {
  display: grid;
  justify-items: start;
  gap: var(--vectis-space-3);
}
.value {
  font-family: var(--vectis-text-family-code);
  font-size: var(--vectis-text-body-sm-size);
  color: var(--vectis-color-text-muted);
}
</style>

Dates multiples

selection à multiple fait de la valeur une liste, un jour déjà présent en ressortant à un nouveau clic.

vue
lun.mar.mer.jeu.ven.sam.dim.
2026-06-05, 2026-06-12, 2026-06-19
<script setup lang="ts">
import { ref } from 'vue'
import { VDatePicker } from 'vectis-ui'

const dates = ref<string[]>(['2026-06-05', '2026-06-12', '2026-06-19'])
</script>

<template>
  <div class="column">
    <VDatePicker v-model="dates" selection="multiple" />
    <output class="value" aria-label="Chosen dates">{{ dates.join(', ') || 'none' }}</output>
  </div>
</template>

<style scoped>
.column {
  display: grid;
  justify-items: start;
  gap: var(--vectis-space-3);
}
.value {
  font-family: var(--vectis-text-family-code);
  font-size: var(--vectis-text-body-sm-size);
  color: var(--vectis-color-text-muted);
}
</style>

Raccourcis

Le slot #footer est une bande sous la grille, pour des actions ou pour les dates les plus demandées. Les boutons qui s'y trouvent écrivent le modèle comme n'importe quel autre contrôle.

vue
lun.mar.mer.jeu.ven.sam.dim.
<script setup lang="ts">
import { ref } from 'vue'
import { VButton, VDatePicker } from 'vectis-ui'

const date = ref('2026-06-10')

/* The clock is read in the handler and never at setup: the server cannot know what day it
   is where the reader stands, and a value taken there would not survive hydration. */
function inDays(offset: number) {
  const day = new Date()
  day.setDate(day.getDate() + offset)
  const month = String(day.getMonth() + 1).padStart(2, '0')
  date.value = `${day.getFullYear()}-${month}-${String(day.getDate()).padStart(2, '0')}`
}
</script>

<template>
  <VDatePicker v-model="date">
    <template #footer>
      <VButton variant="ghost" tone="neutral" size="sm" @click="inDays(0)">Today</VButton>
      <VButton variant="ghost" tone="neutral" size="sm" @click="inDays(1)">Tomorrow</VButton>
      <VButton variant="ghost" tone="neutral" size="sm" @click="inDays(7)">In a week</VButton>
    </template>
  </VDatePicker>
</template>

Dates désactivées

disabledDates accepte une liste de jours, ou une fonction interrogée pour une date à la fois. Un jour fermé reste visible, barré, et atteignable au clavier.

vue
a predicate
lun.mar.mer.jeu.ven.sam.dim.
a list
lun.mar.mer.jeu.ven.sam.dim.
<script setup lang="ts">
import { ref } from 'vue'
import { VDatePicker, VTypography } from 'vectis-ui'

const appointment = ref('2026-06-16')
const holiday = ref('2026-06-16')

/* A predicate answers for one date at a time, which is what makes a rule such as "no
   weekends" one line rather than an enumeration. */
function isWeekend(iso: string) {
  const day = new Date(`${iso}T00:00:00`).getDay()
  return day === 0 || day === 6
}

/* The other form: a plain list, for days that follow no rule. */
const closedDays = ['2026-06-11', '2026-06-12', '2026-06-25']
</script>

<template>
  <div class="row">
    <div class="group">
      <VTypography variant="overline" tone="muted">a predicate</VTypography>
      <VDatePicker v-model="appointment" :disabled-dates="isWeekend" />
    </div>

    <div class="group">
      <VTypography variant="overline" tone="muted">a list</VTypography>
      <VDatePicker v-model="holiday" :disabled-dates="closedDays" />
    </div>
  </div>
</template>

<style scoped>
.row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--vectis-space-6);
}
.group {
  display: grid;
  gap: var(--vectis-space-2);
}
</style>

Minimum et maximum

min et max bornent la navigation autant que le choix, dans toutes les vues.

vue
lun.mar.mer.jeu.ven.sam.dim.
<script setup lang="ts">
import { ref } from 'vue'
import { VDatePicker } from 'vectis-ui'

const date = ref('2026-06-15')
</script>

<template>
  <VDatePicker v-model="date" min="2026-06-05" max="2026-06-24" />
</template>

Pastilles

events dessine jusqu'à trois points sous un jour. Chacun accepte n'importe quelle couleur CSS et un label, qui est ce que lisent les technologies d'assistance.

vue
lun.mar.mer.jeu.ven.sam.dim.
<script setup lang="ts">
import { ref } from 'vue'
import { VDatePicker, type DatePickerEvent } from 'vectis-ui'

const date = ref('2026-06-10')

/* Up to three dots a day, in any CSS colour. A token keeps them in step with both themes,
   and a dot given none takes the accent. */
const events: DatePickerEvent[] = [
  { date: '2026-06-10', label: 'Kick-off' },
  { date: '2026-06-18', color: 'var(--vectis-color-danger)', label: 'Deadline' },
  { date: '2026-06-18', color: 'var(--vectis-color-warning)', label: 'Review' },
  { date: '2026-06-24', color: 'var(--vectis-color-success)', label: 'Release' },
]
</script>

<template>
  <VDatePicker v-model="date" :events="events" />
</template>

Jours adjacents

showAdjacentDays remplit les coins de la grille avec les mois voisins, grisés et inertes. selectAdjacentDays les rend aussi choisissables, et en choisir un déplace le calendrier vers son mois.

vue
hidden, the default
lun.mar.mer.jeu.ven.sam.dim.
shown
lun.mar.mer.jeu.ven.sam.dim.
1
2
3
4
5
6
7
8
9
10
11
12
shown and choosable
lun.mar.mer.jeu.ven.sam.dim.
<script setup lang="ts">
import { ref } from 'vue'
import { VDatePicker, VTypography } from 'vectis-ui'

const hidden = ref('2026-06-10')
const shown = ref('2026-06-10')
const selectable = ref('2026-06-10')
</script>

<template>
  <div class="row">
    <div class="group">
      <VTypography variant="overline" tone="muted">hidden, the default</VTypography>
      <VDatePicker v-model="hidden" />
    </div>

    <div class="group">
      <VTypography variant="overline" tone="muted">shown</VTypography>
      <VDatePicker v-model="shown" show-adjacent-days />
    </div>

    <div class="group">
      <VTypography variant="overline" tone="muted">shown and choosable</VTypography>
      <VDatePicker v-model="selectable" select-adjacent-days />
    </div>
  </div>
</template>

<style scoped>
.row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--vectis-space-6);
}
.group {
  display: grid;
  gap: var(--vectis-space-2);
}
</style>

Localisation

locale décide des noms de mois et de jours et du jour où commencent les semaines, et l'emporte sur la locale globale. firstDayOfWeek remplace le jour que cette locale aurait choisi.

vue
en-US, weeks from Sunday
SunMonTueWedThuFriSat
fr-FR, weeks from Monday
lun.mar.mer.jeu.ven.sam.dim.
ja-JP
en-US, weeks forced to Monday
MonTueWedThuFriSatSun
<script setup lang="ts">
import { ref } from 'vue'
import { VDatePicker, VTypography } from 'vectis-ui'

/* Each keeps its own value, so switching one does not disturb the others. */
const locales = ref([
  { tag: 'en-US', caption: 'en-US, weeks from Sunday', date: '2026-06-10' },
  { tag: 'fr-FR', caption: 'fr-FR, weeks from Monday', date: '2026-06-10' },
  { tag: 'ja-JP', caption: 'ja-JP', date: '2026-06-10' },
])

const forced = ref('2026-06-10')
</script>

<template>
  <div class="row">
    <div v-for="locale in locales" :key="locale.tag" class="group">
      <VTypography variant="overline" tone="muted">{{ locale.caption }}</VTypography>
      <VDatePicker v-model="locale.date" :locale="locale.tag" />
    </div>

    <div class="group">
      <VTypography variant="overline" tone="muted">en-US, weeks forced to Monday</VTypography>
      <VDatePicker v-model="forced" locale="en-US" :first-day-of-week="1" />
    </div>
  </div>
</template>

<style scoped>
.row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--vectis-space-6);
}
.group {
  display: grid;
  gap: var(--vectis-space-2);
}
</style>

API

Props

PropTypeDéfaut
selectionDatePickerSelection'single' | 'range' | 'multiple''single'
Ce que le lecteur choisit : une date unique, une période entre deux dates, ou un nombre quelconque de dates séparées. Cela détermine la forme de la valeur.
localestringaucune
Une locale BCP 47, qui décide des noms de mois et de jours et du premier jour de la semaine. Elle l'emporte sur la locale globale du design system et retombe dessus, ce pourquoi elle n'a pas de valeur par défaut littérale.
firstDayOfWeeknumberaucune
Force le jour où commencent les semaines, de 0 pour dimanche à 6 pour samedi. Omise, la locale décide.
minstringaucune
La première date sélectionnable, en chaîne ISO. Ni la navigation ni la sélection ne remontent au-delà.
maxstringaucune
La dernière date sélectionnable, en chaîne ISO. Ni la navigation ni la sélection ne vont au-delà.
disabledDatesDatePickerMatcheraucune
Les dates qui ne peuvent pas être choisies, en liste de chaînes ISO ou en fonction. Elles restent visibles, barrées, et restent atteignables au clavier.
showAdjacentDaysbooleanfalse
Remplit aussi les coins vides de la grille avec les jours grisés des mois voisins.
selectAdjacentDaysbooleanfalse
Permet de cliquer ces jours voisins, ce qui déplace le calendrier sur leur mois. Un jour cliquable doit être visible : cela implique donc de les afficher.
eventsDatePickerEvent[]aucune
Les événements à marquer, en trois points colorés au plus sous le jour concerné.
disabledbooleanfalse
Rend tout le calendrier inutilisable : aucune date ne peut être choisie, aucun mois atteint, et tout se grise par les jetons de couleur.
readonlybooleanfalse
Montre la sélection sans permettre de la changer. Le calendrier reste lisible et parcourable, un autre mois ou une autre année, ce qui le distingue de disabled.
labelstringaucune
Le nom accessible du sélecteur entier, son en-tête et sa grille ensemble. Une plage montrée comme deux calendriers côte à côte en demande un chacun, sinon un lecteur d'écran annonce deux fois le même groupe. Il retombe sur le dictionnaire, et un aria-label du consommateur l'emporte.
v-modelDatePickerValuenull
Ce qui est sélectionné, et sa forme suit selection : une chaîne ISO pour une date unique, une paire début et fin pour une période, un tableau pour plusieurs. Rien n'est sélectionné au départ.

Événements

ÉvénementType
select[value: DatePickerValue]
Une date a été choisie, avec la valeur telle qu'elle est désormais. Choisi ne veut pas dire terminé : une période ou une liste est encore en construction après lui, et c'est pourquoi VTimePicker nomme confirm la fin d'un choix.

Slots

SlotType
dayDatePickerDaySlotProps
Remplace le contenu d'une cellule de jour, pour afficher un prix ou une disponibilité sous le numéro. Elle reçoit tout ce que l'on sait de ce jour, y compris s'il appartient au mois affiché.
footer{}
La bande sous la grille, pour des actions comme Fermer ou Enregistrer, ou pour des dates prédéfinies.

Types

Les types que les tables ci-dessus nomment, écrits comme la librairie les déclare. Ceux qui portent export s'importent depuis vectis-ui pour typer votre propre code ; les autres décrivent la forme de ce qu'un slot fournit.

export interface DatePickerDaySlotProps {
  iso: string
  day: number
  inMonth: boolean
  disabled: boolean
  selected: boolean
  today: boolean
  inRange: boolean
  events: DatePickerEvent[]
}
export interface DatePickerEvent {
  date: string
  color?: string
  label?: string
}
export type DatePickerMatcher = string[] | ((iso: string) => boolean)
export interface DatePickerRange {
  start: string | null
  end: string | null
}
export type DatePickerValue = string | null | DatePickerRange | string[]

Variables CSS

TokenValeur
--vectis-control-size-date-picker-cell2.5rem
--vectis-control-size-date-picker-dayvar(--vectis-control-height-md)
--vectis-control-size-date-picker-dot0.25rem
--vectis-control-size-date-picker-nav-min5.375rem