Calendar
Calendar is the date-grid primitive for a date field or range. Choose it when the date grid belongs in your layout; choose DatePicker or DateRangePicker when the grid should open from a compact field.
Examples
A selected date and today shortcut
Use a date-only ISO string for an initial local date. todayButton adds a shortcut that selects
today and returns the grid to its month.
A complete range
Set range to let the first selection start a range and the second complete it. Selecting a date
before the start reverses the bounds, so the resulting range is always in chronological order.
Brazilian Portuguese dates
locale="pt-BR" uses Intl for the month name, weekday headings and spoken date labels. Pass
labels as well when the calendar controls need translated strings.
When to use
Use Calendar when a visible date grid is the right part of the surrounding form or scheduling interface, including when a person needs to compare nearby dates before choosing one.
Reach for something else when:
- The grid should stay hidden until a field is activated — use DatePicker for one date or DateRangePicker for a start and end date.
- A person knows the exact date and must type it quickly — use a text input with clear validation instead of requiring navigation through a grid.
- Only a time is being selected — use TimePicker for an available-time list or TimeInput for typed 24-hour entry.
Accessibility
- The active day cell is the single tab stop in the grid: all other day buttons use roving
tabIndex="-1". Arrow keys move by day or week; Home and End move to the current week's edges; PageUp and PageDown move by month. - Every day has a locale-formatted accessible name. Weekday headings expose the full weekday name, while their visible text is the locale's narrow form.
- The selected start and end days use
aria-pressed. The header button cycles days, months and years; month and year selection returns to the next more specific view. - Disabled dates intentionally remain focusable and use
aria-disabled="true"rather than nativedisabled. This lets keyboard users discover unavailable dates and continue arrow-key navigation; activation does not change the selection. labelsprovides the navigation, view-change and today strings. Date formatting usesIntl, so there are no hardcoded month, weekday or date strings in the grid.
API and code
| Name | Type | Required | Description |
|---|---|---|---|
range | boolean | — | Whether selection is a date range. Default: `false`. |
value | Date | string | CalendarRange | null | — | Controlled selected local date, ISO `YYYY-MM-DD` string, or range. |
defaultValue | Date | string | CalendarRange | — | Initial selected local date, ISO `YYYY-MM-DD` string, or range when uncontrolled. |
onChange | (value: Date | CalendarRange) => void | — | Called after a date or range is selected. |
min | Date | string | — | Inclusive lower selection limit as a local date or ISO `YYYY-MM-DD` string. |
max | Date | string | — | Inclusive upper selection limit as a local date or ISO `YYYY-MM-DD` string. |
isDateDisabled | (date: Date) => boolean | — | Returns whether a local date cannot be selected. Disabled dates remain visible. |
renderDayMarker | (date: Date) => ReactNode | — | Renders extra content inside each day cell, such as a `.lyra-cal__dot` availability marker. |
weekStartsOn | 0 | 1 | 2 | 3 | 4 | 5 | 6 | — | First weekday, where `0` is Sunday and `6` is Saturday. Default: `0`. |
size | 'sm' | 'md' | — | Calendar cell size. Default: `"sm"`. |
todayButton | boolean | — | Whether to render the today shortcut. Default: `false`. |
locale | string | — | BCP 47 locale used for month names, weekday headings, and date labels. Default: `"en-US"`. |
labels | CalendarLabels | — | Translatable control labels, merged over the English defaults. |
x-data="lyraCalendar({ … })"
| Option | Type | Required | Description |
|---|---|---|---|
range | boolean | — | Whether selection is a date range. Default: `false`. |
defaultValue | string | {
start?: string | null;
end?: string | null;
} | null | — | Initial ISO date, or range of ISO dates. |
min | string | — | Inclusive lower selection limit as ISO `YYYY-MM-DD`. |
max | string | — | Inclusive upper selection limit as ISO `YYYY-MM-DD`. |
disabledDates | string[] | — | ISO dates that cannot be selected; this replaces React's function-only data API. |
isDateDisabled | (date: Date) => boolean | — | Optional JavaScript-only disabled-date predicate; it combines with `disabledDates`. |
weekStartsOn | 0 | 1 | 2 | 3 | 4 | 5 | 6 | — | First weekday, where `0` is Sunday and `6` is Saturday. Default: `0`. |
locale | string | — | BCP 47 locale used for labels and names. Default: `"en-US"`. |
labels | LyraCalendarLabels | — | Translatable labels merged over English defaults. |
Without React, compose the calendar classes and implement local-date parsing, roving focus, selection and view changes yourself:
<div class="lyra-cal">
<div class="lyra-cal__head">
<button class="lyra-cal__nav" type="button" aria-label="Previous month">‹</button>
<button class="lyra-cal__label" type="button" aria-label="Change month or year">
August 2026
</button>
<button class="lyra-cal__nav" type="button" aria-label="Next month">›</button>
</div>
<div class="lyra-cal__grid">
<span class="lyra-cal__wd" aria-label="Sunday">S</span>
<button
class="lyra-cal__day"
type="button"
tabindex="0"
aria-label="Tuesday, August 4, 2026"
aria-pressed="true"
>
4
</button>
<button
class="lyra-cal__day"
type="button"
tabindex="-1"
aria-disabled="true"
aria-label="Wednesday, August 5, 2026"
>
5
</button>
</div>
<div class="lyra-cal__foot"><button class="lyra-cal__today" type="button">Today</button></div>
</div><lyra:calendar> Generated from lyra-ds/blade v0.10.0.
The behavior comes from lyraCalendar() — install @lyra-ds/alpine and see the HTML + Alpine tab.
| Prop | Default | Required | Example values |
|---|---|---|---|
range | false | — | — |
defaultValue | null | — | — |
min | null | — | — |
max | null | — | — |
disabledDates | [] | — | — |
weekStartsOn | 0 | — | — |
size | 'sm' | — | md |
todayButton | false | — | — |
locale | 'en-US' | — | — |
labels | [] | — | — |
dateDisabledPredicate | null | — | — |
<lyra:calendar
default-value="2026-03-17"
min="2026-01-01"
max="2026-12-31"
:week-starts-on="1"
locale="en-US"
today-button
/>