Calendar
A versatile and customizable calendar component for Nuxt UI, supporting date and range selection, time picking, and i18n.
Use Calendar to select dates, date ranges, and optional times. It requires Vue, Tailwind CSS, and dayjs, inherits Nuxt UI colors when available, and emits selections without showing notifications or changing the global locale.
Example
Here's an example of the Calendar in action:
<script lang="ts" setup>
import { CalendarSelectionMode } from '~/components/Calendar/types'
</script>
<template>
<div class="bg-elevated/50 flex w-full items-center justify-center py-16">
<Calendar :selection-mode="CalendarSelectionMode.Range" />
</div>
</template>
nuxt-charts add Calendar
Props
| Prop | Type | Default | Description |
|---|---|---|---|
selectionMode | 'single' | 'range' | 'multiple' | 'single' | The selection mode for dates. |
initialDate | Date | undefined | The initially selected date (for single and multiple modes). |
initialStartDate | Date | undefined | The initially selected start date (for range mode). |
initialEndDate | Date | undefined | The initially selected end date (for range mode). |
showTimePicker | boolean | false | If true, the time picker is displayed. |
timeSlots | string[] | ['09:00', ...] | An array of time slots to display in the time picker. |
initialTime | string | undefined | The initially selected time. |
dateFormat | string | 'dddd, MMMM D, YYYY' | The format for displaying selected dates. |
timeFormat | string | 'HH:mm' | The format for displaying selected times. |
weekDayLabels | [string, string, string, string, string, string, string] | Locale weekday names | An array of labels for the days of the week. |
orientation | 'vertical' | 'horizontal' | 'horizontal' | The orientation of the calendar and time picker. |
visibleMonths | number | 1 | The number of months to display at once. |
locale | string | 'en' | The locale for dayjs (e.g., 'en', 'es', 'fr'). |
disabledDates | Date[] | undefined | An array of dates to disable. |
minDate | Date | undefined | The minimum selectable date. |
maxDate | Date | undefined | The maximum selectable date. |
classNames | object | {} | An object with classes to customize the calendar's appearance. |
Events
| Event | Payload | Description |
|---|---|---|
date-select | Date | Date[] | Emitted when a date is selected. The payload is a Date object in single mode and an array of Date objects in multiple mode. |
range-select | { start: Date | null, end: Date | null } | Emitted when a date range is selected in range mode. |
time-select | string | Emitted when a time is selected from the time picker. |
month-change | Dayjs | Emitted when the displayed month changes. The payload is a dayjs object. |
year-change | number | Emitted when the displayed year changes. |
Styling
You can customize the calendar's appearance by passing a classNames object with the following keys:
container: The main container of the calendar.header: The header section with the month and navigation buttons.weekdays: The container for the weekday labels.day: A single day in the calendar grid.today: A class for the current day.selected: A class for selected dates.disabled: A class for disabled dates.inRange: A class for dates within a selected range.
Example:
<template>
<Calendar :class-names="customClasses" />
</template>
<script setup lang="ts">
const customClasses = {
header: 'bg-elevated',
selected: '!bg-success !text-inverted',
}
</script>
Internationalization (i18n)
To use the calendar in different locales, import the desired locale from dayjs and pass the locale prop. For example, for Spanish:
<script setup>
import 'dayjs/locale/es'
</script>
<template>
<Calendar locale="es" />
</template>
<template>
<Calendar />
</template>
Controlled Selection
Use v-model to update a selection from the parent. The value is a Date for single mode, Date[] for multiple mode, or { start: Date | null, end: Date | null } for range mode. Passing null clears the selection. The initialDate, initialStartDate, and initialEndDate props remain available for uncontrolled usage.
<script setup lang="ts">
import { ref } from 'vue'
const range = ref<{ start: Date | null, end: Date | null }>({ start: null, end: null })
const time = ref<string>()
</script>
<template>
<Calendar v-model="range" v-model:time="time" selection-mode="range" show-time-picker :week-starts-on="1" />
</template>
weekStartsOn accepts 0 (Sunday) through 6 (Saturday) and defaults to 0. Custom weekDayLabels are supplied in Sunday-to-Saturday order and rotated to match the week start. Import any required dayjs locale in the parent project.
The header slot receives monthsToShow, previousMonth, and nextMonth. The previous and next slots customize navigation content. The day slot receives a Date and a selected boolean.
Install the date dependency with npm install dayjs. Date buttons use dateFormat for accessible labels, and time slots use timeFormat for display.