Theme
Version
GitHub PyPI Discord
On this page

Calendar

Use CCalendar when the active Citry locale must determine an inline calendar's month heading, weekday order, day names, and accessible date labels. The public value remains a canonical YYYY-MM-DD date regardless of display locale or calendar system.

Select one date

Compose Calendar in CField for a visible label, description, error, and shared state. A standalone Calendar uses its localized label by default.

<c-CField required>
  <c-fill name="label">Arrival date</c-fill>
  <c-fill name="default"><c-CCalendar name="arrival" /></c-fill>
</c-CField>
Select one date
Show code
from datetime import date
from typing import Any

import citry_ui
from citry import Component, citry
from citry_ui import CCalendar

citry.register_library(citry_ui)

# ruff: noqa: E501 - template and CSS lines stay readable in public source examples


class BasicCalendar(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    def template_data(self, kwargs: Kwargs, slots: Slots) -> dict[str, Any]:  # noqa: ARG002
        return {"python_calendar": CCalendar(value=date(2026, 8, 19), label="Python-composed calendar")}

    template = """
      <section class="calendar-demo-grid">
        <c-CField required>
          <c-fill name="label">Arrival date</c-fill>
          <c-fill name="description">Choose your check-in day.</c-fill>
          <c-fill name="default"><c-CCalendar name="arrival" value="2026-08-19" /></c-fill>
        </c-CField>
        <article><h3>Python composition</h3>{{ python_calendar }}</article>
      </section>
    """
    css = ":where(.calendar-demo-grid){display:grid;grid-template-columns:repeat(auto-fit,minmax(20rem,1fr));gap:1.25rem}:where(.calendar-demo-grid article){display:grid;align-content:start;gap:.75rem}:where(.calendar-demo-grid h3){margin:0}"


preview = BasicCalendar()
preview  # noqa: B018

The enhanced grid uses one roving tab stop. Arrow keys move by day or week, Home and End move within the locale week, Page Up/Down move by calendar month, and Shift+Page Up/Down move by calendar year. Enter or Space selects the focused date.

Submit and reset a canonical value

name contributes exactly one canonical date through the owned native Date input. Disabled Calendar is omitted; readonly Calendar remains submitted. An uncanceled reset restores the server value and visible month.

Submit and reset Calendar
Show code
from citry import Component


class CalendarForm(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    template = """
      <section x-data="{submitted:'Submit to inspect FormData'}">
        <form @submit.prevent="submitted=JSON.stringify(Object.fromEntries(new FormData($event.target)))">
          <c-CField control_id="trip-date" required>
            <c-fill name="label">Trip date</c-fill>
            <c-fill name="description">The native Form value remains YYYY-MM-DD.</c-fill>
            <c-fill name="default"><c-CCalendar id="trip-date" name="trip_date" value="2026-08-19" /></c-fill>
            <c-fill name="error">Choose a trip date.</c-fill>
          </c-CField>
          <div><button type="submit">Submit</button> <button type="reset">Reset</button></div>
        </form>
        <output x-text="submitted">Submit to inspect FormData</output>
      </section>
    """
    css = ":where(form,section){display:grid;justify-items:start;gap:.75rem}"


preview = CalendarForm()
preview  # noqa: B018

Without JavaScript, that Date input remains visible and usable. After enhancement it becomes the visually hidden Form, validity, and reset transport; the browser-generated grid is the interaction surface.

Bound and block dates

min and max are inclusive. Dates outside them are disabled and leave the focus sequence. unavailable_dates accepts up to 4096 unique exact dates; those dates stay focusable so keyboard users can inspect the calendar, but selection is rejected.

Constrain available dates
Show code
from citry import Component


class CalendarConstraints(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    template = """
      <c-CCalendar
        label="Book an appointment"
        visible_date="2026-08-19"
        min="2026-08-10"
        max="2026-09-15"
        c-unavailable_dates="('2026-08-18', '2026-08-20', '2026-08-24')"
      />
    """


preview = CalendarConstraints()
preview  # noqa: B018

This bounded exact list is for known application dates such as booked days. The server must validate submitted availability again.

Control selection and the visible month

Client value and visibleDate are independent controlled channels. A controlled request invokes onValueChange or onVisibleDateChange without claiming the selection or page changed; return the accepted canonical value to commit it. Omitting a prop releases that channel at its latest accepted state.

Control selection and month
Show code
from citry import Component

# ruff: noqa: E501 - Alpine expressions stay readable in the public source example


class ControlledCalendar(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    template = """
      <section x-data="{selected:'2026-08-19',visible:'2026-08-19',last:'No request yet'}">
        <c-CCalendar
          label="Controlled calendar"
          value="2026-08-19"
          visible_date="2026-08-19"
          $c-props="{value:selected,visibleDate:visible,onValueChange:(value,detail)=>{last=`selection: ${value}`;selected=value},onVisibleDateChange:(value,detail)=>{last=`month: ${value}`;visible=value}}"
        />
        <output x-text="last">No request yet</output>
      </section>
    """
    css = ":where(section){display:grid;justify-items:start;gap:.75rem}"


preview = ControlledCalendar()
preview  # noqa: B018

Uncontrolled selection emits bubbling native input followed by change from the fallback input. Controlled requests do not emit those transport events.

Follow the active locale

Under a client-enabled <c-i18n> provider, Calendar rebuilds its heading, weekday order, day numbers, and full accessible date labels immediately when the locale changes. first_day_of_week can override only the week start; leave it as None to follow locale week data.

Configure locale-sensitive weeks
Show code
from citry import Component

# ruff: noqa: E501 - template and CSS lines stay readable in the public source example


class CalendarLocales(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    template = """
      <section class="calendar-demo-grid">
        <article><h3>Locale week start</h3><c-CCalendar label="Locale week start" visible_date="2026-08-19" /></article>
        <article><h3>Explicit Monday</h3><c-CCalendar label="Monday week start" visible_date="2026-08-19" c-first_day_of_week="1" /></article>
      </section>
    """
    css = ":where(.calendar-demo-grid){display:grid;grid-template-columns:repeat(auto-fit,minmax(20rem,1fr));gap:1.25rem}:where(.calendar-demo-grid article){display:grid;align-content:start;gap:.5rem}:where(.calendar-demo-grid h3){margin:0}"


preview = CalendarLocales()
preview  # noqa: B018

Calendar navigates locale calendar months while retaining ISO Gregorian domain dates for callbacks and FormData. The provider time zone determines today's marker when explicit; otherwise Calendar uses the browser's local date.

Choose stable or natural rows

fixed_weeks=True keeps six rows so surrounding layout does not jump between months. Set it to False for the month's natural row count. Hide neighboring month dates with show_adjacent_days=False when they should not be selectable from the current page.

Compare calendar row layouts
Show code
from citry import Component

# ruff: noqa: E501 - template and CSS lines stay readable in the public source example


class CalendarNaturalWeeks(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    template = """
      <section class="calendar-demo-grid">
        <article><h3>Fixed six rows</h3><c-CCalendar label="Fixed weeks" visible_date="2026-02-01" /></article>
        <article><h3>Natural rows</h3><c-CCalendar label="Natural weeks" visible_date="2026-02-01" c-fixed_weeks="False" c-show_adjacent_days="False" /></article>
      </section>
    """
    css = ":where(.calendar-demo-grid){display:grid;grid-template-columns:repeat(auto-fit,minmax(20rem,1fr));align-items:start;gap:1.25rem}:where(.calendar-demo-grid article){display:grid;gap:.5rem}:where(.calendar-demo-grid h3){margin:0}"


preview = CalendarNaturalWeeks()
preview  # noqa: B018

Compare states and sizes

Outline and plain variants combine with sm, md, and lg sizes. Readonly Calendar allows focus and navigation but blocks selection. Disabled Calendar removes all day tab stops and disables navigation.

Compare Calendar states
Show code
from citry import Component

# ruff: noqa: E501 - template and CSS lines stay readable in the public source example


class CalendarStates(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    template = """
      <section class="calendar-demo-grid">
        <article><h3>Small plain</h3><c-CCalendar label="Small plain calendar" value="2026-08-19" size="sm" variant="plain" /></article>
        <article><h3>Readonly</h3><c-CCalendar label="Readonly calendar" value="2026-08-19" readonly /></article>
        <article><h3>Disabled</h3><c-CCalendar label="Disabled calendar" value="2026-08-19" disabled /></article>
        <article><h3>Invalid large</h3><c-CCalendar label="Invalid calendar" value="2026-08-19" invalid size="lg" /></article>
      </section>
    """
    css = ":where(.calendar-demo-grid){display:grid;grid-template-columns:repeat(auto-fit,minmax(20rem,1fr));align-items:start;gap:1.25rem}:where(.calendar-demo-grid article){display:grid;gap:.5rem}:where(.calendar-demo-grid h3){margin:0}"


preview = CalendarStates()
preview  # noqa: B018

Customize documented anatomy

Public --cui-calendar-* variables style the root, navigation, dates, selected day, today, and unavailable dates. Stable data-citry-ui-part selectors expose the documented anatomy without making generated classes or arrow markup public.

Customize Calendar
Show code
from citry import Component

# ruff: noqa: E501 - template and CSS lines stay readable in the public source example


class StyledCalendar(Component):
    class Kwargs:
        pass

    class Slots:
        pass

    template = """
      <c-CCalendar class_="brand-calendar" label="Brand calendar" value="2026-08-19" c-unavailable_dates="('2026-08-20',)" />
    """
    css = """
      :where(.brand-calendar){--cui-calendar-background:#fff8eb;--cui-calendar-border-color:#9a6700;--cui-calendar-focus-color:#6f42c1;--cui-calendar-selected-background:#7c3aed;--cui-calendar-selected-foreground:white;--cui-calendar-today-color:#9a3412;--cui-calendar-radius:1rem}
      @media (prefers-color-scheme:dark){:where(.brand-calendar){--cui-calendar-background:#211a10;--cui-calendar-foreground:#fff7e6}}
    """


preview = StyledCalendar()
preview  # noqa: B018

Use CDateInput when browser-owned editing and picker UI are preferable. Use CDatePicker for a popup field composed from DateInput and Calendar, and CDateRange when the application value is an ordered start/end pair.

API reference

Inputs

CCalendar server inputs

Server inputs are passed in a template through <c-CCalendar ... /> or in Python through CCalendar(...).

InputTypeDefaultEffect
valueCCalendarDate | None (CCalendarDate)NoneSets the initial/reset selected canonical date or empty value.
visible_dateCCalendarDate | None (CCalendarDate)Selected date or today.Sets the initially visible calendar month; otherwise uses value or today.
namestr | NoneNoneSets the native fallback input Form field name.
formstr | NoneNoneAssociates the native fallback input with an external Form ID.
idstr | NonegeneratedSets the public fallback input ID and the prefix for owned IDs.
minCCalendarDate | None (CCalendarDate)NoneSets the inclusive minimum selectable canonical date.
maxCCalendarDate | None (CCalendarDate)NoneSets the inclusive maximum selectable canonical date.
unavailable_datesSequence[CCalendarDate]()Marks at most 4096 unique in-range dates focusable but unavailable.
requiredbool | NoneNoneEnables native empty-value validity outside Field; Field owns it inside Field.
disabledbool | NoneNoneBlocks interaction and Form participation outside Field; Form disabledness also wins.
readonlybool | NoneNoneKeeps a focusable submitted value while blocking selection changes.
invalidbool | NoneNoneAdds application invalid state to revealed native validity.
first_day_of_weekLiteral[1, 2, 3, 4, 5, 6, 7] | NoneNoneOverrides the locale week start using ISO Monday 1 through Sunday 7.
show_adjacent_daysboolTrueShows selectable dates from neighboring months in leading and trailing cells.
fixed_weeksboolTrueUses six stable week rows instead of the natural month row count.
labelstr"Calendar"Names a standalone calendar; Field supplies the name when composed.
previous_labelstr"Previous month"Names the previous-month button.
next_labelstr"Next month"Names the next-month button.
unavailable_messagestr"Choose an available date."Supplies native custom validity when a formerly selected date becomes unavailable.
variant"outline" | "plain" (CCalendarVariant)"outline"Selects bordered or unframed treatment.
size"sm" | "md" | "lg" (CCalendarSize)"md"Selects coordinated cell navigation and text sizing.
class_CClassValue | None (CClassValue)NoneAdds classes to the root group and merges with attrs.
styleCStyleValue | None (CStyleValue)NoneAdds styles to the root group and merges with attrs.
attrsMapping[str, object] | NoneNoneAdds copied allowed root attributes without replacing owned roles state IDs or runtime markers.

CCalendar client inputs

Client inputs are passed in the browser through the $c-props="{ ... }" attribute on <c-CCalendar />.

InputTypeOmitted behaviorEffect
valuecanonical string | nullReleases control at the latest accepted value.Controls the selected date while supplied.
visibleDatecanonical stringReleases visible-month control at its latest accepted month.Controls the month containing this date while supplied.
mincanonical string | nullUses the server minimum.Replaces or removes the inclusive minimum.
maxcanonical string | nullUses the server maximum.Replaces or removes the inclusive maximum.
unavailableDatescanonical string arrayUses the server sequence.Replaces the bounded unavailable-date set.
requiredbooleanUses server or Field state.Controls standalone required validity.
disabledbooleanUses server or owner state.Controls navigation selection and Form participation.
readonlybooleanUses server or owner state.Controls focusable nonmutable state.
invalidbooleanUses server or Field state.Controls application invalid state.
firstDayOfWeek1 | 2 | 3 | 4 | 5 | 6 | 7 | nullUses the server input.Replaces or restores the locale week start.
showAdjacentDaysbooleanUses the server input.Controls neighboring-month cell visibility.
fixedWeeksbooleanUses the server input.Controls six-row versus natural-row layout.
variantCCalendarVariant (CCalendarVariant)Uses the server input.Controls presentation.
sizeCCalendarSize (CCalendarSize)Uses the server input.Controls coordinated sizing.
onValueChangefunctionNo semantic selection callback.Receives pointer keyboard or reset selection requests.
onVisibleDateChangefunctionNo semantic month callback.Receives button keyboard or selection-driven month requests.

Slots

-

Events

Component events are callback inputs supplied through $c-props. Native browser events remain available through Alpine @... attributes.

CCalendar events

EventSignatureTrigger and timingDetailControlled and cancellation behavior
onValueChange(value: string | null, detail: CCalendarValueChangeDetail) => void (CCalendarValueChangeDetail)A pointer or keyboard selection requests a new date or the owning Form resets.{value, previousValue, controlled, source, sourceEvent} (CCalendarValueChangeDetail)Uncontrolled selection commits before notification and emits native input/change; controlled selection is request-only.
onVisibleDateChange(visibleDate: string, detail: CCalendarVisibleDateChangeDetail) => void (CCalendarVisibleDateChangeDetail)Navigation or focus crossing a month requests another visible calendar month.{visibleDate, previousVisibleDate, controlled, source, sourceEvent} (CCalendarVisibleDateChangeDetail)Uncontrolled navigation commits before notification; controlled navigation waits for its owner.

Methods

-

CSS

CSS variables to theme the components. Set them on an ancestor or the component itself.

CCalendar CSS variables

Apply these variables to CCalendar or one of its ancestors.

VariableTypePurposeDefault
--cui-calendar-backgroundcolorRoot and native fallback background.Canvas
--cui-calendar-foregroundcolorRoot foreground.CanvasText
--cui-calendar-border-colorcolorRoot fallback and cell border.Mixed CanvasText.
--cui-calendar-focus-colorcolorNavigation and day focus outline.Highlight
--cui-calendar-selected-backgroundcolorSelected day background and border.Highlight
--cui-calendar-selected-foregroundcolorSelected day text.HighlightText
--cui-calendar-today-colorcolorToday marker border.LinkText
--cui-calendar-adjacent-colorcolorWeekdays and neighboring-month dates.Muted CanvasText.
--cui-calendar-unavailable-colorcolorUnavailable date text.GrayText
--cui-calendar-radiuslengthRoot corner radius.0.75rem
--cui-calendar-paddinglengthRoot inset.0.75rem
--cui-calendar-gaplengthHeader grid and cell spacing.0.25rem
--cui-calendar-cell-sizelengthDay cell minimum target size.2.5rem
--cui-calendar-navigation-sizelengthPrevious and next button size.2.5rem
--cui-calendar-font-sizelengthRoot text size.1rem
--cui-calendar-invalid-border-colorcolorInvalid root border.Theme error.

Attributes

HTML attributes defined on the components that you can refer to for CSS, inspection, and testing. Read-only.

CCalendar attributes

AttributeElementTypeMeaning
data-requiredRoot grouppresent | absentMirrors effective requiredness.
data-disabledRoot grouppresent | absentMirrors effective disabledness.
data-readonlyRoot grouppresent | absentMirrors effective readonly state.
data-invalidRoot grouppresent | absentMirrors application or revealed native invalidity.
data-emptyRoot grouppresent | absentMarks no selected canonical value.
data-variantRoot groupCCalendarVariant (CCalendarVariant)Mirrors visual treatment.
data-sizeRoot groupCCalendarSize (CCalendarSize)Mirrors coordinated sizing.

CCalendar attributes

AttributeElementTypeMeaning
data-dateDate gridcellcanonical dateIdentifies the exact ISO domain date.
data-selectedDate gridcellpresent | absentMarks the committed selected date.
data-todayDate gridcellpresent | absentMarks today in the effective provider time zone.
data-outsideDate gridcellpresent | absentMarks a neighboring-month date or blank.
data-unavailableDate gridcellpresent | absentMarks a focusable date that selection rejects.

Selectors

Selectors for the DOM nodes in the components that you can use for CSS, inspection, and testing.

CCalendar selectors

SelectorElementPurpose
[data-citry-ui-part="calendar"]Root groupState reflections root attrs and styling destination.
[data-citry-ui-part="header"]Header divNavigation and localized heading layout.
[data-citry-ui-part="previous"]ButtonRequests the previous calendar month.
[data-citry-ui-part="heading"]Live h2Announces the localized visible month and year.
[data-citry-ui-part="next"]ButtonRequests the next calendar month.
[data-citry-ui-part="grid"]Table gridOwns localized weekdays and roving date cells.
[data-citry-ui-part="weekday-row"]Header rowOwns the seven localized weekday headers.
[data-citry-ui-part="weekday"]Column headerDisplays abbreviated and full localized weekday names.
[data-citry-ui-part="week"]Grid rowGroups one locale-ordered week.
[data-citry-ui-part="day"]GridcellExact roving focus selection and day-state hook.
[data-citry-ui-part="fallback-input"]Native Date inputForm reset validity and no-JavaScript transport.

Interfaces

Aliases and data shapes referenced above.

Input type aliases

InterfaceDefinition
CCalendarDatedate | str
CCalendarVariantLiteral["outline", "plain"]
CCalendarSizeLiteral["sm", "md", "lg"]
CCalendarChangeSourceLiteral["pointer", "keyboard", "button", "value", "reset"]
CClassValuestr | Mapping[str, bool] | Sequence[CClassValue]
CStyleValuestr | Mapping[str, object] | Sequence[CStyleValue]

CCalendarValueChangeDetail

FieldTypeDefaultMeaning
valuestring | null-Requested selected canonical date or empty state.
previousValuestring | null-Effective selected date before the request.
controlledboolean-Whether client value owns committed selection.
sourceCCalendarChangeSource (CCalendarChangeSource)-Pointer keyboard value or reset cause.
sourceEventobject | null-Native interaction event when one exists.

CCalendarVisibleDateChangeDetail

FieldTypeDefaultMeaning
visibleDatestring-Requested canonical date inside the new visible month.
previousVisibleDatestring-Visible canonical date before the request.
controlledboolean-Whether client visibleDate owns the visible month.
sourceCCalendarChangeSource (CCalendarChangeSource)-Button keyboard selection value or reset cause.
sourceEventobject | null-Native interaction event when one exists.

Translation keys

Catalog keys used by this family. An explicit component input or slot listed in Override takes precedence over the catalog for that instance.

CCalendar translation keys

KeyPurposeVariablesOverrideBrowser updates
citry-ui-calendar-labelNames a standalone root group and its native fallback.nonelabel or root attrs aria-label/aria-labelledby$c-tr updates both stable aria-label destinations.
citry-ui-calendar-previous-monthNames the previous-month button.noneprevious_label$c-tr updates the stable aria-label destination.
citry-ui-calendar-next-monthNames the next-month button.nonenext_label$c-tr updates the stable aria-label destination.
citry-ui-calendar-unavailableSupplies custom native validity when a selected date becomes unavailable.noneunavailable_messagei18n.bind() updates the browser-owned validity message.