Create a date field with a calendar popup. Users type the date into a section-based mask or pick it from the calendar, and the two stay in sync.
Example
Below is an example of a basic Date Picker.
Days
The input is a section-based mask — type the date directly, adjust a section with the arrow keys, or pick a day from the calendar. There is no free-text parsing and no debounce: the field always holds a valid partial date.
<div class="row">
<div class="col-sm-6 col-lg-5 mb-4 mb-sm-0">
<div data-coreui-locale="en-US" data-coreui-date-picker></div>
</div>
<div class="col-sm-6 col-lg-5">
<div data-coreui-date="2026/03/15" data-coreui-locale="en-US" data-coreui-date-picker></div>
</div>
</div>With footer
There is no footer option. Project a <template data-coreui-template="footer">
child instead — its content is cloned into the dropdown. Buttons act through
data-coreui-picker-action (today, clear, reset, close), so labels,
order, and translations are yours. A button opting into the today action
opts into its state too: it is disabled at initialization when today falls
outside minDate/maxDate/disabledDates. This is one-way — the picker only
ever sets disabled, so a button you disable in the template stays disabled.
<div class="row">
<div class="col-lg-5">
<div data-coreui-locale="en-US" data-coreui-date-picker>
<template data-coreui-template="footer">
<button type="button" class="btn-ghost theme-danger btn-sm me-auto" data-coreui-picker-action="today">Today</button>
<button type="button" class="btn-ghost theme-primary btn-sm" data-coreui-picker-action="clear">Clear</button>
<button type="button" class="btn-solid theme-primary btn-sm" data-coreui-picker-action="close">OK</button>
</template>
</div>
</div>
</div>Here maxDate is the end of last month, so the today button disables
itself. The state of any other button is yours — the slot context exposes
isDateSelectable(date), which answers whether a date, expressed in the
field’s mask, passes the minDate/maxDate/disabledDates validation (a day
mask checks the calendar day, so new Date() passes with a maxDate of
today, and a month, quarter or year mask checks the whole period) — and every
programmatic date still runs through the field’s
validation: out of range, the field turns is-invalid, errorChange reports
the reason, and getDate() reports null, the same outcome as typing that
date. setDate() fires no dateChange; an action such as today fires it
with null.
<div class="row">
<div class="col-lg-5">
<div id="myDatePickerFooterToday">
<template data-coreui-template="footer">
<button type="button" class="btn-ghost theme-danger btn-sm me-auto" data-coreui-picker-action="today">Today</button>
<button type="button" class="btn-solid theme-primary btn-sm" data-coreui-picker-action="close">OK</button>
</template>
</div>
</div>
</div>Weeks
Add data-coreui-selection-type="week" to select week numbers, and
data-coreui-show-week-number="true" to show them in the grid. The field
renders the native <input type="week"> presentation — a fixed, non-editable
localized label followed by the week and year sections (Week 29, 2026,
Tydzień 29, 2026, …). The year is the ISO week-numbering year, which can
differ from the calendar year around January 1st, and the reported Date is
the Monday of the selected week. Prefer the ISO wire format in the field?
Set data-coreui-format="yyyy-Www".
<div class="row">
<div class="col-lg-5">
<div
data-coreui-locale="en-US"
data-coreui-selection-type="week"
data-coreui-show-week-number="true"
data-coreui-date-picker></div>
</div>
</div>Months
Add data-coreui-selection-type="month" to select months. The field mask
narrows to month and year automatically.
<div class="row">
<div class="col-lg-5">
<div
data-coreui-locale="en-US"
data-coreui-selection-type="month"
data-coreui-date-picker></div>
</div>
</div>Quarters
Add data-coreui-selection-type="quarter" to select quarters — the equivalent
of the <input type="quarter"> that HTML never shipped. The field mask narrows
to a quarter and year section (Q4 2026), and the reported Date is the
first day of the selected quarter.
<div class="row">
<div class="col-lg-5">
<div
data-coreui-locale="en-US"
data-coreui-selection-type="quarter"
data-coreui-date-picker></div>
</div>
</div>Years
Add data-coreui-selection-type="year" to select years. The field mask narrows
to the year automatically.
<div class="row">
<div class="col-lg-5">
<div
data-coreui-locale="en-US"
data-coreui-selection-type="year"
data-coreui-date-picker></div>
</div>
</div>With time
Set timepicker to add the time half. The field switches to a date and time
mask, the panel grows a row of time selects under the calendar, and picking a
day no longer closes the panel — the two halves own different parts of one
value, so the interaction is not over until the user says so. While no time is
picked, or the field holds a time a list does not offer, each select stands on a
-- placeholder, so every enabled option, the first allowed one included, sets
the time.
<div class="row">
<div class="col-lg-5">
<div data-coreui-locale="en-US" data-coreui-timepicker="true" data-coreui-date-picker></div>
</div>
</div>hours, minutes and seconds narrow what the time half offers, and are
ignored without timepicker. Hours are 0 to 23 in every locale; on a 12-hour
clock an hour that only one period allows sets that period. The four ariaSelect*Label options name its
selects, and with the flag on the field actions call themselves “Clear date and
time” and “Toggle calendar and time selection” unless the page passed its own
label.
minDate and maxDate can carry a time of day. Their day stays selectable in
the calendar and the time selects disable the hours, minutes and seconds before
minDate or after maxDate on that day. A time the panel sets beyond a limit,
such as the current time when the day of minDate is picked, moves to the
limit; a typed time beyond it marks the field invalid. Until a date is picked,
the time selects work on today moved into the limits. A limit without a time of
day covers its whole day.
<div class="row">
<div class="col-lg-5">
<div data-coreui-locale="en-US" data-coreui-timepicker="true" data-coreui-min-date="2026-10-15T09:30" data-coreui-max-date="2026-10-30T17:00" data-coreui-date-picker></div>
</div>
</div>With form field
Wrap the control in .form-field to lay it out with its label and description, and to get validation feedback in the right place.
<div class="form-field">
<span class="form-label" id="datePickerDeliveryDateLabel">Delivery date</span>
<div data-coreui-locale="en-US" data-coreui-date-picker aria-labelledby="datePickerDeliveryDateLabel"></div>
<div class="form-text">We deliver on working days only.</div>
</div>Composing the markup
The picker is built from other components — the date input field, the calendar and a popup — held together by the date it owns. The markup is where you choose the parts: mark an element with a role attribute and the picker adopts it instead of building its own; leave a part out and it is generated as in the examples above.
| Role | Element | What the picker does with it |
|---|---|---|
data-coreui-picker-field | a div | Hosts the date input’s sections. Without it the field is generated (and wrapped in .form-floating when floatingLabel is set). |
data-coreui-picker-toggle | a button or any element | Opens and closes the calendar. Gets aria-expanded and aria-haspopup, and aria-controls while the calendar is open, and ariaPickerLabel as its name unless it has one or shows text of its own. |
data-coreui-picker-cleaner | a button | Clears the value. Gets ariaCleanerLabel as its name unless it has one or shows text of its own. |
A decorative <svg> inside an adopted button is marked aria-hidden for you. So a trigger can be a regular button with its own text and icon, the way a combobox has one:
<div data-coreui-locale="en-US" data-coreui-date-picker>
<div data-coreui-picker-field></div>
<button type="button" class="btn btn-subtle btn-sm" data-coreui-picker-cleaner>
<svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M3 3l10 10M13 3L3 13"/></svg>
</button>
<button type="button" class="btn btn-subtle btn-sm" data-coreui-picker-toggle>
<svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="1.5" y="2.5" width="13" height="12" rx="1.5"/><path d="M1.5 6.5h13M5 1v3M11 1v3"/></svg>
Pick a date
</button>
</div>The cleanerIcon and pickerIcon options only feed the generated buttons; with your own markup the icon is whatever you put in the HTML, and nothing is sanitized because nothing is rendered from a string.
Floating labels
The date picker supports floating labels: set floatingLabel and the component renders the label itself — no wrapper markup needed — and the text also becomes the field’s accessible name. The mask placeholders stay hidden while the label rests inside the field; focusing any part of the field — the sections or the picker button — floats the label and reveals the mask.
<div data-coreui-locale="en-US" data-coreui-floating-label="Delivery date" data-coreui-date-picker></div>Add .form-floating-always to the component element to keep the label always floating with the mask showing.
Sizing
Set heights using the data-coreui-size attribute like data-coreui-size="lg"
and data-coreui-size="sm".
<div class="row mb-4">
<div class="col-lg-5">
<div data-coreui-locale="en-US" data-coreui-size="lg" data-coreui-date-picker></div>
</div>
</div>
<div class="row">
<div class="col-lg-5">
<div data-coreui-locale="en-US" data-coreui-size="sm" data-coreui-date-picker></div>
</div>
</div>Disabled
Add the data-coreui-disabled="true" attribute to give the picker a grayed out
appearance and remove pointer events.
<div class="row">
<div class="col-lg-5">
<div data-coreui-disabled="true" data-coreui-locale="en-US" data-coreui-date-picker></div>
</div>
</div>Disabled dates
The disabledDates option excludes specific dates — single Dates,
[start, end] ranges, or a matcher function. The calendar grays them out and
the field refuses them: a completed date that hits a disabled entry gets the
.is-invalid class and the picker reports null, and submits no date, until it is corrected.
In week, month, quarter and year selection the calendar and the field judge the
whole period: it is refused only when it lies wholly before minDate or after
maxDate, or disabledDates covers every day of it that the limits leave. In week selection the limits count as whole weeks, so for a week that is all seven days.
<div class="row">
<div class="col-lg-5">
<div id="myDatePickerDisabledDates"></div>
</div>
</div>const myDatePickerDisabledDates = document.getElementById('myDatePickerDisabledDates')
const datePickerDisabledDates = new coreui.DatePicker(myDatePickerDisabledDates, {
locale: 'en-US',
date: new Date(2026, 6, 10),
disabledDates: [
[new Date(2026, 6, 4), new Date(2026, 6, 7)],
new Date(2026, 6, 16)
],
minDate: new Date(2026, 6, 1),
maxDate: new Date(2026, 6, 31)
})
myDatePickerDisabledDates.addEventListener('dateChange.coreui.date-picker', event => {
console.log('dateChange', event.date)
})Disabling weekends
Pass a function to disable every date that matches a rule.
<div class="row">
<div class="col-lg-5">
<div id="myDatePickerWeekends"></div>
</div>
</div>const myDatePickerWeekends = document.getElementById('myDatePickerWeekends')
const datePickerWeekends = new coreui.DatePicker(myDatePickerWeekends, {
locale: 'en-US',
disabledDates: date => date.getDay() === 0 || date.getDay() === 6
})Validation
The picker shows its validation state on the frame and on the sections of its field, which the message after the picker describes, the way the form plugin does for a native field. The field keeps its value in a <textarea> laid invisibly over it, so a required picker that is empty, incomplete or holds a rejected date blocks the submit, as the date input does.
You give a state with the validationState option ('valid', 'invalid' or a state of $form-validation-states, with invalid and valid as deprecated aliases) or with an .is-invalid or .is-valid class written on the picker element, the server-side route, which is read once, when the picker starts; the option wins over the class. A given state is a verdict on the date it was given for, so the next change of the date the user makes drops it: a day picked in the calendar, a time picked with timepicker, the cleaner, a footer button that changes the date through the context, or typing in the field. An action that leaves the date as it is keeps the state. A change your own code makes, with setDate(), clear(), reset() or today(), keeps it. setValidationState() sets it again without rebuilding the picker. A class or an aria-invalid written on the picker element after it starts is not read. While the given state is 'invalid', the picker blocks the submit with the text of the message after it, or Invalid value. when there is none. A native form reset puts back the date the picker started with and drops the state.
<div class="row">
<div class="col-lg-5 form-field">
<div class="is-invalid" data-coreui-date-picker data-coreui-locale="en-US" data-coreui-date="2026-07-14"></div>
<div class="invalid-feedback">We have no delivery slots left on this date.</div>
</div>
</div>Locale
Auto
The locale drives both layers: the section order and separators of the field, and the month/weekday names of the calendar. By default it comes from the browser.
<div class="row">
<div class="col-lg-5">
<div data-coreui-date-picker></div>
</div>
</div>Chinese
<div class="row">
<div class="col-lg-5">
<div data-coreui-locale="zh-CN" data-coreui-date-picker></div>
</div>
</div>Japanese
<div class="row">
<div class="col-lg-5">
<div data-coreui-locale="ja" data-coreui-date-picker></div>
</div>
</div>Korean
<div class="row">
<div class="col-lg-5">
<div data-coreui-locale="ko" data-coreui-date-picker></div>
</div>
</div>Right to left support
RTL support is built-in and can be explicitly controlled through the
$enable-rtl variable in Sass. The popup flips its anchoring side with the
document direction.
Hebrew
<div class="row" dir="rtl">
<div class="col-lg-5">
<div data-coreui-locale="he-IL" data-coreui-date-picker></div>
</div>
</div>Persian
The date picker is Gregorian: with a locale whose own calendar has different months, like Persian, its calendar shows the Gregorian months in that locale’s language and digits, and its field holds Gregorian numbers.
<div class="row" dir="rtl">
<div class="col-lg-5">
<div data-coreui-locale="fa-IR" data-coreui-date-picker></div>
</div>
</div>Custom formats
The mask of the field defines the format. Set it with data-coreui-format (or
the format option), which the field forwards from the shell. The parser accepts both dayjs/moment-style tokens
(DD, MM, YYYY, YY) and date-fns/Unicode-style tokens (dd, MM,
yyyy, yy), plus ww for ISO week numbers and q (numeric) or QQQ
(Q1–Q4) for quarters; any other character becomes a literal separator.
<div class="row">
<div class="col-sm-6 col-lg-5 mb-4 mb-sm-0">
<label class="form-label" id="datePickerDdMMYyyyLabel">dd.MM.yyyy</label>
<div data-coreui-format="dd.MM.yyyy" data-coreui-locale="en-US" data-coreui-date-picker aria-labelledby="datePickerDdMMYyyyLabel"></div>
</div>
<div class="col-sm-6 col-lg-5">
<label class="form-label" id="datePickerYYYYMMDDLabel">YYYY-MM-DD</label>
<div data-coreui-format="YYYY-MM-DD" data-coreui-locale="en-US" data-coreui-date-picker aria-labelledby="datePickerYYYYMMDDLabel"></div>
</div>
</div>A format does not have to include every section — a month-and-year mask reports the first day of the month.
<div class="row">
<div class="col-lg-5">
<div data-coreui-format="MMMM yyyy" data-coreui-locale="en-US" data-coreui-date-picker></div>
</div>
</div>Accessibility
The field is a date input — a group of spinbutton sections — so its own arrow keys belong to the value, and the popup opens on the native control’s dropdown keys. Focus enters the calendar on the selected date, else on today or on the minDate / maxDate today falls outside of, also when that date cannot be picked: it is announced as unavailable and the arrows move on from it. In week selection it enters on the row of that week.
Clicking a label that names the field, through aria-labelledby or a <label for> pointing at the element, moves focus to the first empty section of the field.
An aria-label, aria-labelledby or aria-describedby on the picker element moves to the field, so a screen reader announces the name and the description when focus enters it, and the picker element gets them back on dispose. Point aria-labelledby at the visible label, as the examples on this page do; it names the field over floatingLabel and an ariaLabel in inputOptions, the way the browser ranks names. A data-coreui-picker-field you wrote that already has an aria-label or aria-labelledby keeps its own name, and its own aria-describedby comes first, followed by the one that moves.
While the picker shows an invalid state, the sections of its field carry aria-invalid="true" and are described by the error message after the picker, see Validation. An aria-invalid written on the picker element is not read; give the state with validationState or with the class.
The toggle’s name ends with the date the picker holds, written in full (Toggle calendar, Friday, August 14, 2026, with the time after it with timepicker), so a screen reader reads the picked date when the popup closes and focus goes back to the toggle. A live message would be lost at that moment, so the calendar does not announce a pick that closes the popup onto that toggle. With timepicker the popup stays open, and the calendar announces the pick through ariaSelectedDateAnnouncement; it does the same without a toggle (pickerIcon: false) and with a data-coreui-picker-toggle that has a name or text of its own, which keeps it unchanged.
Keyboard support
| Key | Action |
|---|---|
| Alt (Option on macOS) + Arrow Down / F4 | Open the calendar popup and move focus into the grid |
| Escape | Close the popup and return focus to the field or the toggle that opened it |
| Tab / Shift + Tab | Move within the open calendar; the field is outside the dialog and stays out of the cycle |
| Arrow Right / Arrow Left | Move focus to the next / previous day; crossing the edge of the grid moves to the adjacent month |
| Arrow Down / Arrow Up | Move focus to the same day of the next / previous week |
| Home / End | Move focus to the first / last day of the week inside minDate / maxDate, into the previous / next month when the week starts or ends there |
| Page Down / Page Up | Move focus to the same day of the next / previous month, keeping the day number when the target month is long enough; a series of presses keeps the day it started from, so January 31 goes to February 28 and then March 31, also across a stop at minDate / maxDate; any other key or a click starts a new series |
| Shift + Page Down / Shift + Page Up | Move focus to the same day of the next / previous year, keeping the day of a series the same way |
| Enter / Space | Select the focused date, and close the popup unless timepicker is on, where the time half still has to be set; nothing happens on a date that cannot be picked |
In the calendar grid, a key from the table pressed with Alt, Ctrl or Cmd is neither handled nor cancelled: focus stays where it is and the key stays free for the browser and assistive technology.
Usage
Via data attributes
Add data-coreui-date-picker to a div element.
<div data-coreui-date-picker></div>Inside it, data-coreui-picker-field, data-coreui-picker-toggle and data-coreui-picker-cleaner name the parts you supply yourself — see Composing the markup.
Via JavaScript
<div class="my-date-picker"></div>const datePickerElementList = Array.prototype.slice.call(document.querySelectorAll('.my-date-picker'))
const datePickerList = datePickerElementList.map(datePickerEl => {
return new coreui.DatePicker(datePickerEl)
})Options
Options can be passed via data attributes or JavaScript. For data attributes,
append the option name to data-coreui-, converting “camelCase” to
“kebab-case” — write data-coreui-selection-type="week", not
data-coreui-selectionType="week".
Options belonging to the inner calendar,
date input or, with timepicker, the time
columns of the time picker are forwarded by
name, so their data attributes work on the picker element too. The calendar’s
startDate and the time columns’ hourCycle, onChange and time are set
by the picker itself.
| Property | Type | Default |
|---|---|---|
allowList | object | SVGAllowlist |
Allowlist used when sanitizing the icon markup. | ||
ariaCleanerLabel | string | 'Clear date' |
Accessible label of the cleaner button. | ||
ariaLabel | string | 'Date input' |
Accessible name of the field. It lands on the | ||
ariaPickerLabel | string | 'Toggle calendar' |
Accessible label of the picker button, followed by the date the picker holds. | ||
ariaPopupLabel | string | 'Calendar' |
Accessible name of the calendar panel, which opens as a | ||
calendarOptions | object | {} |
Programmatic escape hatch for calendar options. | ||
cleaner | boolean | true |
Renders a button that clears the value. It appears only once the field holds one. | ||
cleanerIcon | string | cross SVG |
Inline SVG of the generated cleaner (sanitized). Not used for a | ||
container | string, element, false | false |
Teleport target for the dropdown. Inside a modal dialog it goes into the dialog instead, because the rest of the page is inert. | ||
date | date, string, null | null |
Initial value. | ||
disabled | boolean | false |
Disables the field and the popup. | ||
floatingLabel | string, null | null |
Renders a floating label over the field, which also becomes its accessible name. Not rendered for a | ||
format | function, string, null | null |
Mask layout of the field: | ||
inputOptions | object | {} |
Programmatic escape hatch for date input options, except | ||
invalid | boolean | false |
Deprecated alias of | ||
locale | string | browser locale |
Drives section order, separators, and calendar labels. | ||
maxDate | date, string, null | null |
Upper bound, enforced by both layers. With | ||
minDate | date, string, null | null |
Lower bound, enforced by both layers. With | ||
monthNames | array, null | null |
Twelve custom month names for text month sections ( | ||
name | string, null | null |
Name of the generated value input. Without it the field is not submitted with the form. | ||
pickerIcon | string, boolean | true |
The button that opens the calendar: | ||
sanitize | boolean | true |
Sanitize the icon markup. | ||
sanitizeFn | function, null | null |
Custom sanitizer. | ||
seconds | array, boolean, function | true |
Seconds offered by the time half. Ignored without | ||
selectionOptions | object | {} |
Programmatic escape hatch for the time half, except | ||
selectionType | string | 'day' |
What the picker selects: | ||
size | string, null | null |
| ||
timepicker | boolean | false |
Add a time half to the panel and switch the field to a date and time mask. | ||
valid | boolean | false |
Deprecated alias of | ||
validationState | string, null | null |
The validation state the picker shows: | ||
Methods
| Method | Description |
|---|---|
clear | Clears the value. |
dispose | Destroys the picker and its inner components. |
getContext | Returns the slot context (see below). |
getDate | Returns the current value (Date or null). |
getInstance | Static — returns the instance for a DOM element. |
getOrCreateInstance | Static — returns the instance, creating it if needed. |
hide | Closes the popup. |
reset | Restores the initial value. |
setValidationState(state) | Gives the picker a validation state ('valid', 'invalid' or a state added to $form-validation-states), or drops it with null. The value stays. See Validation. |
setDate | Sets the value without firing dateChange. The open calendar, the time selection and the name of the toggle follow it. |
show | Opens the popup. |
today | Sets today’s date. |
toggle | Toggles the popup. |
Slot context
Projected regions (and any custom code) drive the picker through a small imperative contract instead of configuration:
const picker = coreui.DatePicker.getOrCreateInstance(element)
const context = picker.getContext()
context.today() // set today's date
context.setDate(date) // set any date
context.clear() // clear the value
context.reset() // restore the initial value
context.close() // close the popup
context.date // current value (Date | null)
context.disabled // disabled stateEvents
| Event | Description |
|---|---|
dateChange.coreui.date-picker | Fired when the value changes — from the calendar, the field, or a context action. event.date is the validated Date, or null; event.formattedDate is the same value in the shape of selectionType (2026-01, 2026W03, 2026Q1, 2026, or the Date itself for day), with the year in at least four digits (0026-01). |
hidden.coreui.date-picker | Fired once the popup has finished its exit transition and left the page. Skipped when the popup reopens first. |
hide.coreui.date-picker | Fired immediately when hide is called — by the API, the indicator, Escape or an outside click. Call event.preventDefault() to keep the popup open. |
show.coreui.date-picker | Fired immediately when show is called. Call event.preventDefault() to keep the popup closed. |
shown.coreui.date-picker | Fired once the popup has finished its entry transition. Skipped when the popup closes first. |
The field’s own events (dateChange.coreui.date-input,
errorChange.coreui.date-input) still bubble from the inner element — the shell
does not duplicate them. dateChange.coreui.date-picker fires before the
field’s errorChange for the same change, whether it comes from the calendar,
the field or an action, so a date an errorChange listener sets replaces the one
just reported.
const myDatePicker = document.getElementById('myDatePicker')
myDatePicker.addEventListener('dateChange.coreui.date-picker', event => {
console.log(event.date)
})Customizing
CSS variables
The field is a .form-control-group on the picker element itself, so its frame, the cleaner and the toggle read the --cui-control-* and --cui-control-group-* tokens. Set them on the picker element to restyle one field.
The picker declares its local CSS variables on its panel, .date-picker-popup,
for real-time customization. Values are set via Sass, so Sass customization is
supported too.
$date-picker-tokens: defaults(
(
--cui-date-picker-ranges-padding-y: .5rem,
--cui-date-picker-ranges-padding-x: .5rem,
--cui-date-picker-ranges-gap: .25rem,
--cui-date-picker-ranges-border-width: var(--cui-border-width),
--cui-date-picker-ranges-border-color: var(--cui-border-color),
--cui-date-picker-timepickers-border-width: var(--cui-border-width),
--cui-date-picker-timepickers-border-color: var(--cui-border-color),
--cui-date-picker-footer-padding-y: .5rem,
--cui-date-picker-footer-padding-x: .5rem,
--cui-date-picker-footer-gap: .5rem,
--cui-date-picker-footer-border-width: var(--cui-border-width),
--cui-date-picker-footer-border-color: var(--cui-border-color),
),
$date-picker-tokens
);The time half declares its own on .date-picker-time-body, so it can be
restyled without touching the panel around it.
$date-picker-time-tokens: defaults(
(
--cui-date-picker-time-body-padding-y: var(--cui-spacer-3),
--cui-date-picker-time-body-padding-x: var(--cui-spacer-3),
--cui-date-picker-time-icon-width: 2.5rem,
--cui-date-picker-time-icon-size: 1rem,
--cui-date-picker-time-icon-color: var(--cui-fg-3),
--cui-date-picker-time-select-border-radius: var(--cui-radius-4),
--cui-date-picker-time-select-font-size: var(--cui-btn-input-sm-font-size),
--cui-date-picker-time-select-color: var(--cui-btn-input-fg),
--cui-date-picker-time-select-padding-y: var(--cui-btn-input-sm-padding-y),
--cui-date-picker-time-select-padding-x: var(--cui-btn-input-sm-padding-x),
--cui-date-picker-time-select-disabled-color: var(--cui-fg-body),
),
$date-picker-time-tokens
);The panel is a .popup: its surface, border, shadow, stacking and fade come from the tokens every popup panel shares with the other pickers, Combobox, Autocomplete and Multi Select. .popup declares them itself, so set them on .date-picker-popup to restyle this panel or on .popup for all of them; a value set on an ancestor or on :root does not reach it.
$popup-tokens: () !default;
$popup-tokens: defaults(
(
--cui-popup-zindex: var(--cui-z-dropdown),
--cui-popup-bg: var(--cui-bg-body),
--cui-popup-border-width: var(--cui-border-width),
--cui-popup-border-color: var(--cui-border-color),
--cui-popup-border-radius: var(--cui-radius-7),
--cui-popup-box-shadow: var(--cui-box-shadow),
--cui-popup-transition-duration: .15s,
--cui-popup-transition-timing: var(--cui-transition-timing-overlay),
),
$popup-tokens
);$calendar-tokens: defaults(
(
--cui-calendar-table-margin: .5rem,
--cui-calendar-table-cell-size: 2.75rem,
--cui-calendar-nav-padding-y: .5rem,
--cui-calendar-nav-padding-x: .5rem,
--cui-calendar-nav-border-color: var(--cui-border-color),
--cui-calendar-nav-border: var(--cui-border-width) solid var(--cui-calendar-nav-border-color),
--cui-calendar-nav-btn-padding-x: .5rem,
--cui-calendar-nav-btn-padding-y: .25rem,
--cui-calendar-nav-btn-font-size: var(--cui-font-size-sm),
--cui-calendar-nav-btn-bg: transparent,
--cui-calendar-nav-btn-border-width: 1px,
--cui-calendar-nav-btn-border-color: transparent,
--cui-calendar-nav-btn-border-radius: var(--cui-radius-4),
--cui-calendar-nav-btn-hover-bg: transparent,
--cui-calendar-nav-btn-hover-border-color: transparent,
--cui-calendar-nav-btn-focus-border-color: transparent,
--cui-calendar-nav-date-font-weight: 600,
--cui-calendar-nav-date-color: var(--cui-fg-body),
--cui-calendar-nav-date-hover-color: var(--cui-primary-base),
--cui-calendar-nav-icon-width: 1rem,
--cui-calendar-nav-icon-height: 1rem,
--cui-calendar-nav-icon-color: var(--cui-fg-3),
--cui-calendar-nav-icon-hover-color: var(--cui-fg-body),
--cui-calendar-cell-header-inner-font-weight: 600,
--cui-calendar-cell-header-inner-color: var(--cui-fg-3),
--cui-calendar-cell-week-number-font-weight: 600,
--cui-calendar-cell-week-number-color: var(--cui-fg-2),
--cui-calendar-cell-border-radius: var(--cui-radius-4),
--cui-calendar-cell-hover-color: var(--cui-fg-body),
--cui-calendar-cell-hover-bg: var(--cui-bg-2),
--cui-calendar-cell-disabled-color: var(--cui-fg-4),
--cui-calendar-cell-selected-color: var(--cui-primary-contrast),
--cui-calendar-cell-selected-bg: var(--cui-primary-base),
--cui-calendar-cell-selected-hover-color: var(--cui-calendar-cell-selected-color),
--cui-calendar-cell-selected-hover-bg: oklch(from var(--cui-calendar-cell-selected-bg) calc(l * var(--cui-theme-hover-lightness)) calc(c * var(--cui-theme-hover-chroma)) h),
--cui-calendar-cell-selected-adjacent-color: var(--cui-primary-fg-emphasis),
--cui-calendar-cell-selected-adjacent-bg: var(--cui-primary-bg-subtle),
--cui-calendar-cell-selected-adjacent-hover-color: var(--cui-calendar-cell-selected-adjacent-color),
--cui-calendar-cell-selected-adjacent-hover-bg: var(--cui-primary-bg-muted),
--cui-calendar-cell-range-bg: var(--cui-primary-bg-subtle),
--cui-calendar-cell-range-hover-border-color: var(--cui-primary-base),
--cui-calendar-cell-today-color: var(--cui-danger-base),
),
$calendar-tokens
);