Options
Picker
Calendars
Dates
Time
Duration
Ranges
Footer
Custom Classes
Locale
Live Preview
Click the field above to open the picker.
Configuration
Event Log

Usage

Installation

Install via npm:

npm install @bornova/daterangepicker

ES Module

Import the picker and its stylesheet from your bundler:

          
            import DateRangePicker from '@bornova/daterangepicker'
            import '@bornova/daterangepicker/dist/daterangepicker.css'
          
        

Browser (script tag)

Load Luxon 3.x before the picker. Pin to a specific version (e.g. @bornova/daterangepicker@1.0.0) for production.

          
            <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@bornova/daterangepicker/dist/daterangepicker.css" />
            <script src="https://cdn.jsdelivr.net/npm/luxon@3/build/global/luxon.min.js"></script>
            <script src="https://cdn.jsdelivr.net/npm/@bornova/daterangepicker/dist/browser/daterangepicker.min.js"></script>
          
        

Quick Start

The constructor accepts a CSS selector or DOM element, an options object, and an optional callback fired on apply. The callback receives Luxon DateTime objects for start and end, plus the predefined range label (chosenLabel, or null for a custom range).

          
            <input type="text" id="daterange" />
          
        
          
            const picker = new DateRangePicker(
              '#daterange',
              {
                startDate: '01/01/2025',
                endDate: '01/31/2025'
              },
              (start, end, chosenLabel) => {
                console.log(start.toISODate(), end.toISODate())
              }
            )
          
        

Alternate Elements

Button Trigger

The picker can attach to any element, not just <input>. When attached to a <button>, it opens on click and focus. Use the apply event to update the button label manually, since autoUpdateInput only writes to <input> elements.

          
            const btn = document.querySelector('#btn-trigger')

            const picker = new DateRangePicker(btn, { autoUpdateInput: false })

            picker.on('apply', (start, end) => {
              btn.textContent = `${start.toFormat('MM/dd/yyyy')} - ${end.toFormat('MM/dd/yyyy')}`
            })
          
        

Options

Picker

Option
Type
Default
Description
showInline
boolean
false
Render the picker inline (always visible) instead of as a dropdown. The attached element is hidden and the calendar is inserted in its place.
showVertical
boolean
false
Lay out calendars vertically in a single column instead of horizontally in a row.
verticalColumns
number
1
When showVertical is true, number of columns of stacked calendars before wrapping. Calendars fill each row left-to-right before moving to the next. Capped at calendarCount; values less than 1 clamp to 1.
syncCalendars
boolean
true
When true, all calendars move together when navigating months. When false, each calendar's month can be changed independently.
wrapCalendars
boolean
false
Allow calendars to wrap onto multiple rows instead of laying out on a single row. Useful when displaying many calendars in a constrained width.
calendarCount
number
2
Number of calendar months to display (1-12).
dropDirection
'auto' | 'down' | 'up'
'auto'
Whether the picker drops down or up relative to the attached element.
openDirection
'left' | 'right' | 'center'
'right'
Which side the picker opens on relative to the attached element.
appendTo
string | Element
'body'
Element (or CSS selector) to append the picker container to.
autoApply
boolean
false
When true, hide the Apply button and apply the selection immediately on pick. When false, the Apply button is shown and the user must click it to confirm.
autoUpdateInput
boolean
true
Write the selected range back to the attached <input> on apply.
closeOnApply
boolean
true
Close the picker after applying. When false, the picker stays open after the user clicks Apply (or after auto-apply on pick).
closeOnCancel
boolean
true
Close the picker after cancelling. When false, the picker stays open after the user clicks Cancel.
closeOnEsc
boolean
true
Close the picker when the user presses Escape.
cancelOnClose
boolean
false
When true, closing the picker without applying (outside click or Esc) cancels and reverts the selection. When false, closing keeps the in-progress selection.
template
string | Element
Custom HTML string or Element to use as the picker container, replacing the default template.

Calendars

Option
Type
Default
Description
showMonthYearDropdowns
boolean
false
Show month and year dropdown menus in the calendar header.
showWeekNumbers
boolean
false
Show locale-based week numbers in a column to the left of each row.
showISOWeekNumbers
boolean
false
Show ISO-8601 week numbers instead of locale week numbers.
highlightToday
boolean
true
Add the drp-today CSS class to today's cell.
disabledDates
DateTime[] | function(DateTime): boolean
[]
Dates to disable. Pass an array of date values or a predicate that receives a Luxon DateTime and returns true to disable that day.
dayClassFn
function(DateTime): string | string[] | false
undefined
Called for every day cell. Return a CSS class string, an array of class strings, or false to add no class.

Dates

Option
Type
Default
Description
startDate
string | Date | DateTime
Initial start date. Accepts a formatted string (per locale.format), a JS Date, or a Luxon DateTime. When omitted the picker opens with no selection and a blank input.
endDate
string | Date | DateTime
Initial end date. Ignored when startDate is not provided.
minDate
string | Date | DateTime | false
false
Earliest selectable date. Dates before this are disabled.
maxDate
string | Date | DateTime | false
false
Latest selectable date. Dates after this are disabled.

Time

Option
Type
Default
Description
showTimePicker
boolean
false
Show hour and minute dropdowns below each calendar.
timePicker24Hour
boolean
false
Use 24-hour format in the time picker. When false, AM/PM selector is shown.
timePickerSeconds
boolean
false
Show a seconds dropdown in the time picker.
minuteIncrement
number
1
Minute increment for the minutes dropdown.

Duration

Option
Type
Default
Description
inclusiveDuration
boolean
true
When true, duration counts both the start and end day (e.g. Apr 7-10 = 4 days). When false, duration is the elapsed difference (3 days).
minDuration
number | false
false
Minimum number of days that must be selected.
maxDuration
number | false
false
Maximum number of days that can be selected.
durationFormat
string
"d 'days'"
Luxon duration format string, e.g. "d 'days'". When showTimePicker is enabled and no value is supplied, the default becomes "d 'days', h 'hrs'". Use showDuration: false to hide the duration entirely.

Ranges

Option
Type
Default
Description
ranges
object
Predefined date ranges shown in a list. Flat: { 'Today': [start, end] }. Grouped: { 'Group': { 'Label': [start, end] } }.
showCustomRange
boolean
true
Show a "Custom Range" item at the bottom of the ranges list that opens the calendars.
alwaysShowCalendars
boolean
false
Show the calendar panels even when predefined ranges are defined.

Footer

Option
Type
Default
Description
showSelectedDates
boolean
true
Show the selected date range string in the picker footer.
showDuration
boolean
true
Show the selected duration next to the range string in the footer.
showCancelButton
boolean
true
Show the Cancel button.
showClearButton
boolean
true
Show a Clear button that resets startDate/endDate to null, empties the input, and fires a clear event.

Custom Classes

Option
Type
Default
Description
pickerClasses
string | string[]
''
CSS class(es) added to the picker container element.
buttonClasses
string | string[]
''
CSS class(es) applied to all action buttons (Apply, Cancel, and Clear).
applyButtonClasses
string | string[]
''
Additional CSS class(es) applied to the Apply button only.
cancelButtonClasses
string | string[]
''
Additional CSS class(es) applied to the Cancel button only.

Locale

Option
Type
Default
Description
locale.format
string
locale-detected
Luxon format string used to parse and display dates, e.g. 'MM/dd/yyyy'.
locale.separator
string
' - '
String placed between the start and end date in the input value.
locale.applyButtonLabel
string
'Apply'
Label for the Apply button.
locale.cancelButtonLabel
string
'Cancel'
Label for the Cancel button.
locale.clearButtonLabel
string
'Clear'
Label for the Clear button.
locale.customRangeLabel
string
'Custom Range'
Label for the custom range list item.
locale.weekLabel
string
'W'
Header label for the week-number column.
locale.daysOfWeek
string[]
locale-detected
Short weekday names, Sunday-first, e.g. ['Su','Mo','Tu','We','Th','Fr','Sa'].
locale.monthNames
string[]
locale-detected
Month names, January-first.
locale.firstDay
number
locale-detected
First day of the week: 0 = Sunday, 1 = Monday, etc.
locale.direction
'ltr' | 'rtl'
'ltr'
Text direction. Sets a corresponding CSS class on the picker container.

data-* Attributes

All scalar options (booleans, numbers, and strings) can be set directly on the element via data-* attributes using kebab-case — no JavaScript configuration needed. The picker below is initialised with a single new DateRangePicker('#data-trigger') call; all other options come from the markup.

          
            <input
              id="data-trigger"
              data-start-date="01/09/2026"
              data-end-date="02/25/2026"
              data-show-week-numbers="true"
              data-highlight-today="true"
              data-open-direction="left"
            />

            <script>
              new DateRangePicker('#data-trigger')
            </script>
          
        

Options requiring objects, arrays, or functions — such as ranges, disabledDates, dayClassFn, and locale — must be passed via the constructor.

Methods

All methods operate on the same picker instance.

Method
Description
setStartDate(date)
Programmatically set the start date. Accepts a formatted string, JS Date, or Luxon DateTime. Clamps to minDate/maxDate.
setEndDate(date)
Programmatically set the end date. Enforces minDuration distance from start, clamps to maxDate/maxDuration.
setDateRange(start, end)
Set both start and end dates atomically with a single render. Accepts the same value types as setStartDate / setEndDate.
updateInput()
Write the current selection back to the attached <input>. Only needed when autoUpdateInput is false and you want to sync the input manually.
apply()
Apply the current in-picker selection and fire the apply event. Hides the picker unless closeOnApply is false. Equivalent to clicking the Apply button.
clear()
Reset startDate and endDate to null, empty the attached input, and fire the clear event.
cancel()
Revert selection to the values captured when the picker was opened and fire the cancel event.
show()
Open the picker. Saves the current selection as the revert point for cancel.
hide()
Close the picker. Fires the callback if the selection changed.
toggle()
Open if closed, close if open.
setOptions(options)
Apply partial option updates at runtime and refresh the picker UI (labels, classes, ranges, and view).
getDateRange()
Return the current selection as { startDate, endDate }.
getState()
Return a snapshot of state as { isShowing, startDate, endDate, chosenLabel }.
on(event, fn)
Subscribe to a picker event. The handler receives (startDate, endDate, chosenLabel).
once(event, fn)
Subscribe to a picker event and auto-unsubscribe after the first call.
off(event, fn)
Remove a handler previously added with on().
remove()
Remove the picker from the DOM and clean up all event listeners.

Events

All events are dispatched as CustomEvents on the attached element. Listen with element.addEventListener(name, fn) or use the on() method. For show/hide, event.detail is the internal picker instance. For apply/cancel, event.detail is an object containing selection data (startDate, endDate, and optional chosenLabel). The custom change event fires only when a committed selection is different from the previously committed selection; its payload includes old and new values. For clear, event.detail is an empty object.

Event
Fired when
show
The picker has opened and is visible.
hide
The picker has closed and is no longer visible.
apply
Fired when the selection is applied. event.detail includes startDate, endDate, and chosenLabel.
change
Fired only when a commit changes the selected range/date-time (for example Apply or Auto Apply). event.detail includes oldStartDate, oldEndDate, startDate, endDate, chosenLabel, and source (apply or autoApply).
cancel
The user clicks Cancel, or closes the picker while cancelOnClose is true.
clear
The user clicks Clear; startDate and endDate are set to null and the input is emptied.