Date and time

Calendar

A month grid for picking a single date.

Rust
1use herogpui::components::calendar::{Calendar, CalendarState};

Usage

Indian and Hebrew calendar grids use English labels here. Navigation follows each calendar while selected values remain Gregorian dates.

Rust
1use herogpui::prelude::{Calendar, CalendarState, Date};
2use gpui::prelude::*;
3
4row(vec![
5    Calendar::new(self.demo_calendar("cal-indian", cx))
6        .locale("en-US-u-ca-indian")
7        .default_value(Date::new(2026, 1, 15))
8        .into_any_element(),
9    Calendar::new(self.demo_calendar("cal-hebrew", cx))
10        .locale("en-US-u-ca-hebrew")
11        .default_value(Date::new(2024, 3, 25))
12        .into_any_element(),
13])

Live HeroGPUI compiled to WebAssembly. Select any example without loading another WASM instance.

Anatomy

Rust types

Calendar

Calendar is assembled from these builders. The API reference lists each one.

Customization

Appearance builders and theme tokens Calendar uses.

Styling

Calendar styling
StyleDescription
CALENDAR_WIDTH = 252pxSingle-month width is exact; multiple months use the documented 256px panels, 32px gaps and horizontal scrolling. GPUI has no CSS container-query context.
VisibleDuration::Weeks + seven 36px circlesSeven fixed circular cells reproduce the week grid geometry through GPUI flex rows.
week_aligned_rows + visible_start disabled guardSeven weekday columns, disabled leading dates and trailing blanks match, with 4px between the weekday block and date rows.
items_center + justify_between + px(2px) + pb(16px)The header aligns its controls with a 2px horizontal inset and 16px bottom padding.
text_size(14px) + line_height(20px) + MEDIUMMonth headings use 14px/20px medium text independent of the host line height.
year_picker_open header branchThe open picker substitutes same-size spacers instead of fading buttons in place.
24px + soft_radius + hover + ring_if_focusedGeometry, disabled state and focus ring exist; pressed and state transitions are incomplete.
svg size(16px)Icon size matches; direction-aware rotation is not available.
seven flex_1 cells per row + no horizontal gapAll views divide each panel into seven equal columns without horizontal gaps; multi-month panels are 256px wide.
weekday_header seven flex_1 childrenWeekday cells are a separate seven-column flex sibling rather than flattened table contents.
month_grid flex_col + preceding gap(4px)Date rows start 4px below the weekday block and remain contiguous.
text_size(12px) + line_height(16px) + MEDIUM + muted + pb(8px)Weekday labels use 12px/16px medium muted text with 8px bottom padding.
cell_size = column_width / 7 + text_size(14px) + line_height(20px) + MEDIUMDay cells center 14px/20px medium text in a square one seventh of the panel width, including selected, disabled and custom cells.
anim::pressed on selectable unselected branchUnselected press geometry animates; selected and focus-shadow interpolation is incomplete.
is_today border_1(marker)Uses a border rather than v3's soft fill treatment.
is_sel accent fillThe selected fill matches; selected press interpolation and accent-hover are absent.
muted + outer opacity(0.5)The whole cell subtree, including custom content and indicators, is dimmed.
unavailable muted + selectable gatePointer inertia matches; muted text replaces v3's opacity and not-allowed cursor.
disabled branch + line_throughOut-of-range dates are muted and struck through; unavailable dates are not struck.
absolute bottom(2px) + size(3px) + marker colorSize and selected color match; GPUI uses a 2px inset and accent resting color rather than 4px and muted.
gap(4px) + key_radius + px(6px) py(2px)The trigger is composed and focusable, with extra GPUI padding and hover fill.
12px CHEVRON_UP / CHEVRON_DOWNGPUI swaps muted up/down glyphs instead of rotating and interpolating one indicator.
absolute inset_0 + retained day layout + ScrollHandle + three-cell rows + gap(4px) + p(4px)The scrollable three-column year grid occupies the retained day area; opening and keyboard movement reveal the active row.
h(32px) + px(10px) + control_radius + text_size(14px) + line_height(20px) + MEDIUMYear geometry and selected/hover/focus treatments are present; transitions are absent.

API reference

Builders

Calendar builders
BuilderTypeDefaultDescription
selection_mode(SelectionMode)SelectionModeSelectionMode::SingleWhether one or many dates can be selected.
value(value, cx) / values(values, cx)value, cx / values, cxControlled scalar or multiple selection.
default_value(value) / default_values(values)DateValue | null or DateValue[] | null / valuesInitial uncontrolled scalar or multiple selection.
on_change(callback) / on_change_all(callback)(DateValue | null) or Fn(DateValue[] | null) -> ()Reports scalar or complete multiple-selection changes.
focused_value(Date)DateControls the constrained focus date and realigns the visible range; movement waits for owner acceptance.
on_focus_change(callback)Fn(value: DateValue) -> ()Reports keyboard or selectable-cell focus movement.
min_value(Date)DateCalendar-aware 1900-01-01Defaults to Gregorian 1900-01-01; an explicit minimum overrides it.
max_value(Date)DateCalendar-aware 2099-12-31Defaults to Gregorian 2099-12-31; an explicit maximum overrides it.
weeks_in_month(usize)usizeOverrides the derived number of visible week rows.
is_date_unavailable(callback)Fn(date: DateValue) -> boolMarks real in-month and adjacent-month dates unavailable.
first_day_of_week(Weekday)WeekdayLocale defaultDefaults from the operating system's regional date preferences through CLDR week data; an explicit weekday overrides it, with Sunday as the invalid-locale fallback.
page_behavior(PageBehavior)PageBehaviorPageBehavior::VisiblePages by the visible duration or one displayed unit.
selection_alignment(SelectionAlignment)SelectionAlignmentSelectionAlignment::CenterAligns the initial visible range around the selection; picking preserves that displayed range.
is_disabled(bool)boolfalseDisables navigation, focus and selection and dims the whole calendar.
is_read_only(bool)boolfalseKeeps keyboard navigation while preventing pointer and selection changes.
is_invalid(bool)boolfalseMarks selected and today treatments with an invalid accent, without v3's browser validation surface.
visible_duration(VisibleDuration)VisibleDuration{months: 1}Selects month, week or day view and its visible count.
default_year_picker_open(bool)boolfalseSeeds the uncontrolled internal year picker open.
is_year_picker_open(bool)boolControls the internal year picker open state.
on_year_picker_open_change(callback)Fn(isOpen: bool) -> ()Reports changes to the internal year picker.
offset(i32)i32Shifts every visible heading globally rather than configuring one composed heading.
visible_years(usize)usizemin-max span or 20Controls the bounded year window; otherwise the implicit 1900–2099 span is shown.
cell(render)stringHands the day label to custom cell content; it is numeric rather than locale-formatted.

Parts

Calendar parts
PartDescription
CalendarRoot state, layout and keyboard-navigation owner.
CalendarHeader row containing navigation and the visible-range heading.
CalendarFormatted heading for one visible month or linear range.
CalendarPrevious and next section controls with replaceable icons.
CalendarOne seven-column month, week or day grid.
CalendarWeekday header container.
CalendarVisible date-row container.
CalendarOne weekday label.
CalendarFocusable date cell with state-driven custom content.
CalendarOptional three-pixel metadata indicator inside a cell.
CalendarFocusable heading control that toggles year-picker mode.
CalendarHeading content inside the year-picker trigger.
CalendarChevron showing the year-picker open state.
CalendarScrollable three-column year surface overlaying the retained day area.
CalendarFragment-style body that maps the visible year window into three-cell rows.
CalendarFocusable year option that returns to the day grid after selection.

States

Calendar states
BuilderStateDescription
eligible membership + accent fillSelectedAccent fill and foreground on selectable selected dates.
is_today borderTodayUses an accent-soft fill; currently draws an accent outline.
is_unavailable + selectable gateUnavailableKeyboard-focusable but pointer-inert date with disabled styling.
outside_month + opacity(0.5)Outside monthReal adjacent-month date, -disabled and unselected at half opacity.
hover(default.soft_hover())HoveredDefault fill on selectable cells; v3's today-specific hover token is missing.
anim::pressed + active(default)PressedDefault fill and 0.95 scale on unselected cells; selected press styling is missing.
grid_focus + with_focus_ringFocus visibleRoving in-month focus ring driven by the calendar cursor. Month boundaries, paging, alignment and year selection follow the chosen calendar system while focus values stay Gregorian.
is_disabled / out_of_rangeDisabledInert calendar or date with disabled opacity and in-month line-through.
is_read_only + selectable gateRead onlyPointer-inert cells retain keyboard focus and navigation without selection.
year_picker_open overlay + invisible day bodyYear picker openThe scrollable year grid overlays the retained day layout, without the staggered crossfade.
active_year accent branchYear cell selectedAccent fill follows the roving year cursor and closes on activation.