Skip to content

Import

import { DatePicker } from '@dnb/eufemia'

Description

The DatePicker component should be used whenever the user is to enter a single date or a date range/period with a start and end date.

Relevant links

Date Object

The DatePicker operates with a default JavaScript Date instance as well as string (ISO 8601) like date="2019-05-05" (yyyy-MM-dd).

Handling time zones

The DatePicker component has no built-in time zone support, because it only deals with dates (not time).

Ensure you do not create Date objects with time information (new Date()), as that will introduce time zone issues.

If you need to use a Date object but want the same date everywhere, regardless of runtime timezone, you have to normalize it first.

Use an ISO string with an explicit offset:

const isoDate = '2025-01-01T00:00:00Z'

Or use UTC constructors:

const utcDate = new Date(Date.UTC(2025, 0, 1))

Root Element (React Portal)

The DatePicker component uses PortalRoot internally to render its calendar. See the PortalRoot documentation for information on how to control where the portal content appears in the DOM.

Manipulate the days in the calendar view

The callback event on_days_render gives you the possibility to manipulate the "day" object, before it gets rendered. This callback will be called many times. Both on the first render, and on every user interaction, like hover and selection, etc. This means you have to ensure a performant date calculation.

Please use date-fns to make the calculations.

Code Editor
<DatePicker
  onDaysRender={(days, calendarNumber = 0) => {
    return days.map((dayObject) => {
      if (isWeekend(dayObject.date)) {
        dayObject.isInactive = true
        dayObject.className = 'dnb-date-picker__day--weekend' // custom css
      }

      return dayObject
    })
  }}
/>

The dayObject object contains:

[
{
date: Date,// Vanilla JavaScript Date object
className: // define your custom css classes
isInactive: boolean,// shows it as disabled only
isDisabled: boolean,// shows it as disabled and with a strikethrough
isPreview: boolean,// date is between startDate (exclusive) and hoverDate (inclusive)
isSelectable: boolean,// if not last and next month and not disabled – handles z-index
isStartDate: boolean,// date selected is start date
isEndDate: boolean,// date selected is end date
isToday: boolean,
isWithinSelection: boolean,// date is between selection range
isNextMonth: boolean,// used for selection and inactive calculation
isLastMonth: boolean,// used for selection and inactive calculation
},
...
]

Highlighting "today"

By default the DatePicker highlights the "today" date based on the user's local time zone.

If you need to treat another time zone as "today", mutate the dayObject.isToday flag inside the on_days_render callback. The example below demonstrates how to compare every day against getOsloDate() and keep the highlight in sync with Oslo time.

Code Editor
const osloDate = getOsloDate()
render(
  <DatePicker
    onDaysRender={(days) => {
      return days.map((dayObject) => {
        dayObject.isToday = isSameDay(dayObject.date, osloDate)
        return dayObject
      })
    }}
  />,
)

Here is how to import the required helper:

import { isSameDay } from 'date-fns'
import { DatePicker } from '@dnb/eufemia'
import { getOsloDate } from '@dnb/eufemia/components/date-format/DateFormatUtils'

Validation for minDate, maxDate and invalid dates

Field.Date has built in validation for minDate, maxDate and invalid dates. This is the preferred method of handling scenarios where the user has typed in an invalid date, or a date outside of the set date limits. Automatically changing the user input on the other hand, leads to worse UX, and confusion, as the user might not understand why the date is changed, for seemingly no reason. So it's best practice to actually tell the user what is wrong, and let them correct it.

Min & Max date

If min_date or max_date is given, the return object also contains info about if the start_date or end_date is in between the given limits. The reason is that the user can still enter an invalid date in the input.

{
is_valid_start_date: boolean,
is_valid_end_date: boolean,
...
}

Validation during input changes

In order to validate dates during typing, you can make use of is_valid or is_valid_start_date and is_valid_end_date. Because the user can change a date in the input field, and the on_type event will then return a falsy is_valid.

Additional event return object properties:

{
is_valid: boolean, /* Available if `range` is `false` */
is_valid_start_date: boolean, /* Available if `range` is `true` */
is_valid_end_date: boolean, /* Available if `range` is `true` */
}