Options API Reference
Every option of @pglejzer/datepicker-ui, the companion of timepicker-ui, grouped by area.
Option groups
calendar, ui, labels, behavior and callbacks. Every option is optional. For what each group does in practice, see the guides.import DatepickerUI from "@pglejzer/datepicker-ui";import "@pglejzer/datepicker-ui/index.css";new DatepickerUI("#date", {calendar: { mode: "range", minDate: "today" },ui: { theme: "m3-green", displayMode: "docked" },labels: { confirm: "Done" },behavior: { closeOnSelect: true, id: "trip-dates" },callbacks: {onConfirm: ({ value }) => console.log(value),},}).create();
Invalid options
#A value of the wrong type or an unknown choice falls back to the default. The picker also emits an error event with code invalid-option and the option path in option, for example ui.theme.
import DatepickerUI from "@pglejzer/datepicker-ui";const picker = new DatepickerUI("#date", {ui: { theme: "neon" },});picker.on("error", ({ code, option, message }) => {if (code === "invalid-option") {console.warn(option, message);}});picker.create();
Calendar options
#Which days exist, what the user selects and how the weeks are laid out:
| Option | Type | Default | Description |
|---|---|---|---|
mode | "single" | "range" | "multiple" | "single" | What the user selects. |
range.minLength | number | undefined | Shortest range in days, a positive integer. |
range.maxLength | number | undefined | Longest range in days. Ignored, with an error, when below minLength. |
range.presets | RangePreset[] | [] | Range shortcuts. See the RangePreset shape below. |
multiple.max | number | undefined | Most dates in a multiple selection, a positive integer. |
months | number | 1 | Months side by side, a positive integer. Docked and inline only. |
pageBy | "month" | "view" | "view" | Whether the arrows move one month or as many as are shown. |
precision | "day" | "month" | "year" | "day" | What one pick selects. Single mode only. |
locale | string | page locale | BCP 47 tag. Falls back to <html lang>, then navigator.language, then en-US. An invalid tag emits invalid-option. |
weekStart | "auto" | "sunday" | "monday" | "saturday" | "auto" | First day of the week. "auto" follows the locale. |
minDate | Date | string | "today" | undefined | Earliest selectable day. Strings are ISO YYYY-MM-DD. |
maxDate | Date | string | "today" | undefined | Latest selectable day. |
disabledDates | (Date | string)[] | [] | Days that cannot be selected. |
enabledDates | (Date | string)[] | undefined | When set, only these days can be selected. |
disabledWeekdays | number[] | [] | Weekdays that cannot be selected. 0 is Sunday and 6 is Saturday. |
isDateDisabled | (date: Date) => boolean | undefined | Return true for a day that cannot be selected. |
decorateDate | (date: Date) => DateDecoration | undefined | undefined | Return extra presentation for a day. |
renderDate | (date: Date) => string | Node | null | undefined | Return content shown under the day number. A string is always text, never HTML, and it is added to the accessible name of the day. |
validate | (value: PickerValue | null) => string | null | undefined | Return a message to mark the field invalid, or null or undefined when it is fine. It never blocks a pick or a commit. |
isDateDisabled and decorateDate may throw. The error is rethrown asynchronously and the day counts as enabled and undecorated. renderDate and validate follow the same rule: the day gets no content, and the value counts as valid.
UI options
#Presentation and display behaviour:
| Option | Type | Default | Description |
|---|---|---|---|
displayMode | "auto" | "docked" | "modal" | "auto" | Which surface opens. "auto" uses the modal below 600 px wide or 480 px tall and the docked popover otherwise. |
inline.enabled | boolean | false | Render the calendar permanently instead of opening it. |
inline.container | string | HTMLElement | undefined | Selector or element for the inline picker. |
format | string | "auto" | Date text format: "auto" or a pattern of d, dd, M, MM, yy, yyyy with one separator of /, ., - or a space. |
theme | ThemeName | "basic" | Theme name. |
colorScheme | "auto" | "light" | "dark" | "auto" | Light or dark. "auto" detects it when the picker opens. |
fullscreen | boolean | number | true | Width below which a modal range picker goes full screen. true means 600 px, a number is a width in pixels, false means never. |
toggleButton | string | HTMLElement | undefined | Extra element that opens the picker, such as a calendar icon button. |
weekNumbers | boolean | false | Show ISO week numbers before each row. |
outsideDays | boolean | { selectable?: boolean } | false | Show days of neighbouring months. true keeps them selectable, { selectable: false } makes them inert. |
fixedWeeks | boolean | false | Always show six rows. |
startView | "day" | "month" | "year" | "day" | Panel shown first. Ignored in range mode and for month or year precision. |
endInput | string | HTMLElement | undefined | Second page input for a range. Read on create() and used in range mode only. A value that is not an <input> emits invalid-option. |
yearRange.before | number | 100 | Years offered before the current year. |
yearRange.after | number | 20 | Years offered after the current year. |
todayButton | boolean | false | Show the Today button in the footer. |
clearButton | boolean | { clearInput?: boolean } | false | Show the Clear button. true also clears and commits the input. |
clearButton.clearInput | boolean | true | With false, Clear only empties the selection in the picker. Nothing is committed and the picker stays open. |
footer | boolean | undefined | Show the footer. Unset means shown, except inline. true or false forces it. |
animation | boolean | true | Play motion. With prefers-reduced-motion: reduce only short fades remain. |
allowPageScroll | boolean | false | Keep the page scrollable while the modal is open. |
cssClass | string | "" | Extra class names for the picker surface, separated by spaces. |
appendTo | string | HTMLElement | undefined | Where the modal dialog is appended. Defaults to the host. |
swipe | boolean | true | Drag, wheel and swipe between months. |
viewSwitch | boolean | true | Show the button that switches between the calendar and the input view. |
initialView | "calendar" | "input" | "calendar" | View shown on open, where the input view is supported. |
mask | boolean | false | Format typed digits to the date format while typing. Single mode and the two range fields, day precision only. |
The input view exists for single pickers in a modal and for every range picker. Multiple pickers have no input view. The theme names are basic, m3-green, crane, crane-straight, m2, glassmorphic, pastel, ai, cyberpunk and blueprint.
Labels options
#Every visible and assistive text is a label. Month and weekday names come from Intl, not from labels.
| Option | Default | Used for |
|---|---|---|
title | "Select date" | Modal header supporting text |
monthTitle | "Select month" | Header supporting text with calendar.precision: "month" |
yearTitle | "Select year" | Header supporting text with calendar.precision: "year" |
noDate | "No date selected" | Modal headline while nothing is selected |
confirm | "OK" | Confirm button |
cancel | "Cancel" | Cancel button |
today | "Today" | Today button |
clear | "Clear" | Clear button |
openCalendar | "Choose date" | Accessible name of the toggle button |
previousMonth | "Previous month" | Previous month button |
nextMonth | "Next month" | Next month button |
previousYear | "Previous year" | Previous year button |
nextYear | "Next year" | Next year button |
chooseMonth | "Choose month" | Month menu button and list |
chooseYear | "Choose year" | Year menu button and list |
weekNumber | "Week" | Week number column header |
invalidDate | "Enter a valid date" | Message for typed text that is not a date |
unavailableDate | "This date is not available" | Message for a typed date that is disabled |
rangeTitle | "Select dates" | Header supporting text in range mode |
rangeStart | "Start" | Headline placeholder for a missing range start |
rangeEnd | "End" | Headline placeholder for a missing range end |
multipleSelected | "{count} selected" | Headline in multiple mode. A PluralLabel. |
save | "Save" | Save button of the full-screen range picker |
close | "Close" | Close button of the full-screen range picker |
switchToInput | "Switch to text input" | Name of the button that shows the input view |
switchToCalendar | "Switch to calendar" | Name of the button that shows the calendar view |
dateField | "Date" | Text field label in single mode |
startDateField | "Start date" | Start text field label in range mode |
endDateField | "End date" | End text field label in range mode |
invalidRange | "End date must be on or after the start date" | Message for a range that is reversed or too long or short |
presets | "Presets" | Accessible name of the range presets group |
beforeMinDate | "Enter a date on or after {date}" | Message for a typed date before minDate. {date} is the limit in the display format. |
afterMaxDate | "Enter a date on or before {date}" | Message for a typed date after maxDate. {date} is the limit in the display format. |
multipleSelected is a PluralLabel: a string, or an object keyed by Intl.PluralRules categories. {count} is replaced by the number of dates.
new DatepickerUI("#date", {calendar: { mode: "multiple" },labels: {multipleSelected: { one: "{count} date", other: "{count} dates" },},}).create();
Behavior options
#Interaction rules:
| Option | Type | Default | Description |
|---|---|---|---|
closeOnSelect | boolean | false | Commit and close as soon as a day is picked. Not used in multiple mode. |
closeOnCancel | boolean | true | Close the picker when the Cancel button is pressed. |
commitOnChange | boolean | false | Commit every change to the input without the confirm button. |
ignoreOutsideClick | boolean | false | Keep the picker open when the user clicks outside of it. |
returnFocus | boolean | true | Move focus back to the input when the picker closes. |
id | string | undefined | Instance id for DatepickerUI.getById(). |
Callbacks options
#Each callback receives the payload of its event. The payload types and when each event fires are on the Events page.
| Option | Type | Default | Description |
|---|---|---|---|
onOpen | (data: OpenEventData) => void | undefined | Called on the open event. |
onClose | (data: CloseEventData) => void | undefined | Called on the close event. |
onCancel | (data: CancelEventData) => void | undefined | Called on the cancel event. |
onConfirm | (data: ConfirmEventData) => void | undefined | Called on the confirm event. |
onUpdate | (data: UpdateEventData) => void | undefined | Called on the update event. |
onError | (data: ErrorEventData) => void | undefined | Called on the error event. |
onSelectDay | (data: SelectDayEventData) => void | undefined | Called on the select:day event. |
onSelectMonth | (data: SelectMonthEventData) => void | undefined | Called on the select:month event. |
onSelectYear | (data: SelectYearEventData) => void | undefined | Called on the select:year event. |
onNavigate | (data: NavigateEventData) => void | undefined | Called on the navigate event. |
onRangeStart | (data: RangeStartEventData) => void | undefined | Called on the range:start event. |
onRangeEnd | (data: RangeEndEventData) => void | undefined | Called on the range:end event. |
Shapes used by the options
#DateDecoration is what calendar.decorateDate returns. RangePreset and RangePresetValue describe calendar.range.presets.
| Option | Type | Default | Description |
|---|---|---|---|
DateDecoration.className | string | undefined | Class name added to the day cell. |
DateDecoration.badge | boolean | undefined | Show a small dot on the day. |
DateDecoration.label | string | undefined | Text appended to the accessible name of the day. |
RangePreset.label | string | required | Text of the preset button. |
RangePreset.value | RangePresetValue | (() => RangePresetValue) | required | The range, or a function that returns it. The function runs each time the picker refreshes, so relative presets stay current. |
RangePresetValue.start | Date | string | required | First day of the range. |
RangePresetValue.end | Date | string | required | Last day of the range, on or after start. |
new DatepickerUI("#date", {calendar: {decorateDate: (date) =>date.getDate() === 1? { className: "first-of-month", badge: true, label: "First of the month" }: undefined,},}).create();
const day = 24 * 60 * 60 * 1000;new DatepickerUI("#range", {calendar: {mode: "range",range: {presets: [{label: "Last 7 days",value: () => ({start: new Date(Date.now() - 6 * day),end: new Date(),}),},{ label: "Q4 2026", value: { start: "2026-10-01", end: "2026-12-31" } },],},},}).create();
A preset click completes the range as if the user had picked both ends. It emits range:end, not select:day, and follows behavior.closeOnSelect and behavior.commitOnChange. A preset is disabled when its value is invalid or the length limits refuse the range.