Skip to content

Calendar ​

A calendar tool for choosing individual dates, multiple dates, or date spans.

INFO

This component relies on the @internationalized/date package which provides objects and functions for representing and manipulating dates and times in a locale-aware manner.

Usage ​

Use the v-model directive to control the selected date.

vue
<script setup lang="ts">
import { shallowRef } from 'vue'
import { CalendarDate } from '@internationalized/date'

const value = shallowRef(new CalendarDate(2012, 4, 12))
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar v-model="value" />
  </div>
</template>

Use the default-value prop to set the initial value when you do not need to control its state.

Details
vue
<script setup lang="ts">
import { shallowRef } from 'vue'
import { CalendarDate } from '@internationalized/date'

const value = shallowRef(new CalendarDate(2012, 4, 12))
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar v-model="value" />
  </div>
</template>

Multiple ​

Use the multiple prop to allow multiple selections.

Details
vue
<script setup lang="ts">
import { shallowRef } from 'vue'
import { CalendarDate } from '@internationalized/date'

const value = shallowRef([
  new CalendarDate(2012, 4, 12),
  new CalendarDate(2012, 4, 14),
  new CalendarDate(2012, 4, 24)
])
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar
      v-model="value"
      multiple
    />
  </div>
</template>

Locale ​

Use the locale prop to change the locale of the calendar.

Details
vue
<script setup lang="ts">
export interface ExampleProps {
  locale?: string
}

withDefaults(defineProps<ExampleProps>(), {
  locale: 'en' as const
})
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar
      :locale="locale"
    />
  </div>
</template>

Range ​

Use the range prop to select a range of dates.

Details
vue
<script setup lang="ts">
import { shallowRef } from 'vue'
import { CalendarDate } from '@internationalized/date'

const value = shallowRef({
  start: new CalendarDate(2012, 4, 11),
  end: new CalendarDate(2012, 4, 21)
})
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar v-model="value" range />
  </div>
</template>

Color ​

Use the color prop to change the color of the calendar.

Details
vue
<script setup lang="ts">
import type { Calendar } from '@bitrix24/b24ui-nuxt'

export interface ExampleProps {
  color?: Calendar['color']
}

withDefaults(defineProps<ExampleProps>(), {
  color: 'default'
})
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar :color="color" />
  </div>
</template>

Size ​

Use the size prop to change the size of the calendar.

Details
vue
<script setup lang="ts">
import type { Calendar } from '@bitrix24/b24ui-nuxt'

export interface ExampleProps {
  size?: Calendar['size']
}

withDefaults(defineProps<ExampleProps>(), {
  size: 'md' as const
})
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar :size="size" />
  </div>
</template>

Disabled ​

Use the disabled prop to disable the calendar.

Details
vue
<script setup lang="ts">
export interface ExampleProps {
  isDisabled?: boolean
}

withDefaults(defineProps<ExampleProps>(), {
  isDisabled: true
})
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar :disabled="isDisabled" />
  </div>
</template>

Number Of Months ​

Use the numberOfMonths prop to change the number of months in the calendar.

Details
vue
<script setup lang="ts">
export interface ExampleProps {
  numberOfMonths?: number
}

withDefaults(defineProps<ExampleProps>(), {
  numberOfMonths: 2
})
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded min-w-[300px] p-2">
    <B24Calendar :number-of-months="numberOfMonths" />
  </div>
</template>

Month Controls ​

Use the month-controls prop to show the month controls. Defaults to true.

Details
vue
<script setup lang="ts">
export interface ExampleProps {
  monthControls?: boolean
}

withDefaults(defineProps<ExampleProps>(), {
  monthControls: true
})
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar :month-controls="monthControls" />
  </div>
</template>

Year Controls ​

Use the year-controls prop to show the year controls. Defaults to true.

Details
vue
<script setup lang="ts">
export interface ExampleProps {
  yearControls?: boolean
}

withDefaults(defineProps<ExampleProps>(), {
  yearControls: true
})
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar :year-controls="yearControls" />
  </div>
</template>

Fixed Weeks ​

Use the fixed-weeks prop to display the calendar with fixed weeks.

Details
vue
<script setup lang="ts">
export interface ExampleProps {
  fixedWeeks?: boolean
}

withDefaults(defineProps<ExampleProps>(), {
  fixedWeeks: true
})
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar :fixed-weeks="fixedWeeks" />
  </div>
</template>

Examples ​

With chip events ​

Use the Chip component to add events to specific days.

Details
vue
<script setup lang="ts">
import { shallowRef } from 'vue'
import { CalendarDate } from '@internationalized/date'

const modelValue = shallowRef(new CalendarDate(2012, 4, 12))
function getColorByDate(date: Date) {
  const isWeekend = date.getDay() % 6 == 0
  const isDayMeeting = date.getDay() % 3 == 0

  if (isWeekend) {
    return undefined
  }

  if (isDayMeeting) {
    return 'danger'
  }

  return 'success'
}
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar v-model="modelValue">
      <template #day="{ day }">
        <B24Chip
          :show="!!getColorByDate(day.toDate('UTC'))"
          :color="getColorByDate(day.toDate('UTC'))"
          size="3xs"
        >
          {{ day.day }}
        </B24Chip>
      </template>
    </B24Calendar>
  </div>
</template>

With disabled dates ​

Use the is-date-disabled prop with a function to mark specific dates as disabled.

Details
vue
<script setup lang="ts">
import { shallowRef } from 'vue'
import { CalendarDate, type DateValue } from '@internationalized/date'

const modelValue = shallowRef({
  start: new CalendarDate(2012, 4, 12),
  end: new CalendarDate(2012, 4, 14)
})
const isDateDisabled = (date: DateValue) => {
  return date.day >= 15 && date.day <= 17
}
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar
      v-model="modelValue"
      :is-date-disabled="isDateDisabled"
      range
    />
  </div>
</template>

With unavailable dates ​

Use the is-date-unavailable prop with a function to mark specific dates as unavailable.

Details
vue
<script setup lang="ts">
import { shallowRef } from 'vue'
import { CalendarDate, type DateValue } from '@internationalized/date'

const modelValue = shallowRef({
  start: new CalendarDate(2012, 4, 12),
  end: new CalendarDate(2012, 4, 14)
})
const isDateUnavailable = (date: DateValue) => {
  return date.day >= 15 && date.day <= 17
}
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar
      v-model="modelValue"
      :is-date-unavailable="isDateUnavailable"
      range
    />
  </div>
</template>

With min/max dates ​

Use the min-value and max-value props to limit the dates.

Details
vue
<script setup lang="ts">
import { shallowRef } from 'vue'
import { CalendarDate } from '@internationalized/date'

const modelValue = shallowRef(new CalendarDate(2012, 4, 12))
const minDate = new CalendarDate(2012, 4, 1)
const maxDate = new CalendarDate(2012, 4, 30)
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar
      v-model="modelValue"
      :min-value="minDate"
      :max-value="maxDate"
    />
  </div>
</template>

With other calendar systems ​

You can use other calenders from @internationalized/date to implement a different calendar system.

TIP

You can check all the available calendars on @internationalized/date docs.

Details
vue
<script setup lang="ts">
import { shallowRef } from 'vue'
import { CalendarDate, HebrewCalendar } from '@internationalized/date'

const hebrewDate = shallowRef(new CalendarDate(new HebrewCalendar(), 5781, 1, 1))
</script>

<template>
  <div class="relative bg-white dark:bg-base-900 rounded w-[300px] p-2">
    <B24Calendar
      v-model="hebrewDate"
    />
  </div>
</template>

As a DatePicker ​

Use a Button and a Popover component to create a date picker.

Details
vue
<script setup lang="ts">
import { shallowRef } from 'vue'
import { CalendarDate, DateFormatter, getLocalTimeZone } from '@internationalized/date'
import Calendar1Icon from '@bitrix24/b24icons-vue/main/Calendar1Icon'

const df = new DateFormatter('en-US', {
  dateStyle: 'medium'
})

const modelValue = shallowRef(new CalendarDate(2012, 4, 12))
</script>

<template>
  <B24Popover>
    <B24Button :icon="Calendar1Icon">
      {{ modelValue ? df.format(modelValue.toDate(getLocalTimeZone())) : 'Select a date' }}
    </B24Button>

    <template #content>
      <B24Calendar v-model="modelValue" class="p-2" />
    </template>
  </B24Popover>
</template>

As a DateRangePicker ​

Use a Button and a Popover component to create a date range picker.

Details
vue
<script setup lang="ts">
import { shallowRef } from 'vue'
import { CalendarDate, DateFormatter, getLocalTimeZone } from '@internationalized/date'
import Calendar1Icon from '@bitrix24/b24icons-vue/main/Calendar1Icon'

const df = new DateFormatter('en-US', {
  dateStyle: 'medium'
})

const modelValue = shallowRef({
  start: new CalendarDate(2012, 4, 12),
  end: new CalendarDate(2012, 5, 12)
})
</script>

<template>
  <B24Popover>
    <B24Button :icon="Calendar1Icon">
      <template v-if="modelValue.start">
        <template v-if="modelValue.end">
          {{ df.format(modelValue.start.toDate(getLocalTimeZone())) }} - {{ df.format(modelValue.end.toDate(getLocalTimeZone())) }}
        </template>

        <template v-else>
          {{ df.format(modelValue.start.toDate(getLocalTimeZone())) }}
        </template>
      </template>
      <template v-else>
        Pick a date
      </template>
    </B24Button>

    <template #content>
      <B24Calendar
        v-model="modelValue"
        class="p-2"
        :number-of-months="2"
        range
      />
    </template>
  </B24Popover>
</template>

API ​

Props ​

Prop Default Type
as'div'any
The element or component this component should render as.
nextYearIconicons.chevronDoubleRight(props: HTMLAttributes & VNodeProps & {}, ctx: Omit<{ attrs: Data; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<...>>(exposed?: Exposed) => void; }, "expose">): any
The icon to use for the next year control.
nextYearButtonProps
Configure the next year button. `{ color: 'link' }`{lang="ts"}
nextMonthIconicons.chevronRight(props: HTMLAttributes & VNodeProps & {}, ctx: Omit<{ attrs: Data; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<...>>(exposed?: Exposed) => void; }, "expose">): any
The icon to use for the next month control.
nextMonthButtonProps
Configure the next month button. `{ color: 'link' }`{lang="ts"}
prevYearIconicons.chevronDoubleLeft(props: HTMLAttributes & VNodeProps & {}, ctx: Omit<{ attrs: Data; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<...>>(exposed?: Exposed) => void; }, "expose">): any
The icon to use for the previous year control.
prevYearButtonProps
Configure the prev year button. `{ color: 'link' }`{lang="ts"}
prevMonthIconicons.chevronLeft(props: HTMLAttributes & VNodeProps & {}, ctx: Omit<{ attrs: Data; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<...>>(exposed?: Exposed) => void; }, "expose">): any
The icon to use for the previous month control.
prevMonthButtonProps
Configure the prev month button. `{ color: 'link' }`{lang="ts"}
color'primary'"default" | "danger" | "success" | "warning" | "primary" | "secondary" | "collab" | "ai"
size'md'"lg" | "md" | "xs" | "sm"
rangeboolean
Whether a range of dates can be selected
multipleboolean
Whether multiple dates can be selected
monthControlstrueboolean
Show month controls
yearControlstrueboolean
Show year controls
defaultValueCalendarDate | CalendarDateTime | ZonedDateTime | DateRange | DateValue[]
modelValuenull | CalendarDate | CalendarDateTime | ZonedDateTime | DateRange | DateValue[]
b24ui{ root?: ClassNameValue; header?: ClassNameValue; body?: ClassNameValue; heading?: ClassNameValue; grid?: ClassNameValue; ... 5 more ...; cellTrigger?: ClassNameValue; }
disabledboolean
Whether or not the calendar is disabled
defaultPlaceholderCalendarDate | CalendarDateTime | ZonedDateTime
The default placeholder date
placeholderCalendarDate | CalendarDateTime | ZonedDateTime
The placeholder date, which is used to determine what month to display when no date is selected. This updates as the user navigates the calendar and can be used to programmatically control the calendar view
allowNonContiguousRangesboolean
When combined with `isDateUnavailable`, determines whether non-contiguous ranges, i.e. ranges containing unavailable dates, may be selected.
pagedNavigationboolean
This property causes the previous and next buttons to navigate by the number of months displayed at once, rather than one month
preventDeselectboolean
Whether or not to prevent the user from deselecting a date without selecting another date first
weekStartsOn0 | 1 | 2 | 3 | 4 | 5 | 6
The day of the week to start the calendar on
weekdayFormat"narrow" | "short" | "long"
The format to use for the weekday strings provided via the weekdays slot prop
fixedWeekstrueboolean
Whether or not to always display 6 weeks in the calendar
maxValueCalendarDate | CalendarDateTime | ZonedDateTime
The maximum date that can be selected
minValueCalendarDate | CalendarDateTime | ZonedDateTime
The minimum date that can be selected
numberOfMonthsnumber
The number of months to display at once
readonlyboolean
Whether or not the calendar is readonly
initialFocusboolean
If true, the calendar will focus the selected day, today, or the first day of the month depending on what is visible when the calendar is mounted
isDateDisabled(date: DateValue): boolean
A function that returns whether or not a date is disabled
isDateUnavailable(date: DateValue): boolean
A function that returns whether or not a date is unavailable
nextPage(placeholder: DateValue): DateValue
A function that returns the next page of the calendar. It receives the current placeholder as an argument inside the component.
prevPage(placeholder: DateValue): DateValue
A function that returns the previous page of the calendar. It receives the current placeholder as an argument inside the component.

Slots ​

Slot Type
heading{ value: string; }
dayPick<CalendarCellTriggerProps, "day">
week-day{ day: string; }

Emits ​

Event Type

Released under the MIT License.