Calendar Table
A calendar board is a component that presents dates in a structured grid layout, typically organized by weeks and days, allowing users to view and interact with calendar data at a glance. Commonly used in scheduling applications, event planners, and dashboard interfaces, the calendar board renders dates as cells within a table grid, making it easy to scan across days, weeks, or months.
This headless component renders a <table> element with role="grid" and an accessible label. The consumer provides the table rows and cells as children, along with any header rows for day-of-week labels.
Example
Show demo markup
<table class="calendar-table" aria-label="Calendar"><thead class="calendar-table-head"><tr class="calendar-table-row"><th class="calendar-table-th">Mon</th><th class="calendar-table-th">Tue</th><th class="calendar-table-th">Wed</th></tr></thead><tbody class="calendar-table-body"><tr class="calendar-table-row"><td class="calendar-table-td">1</td><td class="calendar-table-td">2</td><td class="calendar-table-td">3</td></tr></tbody></table>
Usage example
<script lang="ts">
import CalendarTable from './CalendarTable.svelte';
import CalendarTableHead from '../CalendarTableHead/CalendarTableHead.svelte';
import CalendarTableBody from '../CalendarTableBody/CalendarTableBody.svelte';
import CalendarTableFoot from '../CalendarTableFoot/CalendarTableFoot.svelte';
import CalendarTableRow from '../CalendarTableRow/CalendarTableRow.svelte';
import CalendarTableTD from '../CalendarTableTD/CalendarTableTD.svelte';
</script>
<CalendarTable label="January 2025">
<CalendarTableHead>
<CalendarTableRow>
<th>Sun</th><th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th>
</CalendarTableRow>
</CalendarTableHead>
<CalendarTableBody>
<CalendarTableRow>
{#each [1, 2, 3, 4, 5, 6, 7] as d}
<CalendarTableTD>{d}</CalendarTableTD>
{/each}
</CalendarTableRow>
</CalendarTableBody>
<CalendarTableFoot>
<CalendarTableRow>
<CalendarTableTD>Week total: 7</CalendarTableTD>
</CalendarTableRow>
</CalendarTableFoot>
</CalendarTable>
Show Svelte source
// In your Svelte component:
import CalendarTable from "lily-design-system-svelte-headless/components/CalendarTable/CalendarTable.svelte";
<CalendarTable label="Table">
<!-- thead, tbody, tfoot -->
</CalendarTable>
Usage
<CalendarTable label="April 2026">
<CalendarTableHead>
<CalendarTableRow>
<th>Mon</th><th>Tue</th><th>Wed</th><th>Thu</th><th>Fri</th><th>Sat</th><th>Sun</th>
</CalendarTableRow>
</CalendarTableHead>
<CalendarTableBody>
<CalendarTableRow>
<CalendarTableTD>1</CalendarTableTD>
<CalendarTableTD>2</CalendarTableTD>
<CalendarTableTD>3</CalendarTableTD>
<CalendarTableTD>4</CalendarTableTD>
<CalendarTableTD>5</CalendarTableTD>
<CalendarTableTD>6</CalendarTableTD>
<CalendarTableTD>7</CalendarTableTD>
</CalendarTableRow>
<CalendarTableRow>
<CalendarTableTD today selected>8</CalendarTableTD>
<CalendarTableTD>9</CalendarTableTD>
<CalendarTableTD>10</CalendarTableTD>
<CalendarTableTD>11</CalendarTableTD>
<CalendarTableTD>12</CalendarTableTD>
<CalendarTableTD>13</CalendarTableTD>
<CalendarTableTD>14</CalendarTableTD>
</CalendarTableRow>
</CalendarTableBody>
<CalendarTableFoot>
<CalendarTableRow>
<td colspan="7">3 events this week</td>
</CalendarTableRow>
</CalendarTableFoot>
</CalendarTable>
Props
label: string (required) -- accessible name describing the calendar period (e.g., month and year), applied via aria-label
children: slot (required) -- table rows and cells representing the calendar grid
Keyboard Interactions
None built-in -- the consumer should implement grid keyboard navigation on cells as needed (arrow keys for cell-to-cell movement, Enter/Space for selection).
ARIA
role="grid" -- identifies the table as an interactive grid widget
aria-label={label} -- provides an accessible name describing the calendar period
When to Use
- Use to display an interactive calendar grid for managing dates, scheduling, and date selection
- Use when users need to view and interact with dates in a monthly or weekly grid format
- Use in scheduling applications, event planners, and dashboard calendars where a visual date layout is needed
- Use as the container for CalendarTableHead, CalendarTableBody, CalendarTableFoot, CalendarTableRow, and CalendarTableTD
When Not to Use
- Do not use for displaying general tabular data -- use Table or DataTable instead
- Do not use for date range selection without a grid -- use CalendarRangePicker for start-and-end-date picking
- Do not use for simple date entry where users already know the date -- use DateInput for a compact input field
Headless
This component provides a <table> element with role="grid" and aria-label for accessible calendar grid semantics, with zero visual styling. The consumer is responsible for all CSS including cell sizing, grid lines, day-of-week header styling, selected/today state highlights, and month navigation controls.
Styles
The consumer provides all CSS styling. The component renders with a .calendar-table class for targeting. No default styles are included — this is a fully headless component.
Testing
- Verify the component renders a
<table> element with class calendar-table
- Verify role="grid"` -- identifies the table as an interactive grid widget
- Verify aria-label={label}` -- provides an accessible name describing the calendar period
- Verify pass-through attributes are applied
Advice
- Designers: Clearly distinguish today's date and selected dates from other days. Use consistent cell sizing and ensure enough contrast for day numbers.
- Developers: Implement arrow key navigation between cells, Enter/Space for selection, and ensure the
label prop describes the calendar period (e.g., "January 2025") for screen readers.
Implementation Notes
- Renders a
<table> element with role="grid" for structured calendar grid semantics
- Consumer provides
<tr> rows with <td> or <th> cells as children
- The
label prop should describe the calendar period (e.g., "January 2025")
- Accepts
...restProps for forwarding additional attributes to the table element
- No internal state -- purely a structural wrapper
Composition
CalendarTable follows the Table composition pattern:
- CalendarTable -- outer
<table> with role="grid" and aria-label.
- CalendarTableHead --
<thead> containing day-of-week column headers.
- CalendarTableBody --
<tbody> containing rows of day cells.
- CalendarTableFoot --
<tfoot> for optional summary or navigation content.
- CalendarTableRow --
<tr> representing one week.
- CalendarTableCell --
<td> representing one day with selection and today state.
<CalendarTable label="January 2025">
<CalendarTableHead>
<CalendarTableRow><th>Sun</th><th>Mon</th><th>Tue</th></CalendarTableRow>
</CalendarTableHead>
<CalendarTableBody>
<CalendarTableRow>
<CalendarTableCell>1</CalendarTableCell>
<CalendarTableCell today selected>2</CalendarTableCell>
<CalendarTableCell>3</CalendarTableCell>
</CalendarTableRow>
</CalendarTableBody>
</CalendarTable>
Related components
calendar-table-body — a calendar table interactive grid tbody for managing dates, days, etc. <tbody>
calendar-table-foot — a calendar table interactive grid tfoot for managing dates, days, etc. <tfoot>
calendar-table-head — a calendar table interactive grid thead for managing dates, days, etc. <thead>
calendar-table-row — a calendar table interactive grid row for managing dates, days, etc. <tr>
calendar-table-td — a calendar table interactive grid data cell for managing dates, days, etc. <td>
calendar-table-th — a calendar table interactive grid header cell for managing dates, days, etc. <th>
table — a table with rows and columns <table>
References
- WAI-ARIA Grid Pattern: https://www.w3.org/WAI/ARIA/apg/patterns/grid/
Canonical contract
Generated from this component's canonical metadata — the machine-checked source the implementations are held to.
Metadata
- Component: calendar-table
- PascalCase: CalendarTable
- Description: a calendar table interactive grid for managing dates, days, etc. <table>
- Status: beta — implemented and unit-tested in all seven frameworks with an axe-clean demo page; not yet exercised in composed flows
- HTML tag: <table>
- CSS class: .calendar-table
- Interactive: no
ARIA
role="grid" -- identifies the table as an interactive grid widget aria-label={label} -- provides an accessible name describing the calendar period
Keyboard
- No keyboard interactions — this is a passive element
Props
label: string (required) -- accessible name describing the calendar period (e.g., month and year), applied via aria-label children: slot (required) -- table rows and cells representing the calendar grid