This is a calendar component for Vue.js 3+.

Loading component...

Installation

Yarn
yarn add @vlalg-nimbus/nb-calendar
NPM
npm install @vlalg-nimbus/nb-calendar

Usage

Vue 3
import { createApp } from 'vue'
import App from './App.vue'

import NbCalendarComponents from '@vlalg-nimbus/nb-calendar'
import "@vlalg-nimbus/nb-calendar/dist/style.css";

const app = createApp(App)
app.use(NbCalendarComponents)
app.mount('#app')
Nuxt 3
import NbCalendarComponents from '@vlalg-nimbus/nb-calendar'
import "@vlalg-nimbus/nb-calendar/dist/style.css";

export default defineNuxtPlugin(context => {
  context.vueApp.use(NbCalendarComponents)
})

To use, simply call the component, in this case it will be NbCalendar or nb-calendar.

Mode 1
<template>
  <NbCalendar />
</template>
Mode 2
<template>
  <nb-calendar />
</template>
Mode 3
<template>
  <nb-calendar></nb-calendar>
</template>

Preview & Playground

Select the component you want to edit/test

Loading Sandbox...

Props

Items with an (*) mean they are required

To set initial value, use the value prop.

nameValue typeDefaultDescription
valueDate/String/ObjectnullDefines the initial calendar value. Accepts Date, String ISO, ou Object (para ranges)

Other props

nameValue typeDefaultDescription
nbId (*)StringSets the id attribute to differentiate from other components
displayString'b'Defines the display type. Accepts ib and b.
tabIndexNumber0Defines the tab index. Set this property to make the calendar focusable by the keyboard.
ariaLabelString'Calendar'Defines the aria-label attribute for screen readers.
ariaAttrsObject{}Allows passing custom aria attributes as an object. Keys will automatically receive the aria- prefix. Example: { 'describedby': 'help-id', 'invalid': 'false' }
themeString'light'Defines the theme. Accepts light and dark.
disabledBooleanfalseDefines if the calendar is disabled
isRequiredBooleanfalseDefines if the calendar is required
widthNumber280Defines the calendar width in pixels. Minimum value is 280px.
widthFullBooleanfalseDefines if the calendar should occupy 100% of its parent container width.
fontFamilyString"'Lato', sans-serif"Defines the font-family
fontSizeString'1.6em'Defines the font-size
fontWeightNumber400Defines the font-weight
valueDate/String/ObjectnullDefines the initial calendar value. Accepts Date, String (YYYY-MM-DD, YYYY-MM-DDTHH:mm, YYYY-MM-DDTHH:mm:ss, YYYY-MM, YYYY-Www), or Object with startDate and endDate for range mode.
goToDateDate/StringnullNavigates the calendar to a specific date. Accepts Date or String (YYYY-MM-DD).
inputTypeString'date'Defines the input type. Accepts date, month, time, datetime-local, week.
hasSecondsBooleanfalseDefines if the time picker should include seconds. Only works with inputType="time" or inputType="datetime-local".
localeString'en-US'Defines the locale. Accepts pt-BR and en-US.
isoStringTimezoneFormatString'Z'Defines the timezone format for isoString in events. Accepts Z (e.g., "2024-01-15T17:30:00.000Z") or +00:00 (e.g., "2024-01-15T17:30:00.000+00:00"). Both represent UTC.
startWeekOnMondayBooleanfalseDefines if the week should start on Monday instead of Sunday.
allowRangeBooleanfalseDefines if date range selection is allowed.
editRangeBooleantrueDefines if the range can be edited by dragging the start or end dates. Only works when allowRange is true.
maxRangeDaysNumbernullDefines the maximum number of days that can be selected in a range. If null, there is no limit.
minDate/StringnullDefines the minimum selectable date. Accepts Date or String (YYYY-MM-DD). For time types, accepts String (HH:mm or HH:mm:ss).
maxDate/StringnullDefines the maximum selectable date. Accepts Date or String (YYYY-MM-DD). For time types, accepts String (HH:mm or HH:mm:ss).
stepString/NumbernullDefines the step for date selection. For inputType="date", step is in days. For inputType="time" or inputType="datetime-local", step is in seconds.
minYearNumber1900Defines the minimum year available in the year picker.
maxYearNumber2100Defines the maximum year available in the year picker.
primaryColorString'#007bff'Defines the primary color. Accepts Hex format (e.g., #007bff).
selectionColorString'#1976d2'Defines the background color for selected dates. Accepts Hex format (e.g., #1976d2).
eventColorString'#4caf50'Defines the color for event indicators. Accepts Hex format (e.g., #4caf50).
todayColorString'#007bff'Defines the color for today's date. Accepts Hex format (e.g., #007bff).
normalTextColorStringnullDefines the text color for month/year picker items. If null, uses theme default. Accepts Hex format.
hoverTextColorStringnullDefines the text color for month/year picker items on hover. If null, uses theme default. Accepts Hex format.
monthYearItemBgStringnullDefines the background color for month/year picker items. If null, uses theme default. Accepts Hex or RGB/RGBA format.
monthYearItemBgHoverStringnullDefines the background color for month/year picker items on hover. If null, uses theme default. Accepts Hex or RGB/RGBA format.
dayHoverBgStringnullDefines the background color for days on hover. If null, uses theme default. Accepts Hex or RGB/RGBA format.
dayHoverTextColorStringnullDefines the text color for days on hover. If null, uses theme default. Accepts Hex format.
timeDisplayTextColorStringnullDefines the text color for the time display section. If null, uses theme default. Accepts Hex format.
timeEditButtonBgStringnullDefines the background color for the time edit button. If null, uses theme default. Accepts Hex or RGB/RGBA format.
timeEditButtonTextColorStringnullDefines the text color for the time edit button. If null, uses theme default. Accepts Hex format.
timeEditButtonBgHoverStringnullDefines the background color for the time edit button on hover. If null, uses theme default. Accepts Hex or RGB/RGBA format.
timeEditButtonTextColorHoverStringnullDefines the text color for the time edit button on hover. If null, uses theme default. Accepts Hex format.
timeEditButtonFontFamilyString"'Lato', sans-serif"Defines the font-family for the time edit button.
timeEditButtonFontSizeString'14px'Defines the font-size for the time edit button.
timeEditButtonPaddingStringnullDefines the padding for the time edit button. If null, uses default.
timeEditButtonBorderRadiusStringnullDefines the border-radius for the time edit button. If null, uses default.
timeEditButtonFontWeightNumber500Defines the font-weight for the time edit button.
timeEditButtonBorderStringnullDefines the border for the time edit button. If null, uses default.
todayButtonBgStringnullDefines the background color for the "Hoje" (Today) button. If null, uses theme default. Accepts Hex or RGB/RGBA format.
todayButtonTextColorStringnullDefines the text color for the "Hoje" (Today) button. If null, uses theme default. Accepts Hex format.
todayButtonBgHoverStringnullDefines the background color for the "Hoje" (Today) button on hover. If null, uses theme default. Accepts Hex or RGB/RGBA format.
todayButtonTextColorHoverStringnullDefines the text color for the "Hoje" (Today) button on hover. If null, uses theme default. Accepts Hex format.
todayButtonFontFamilyString"'Lato', sans-serif"Defines the font-family for the "Hoje" (Today) button.
todayButtonFontSizeString'1.1rem'Defines the font-size for the "Hoje" (Today) button.
todayButtonPaddingStringnullDefines the padding for the "Hoje" (Today) button. If null, uses default.
todayButtonBorderRadiusStringnullDefines the border-radius for the "Hoje" (Today) button. If null, uses default.
todayButtonFontWeightNumber400Defines the font-weight for the "Hoje" (Today) button.
todayButtonBorderStringnullDefines the border for the "Hoje" (Today) button. If null, uses default.
showClearButtonBooleanfalseDefines if the clear button (×) should be displayed. When clicked, clears the current selection and emits appropriate events.
showTodayButtonBooleanfalseDefines if the "Hoje" (Today) / "Agora" (Now) button should be displayed. When clicked, selects the current date/time and navigates to the current month/year.
clearButtonKeepCurrentMonthBooleanfalseDefines if the calendar should stay on the current month/year when clearing selection. If false, navigates to the current system month/year after clearing.
eventsArrayDefines an array of events to display on the calendar. Each event should have a date property (Date or String) and optionally a color property (Hex format).
blockClicksWithoutEventsBooleanfalseWhen set to true, prevents clicking on dates that don't have events. Only dates with events can be selected. Useful for calendars where only specific dates should be selectable.
borderRadiusNumber0Defines the border radius of the calendar in pixels.
scrollClassString''Defines a custom CSS class for the scrollable content area (useful for custom scrollbar styling). Applied to calendar days, month grid, year grid, weekdays, time picker, and time display sections.

Text Customization Props

All text labels and button texts can be customized via props. Defaults are in English.

nameValue typeDefaultDescription
timeEditButtonTextString'Edit'Defines the text for the time edit button.
todayButtonTextString'Today'Defines the text for the "Today" button (used in calendar/month view).
nowButtonTextString'Now'Defines the text for the "Now" button (used in time picker view).
selectMonthTextString'Select month'Defines the text displayed when selecting a month.
selectYearTextString'Select year'Defines the text displayed when selecting a year.
selectTimeTextString'Select time'Defines the text displayed when selecting a time.
timeDisplayLabelTextString'Time:'Defines the label text for the time display section.
clearButtonTitleString'Clear selection'Defines the title (tooltip) text for the clear button.
clearButtonSymbolString'×'Defines the symbol/text displayed in the clear button.

Note: Month names and weekday names are automatically controlled by the locale prop ('pt-BR' or 'en-US'). They do not need individual props.

Events

changed

Fired when the calendar value changes, returns the current value in different formats depending on the inputType:

For inputType="date":

  • Returns: Date object or String (format: YYYY-MM-DD)
  • Example: new Date('2024-01-15') or "2024-01-15"

For inputType="month":

  • Returns: String (format: YYYY-MM)
  • Example: "2024-01"

For inputType="time":

  • Returns: String (format: HH:mm or HH:mm:ss if hasSeconds is true)
  • Example: "14:30" or "14:30:45"

For inputType="datetime-local":

  • Returns: String (format: YYYY-MM-DDTHH:mm or YYYY-MM-DDTHH:mm:ss if hasSeconds is true)
  • Example: "2024-01-15T14:30" or "2024-01-15T14:30:45"

For inputType="week":

  • Returns: String (format: YYYY-Www - ISO 8601 week format)
  • Example: "2024-W03"

For range mode (allowRange="true"):

  • Returns: Object with startDate and endDate properties
  • Example: { startDate: Date, endDate: Date } or { startDate: null, endDate: null } when cleared

When selection is cleared:

  • Returns: null

date-selected

Fired when a date is selected, returns detailed information about the selection. The return format varies based on the inputType and selection mode:

Single Date Selection (inputType="date")

When a date is selected:

{
  date: Date,                    // Date object of the selected date
  dateString: String,            // Date in YYYY-MM-DD format (e.g., "2024-01-15")
  isoString: String,             // ISO 8601 string with timezone in UTC. Format depends on `isoStringTimezoneFormat` prop:
                                 //   - If `isoStringTimezoneFormat="Z"`: "2024-01-15T00:00:00.000Z"
                                 //   - If `isoStringTimezoneFormat="+00:00"`: "2024-01-15T00:00:00.000+00:00"
  isoStringLocal: String,        // ISO 8601 string without timezone (e.g., "2024-01-15T00:00:00")
  day: {                         // Day object with additional information
    date: Number,                // Day of month (1-31)
    fullDate: Date,              // Full date object
    isOtherMonth: Boolean,       // Whether the day belongs to another month
    isToday: Boolean,            // Whether the day is today
    isSelected: Boolean,        // Whether the day is selected
    isInRange: Boolean,         // Whether the day is in a range (if range mode)
    isRangeStart: Boolean,      // Whether the day is the start of a range
    isRangeEnd: Boolean,        // Whether the day is the end of a range
    isDisabled: Boolean,         // Whether the day is disabled
    events: Array                // Array of events for this day
  }
}

When selection is cleared:

{
  date: null,                    // null when cleared
  dateString: null,              // null when cleared
  isoString: null,               // null when cleared
  isoStringLocal: null,          // null when cleared
  day: null                      // null when cleared
}

Note: The event returns two different formats:

  • With selection: All fields populated with date values
  • When cleared: All fields are null

Date Range Selection (allowRange="true")

{
  startDate: Date,               // Start date of the range (or null)
  endDate: Date,                 // End date of the range (or null)
  isRange: true,                 // Always true for range mode
  isoString: {                   // ISO strings for both dates (null if incomplete)
    start: String,               // ISO string for start date
    end: String                  // ISO string for end date
  } | null,
  isoStringLocal: {              // Local ISO strings (null if incomplete)
    start: String,               // Local ISO string for start date
    end: String                  // Local ISO string for end date
  } | null
}

When range is cleared:

{
  startDate: null,
  endDate: null,
  isRange: true,
  isoString: null,
  isoStringLocal: null
}

Week Selection (inputType="week")

{
  weekString: String,            // Week in YYYY-Www format (e.g., "2024-W03")
  weekStartDate: Date,           // Date object of Monday (start of week)
  weekEndDate: Date,             // Date object of Sunday (end of week)
  weekNumber: Number,            // Week number (1-53)
  weekYear: Number,              // ISO week year
  isoString: String,             // ISO 8601 string of week start date
  isoStringLocal: String         // Local ISO 8601 string of week start date
}

When selection is cleared:

{
  weekString: null,
  weekStartDate: null,
  weekEndDate: null
}

Month Selection (inputType="month")

{
  date: Date,                    // Date object of the first day of selected month
  dateString: String,            // Month in YYYY-MM format (e.g., "2024-01")
  month: Number,                 // Month index (0-11, where 0 = January)
  year: Number,                  // Year (e.g., 2024)
  monthName: String,             // Full month name (e.g., "Janeiro" or "January")
  isoString: String,             // ISO 8601 string of first day of month
  isoStringLocal: String         // Local ISO 8601 string of first day of month
}

Time Selection (inputType="time")

{
  hour: Number,                  // Selected hour (0-23)
  minute: Number,                // Selected minute (0-59)
  second: Number,                // Selected second (0-59, only if hasSeconds is true)
  timeString: String             // Time in HH:mm or HH:mm:ss format (e.g., "14:30" or "14:30:45")
}

DateTime Selection (inputType="datetime-local")

When date/time is selected:

{
  date: Date,                    // Date object of the selected date
  hour: Number,                  // Selected hour (0-23)
  minute: Number,                // Selected minute (0-59)
  second: Number,                // Selected second (0-59, only if hasSeconds is true)
  datetimeString: String,       // Combined date and time in YYYY-MM-DDTHH:mm format (e.g., "2024-01-15T14:30")
  isoString: String,             // ISO 8601 string with timezone in UTC. Format depends on `isoStringTimezoneFormat` prop:
                                 //   - If `isoStringTimezoneFormat="Z"`: "2024-01-15T17:30:00.000Z"
                                 //   - If `isoStringTimezoneFormat="+00:00"`: "2024-01-15T17:30:00.000+00:00"
  isoStringLocal: String,        // Local ISO 8601 string without timezone (e.g., "2024-01-15T14:30:00")
  day: {                         // Day object (same structure as single date selection)
    date: Number,
    fullDate: Date,
    isOtherMonth: Boolean,
    isToday: Boolean,
    isSelected: Boolean,
    isInRange: Boolean,
    isRangeStart: Boolean,
    isRangeEnd: Boolean,
    isDisabled: Boolean,
    events: Array
  }
}

When selection is cleared:

{
  date: null,
  hour: 0,
  minute: 0,
  second: 0,
  datetimeString: null,
  isoString: null,
  isoStringLocal: null,
  day: null
}

valid

Fired to indicate whether the current value is valid according to format validation and min/max constraints. This event is emitted:

  • When the component is mounted with an initial value
  • When the value prop changes
  • When the user selects a date/time
  • When min or max props change
  • When the view mode changes (calendar/time picker opens)
  • When navigating months/years

Returns: Boolean - true if the value is valid, false if invalid

Validation Rules:

  1. Format Validation:
    • The value must match the expected format for the inputType:
      • date: Valid date within min/max range
      • time: Valid time within min/max range
      • datetime-local: Valid date and time within min/max range
      • month: Valid month within min/max range
      • week: Valid week within min/max range
    • Invalid formats return false
  2. Empty Values:
    • Empty values (no selection) return true (valid, as the field is optional)
    • For time and datetime-local types, if no time has been explicitly set and the default 00:00 is outside the min/max range, it returns false
  3. Range Validation (min/max):
    • If min is set, values before the minimum return false
    • If max is set, values after the maximum return false
    • Both format and range must be valid for the value to be considered valid

Example:

<template>
  <NbCalendar
    nb-id="calendar-validation"
    input-type="date"
    :value="selectedDate"
    :min="'2024-01-01'"
    :max="'2024-12-31'"
    @valid="handleValidation"
  />
  <p>Is Valid: {{ isValid ? 'Yes' : 'No' }}</p>
</template>

<script setup>
import { ref } from 'vue'

const selectedDate = ref('2024-06-15')
const isValid = ref(true)

const handleValidation = (valid) => {
  isValid.value = valid
  console.log('Value is valid:', valid)
  
  if (!valid) {
    console.log('Current value is invalid. Check format and min/max constraints.')
  }
}
</script>

Example - Time Validation:

<template>
  <NbCalendar
    nb-id="calendar-time-validation"
    input-type="time"
    :min="'08:00'"
    :max="'18:00'"
    @valid="handleValidation"
  />
</template>

<script setup>
import { ref } from 'vue'

const isValid = ref(true)

const handleValidation = (valid) => {
  isValid.value = valid
  if (!valid) {
    console.log('Selected time is outside the allowed range (08:00 - 18:00)')
  }
}
</script>

Example - DateTime Validation:

<template>
  <NbCalendar
    nb-id="calendar-datetime-validation"
    input-type="datetime-local"
    :min="'2024-01-01T00:00'"
    :max="'2024-12-31T23:59'"
    @valid="handleValidation"
  />
</template>

<script setup>
import { ref } from 'vue'

const isValid = ref(true)

const handleValidation = (valid) => {
  isValid.value = valid
}
</script>

month-changed

Fired when the month/year changes through navigation (using previous/next buttons or month/year pickers), returns:

{
  year: Number,                  // Current year (e.g., 2024)
  month: Number,                 // Current month index (0-11, where 0 = January)
  monthName: String              // Full month name in current locale (e.g., "Janeiro" or "January")
}

Example:

{
  year: 2024,
  month: 0,                      // January
  monthName: "Janeiro"           // or "January" if locale is "en-US"
}

Slots

The component does not have custom slots. All customization is done through props.

Examples

Basic Date Selection

<template>
  <NbCalendar
    nb-id="calendar-basic"
    @changed="onDateChanged"
  />
</template>

<script setup>
const onDateChanged = (value) => {
  console.log('Selected date:', value)
}
</script>

Date Range Selection

<template>
  <NbCalendar
    nb-id="calendar-range"
    :allow-range="true"
    :edit-range="true"
    :max-range-days="30"
    @date-selected="onRangeChanged"
  />
</template>

<script setup>
const onRangeChanged = (value) => {
  console.log('Selected range:', value)
}
</script>

Week Selection

<template>
  <NbCalendar
    nb-id="calendar-week"
    input-type="week"
    @changed="onWeekChanged"
  />
</template>

<script setup>
const onWeekChanged = (value) => {
  console.log('Selected week:', value) // Format: YYYY-Www
}
</script>

Month Selection

<template>
  <NbCalendar
    nb-id="calendar-month"
    input-type="month"
    @changed="onMonthChanged"
  />
</template>

<script setup>
const onMonthChanged = (value) => {
  console.log('Selected month:', value) // Format: YYYY-MM
}
</script>

Time Selection

<template>
  <NbCalendar
    nb-id="calendar-time"
    input-type="time"
    :has-seconds="true"
    @date-selected="onTimeChanged"
  />
</template>

<script setup>
const onTimeChanged = (value) => {
  console.log('Selected time:', value)
}
</script>

DateTime Selection

<template>
  <NbCalendar
    nb-id="calendar-datetime"
    input-type="datetime-local"
    :has-seconds="true"
    @date-selected="onDateTimeChanged"
  />
</template>

<script setup>
const onDateTimeChanged = (value) => {
  console.log('Selected datetime:', value)
}
</script>

Calendar with Clear and Today Buttons

<template>
  <NbCalendar
    nb-id="calendar-clear-today"
    input-type="date"
    :show-clear-button="true"
    :show-today-button="true"
    :clear-button-keep-current-month="false"
    @changed="onDateChanged"
  />
</template>

<script setup>
const onDateChanged = (value) => {
  console.log('Selected date:', value)
}
</script>

Props:

  • showClearButton: Controls visibility of the clear button (×). Default: false
  • showTodayButton: Controls visibility of the "Hoje" (Today) / "Agora" (Now) button. Default: false
  • clearButtonKeepCurrentMonth: If false, navigates to current month/year after clearing. If true, stays on current view. Default: false

Behavior:

  • Clear Button: Clears the current selection and emits changed and date-selected events with null or empty values. If clearButtonKeepCurrentMonth is false, also navigates to the current system month/year.
  • Today/Now Button: Selects the current date/time and navigates to the current month/year. Emits changed and date-selected events with the current date/time values.

Calendar with Events

<template>
  <NbCalendar
    nb-id="calendar-events"
    :events="events"
    @date-selected="onDateChanged"
  />
</template>

<script setup>
const events = [
  { date: new Date('2024-01-15'), color: '#4caf50' },
  { date: new Date('2024-01-20'), color: '#ff9800' },
  { date: '2024-01-25', color: '#f44336' }
]

const onDateChanged = (value) => {
  console.log('Selected date:', value)
}
</script>

Dark Theme Calendar

<template>
  <NbCalendar
    nb-id="calendar-dark"
    theme="dark"
    :width="400"
    @changed="onDateChanged"
  />
</template>

<script setup>
const onDateChanged = (value) => {
  console.log('Selected date:', value)
}
</script>

Calendar with Custom Colors

<template>
  <NbCalendar
    nb-id="calendar-custom"
    primary-color="#9c27b0"
    selection-color="#7b1fa2"
    event-color="#e91e63"
    today-color="#673ab7"
    @changed="onDateChanged"
  />
</template>

<script setup>
const onDateChanged = (value) => {
  console.log('Selected date:', value)
}
</script>

Calendar with Min/Max Dates

<template>
  <NbCalendar
    nb-id="calendar-limited"
    min="2024-01-01"
    max="2024-12-31"
    :step="7"
    @changed="onDateChanged"
  />
</template>

<script setup>
const onDateChanged = (value) => {
  console.log('Selected date:', value)
}
</script>

Full Width Calendar

<template>
  <div style="width: 100%; padding: 20px;">
    <NbCalendar
      nb-id="calendar-full"
      :width-full="true"
      @changed="onDateChanged"
    />
  </div>
</template>

<script setup>
const onDateChanged = (value) => {
  console.log('Selected date:', value)
}
</script>

Calendar with Custom Scrollbar

<template>
  <NbCalendar
    nb-id="calendar-scroll"
    scroll-class="custom-scrollbar"
    @changed="onDateChanged"
  />
</template>

<script setup>
const onDateChanged = (value) => {
  console.log('Selected date:', value)
}
</script>

<style scoped>
:deep(.calendar) {
  .custom-scrollbar {
    &::-webkit-scrollbar {
      width: 8px;
    }

    &::-webkit-scrollbar-track {
      background: tomato;
    }

    &::-webkit-scrollbar-thumb {
      background: #640dfb;
      border-radius: 4px;

      &:hover {
        background: #4d0bc0;
      }
    }
  }
}
</style>