Skip to content
Glint UI

DatePicker

A calendar in a popup, opened by a trigger you own and closed by the pick.

Usage

import { CalendarMonth } from "@glint/components/calendar.slint";
import { DatePicker } from "@glint/components/date-picker.slint";
import { Button } from "@glint/components/button.slint";
export component AppWindow inherits Window {
in property <[CalendarMonth]> months;
in-out property <int> chosen;
in property <string> label;
picker := DatePicker {
months: root.months;
selected-serial <=> root.chosen;
day-selected(serial) => { /* store it */ }
prev-month => { /* roll your model back one month */ }
next-month => { /* roll your model forward one month */ }
Button {
text: root.label;
haspopup: true;
clicked => { picker.show(); }
}
}
}

The trigger is yours. Glint’s overlay components never own it: whatever you slot into the picker is what opens the popup, and the picker publishes the state a trigger needs to reflect — is-open, and the selection itself. A pointer click anywhere on the trigger opens the popup for free; wire your trigger’s keyboard activation to show() so the calendar is reachable without a mouse.

Everything below the trigger is Calendar’s: the months are yours to describe, a day is an absolute serial, and paging is rolling your own model. The picker keeps no date model of its own — there is none to keep — so every calendar property is forwarded rather than aliased: a PopupWindow’s insides cannot be reached from outside it, which is also why the calendar’s strings are declared here again and defaulted from the same CalendarStrings global.

show() and close() mirror PopupWindow’s API (ADR-0006). Esc and a click outside dismiss the calendar, and closing — by Esc, by a click outside, or by picking a day — returns the keyboard focus to whatever held it before, which is your trigger.

Examples

A single date

CalendarMode.single closes the popup on the pick: one day, one gesture, and the focus back on the trigger ready for the next Enter.

A range

CalendarMode.range keeps the popup up until both ends are in: the first pick opens the interval and leaves the calendar on screen, the second closes both the interval and the popup. The trigger is @children, so showing “5 – 9 May” in it is yours — bind to range-from, range-to, and to preview-serial for the end still under the pointer.

Reaching a distant month from inside the popup

caption is forwarded like every other calendar property, so CalendarCaption.dropdown puts the month and year pickers inside the popup — which is what makes a birthday twenty years back a pick rather than two hundred and forty chevron clicks. The dropdowns report an index and page nothing themselves, exactly as they do on a bare calendar.

Bounds and unavailable days

can-prev-month, can-next-month and day-states pass straight through to the calendar inside the popup. The picker computes none of them, for the reason it computes nothing else: it holds no date model, so a host that restricts a range works the two bounds out the same way it works out day-count.

API Reference

Properties

PropertyTypeDefaultDescription
monthsin [CalendarMonth][ }]The months the popup calendar draws — see Calendar.months.
day-statesin [CalendarDay]no defaultPer-day states, indexed from the first rendered day — see Calendar.day-states.
weekday-labelsin [string]CalendarStrings.weekday-initialsColumn headers of the popup calendar — see Calendar.weekday-labels. A PopupWindow's insides are unreachable from here, so this cannot alias the Calendar's property; it takes its default from the same global the Calendar does and is passed down instead. Every string below is here for that reason.
modein CalendarModeCalendarMode.singleWhether a pick is a day or an end of an interval — see Calendar.mode. A range picker stays open until both ends are in.
selected-serialin-out int0Two-way; the serial of the selected day, or 0 for none.
range-fromin-out int0Two-way; the ends of the selected interval, or 0 for none. The trigger is @children, so showing "5 – 9 May" in it is yours to do: bind to these two, and to preview-serial for the end still under the pointer.
range-toin-out int0
preview-serialout intno defaultThe open end of a forming range — see Calendar.preview-serial.
can-prev-monthin booltrueWhether the popup calendar has a month to page to in each direction — forwarded straight to Calendar. The picker keeps no date model of its own (there is none to keep: Slint has no date arithmetic), so a host restricting a range computes the two bounds and passes them through, exactly as it computes day-count.
can-next-monthin booltrue
prev-month-labelin stringCalendarStrings.previous-monthAccessible names for the popup's chevrons, and the week-number column heading — see Calendar. Repeated here for the same reason weekday-labels is: a PopupWindow's insides cannot be aliased from out here.
next-month-labelin stringCalendarStrings.next-month
week-number-labelin stringCalendarStrings.week-number
in-range-notein stringCalendarStrings.in-rangeWhat a day inside a settled range announces — see Calendar.in-range-note.
captionin CalendarCaptionCalendarCaption.labelThe popup calendar's caption, and the two models its dropdowns offer — see Calendar.caption. Forwarded rather than aliased, like everything else that lives inside the PopupWindow; a consumer that wants a year reachable from inside the popup sets these.
month-optionsin [string]no default
year-optionsin [string]no default
month-indexin int-1
year-indexin int-1
month-picker-labelin stringCalendarStrings.month
year-picker-labelin stringCalendarStrings.year
content-widthin length296pxPixel width of the popup panel.
is-openout boolno defaultTrue while the calendar is on screen. The trigger is @children, so reflecting the open state in it is yours to do — bind to this.

Callbacks

CallbackDescription
day-selected(int)Fired with the chosen day's serial. In single mode the popup closes on it; in range mode it fires for each of the two picks and the popup stays up until the second one closes the interval.
range-selected(int, int)Fired with the two ends of a completed range, in order; the popup closes on it.
prev-month()Forwarded from the inner Calendar header chevrons and its caption dropdowns.
next-month()
month-picked(int)
year-picked(int)

Functions

FunctionDescription
show()The overlay API mirrors PopupWindow's, per ADR-0006. Wire your trigger's keyboard activation to show().
close()Hide the calendar. Focus returns to whatever held it before.

Enums

EnumValues
CalendarModesingle, range
CalendarCaptionlabel, dropdown

Accessibility

  • The trigger’s accessibility is yours, because the trigger is. Name it, and mark it as opening a popup — haspopup: true on a Button is that.
  • The grid takes the keyboard on its own way in. Nothing outside a PopupWindow can focus what is inside it, so the calendar grabs the keyboard as it is built. Without that the picker would open and answer no arrow, no page and no Enter — the pointer and an accessible action would be the only ways to pick a day.
  • Everything the calendar announces, it announces here: a month is a table, a day is a named cell that reports its index and whether it is selected, a disabled day refuses every path, and a note rides the description. See Calendar.
  • Esc dismisses, and the focus comes back. The picker keeps no Esc handler of its own — dismissal is the shared overlay surface’s — so a picker opened inside a Popover takes the first Esc and the popover under it survives.
  • A range picker stays up between the two picks, so a keyboard user finishes the interval in the surface they started it in.