Skip to content

Calendar ​

A calendar component with month/year modes, supporting selection, disabled dates, week numbers, and keyboard grid navigation; date descriptions use Intl.DateTimeFormat (locale-aware).

Basic Usage ​

Month view (mode=month)

Click a date to select it and dispatch oas-change; the title opens a month-selection panel for quick month jumps.

On touch screens (pointer: coarse) day cells get a 44px minimum height, month/year cells a 44px minimum height, and header navigation buttons a 44px hit target (day cells only grow in height — their width still shares the container evenly).

Year View ​

Year view (mode=year)

In year mode, selecting a month dispatches yyyy-MM.

Disabled Range ​

min / max limits

Disabled Callback ​

disabled-date (disable weekends)

disabledDate is passed in via a property callback (functions cannot be expressed in JSON).

Week Numbers ​

Show week numbers (show-week-number)

Events ​

oas-change event

Custom Cells ​

Event-marked calendar (oas-cell-render marks holidays)

oas-cell-render is dispatched for each rendered day cell (detail: { date, element }), letting the host append markers/badges/rich content (e.g. holidays, event dots); alternatively drop a <template slot="cell"> inside the component for a static skeleton whose [data-cell-date] node is auto-bound to the day number. Appending <span class="cell-dot"> inside element shows the built-in marker dot (uses the --oas-color-danger token; adapts to light/dark themes).

Scheduled Items (events) ​

events scheduled items (declarative markers + day detail popover)

The events attribute/property channel declares per-day items: [{ date: 'YYYY-MM-DD', title?, color? }]. A day with items renders marker dots (uses color when given, else the primary color); more than 2 items collapse into a +N badge; hovering or focusing the day opens an inline items popover (one row per title with its dot). Fully declarative — no hand-written oas-cell-render listener needed (that event stays as a fallback). Excludes cross-day items / drag-to-reschedule / week view (Scheduler-level capabilities).

Mode Switching ​

Mode switching (month ↔ year quick year jump)

Month viewYear view

mode="year" shows a 12-month grid; the previous/next year buttons in the header quickly switch years. Picking a month selects it (dispatches oas-change with value yyyy-MM) and auto-switches back to the month view (dispatches oas-mode-change). In a controlled scenario, listen to oas-mode-change and re-set the mode attribute to keep a specific mode.

Week Start Override ​

Week start override (first-day-of-week)

first-day-of-week accepts 0 (Sunday) through 6 (Saturday); defaults to the locale (Monday for European/Chinese locales, Sunday for Japanese/Korean/English/Arabic; otherwise derived from Intl.Locale week info).

Panel Month Anchor ​

page-show-date anchor + oas-panel-change

page-show-date anchors the displayed panel to the given month initially and reactively — even when value lives in another year (e.g. echoing a birth date while opening from the current month); it takes precedence over value. oas-panel-change (detail: { date }) fires when the user pages / picks a month / jumps; removing the attribute falls back to the value month.

Paging Boundaries ​

min / max paging boundaries

When the next page would fall entirely outside [min, max] (whole month in the day view, whole year in the month panel, whole decade page in the decade grid), the previous/next buttons grey out.

Range Selection ​

range: two-click range picking with highlight

Selected range: Click the start date, then the end date (hover shows a preview)

Set range to enter range selection mode: the first click sets the start date (highlighted), moving the pointer previews the range on hovered day cells in real time, and the second click sets the end date and emits oas-change (detail: { start, end }, both YYYY-MM-DD strings; swapped automatically when the end precedes the start). Range endpoints get a solid primary background with rounded corners, and the in-between days a light primary tint — all colors via tokens (same visual language as the date-picker daterange). Clicking again after a commit starts a new round (the old range clears immediately). The value attribute reflects/presets the range as a JSON array: value='["2026-08-05","2026-08-15"]'.

Multiple / Week Selection: Use date-picker ​

This component (a persistent selection panel) covers single-date selection out of the box; range selection is now covered by the range attribute above. Multiple dates and week picking remain covered by date-picker — the two share the same date grid with consistent semantics:

  • Multiple dates: <oas-date-picker multiple>
  • Week picking: <oas-date-picker type="week"> (value yyyy-Wnn)

If multiple selection is needed on a persistent page, the host can combine the inner-panel capabilities of oas-date-picker with oas-calendar, or use oas-calendar for single selection while maintaining the set itself.

Custom Header ​

header slot (custom header, built-in nav by default)

Schedule calendarBack to today

slot="header" distributes a custom header (replaces the built-in navigation region entirely — the host takes over paging interaction, e.g. via controlled page-show-date anchoring); without it the built-in prev / title / next / today navigation remains ([part="header"] is targetable and styleable via ::part).

Panel Language & Header Format ​

locale: panel language override

locale overrides the panel language: title/weekday/cell-description Intl formatting, navigation and "Today" labels, and week-start derivation all follow; it defaults to the config-provider injection or the global locale.

format: header date format string

format customizes the header title format (same tokens as date-picker: yyyy/MM/dd/HH/mm/ss; applies to both the day and month panel titles); the decade panel title is a range form (2020-2031) and does not take the format string.

Custom Header Action Bar: Card Composition (extra content, keeps built-in nav) ​

To place a brand/action bar above the calendar while keeping the built-in navigation, wrap oas-calendar in the host's own card with the action bar on top (to replace the header entirely, use the header slot above):

Header composition: custom header action bar

Project scheduleClick the title to drill into year/month; the built-in Today button returns to the current month

Read-only Calendar ​

readonly: read-only detail view with event dots

With readonly, paging and panel drill-down stay available but picking dates / pressing Enter does not commit — combined with oas-cell-render event dots this yields a "viewable, not editable" detail calendar.

Globally Disabled ​

disabled: fully non-interactive

disabled greys out the whole calendar and stops all interaction (picking / paging / keyboard); use it with form-disabled scenarios. readonly still allows browsing.

Keyboard & Fast Year Jump ​

Extended keyboard + decade fast year jump

  • Keyboard: Home/End jump to the start/end of the week; PageUp/PageDown move to the previous/next month (Shift moves by year); arrow keys move cell by cell, Enter/Space selects.
  • Fast year jump: click the title to open the month panel, click the year to open the decade grid (pages step by ±12 years), pick a year to return to that year's month panel, then pick a month to return to the day view — from 2026 to 1980 takes about 7-8 clicks.

Non-Gregorian Calendars (calendar-system) ​

Chinese calendar (calendar-system=chinese)

Islamic calendar (calendar-system=islamic)

calendar-system passes through Intl.DateTimeFormat's calendar option (chinese / islamic / hebrew, etc.): the title, weekday headers, cell numbers and aria descriptions follow that calendar, while date math and the value / data-date stay on the Gregorian internal model — the calendar only affects display and screen-reader output.

Multi-month Panels (months) ​

months=2: two months side by side + linked paging

months sets the number of side-by-side month panels (default 1, positive integer; invalid or below 1 falls back to 1, values above the cap clamp to 12): panels lay out horizontally at equal width, and prev/next page the whole strip (stepping months months at a time) with the title showing the month range. It combines with first-day-of-week, show-week-number, range, and the rest.

API ​

oas-calendar ​

Attributes ​

AttributeDescriptionTypeDefault
calendar-systemNon-Gregorian calendar (Intl calendar option, e.g. chinese/islamic/hebrew): title, weekday headers, cell numbers and aria descriptions follow it; date math and value/data-date stay Gregorianstring—
disabledGlobally disabled: greys out the calendar and stops all interaction (picking / paging / keyboard)boolean—
eventsScheduled items (JSON): [{ date: YYYY-MM-DD, title?, color? }] — marker dots per day (uses color if given, else primary), +N badge beyond 2; hover/focus opens an inline items popoverCalendarEvent[][]
first-day-of-weekWeek start override: 0 (Sunday) to 6 (Saturday); defaults to the locale (Monday for European/Chinese, Sunday for Japanese/Korean/English/Arabic)string—
formatHeader title format string (yyyy/MM/dd tokens; day/month panels)string—
localePanel language override (title/weekdays/cell descriptions/nav copy/week start); defaults to config-provider > globalstring—
maxSelectable range (ISO dates); navigation buttons grey out when the whole target page falls outside the rangestring—
minSelectable range (ISO dates); navigation buttons grey out when the whole target page falls outside the rangestring—
modemonth / year (in year mode, picking a month auto-switches back to month view)stringmonth
monthsNumber of side-by-side month panels (1-12, default 1): panels lay out horizontally and paging steps the whole strip; the title shows the month rangestring—
page-show-datePanel month anchor (ISO yyyy-MM or yyyy-MM-dd): anchors the displayed month initially/on change, taking precedence over value; removing it falls back to the value monthstring—
rangeRange selection mode: two-click picking with hover preview and range highlighting; oas-change carries { start, end }; value mirrors a JSON arrayboolean—
readonlyRead-only: page navigation and panel drill-down stay available, but picking dates / Enter does not commitboolean—
show-week-numberShow the ISO week number columnboolean—
valueSelected value (ISO)string—

Property (JS property; see each row for attribute reflection) ​

PropertyDescriptionTypeDefault
disabledDateDisabled-date predicate (property function channel, (date) => boolean)((d: Date) => boolean) | null—
eventsScheduled items (CalendarEvent[], { date, title?, color? }): el.events reads the effective items; el.events = [...] writes programmatically (syncs the events attribute and re-renders, no event)CalendarEvent[][]

Events ​

EventDescription
oas-cell-renderDispatched when each day cell renders, detail: { date, element } (element is the day button; host can append markers/badges/rich content)
oas-changeSelection change, detail: { value }
oas-mode-changeDispatched when year mode auto-switches back to month view after picking a month, detail: { mode }
oas-panel-changeDispatched when the displayed panel month changes due to user paging/month picking/jumps, detail: { date } (date is the first day of the new page)

Slots ​

NameDescription
headerCustom header replacing the built-in navigation (built-in kept when not distributed)
template[slot="cell"]Static template for day cells, cloned into each day button; the [data-cell-date] node is bound to the day number

Keyboard: ↑/↓/←/→ to move within the grid (auto-paging across months), Home/End to jump to the week start/end, PageUp/PageDown to move between months (Shift for years), Enter/Space to select.

Released under the MIT OR Apache-2.0 License.