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 a 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 onDaysRender 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. This means you have to ensure a performant date calculation.
Please use date-fns to make the calculations.
<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 objectclassName: // define your custom css classesisInactive: boolean,// shows it as disabled onlyisDisabled: boolean,// shows it as disabled and with a strikethroughisPreview: boolean,// date is between startDate (exclusive) and hoverDate (inclusive)isSelectable: boolean,// if not last and next month and not disabled – handles z-indexisStartDate: boolean,// date selected is start dateisEndDate: boolean,// date selected is end dateisToday: boolean,isWithinSelection: boolean,// date is between selection rangeisNextMonth: boolean,// used for selection and inactive calculationisLastMonth: 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 onDaysRender callback. The example below demonstrates how to compare every day against getOsloDate() and keep the highlight in sync with Oslo time.
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'
Min & Max date
The minDate and maxDate props restrict which dates can be selected in the calendar view. Dates outside the given range will be disabled, both for single dates and ranges. However, the user can still type a date outside these limits directly in the input field — minDate and maxDate do not validate typed input.
If minDate or maxDate is given, the return object also contains information about whether the date is within the given limits:
{isValidStartDate: boolean,isValidEndDate: boolean,...}
Validation for minDate, maxDate, and invalid dates
If you need validation of typed input against minDate and maxDate, use Field.Date instead. It has built-in validation for minDate, maxDate, and invalid dates, and will show the user an error message when the entered date is outside the allowed range.
Automatically changing the user input leads to worse UX and confusion, as the user might not understand why the date changed. It's best practice to tell the user what is wrong and let them correct it.
Validation during input changes
In order to validate dates during typing, you can make use of isValid or isValidStartDate and isValidEndDate. Because the user can change a date in the input field, and the onType event will then return a falsy isValid.
Additional event return object properties:
{isValid: boolean, /* Available if `range` is `false` */isValidStartDate: boolean, /* Available if `range` is `true` */isValidEndDate: boolean, /* Available if `range` is `true` */}
Demos
English (US) is not included in Eufemia by default. You can include it like:
import enUS from '@dnb/eufemia/shared/locales/en-US'<EufemiaProvider locale={enUS} ...>App</EufemiaProvider>
Range DatePicker
<DatePicker label="DatePicker" startDate="2019-04-01" endDate="2019-05-17" range showInput onChange={({ startDate, endDate }) => { console.log('onChange', startDate, endDate) }} onSubmit={({ startDate, endDate }) => { console.log('onSubmit', startDate, endDate) }} onCancel={({ startDate, endDate }) => { console.log('onCancel', startDate, endDate) }} onBlur={({ startDate, endDate }) => { console.log('onBlurComplete', startDate, endDate) }} shortcuts={[ { title: 'Set date period', startDate: '1969-07-15', endDate: '1969-08-15', }, { title: 'Today', startDate: new Date(), }, { title: 'This week', startDate: startOfWeek(new Date()), endDate: lastDayOfWeek(new Date()), }, { closeOnSelect: true, title: 'This month', startDate: startOfMonth(new Date()), endDate: lastDayOfMonth(new Date()), }, { title: 'Relative +3 days', // @ts-expect-error -- strictFunctionTypes startDate: ({ startDate }) => startDate || new Date(), // @ts-expect-error -- strictFunctionTypes endDate: ({ endDate }) => addDays(endDate || new Date(), 3), }, ]} />
Default DatePicker
<DatePicker label="DatePicker" date="2019-05-05" returnFormat="dd-MM-yyyy" onChange={({ date }) => { console.log('onChange', date) }} onOpen={({ date }) => { console.log('onOpen', date) }} onBlur={({ startDate, endDate }) => { console.log('onBlur', startDate, endDate) }} />
Default DatePicker with Input
<DatePicker label="DatePicker" date={new Date()} showInput showCancelButton showResetButton onChange={({ date }) => { console.log('onChange', date) }} onCancel={({ date }) => { console.log('onCancel', date) }} onBlur={({ date }) => { console.log('onBlur', date) }} />
Hidden Nav:
<DatePicker label="DatePicker" date="2022/05/05" minDate="2022/05/01" maxDate="2022/05/17" dateFormat="yyyy/MM/dd" returnFormat="dd/MM/yyyy" hideNavigation hideDays onChange={({ date }) => { console.log('onChange', date) }} onClose={({ date }) => { console.log('onClose', date) }} onBlur={({ date }) => { console.log('onBlur', date) }} />
Show days in a specific month
<DatePicker label="DatePicker" date="05/02/2019" dateFormat="MM/dd/yyyy" onlyMonth />
With info message
<DatePicker label="DatePicker" date={new Date()} showInput status="Please select a valid date" statusState="information" />
With suffix
<DatePicker label="DatePicker" date={new Date()} showInput suffix={<HelpButton title="Modal Title">Modal content</HelpButton>} />
Linked DatePickers
<DatePicker label="DatePicker" range link showInput />
Year navigation
<DatePicker showInput yearNavigation />
DatePicker with error status (no input)
<DatePicker label="DatePicker" date="2019-05-05" hideNavigation status="Please select a valid date" />
DatePicker with error
<DatePicker label="DatePicker" date="2019-05-05" showInput showSubmitButton status={ <span> Status message with <b>HTML</b> inside </span> } />
DatePicker with error status
<DatePicker label="DatePicker" date={new Date()} hideNavigation status="error" />
Inline DatePicker
| ma | ti | on | to | fr | lø | sø |
|---|---|---|---|---|---|---|
| ma | ti | on | to | fr | lø | sø |
|---|---|---|---|---|---|---|
<DatePicker inline range startDate="2019-05-05" endDate="2019-06-05" />