nb-date-picker
This is a date picker component for Vue.js 3+.
Loading component...
Installation
yarn add @vlalg-nimbus/nb-inputs
Usage
import { createApp } from 'vue'
import App from './App.vue'
import NbInputComponents from '@vlalg-nimbus/nb-inputs'
import "@vlalg-nimbus/nb-inputs/dist/style.css";
// Import the Calendar component from the npm package to use in the nb-date-picker component
import { Calendar } from '@vlalg-nimbus/nb-calendar';
import "@vlalg-nimbus/nb-calendar/dist/style.css"
const app = createApp(App)
app.use(NbInputComponents)
app.component('Calendar', Calendar); // Register the Calendar component globally
app.mount('#app')
To use, simply call the component, in this case it will be NbDatePicker or nb-date-picker.
<template>
<NbDatePicker />
</template>
Preview & Playground
Select the component you want to edit/test
Props
Items with an (*) mean they are required
To set initial value, use the inputText prop.
Important: The
inputTextprop accepts different formats depending on theinputType. Invalid formats will be automatically cleared (set to empty string). See the Accepted Formats section below for details.
| name | Value type | Default | Description |
|---|---|---|---|
| inputText | String/Date | '' | Defines the initial date value. Accepts different formats depending on inputType. See Accepted Formats section for details. |
Other props
| name | Value type | Default | Description |
|---|---|---|---|
| nbId (*) | String | Sets the id attribute to differentiate from other components | |
| inputName (*) | String | Sets the name attribute for the input element | |
| display | String | 'b' | Defines the display type. Accepts ib and b. |
| tabIndex | Number | 0 | Defines the tab index. Set this property to make the input focusable by the keyboard. |
| hasTabIndexEnter | Boolean | true | Defines if pressing Enter should trigger the entered event. |
| ariaLabel | String | 'Alternate Text Button' | Defines the aria-label attribute for screen readers. |
| ariaAttrs | Object | {} | Allows passing custom aria attributes as an object. Keys will automatically receive the aria- prefix. Example: { 'describedby': 'help-id', 'invalid': 'false' } |
| title | String | '' | Tooltip text shown when hovering over the component. |
| theme | String | 'light' | Defines the theme. Accepts light and dark. |
| disabled | Boolean | false | Defines if the input is disabled |
| required | Boolean | false | Defines if the input is required |
| inputReadonly | Boolean | false | Defines if the input is readonly |
| blockPaste | Boolean | false | When set to true, prevents pasting content into the input field. |
| inputType | String | 'date' | Defines the input type. Accepts date, month, time, datetime-local, week. |
| inputText | String | '' | Defines the initial input value. Accepts String in ISO format (YYYY-MM-DD, YYYY-MM-DDTHH:mm, YYYY-MM-DDTHH:mm:ss, YYYY-MM, YYYY-Www) or JSON string for ranges. |
| locale | String | 'en-US' | Defines the locale. Accepts pt-BR and en-US. |
| allowRange | Boolean | false | Defines if date range selection is allowed. When enabled, the input accepts ranges in format "DD/MM/YYYY - DD/MM/YYYY". |
| calendarZIndex | Number | 10000 | Defines the z-index of the calendar popup when using custom calendar. Useful when the calendar needs to appear above modals or other elements. |
| calendarWidth | Number | 350 | Defines the width of the calendar popup in pixels. Minimum value is 280. |
| blockClicksWithoutEvents | Boolean | false | When set to true, prevents clicking on dates that don't have events in the calendar. Only dates with events can be selected. This prop is passed to the Calendar component. Useful for date pickers where only specific dates should be selectable. |
| min | String | '' | Defines the minimum selectable date. Accepts String (YYYY-MM-DD). For time types, accepts String (HH:mm or HH:mm:ss). |
| max | String | '' | Defines the maximum selectable date. Accepts String (YYYY-MM-DD). For time types, accepts String (HH:mm or HH:mm:ss). |
| step | String/Number | '' | Defines the step for date selection. For inputType="date", step is in days. For inputType="time" or inputType="datetime-local", step is in seconds. |
| hasSeconds | Boolean | null | Defines if the time input includes seconds. When null, detected automatically from the value/format. Only applies to inputType="time" and inputType="datetime-local". |
| hasTrim | Boolean | false | Defines if the input value should be trimmed (spaces removed from start and end). |
| fontFamily | String | "'Lato', sans-serif" | Defines the font-family for the input |
| fontSize | String | null (default: 1.4em) | Defines the font-size for the input. If null, uses 1.4em as default size. Pass a string with the font-size and the unit (e.g., "1.2em"). |
| fontWeight | Number | 400 | Defines the font-weight for the input |
| textColor | String | '#ffffff' | Defines the text color for the input |
| caretColor | String | '' | Defines the caret (cursor) color. If empty, uses theme default. |
| selectionBgColor | String | '' | Defines the background color for selected text. If empty, uses theme default. |
| selectionTextColor | String | '' | Defines the text color for selected text. If empty, uses theme default. |
| hasBorderRadius | Boolean | false | Defines if the input should have border radius |
| borderRadius | Number | 0.5 | Defines the border radius in rem units. Only applies if hasBorderRadius is true and inputStyle is not 'line'. |
| inputWidth | Number | 200 | Defines the input width in pixels. Only applies when display is not 'b'. |
| inputStyle | String | 'background' | Defines the input style. Accepts background, line, and border. |
| activeTextStyle | String | 'normal' | Defines the text style when input is active. Accepts normal, italic, and oblique. |
| inputUppercase | Boolean | false | Defines if the input text should be displayed in uppercase |
| inputAutocomplete | String | 'on' | Defines the autocomplete attribute. Accepts on and off. |
| textAlign | String | 'left' | Defines the text alignment. Accepts left, center, and right. |
| showLabel | Boolean | false | Defines if the label should be displayed |
| label | String | 'Label text' | Defines the label text |
| labelBackground | String | 'transparent' | Defines the background color for the label when active (floating) |
| labelPadding | String | '1px 5px' | Defines the padding for the label when active (floating) |
| labelBorderRadius | Number | 0 | Defines the border radius for the label when active (floating) |
| labelLeft | Number | 5 | Defines the left position of the label when inactive (inside input) |
| labelRight | Number | 0 | Defines the right position of the label when inactive (inside input) |
| inputLabelMarginActive | Number | 15 | Defines the top margin of the input when label is active (floating) |
| labelActiveTop | Number | -13 | Defines the top position of the label when active (floating) |
| labelActiveLeft | Number | 5 | Defines the left position of the label when active (floating) |
| labelActiveRight | Number | 0 | Defines the right position of the label when active (floating) |
| labelBreakOnActive | Boolean | true | Defines if the label text should break or use ellipsis when active |
| fontFamilyLabel | String | "'Lato', sans-serif" | Defines the font-family for the label |
| fontSizeLabel | String | '1em' | Defines the font-size for the label when inactive |
| fontSizeLabelActive | String | '0.8em' | Defines the font-size for the label when active (floating) |
| fontWeightLabel | Number | 400 | Defines the font-weight for the label |
| lightTextColorLabel | String | '#333333' | Defines the text color for the label in light theme |
| lightTextColorLabelActive | String | '#333333' | Defines the text color for the label when active in light theme |
| darkTextColorLabel | String | '#ffffff' | Defines the text color for the label in dark theme |
| darkTextColorLabelActive | String | '#ffffff' | Defines the text color for the label when active in dark theme |
| lightBgColor | String | '#f8f8f2' | Defines the background color for the input in light theme |
| lightBgColorFocus | String | '#eaeaea' | Defines the background color for the input when focused in light theme |
| lightDisabledBgColor | String | '#dfdfd9' | Defines the background color for the input when disabled in light theme |
| lightTextColor | String | '#000000' | Defines the text color for the input in light theme |
| darkBgColor | String | '#353734' | Defines the background color for the input in dark theme |
| darkBgColorFocus | String | '#272936' | Defines the background color for the input when focused in dark theme |
| darkDisabledBgColor | String | 'rgba(40, 42, 54, 1)' | Defines the background color for the input when disabled in dark theme |
| darkTextColor | String | '#000000' | Defines the text color for the input in dark theme |
| fontFamilyMsg | String | "'Lato', sans-serif" | Defines the font-family for the message |
| fontSizeMsg | String | '1em' | Defines the font-size for the message |
| fontWeightMsg | Number | 400 | Defines the font-weight for the message |
| textMessageColor | String | '#f15574' | Defines the text color for the message |
| showMsg | Boolean | false | Defines if the message should be displayed |
| hasMsg | Boolean | false | Defines if there is a message to display |
| message | String | 'Default message text' | Defines the message text |
| hasCustomMsg | Boolean | false | Defines if the message uses custom styling |
| extraContendAbsolute | Boolean | false | Controls whether the auxiliary message is in normal flow (false, default) or position: absolute under the field (true). The calendar popup (Teleport) is unchanged. In templates: extra-contend-absolute. (Prop name keeps the Contend spelling.) |
| sizeMediaQuery | String | 'sm' | Defines the size media query. Accepts xs, sm, md, and lg. Currently always uses 'sm'. |
| tabindex | String/Number | 0 | Defines the tabindex attribute for the input |
Calendar Customization Props
All props prefixed with calendar are passed directly to the underlying NbCalendar component. These props allow you to customize the calendar appearance, behavior, and text labels.
Note: All calendar props use the
calendarprefix to differentiate them from the DatePicker's own props.
Calendar Font Props
| name | Value type | Default | Description |
|---|---|---|---|
| calendarFontFamily | String | "'Lato', sans-serif" | Defines the font-family for the calendar. |
| calendarFontSize | String | '1.6em' | Defines the font-size for the calendar. |
| calendarFontWeight | Number | 400 | Defines the font-weight for the calendar. |
Calendar Color Props
| name | Value type | Default | Description |
|---|---|---|---|
| calendarPrimaryColor | String | '#007bff' | Defines the primary color. Accepts Hex format. |
| calendarSelectionColor | String | '#1976d2' | Defines the background color for selected dates. Accepts Hex format. |
| calendarEventColor | String | '#4caf50' | Defines the color for event indicators. Accepts Hex format. |
| calendarTodayColor | String | '#007bff' | Defines the color for today's date. Accepts Hex format. |
| calendarHoverTextColor | String | null | Defines the text color for month/year picker items on hover. If null, uses theme default. Accepts Hex format. |
| calendarNormalTextColor | String | null | Defines the text color for month/year picker items. If null, uses theme default. Accepts Hex format. |
| calendarMonthYearItemBg | String | null | Defines the background color for month/year picker items. If null, uses theme default. Accepts Hex or RGB/RGBA format. |
| calendarMonthYearItemBgHover | String | null | Defines the background color for month/year picker items on hover. If null, uses theme default. Accepts Hex or RGB/RGBA format. |
| calendarDayHoverBg | String | null | Defines the background color for days on hover. If null, uses theme default. Accepts Hex or RGB/RGBA format. |
| calendarDayHoverTextColor | String | null | Defines the text color for days on hover. If null, uses theme default. Accepts Hex format. |
| calendarTimeDisplayTextColor | String | null | Defines the text color for the time display section. If null, uses theme default. Accepts Hex format. |
Calendar Button Props - Time Edit Button
| name | Value type | Default | Description |
|---|---|---|---|
| calendarTimeEditButtonBg | String | null | Defines the background color for the time edit button. If null, uses theme default. Accepts Hex or RGB/RGBA format. |
| calendarTimeEditButtonTextColor | String | null | Defines the text color for the time edit button. If null, uses theme default. Accepts Hex format. |
| calendarTimeEditButtonBgHover | String | null | Defines the background color for the time edit button on hover. If null, uses theme default. Accepts Hex or RGB/RGBA format. |
| calendarTimeEditButtonTextColorHover | String | null | Defines the text color for the time edit button on hover. If null, uses theme default. Accepts Hex format. |
| calendarTimeEditButtonFontFamily | String | "'Lato', sans-serif" | Defines the font-family for the time edit button. |
| calendarTimeEditButtonFontSize | String | '14px' | Defines the font-size for the time edit button. |
| calendarTimeEditButtonPadding | String | null | Defines the padding for the time edit button. If null, uses default. |
| calendarTimeEditButtonBorderRadius | String | null | Defines the border-radius for the time edit button. If null, uses default. |
| calendarTimeEditButtonFontWeight | Number | 500 | Defines the font-weight for the time edit button. |
| calendarTimeEditButtonBorder | String | null | Defines the border for the time edit button. If null, uses default. |
| calendarTimeEditButtonText | String | 'Edit' | Defines the text for the time edit button. |
Calendar Button Props - Today Button
| name | Value type | Default | Description |
|---|---|---|---|
| calendarTodayButtonBg | String | null | Defines the background color for the "Today" button. If null, uses theme default. Accepts Hex or RGB/RGBA format. |
| calendarTodayButtonTextColor | String | null | Defines the text color for the "Today" button. If null, uses theme default. Accepts Hex format. |
| calendarTodayButtonBgHover | String | null | Defines the background color for the "Today" button on hover. If null, uses theme default. Accepts Hex or RGB/RGBA format. |
| calendarTodayButtonTextColorHover | String | null | Defines the text color for the "Today" button on hover. If null, uses theme default. Accepts Hex format. |
| calendarTodayButtonFontFamily | String | "'Lato', sans-serif" | Defines the font-family for the "Today" button. |
| calendarTodayButtonFontSize | String | '1.1rem' | Defines the font-size for the "Today" button. |
| calendarTodayButtonPadding | String | null | Defines the padding for the "Today" button. If null, uses default. |
| calendarTodayButtonBorderRadius | String | null | Defines the border-radius for the "Today" button. If null, uses default. |
| calendarTodayButtonFontWeight | Number | 400 | Defines the font-weight for the "Today" button. |
| calendarTodayButtonBorder | String | null | Defines the border for the "Today" button. If null, uses default. |
| calendarTodayButtonText | String | 'Today' | Defines the text for the "Today" button (used in calendar/month view). |
| calendarNowButtonText | String | 'Now' | Defines the text for the "Now" button (used in time picker view). |
Calendar Configuration Props
| name | Value type | Default | Description |
|---|---|---|---|
| calendarShowClearButton | Boolean | false | Defines if the clear button (×) should be displayed. When clicked, clears the current selection and emits appropriate events. |
| calendarShowTodayButton | Boolean | false | Defines if the "Today" / "Now" button should be displayed. When clicked, selects the current date/time and navigates to the current month/year. |
| calendarClearButtonKeepCurrentMonth | Boolean | false | Defines if the calendar should stay on the current month/year when clearing selection. If false, navigates to the current system month/year after clearing. |
| calendarStartWeekOnMonday | Boolean | false | Defines if the week should start on Monday instead of Sunday. |
| calendarEditRange | Boolean | true | Defines if the range can be edited by dragging the start or end dates. Only works when allowRange is true. |
| calendarMaxRangeDays | Number | null | Defines the maximum number of days that can be selected in a range. If null, there is no limit. |
| calendarMinYear | Number | 1900 | Defines the minimum year available in the year picker. |
| calendarMaxYear | Number | 2100 | Defines the maximum year available in the year picker. |
| calendarGoToDate | Date/String | null | Navigates the calendar to a specific date. Accepts Date or String (YYYY-MM-DD). |
| calendarIsRequired | Boolean | false | Defines if the calendar is required. |
| calendarWidthFull | Boolean | false | Defines if the calendar should occupy 100% of its parent container width. |
| calendarBorderRadius | Number | 0 | Defines the border radius of the calendar in pixels. |
| calendarScrollClass | String | '' | Defines a custom CSS class for the scrollable content area (useful for custom scrollbar styling). |
| calendarEvents | Array | Defines 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). | |
| calendarIsoStringTimezoneFormat | String | '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. This prop affects the isoString field in @date-selected, @changed-complete, and @current-value-complete events. |
Calendar Text Customization Props
All text labels and button texts can be customized via props. Defaults are in English.
| name | Value type | Default | Description |
|---|---|---|---|
| calendarSelectMonthText | String | 'Select month' | Defines the text displayed when selecting a month. |
| calendarSelectYearText | String | 'Select year' | Defines the text displayed when selecting a year. |
| calendarSelectTimeText | String | 'Select time' | Defines the text displayed when selecting a time. |
| calendarTimeDisplayLabelText | String | 'Time:' | Defines the label text for the time display section. |
| calendarClearButtonTitle | String | 'Clear selection' | Defines the title (tooltip) text for the clear button. |
| calendarClearButtonSymbol | String | '×' | Defines the symbol/text displayed in the clear button. |
Note: Month names and weekday names are automatically controlled by the
localeprop ('pt-BR'or'en-US'). They do not need individual props.
Accepted Formats
The inputText prop accepts different value formats depending on the inputType. The component validates and normalizes these values automatically. Invalid formats are cleared (set to empty string).
Understanding "Cleared" Values
When a value is cleared, it means the component detected an invalid format and automatically set the internal value to an empty string (''). This is different from passing an empty value intentionally.
Key differences:
- Empty values (
null,undefined,''): Accepted as valid empty values, treated as intentional empty state - Cleared values: Invalid formats that are automatically converted to empty string
When values are cleared:
- Invalid date strings (e.g.,
"2026-13-45"- invalid month/day) - Wrong format strings (e.g., passing
"hello world"to a date input) - Numbers or objects (except
Dateobjects fordatetype) - Invalid ISO strings that cannot be parsed
Example - Testing cleared behavior:
<template>
<NbDatePicker
nb-id="datepicker-test"
input-name="test"
input-type="date"
:input-text="invalidValue"
@changed="onValueChanged"
/>
</template>
<script setup>
import { ref } from 'vue'
// Invalid format - will be cleared
const invalidValue = ref('invalid-date-string')
const onValueChanged = (value) => {
console.log('Value:', value)
// If invalidValue was 'invalid-date-string',
// value will be '' (cleared)
// If invalidValue was null or '',
// value will be '' (accepted as empty, not cleared)
}
</script>
Example - Comparing empty vs cleared:
<template>
<div>
<!-- This will be accepted as empty (not cleared) -->
<NbDatePicker
nb-id="datepicker-empty"
input-name="empty"
input-type="date"
:input-text="null"
@changed="(v) => console.log('Empty:', v)"
/>
<!-- This will be cleared (invalid format) -->
<NbDatePicker
nb-id="datepicker-invalid"
input-name="invalid"
input-type="date"
input-text="not-a-date"
@changed="(v) => console.log('Cleared:', v)"
/>
</div>
</template>
Practical use case:
If you're binding inputText to a reactive value that might come from an API or user input, invalid formats will be automatically cleared, ensuring the component always has a valid state:
<template>
<NbDatePicker
nb-id="datepicker-api"
input-name="api-date"
input-type="datetime-local"
:input-text="apiResponse.date"
@changed="handleDateChange"
/>
</template>
<script setup>
import { ref } from 'vue'
const apiResponse = ref({
date: '2026-01-09T21:07:50.624+00:00' // Valid ISO - will be normalized
// date: 'invalid' // Invalid - will be cleared to ''
// date: null // Valid empty - will be accepted as ''
})
const handleDateChange = (value) => {
// value will always be a valid format or empty string
// Never an invalid format
if (value) {
// Process valid date
console.log('Valid date:', value)
} else {
// Handle empty state
console.log('Empty or cleared')
}
}
</script>
For inputType="date"
Accepted formats:
- Native date format (recommended):
- Format:
YYYY-MM-DD - Example:
"2026-01-09" - Behavior: Used as-is, no conversion
- Format:
- ISO string with timezone:
- Format:
YYYY-MM-DDTHH:mm:ss.SSSZorYYYY-MM-DDTHH:mm:ssZorYYYY-MM-DDTHH:mmZ - Examples:
"2026-01-09T00:00:00.000Z""2026-01-09T21:07:50.624+00:00""2026-01-09T00:00:00-03:00"
- Behavior: Converted to local timezone and normalized to
YYYY-MM-DD
- Format:
- Date object:
- Type:
Date - Example:
new Date('2026-01-09') - Behavior: Converted to
YYYY-MM-DDformat using local date values
- Type:
Accepted as empty (not cleared, treated as valid empty value):
- Empty strings (
"") ->is default value nullundefined
Not accepted (will be cleared):
- Strings not matching the formats above
- Numbers
- Objects (except
Date) - Invalid dates (e.g.,
"2026-13-45") with day or month greater than 31 or 12
For inputType="datetime-local"
Accepted formats:
- Native datetime-local format (recommended):
- Format:
YYYY-MM-DDTHH:mmorYYYY-MM-DDTHH:mm:ss - Examples:
"2026-01-09T21:07""2026-01-09T21:07:50"
- Behavior: Used as-is, no conversion
- Format:
- ISO string with timezone:
- Format:
YYYY-MM-DDTHH:mm(:ss[.SSS])?(Z|+/-HH:mm) - Examples:
"2026-01-09T21:07:50.624+00:00""2026-01-09T21:07Z""2026-01-09T21:07:50-03:00"
- Behavior: Converted to local timezone and normalized to
YYYY-MM-DDTHH:mmorYYYY-MM-DDTHH:mm:ss(preserves seconds if present in original)
- Format:
Accepted as empty (not cleared, treated as valid empty value):
- Empty strings (
"") ->is default value nullundefined
Not accepted (will be cleared):
- Strings not matching the formats above
- Numbers
- Objects (including
Dateobjects) - Invalid dates/times
For inputType="time"
Accepted formats:
- Native time format:
- Format:
HH:mmorHH:mm:ss - Examples:
"21:07"or"21:07:50" - Behavior: Used as-is
- Format:
Not accepted (will be cleared):
- ISO strings with date
- Date objects
- Invalid time strings
- Other formats
For inputType="month"
Accepted formats:
- Native month format:
- Format:
YYYY-MM - Example:
"2026-01" - Behavior: Used as-is
- Format:
Not accepted (will be cleared):
- Other formats
For inputType="week"
Accepted formats:
- ISO week format:
- Format:
YYYY-Www - Example:
"2026-W03" - Behavior: Used as-is
- Format:
Not accepted (will be cleared):
- Other formats
For Range Mode (allowRange="true")
Accepted formats:
- JSON string with ISO dates:
- Format:
{"startDate":"YYYY-MM-DD","endDate":"YYYY-MM-DD"} - Example:
'{"startDate":"2026-01-01","endDate":"2026-01-31"}' - Behavior: Parsed and converted to Date objects
- Format:
Not accepted (will be cleared):
- Invalid JSON
- Missing
startDateorendDateproperties - Invalid date formats within JSON
Working with Timezones
By default, when you pass ISO strings with timezone information (e.g., "2026-01-09T21:07:50.624+00:00"), the component automatically converts them to the local timezone of the user's browser. This ensures that dates and times are displayed correctly for the user's location.
However, if you need to work with specific timezones or preserve the original timezone without conversion, you can use timezone libraries. Here are some common approaches:
Understanding Default Behavior
What happens by default:
- ISO strings with timezone are converted to local timezone
- Example:
"2026-01-09T21:07:50.624+00:00"(UTC) → converted to user's local time - The component always stores values in
datetime-localformat (no timezone info)
When you might need timezone libraries:
- Displaying dates in a specific timezone (not user's local)
- Preserving original timezone information
- Converting between different timezones
- Working with UTC explicitly
Using date-fns-tz
date-fns-tz is a timezone extension for date-fns.
Installation:
npm install date-fns date-fns-tz
# or
yarn add date-fns date-fns-tz
Example - Converting to specific timezone before passing to component:
<template>
<NbDatePicker
nb-id="datepicker-timezone"
input-name="datetime"
input-type="datetime-local"
:input-text="localDateTime"
@changed="handleDateTimeChange"
/>
</template>
<script setup>
import { ref, computed } from 'vue'
import { format, parseISO } from 'date-fns'
import { zonedTimeToUtc, utcToZonedTime, format as formatTz } from 'date-fns-tz'
// Example: You have a UTC datetime from API
const utcDateTime = ref('2026-01-09T21:07:50.624Z')
// Convert UTC to a specific timezone (e.g., 'America/Sao_Paulo')
const timezone = 'America/Sao_Paulo'
const zonedDate = computed(() => {
if (!utcDateTime.value) return null
return utcToZonedTime(parseISO(utcDateTime.value), timezone)
})
// Format for datetime-local (no timezone info)
const localDateTime = computed(() => {
if (!zonedDate.value) return null
return format(zonedDate.value, "yyyy-MM-dd'T'HH:mm:ss")
})
const handleDateTimeChange = (value) => {
// value is in datetime-local format (user's local timezone)
// If you need to convert back to UTC or specific timezone:
if (value) {
const date = parseISO(value)
const utcDate = zonedTimeToUtc(date, timezone)
console.log('UTC:', utcDate.toISOString())
}
}
</script>
Example - Displaying in specific timezone:
<template>
<div>
<NbDatePicker
nb-id="datepicker-utc"
input-name="datetime"
input-type="datetime-local"
:input-text="localValue"
@changed="handleChange"
/>
<p>Display in UTC: {{ displayInUTC }}</p>
<p>Display in São Paulo: {{ displayInSP }}</p>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
import { parseISO } from 'date-fns'
import { format as formatTz, utcToZonedTime } from 'date-fns-tz'
const localValue = ref('2026-01-09T21:07:50')
const displayInUTC = computed(() => {
if (!localValue.value) return ''
const date = parseISO(localValue.value)
return formatTz(date, 'yyyy-MM-dd HH:mm:ss', { timeZone: 'UTC' })
})
const displayInSP = computed(() => {
if (!localValue.value) return ''
const date = parseISO(localValue.value)
return formatTz(date, 'yyyy-MM-dd HH:mm:ss', { timeZone: 'America/Sao_Paulo' })
})
const handleChange = (value) => {
localValue.value = value
}
</script>
Using dayjs with timezone plugin
dayjs with timezone plugin is a lightweight alternative.
Installation:
npm install dayjs
npm install dayjs/plugin/timezone
npm install dayjs/plugin/utc
# or
yarn add dayjs
yarn add dayjs/plugin/timezone
yarn add dayjs/plugin/utc
Example:
<template>
<NbDatePicker
nb-id="datepicker-dayjs"
input-name="datetime"
input-type="datetime-local"
:input-text="localDateTime"
@changed="handleChange"
/>
</template>
<script setup>
import { ref, computed } from 'vue'
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'
dayjs.extend(utc)
dayjs.extend(timezone)
// Example: UTC datetime from API
const utcDateTime = ref('2026-01-09T21:07:50.624Z')
// Convert to specific timezone and format for datetime-local
const localDateTime = computed(() => {
if (!utcDateTime.value) return null
return dayjs(utcDateTime.value)
.tz('America/Sao_Paulo')
.format('YYYY-MM-DDTHH:mm:ss')
})
const handleChange = (value) => {
if (value) {
// Convert back to UTC
const utcValue = dayjs(value).tz('America/Sao_Paulo').utc().toISOString()
console.log('UTC:', utcValue)
}
}
</script>
Using moment-timezone
moment-timezone is a popular timezone library (though moment.js is in maintenance mode).
Installation:
npm install moment-timezone
# or
yarn add moment-timezone
Example:
<template>
<NbDatePicker
nb-id="datepicker-moment"
input-name="datetime"
input-type="datetime-local"
:input-text="localDateTime"
@changed="handleChange"
/>
</template>
<script setup>
import { ref, computed } from 'vue'
import moment from 'moment-timezone'
// Example: UTC datetime from API
const utcDateTime = ref('2026-01-09T21:07:50.624Z')
// Convert to specific timezone and format for datetime-local
const localDateTime = computed(() => {
if (!utcDateTime.value) return null
return moment(utcDateTime.value)
.tz('America/Sao_Paulo')
.format('YYYY-MM-DDTHH:mm:ss')
})
const handleChange = (value) => {
if (value) {
// Convert back to UTC
const utcValue = moment(value)
.tz('America/Sao_Paulo')
.utc()
.toISOString()
console.log('UTC:', utcValue)
}
}
</script>
Best Practices
- Store UTC in your backend/database: Always store dates/times in UTC format
- Convert to local timezone for display: Convert UTC to user's timezone or specific timezone when displaying
- Use datetime-local format for input: The component expects
datetime-localformat (no timezone), so convert before passing - Convert back to UTC on save: When user selects a date/time, convert it back to UTC before sending to backend
Complete example workflow:
<template>
<NbDatePicker
nb-id="datepicker-workflow"
input-name="datetime"
input-type="datetime-local"
:input-text="displayDateTime"
@changed="handleDateTimeChange"
/>
</template>
<script setup>
import { ref, computed } from 'vue'
import { format, parseISO } from 'date-fns'
import { utcToZonedTime, zonedTimeToUtc } from 'date-fns-tz'
// 1. UTC datetime from API/backend
const apiDateTime = ref('2026-01-09T21:07:50.624Z')
const userTimezone = 'America/Sao_Paulo'
// 2. Convert UTC to user's timezone for display
const displayDateTime = computed(() => {
if (!apiDateTime.value) return null
const utcDate = parseISO(apiDateTime.value)
const zonedDate = utcToZonedTime(utcDate, userTimezone)
return format(zonedDate, "yyyy-MM-dd'T'HH:mm:ss")
})
// 3. Handle user selection and convert back to UTC
const handleDateTimeChange = async (value) => {
if (value) {
// Parse the datetime-local value (assumed to be in user's timezone)
const localDate = parseISO(value)
// Convert back to UTC
const utcDate = zonedTimeToUtc(localDate, userTimezone)
// Send to backend
const utcISOString = utcDate.toISOString()
console.log('Sending to backend:', utcISOString)
// await saveToBackend(utcISOString)
}
}
</script>
Events
changed
Fired when the input value changes, returns the current value in different formats depending on the inputType:
For inputType="date":
- Returns:
String(format:YYYY-MM-DD) - Example:
"2024-01-15"
For inputType="month":
- Returns:
String(format:YYYY-MM) - Example:
"2024-01"
For inputType="time":
- Returns:
String(format:HH:mmorHH:mm:ss) - Example:
"14:30"or"14:30:45"
For inputType="datetime-local":
- Returns:
String(format:YYYY-MM-DDTHH:mmorYYYY-MM-DDTHH:mm:ss) - 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:
ObjectwithstartDateandendDateproperties (Date objects) - Example:
{ startDate: Date, endDate: Date }or{ startDate: null, endDate: null }when cleared
When input is cleared:
- Returns:
''(empty string) for single date or{ startDate: null, endDate: null }for range mode
Detailed Return Formats
The changed event returns values in different formats based on the inputType. Here are the detailed return formats:
Single Date Selection (inputType="date")
Returns: String in format YYYY-MM-DD
Example:
"2024-01-15"
When selection is cleared:
""
Date Range Selection (allowRange="true")
Returns: Object with startDate and endDate properties
{
startDate: Date, // Start date of the range (or null)
endDate: Date // End date of the range (or null)
}
Example:
{
startDate: new Date('2024-01-15'),
endDate: new Date('2024-01-20')
}
When range is cleared:
{
startDate: null,
endDate: null
}
When only start date is selected (partial range):
{
startDate: new Date('2024-01-15'),
endDate: null
}
Week Selection (inputType="week")
Returns: String in ISO 8601 week format YYYY-Www
Example:
"2024-W03" // Week 3 of year 2024
When selection is cleared:
""
Month Selection (inputType="month")
Returns: String in format YYYY-MM
Example:
"2024-01" // January 2024
When selection is cleared:
""
Time Selection (inputType="time")
Returns: String in format HH:mm or HH:mm:ss
Example:
"14:30" // 2:30 PM
"14:30:45" // 2:30:45 PM (if seconds are included)
When selection is cleared:
""
DateTime Selection (inputType="datetime-local")
Returns: String in format YYYY-MM-DDTHH:mm or YYYY-MM-DDTHH:mm:ss
Example:
"2024-01-15T14:30" // January 15, 2024 at 2:30 PM
"2024-01-15T14:30:45" // January 15, 2024 at 2:30:45 PM (if seconds are included)
When selection is cleared:
""
current-value
Fired whenever the input value changes (same as changed but with a different name for compatibility). Returns the same format as changed.
changed-complete
Fired when a date is selected via the calendar component. Returns the complete data structure from NbCalendar's @date-selected event, including detailed information about the selection.
Returns: Complete data object from NbCalendar (same format as NbCalendar's @date-selected event)
Format varies by inputType:
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 `calendarIsoStringTimezoneFormat` prop:
// - If `calendarIsoStringTimezoneFormat="Z"`: "2024-01-15T00:00:00.000Z"
// - If `calendarIsoStringTimezoneFormat="+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
}
Date Range Selection (allowRange="true")
When a range is selected:
{
startDate: Date, // Start date of the range
endDate: Date, // End date of the range
isRange: true, // Indicates this is a range selection
isoString: { // ISO strings for start and end dates
start: String, // ISO string for start date (format depends on `calendarIsoStringTimezoneFormat`)
end: String // ISO string for end date (format depends on `calendarIsoStringTimezoneFormat`)
},
isoStringLocal: { // Local ISO strings without timezone
start: String, // Local ISO string for start date
end: String // Local ISO string for end date
}
}
When range is cleared:
{
startDate: null,
endDate: null,
isRange: true,
isoString: null,
isoStringLocal: null
}
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 `calendarIsoStringTimezoneFormat` prop:
// - If `calendarIsoStringTimezoneFormat="Z"`: "2024-01-15T17:30:00.000Z"
// - If `calendarIsoStringTimezoneFormat="+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
}
Week Selection (inputType="week")
{
date: Date, // Date object of the first day of the selected week
dateString: String, // Date in YYYY-MM-DD format of the first day
isoString: String, // ISO 8601 string with timezone (format depends on `calendarIsoStringTimezoneFormat`)
isoStringLocal: String // Local ISO 8601 string of first day of week
}
Month Selection (inputType="month")
{
date: Date, // Date object of the first day of the selected month
dateString: String, // Date in YYYY-MM-DD format of the first day
isoString: String, // ISO 8601 string with timezone (format depends on `calendarIsoStringTimezoneFormat`)
isoStringLocal: String // Local ISO 8601 string of first day of month
}
Example:
@changed-complete="handleChangedComplete"
const handleChangedComplete = (data) => {
console.log('Complete data:', data)
// For date: { date: Date, dateString: "2024-01-15", isoString: "2024-01-15T00:00:00.000Z", ... }
// For datetime-local: { date: Date, hour: 14, minute: 30, isoString: "2024-01-15T17:30:00.000Z", ... }
// For range: { startDate: Date, endDate: Date, isoString: { start: "...", end: "..." }, ... }
}
Note: This event fires when:
- A date is clicked/selected in the calendar
- The "Today/Now" button is clicked
- The "Clear" button is clicked (returns null values)
- Time values are changed (hour/minute/second)
- A month or week is selected
- A date range is selected or cleared
- The
inputTextprop is set programmatically (e.g., when loading data from database)It does NOT fire when:
- The user types directly in the input field
- The value changes via native browser input controls
current-value-complete
Fired when a date is selected via the calendar component (same as changed-complete but with a different name for compatibility). Returns the complete data structure from NbCalendar's @date-selected event.
Returns: Same format as changed-complete (complete data object from NbCalendar)
focused
Fired when the input receives focus.
Returns: No return value
Example:
@focused="onInputFocused"
const onInputFocused = () => {
console.log('Input focused')
}
blurred
Fired when the input loses focus.
Returns: No return value
Example:
@blurred="onInputBlurred"
const onInputBlurred = () => {
console.log('Input blurred')
}
clicked
Fired when the input or its container is clicked. Receives the native DOM event as first argument.
Returns: No return value
Example:
@clicked="onInputClicked"
const onInputClicked = () => {
console.log('Input clicked')
}
entered
Fired when the user presses Enter while the input is focused. Only fires if hasTabIndexEnter is true and the input is not disabled or readonly.
Returns: The current input value (same format as changed)
Example:
@entered="onEnterPressed"
const onEnterPressed = (value) => {
console.log('Enter pressed with value:', value)
}
paste
Fired when content is pasted into the input. Always fired, even when blockPaste is true (in which case the paste action is blocked but the event is still emitted).
Returns: String - The pasted value from the clipboard
Example:
@paste="onPaste"
const onPaste = (value) => {
console.log('Pasted value:', value)
}
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
inputTextprop changes - When the value changes (via user interaction or programmatically)
- When
minormaxprops change - When the calendar component emits a validation event
Returns: Boolean - true if the value is valid, false if invalid
Validation Rules:
- Format Validation:
- The value must match the expected format for the
inputType:date:YYYY-MM-DDtime:HH:mmorHH:mm:ssdatetime-local:YYYY-MM-DDTHH:mmorYYYY-MM-DDTHH:mm:ssmonth:YYYY-MMweek:YYYY-Www
- Invalid formats return
false
- The value must match the expected format for the
- Empty Values:
- If
requiredistrue: Empty values ('',null,undefined) returnfalse(invalid) - If
requiredisfalse: Empty values returntrue(valid, as the field is optional)
- If
- Range Validation (min/max):
- If
minis set, values before the minimum returnfalse - If
maxis set, values after the maximum returnfalse - Both format and range must be valid for the value to be considered valid
- If
Example:
<template>
<NbDatePicker
nb-id="datepicker-validation"
input-name="validation-test"
input-type="date"
:input-text="dateValue"
:min="'2024-01-01'"
:max="'2024-12-31'"
:required="true"
@valid="handleValidation"
/>
<p>Is Valid: {{ isValid ? 'Yes' : 'No' }}</p>
</template>
<script setup>
import { ref } from 'vue'
const dateValue = 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 - Required Field:
<template>
<NbDatePicker
nb-id="datepicker-required"
input-name="required-date"
input-type="date"
:input-text="dateValue"
:required="true"
@valid="handleValidation"
/>
</template>
<script setup>
import { ref } from 'vue'
const dateValue = ref('') // Empty value
const handleValidation = (valid) => {
// When required=true and value is empty, valid will be false
console.log('Is valid:', valid) // false
}
</script>
Example - Optional Field:
<template>
<NbDatePicker
nb-id="datepicker-optional"
input-name="optional-date"
input-type="date"
:input-text="dateValue"
:required="false"
@valid="handleValidation"
/>
</template>
<script setup>
import { ref } from 'vue'
const dateValue = ref('') // Empty value
const handleValidation = (valid) => {
// When required=false and value is empty, valid will be true (optional field)
console.log('Is valid:', valid) // true
}
</script>
Example - Real-time Validation:
<template>
<div>
<NbDatePicker
nb-id="datepicker-realtime"
input-name="realtime-date"
input-type="datetime-local"
:input-text="dateTimeValue"
:min="'2024-01-01T00:00'"
:max="'2024-12-31T23:59'"
@valid="handleValidation"
/>
<div v-if="!isValid" style="color: red;">
Invalid date/time. Please select a value between {{ min }} and {{ max }}.
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const dateTimeValue = ref('2024-06-15T12:00')
const isValid = ref(true)
const min = ref('2024-01-01T00:00')
const max = ref('2024-12-31T23:59')
const handleValidation = (valid) => {
isValid.value = valid
}
</script>
date-selected
Fired when a date is selected via the calendar component. This event is repassed from the underlying NbCalendar component's @date-selected event.
Returns: Complete data object from NbCalendar (same format as changed-complete and current-value-complete)
Note: This event provides the same data as changed-complete and current-value-complete, but with a different name for semantic clarity. Use this event when you specifically want to handle date selection events separately from other change events.
Format varies by inputType: Same format as changed-complete (see changed-complete section for detailed formats)
Example:
<template>
<NbDatePicker
nb-id="datepicker-selection"
input-name="date"
input-type="date"
@date-selected="handleDateSelected"
/>
</template>
<script setup>
const handleDateSelected = (data) => {
console.log('Date selected:', data)
// For date: { date: Date, dateString: "2024-01-15", isoString: "2024-01-15T00:00:00.000Z", ... }
// For datetime-local: { date: Date, hour: 14, minute: 30, isoString: "2024-01-15T17:30:00.000Z", ... }
}
</script>
month-changed
Fired when the calendar month/year is changed through navigation (e.g., clicking previous/next month buttons, selecting a month from the month picker, or selecting a year from the year picker). This event is repassed from the underlying NbCalendar component's @month-changed event.
Returns: Object with the following structure:
{
year: Number, // The year (e.g., 2024)
month: Number, // The month index (0-11, where 0 = January, 11 = December)
monthName: String // The localized month name (e.g., "January" or "Janeiro" depending on locale)
}
Example:
<template>
<NbDatePicker
nb-id="datepicker-month-nav"
input-name="date"
input-type="date"
@month-changed="handleMonthChanged"
/>
</template>
<script setup>
const handleMonthChanged = (data) => {
console.log('Month changed:', data)
// Example output: { year: 2024, month: 0, monthName: "January" }
// or: { year: 2024, month: 0, monthName: "Janeiro" } (if locale="pt-BR")
}
</script>
When this event fires:
- User clicks the previous month button (◀)
- User clicks the next month button (▶)
- User selects a month from the month picker
- User selects a year from the year picker
- Programmatic navigation via
calendarGoToDateprop
When this event does NOT fire:
- User selects a date (use
@date-selectedor@changed-completeinstead) - User changes time values (hour/minute/second)
- User clears the selection
Slots
message
Custom slot for the message area. Allows custom HTML/content to be displayed as the message.
Example:
<nb-date-picker nb-id="datepicker-1" input-name="date">
<template #message>
<span>Custom error message</span>
</template>
</nb-date-picker>
Examples
Basic Date Selection
<template>
<NbDatePicker
nb-id="datepicker-basic"
input-name="date"
@changed="onDateChanged"
/>
</template>
<script setup>
const onDateChanged = (value) => {
console.log('Selected date:', value)
}
</script>
Date Range Selection
<template>
<NbDatePicker
nb-id="datepicker-range"
input-name="date-range"
:allow-range="true"
:use-custom-calendar="true"
@changed="onRangeChanged"
/>
</template>
<script setup>
const onRangeChanged = (value) => {
console.log('Selected range:', value)
// value will be: { startDate: Date, endDate: Date }
}
</script>
Week Selection
<template>
<NbDatePicker
nb-id="datepicker-week"
input-name="week"
input-type="week"
@changed="onWeekChanged"
/>
</template>
<script setup>
const onWeekChanged = (value) => {
console.log('Selected week:', value) // Format: YYYY-Www
}
</script>
Month Selection
<template>
<NbDatePicker
nb-id="datepicker-month"
input-name="month"
input-type="month"
@changed="onMonthChanged"
/>
</template>
<script setup>
const onMonthChanged = (value) => {
console.log('Selected month:', value) // Format: YYYY-MM
}
</script>
Time Selection
<template>
<NbDatePicker
nb-id="datepicker-time"
input-name="time"
input-type="time"
@changed="onTimeChanged"
/>
</template>
<script setup>
const onTimeChanged = (value) => {
console.log('Selected time:', value) // Format: HH:mm or HH:mm:ss
}
</script>
DateTime Selection
<template>
<NbDatePicker
nb-id="datepicker-datetime"
input-name="datetime"
input-type="datetime-local"
@changed="onDateTimeChanged"
/>
</template>
<script setup>
const onDateTimeChanged = (value) => {
console.log('Selected datetime:', value) // Format: YYYY-MM-DDTHH:mm
}
</script>
DatePicker with Label
<template>
<NbDatePicker
nb-id="datepicker-label"
input-name="date"
:show-label="true"
label="Select a date"
@changed="onDateChanged"
/>
</template>
<script setup>
const onDateChanged = (value) => {
console.log('Selected date:', value)
}
</script>
Dark Theme DatePicker
<template>
<NbDatePicker
nb-id="datepicker-dark"
input-name="date"
theme="dark"
:input-width="300"
@changed="onDateChanged"
/>
</template>
<script setup>
const onDateChanged = (value) => {
console.log('Selected date:', value)
}
</script>
DatePicker with Min/Max Dates
<template>
<NbDatePicker
nb-id="datepicker-limited"
input-name="date"
min="2024-01-01"
max="2024-12-31"
:step="7"
@changed="onDateChanged"
/>
</template>
<script setup>
const onDateChanged = (value) => {
console.log('Selected date:', value)
}
</script>
DatePicker with Custom Calendar Disabled
<template>
<NbDatePicker
nb-id="datepicker-native"
input-name="date"
:use-custom-calendar="false"
@changed="onDateChanged"
/>
</template>
<script setup>
const onDateChanged = (value) => {
console.log('Selected date:', value)
}
</script>
DatePicker with Custom Styling
<template>
<NbDatePicker
nb-id="datepicker-custom"
input-name="date"
:has-border-radius="true"
:border-radius="0.8"
input-style="border"
:input-width="250"
text-align="center"
@changed="onDateChanged"
/>
</template>
<script setup>
const onDateChanged = (value) => {
console.log('Selected date:', value)
}
</script>
DatePicker with Message
<template>
<NbDatePicker
nb-id="datepicker-message"
input-name="date"
:show-msg="true"
:has-msg="true"
message="Please select a valid date"
@changed="onDateChanged"
/>
</template>
<script setup>
const onDateChanged = (value) => {
console.log('Selected date:', value)
}
</script>
DatePicker with Custom Locale
<template>
<NbDatePicker
nb-id="datepicker-locale"
input-name="date"
locale="en-US"
@changed="onDateChanged"
/>
</template>
<script setup>
const onDateChanged = (value) => {
console.log('Selected date:', value)
}
</script>
