Components / Forms

Calendar

An inline keyboard-accessible single-date or date-range calendar.

Preview

October 2026

October 2026

Install

Run in your project
Package manager
npx @getweini/cli@latest add calendar

Use cases

Inline date selection

Keep a date grid visible when choosing a date is the main task.

Availability range

Let users choose start and end dates directly in a page without opening a popover.

Usage example

Vue
<script setup lang="ts">
import { ref } from 'vue'
import Calendar from './components/ui/calendar/Calendar.vue'
const date = ref('2026-10-12')
const messages = { previousMonth: 'Previous month', nextMonth: 'Next month' }
</script>
<template><Calendar v-model="date" :messages="messages" /></template>

More examples

US and French week layouts

Locale changes labels; firstDayOfWeek separately controls the week grid.

US and French week layouts
<script setup lang="ts">
import { ref } from 'vue'
import Calendar from './components/ui/calendar/Calendar.vue'
const usDate = ref('2026-10-12')
const frenchDate = ref('2026-10-12')
const english = { previousMonth: 'Previous month', nextMonth: 'Next month' }
const french = { previousMonth: 'Mois précédent', nextMonth: 'Mois suivant' }
</script>
<template>
  <section aria-label="US event date">
    <Calendar v-model="usDate" locale="en-US" :first-day-of-week="0" :messages="english" />
  </section>
  <section aria-label="Date de l’événement">
    <Calendar v-model="frenchDate" locale="fr-FR" :first-day-of-week="1" :messages="french" />
  </section>
</template>

Inline availability range

The second tuple entry stays empty until the end date is chosen.

Inline availability range
<script setup lang="ts">
import { ref } from 'vue'
import Calendar from './components/ui/calendar/Calendar.vue'
const range = ref<[string, string]>(['', ''])
const messages = { previousMonth: 'Previous month', nextMonth: 'Next month' }
</script>
<template>
  <section aria-label="Available dates">
    <Calendar v-model="range" mode="range" min="2026-10-01" max="2026-12-31" locale="en-GB" :first-day-of-week="1" :messages="messages" />
  </section>
  <p v-if="range[0]">Start: {{ range[0] }}; end: {{ range[1] || 'choose an end date' }}</p>
</template>

Date and timezone for scheduling

Keep the chosen local date and IANA zone separate; an existing instant can be displayed in that zone with Intl.

Date and timezone for scheduling
<script setup lang="ts">
import { computed, ref } from 'vue'
import Calendar from './components/ui/calendar/Calendar.vue'
const localDate = ref('2026-10-12')
const timeZone = ref('Europe/Luxembourg')
const existingInstant = ref('2026-10-12T13:00:00Z')
const messages = { previousMonth: 'Previous month', nextMonth: 'Next month' }
const existingLocalTime = computed(() => new Intl.DateTimeFormat('en-GB', {
  dateStyle: 'medium', timeStyle: 'short', timeZone: timeZone.value,
}).format(new Date(existingInstant.value)))
const schedulingInput = computed(() => ({ localDate: localDate.value, timeZone: timeZone.value }))
</script>
<template>
  <section aria-label="Meeting date">
    <Calendar v-model="localDate" locale="en-GB" :first-day-of-week="1" :messages="messages" />
  </section>
  <p>Chosen date: {{ schedulingInput.localDate }} in {{ schedulingInput.timeZone }}</p>
  <p>Existing appointment in that zone: {{ existingLocalTime }}</p>
</template>

Locale and time zones

These calendars share one selected YYYY-MM-DD date. Locale changes the displayed month and day names; firstDayOfWeek changes the grid. The underlying date value remains the same. Calendar renders Gregorian dates; setting a locale does not switch calendar systems.

United States · en-US

October 2026

France · fr-FR

octobre 2026

Japan · ja-JP

2026年10月

Selected date: 2026-10-12

One instant in three time zones

An event at 2026-10-12T23:30:00Z lands on different local dates. Calendar does not convert instants; choose and store an IANA time zone in your application when scheduling events.

America/New_York
Mon, Oct 12, 2026, 7:30 PM EDT
Europe/Luxembourg
Tue, Oct 13, 2026, 1:30 AM GMT+2
Asia/Tokyo
Tue, Oct 13, 2026, 8:30 AM GMT+9

Key API

The most useful props, models, slots, events, and methods for this component.

Key API for Calendar
NameTypeDefault or requirement
v-modelstring | [string, string]undefined
modesingle | rangesingle
min / maxYYYY-MM-DDundefined
localestringen-US
firstDayOfWeek0–61
messagesCalendarMessagesrequired

Arrow keys move by day or week; Home/End jump to week edges and Page Up/Down change months. Range mode emits an empty end until the second date is selected.

Implementation notes

  • Calendar stores Gregorian YYYY-MM-DD dates, not timezone-aware instants or dates in another calendar system. Locale affects month/day labels, while firstDayOfWeek sets the grid order.
  • To create an instant from a chosen local date, combine it with a wall-clock time and IANA timezone in your application or backend and resolve daylight-saving gaps or overlaps. Intl formats an existing instant in a zone; it does not turn a date-only Calendar value into an instant.

Accessibility and localization

  • Give each inline calendar a surrounding accessible name and translate previous/next month messages. The roving day button supports arrows, Home/End, and Page Up/Down.
Weini UIDesign system · Vue component library · Free and public