List view
An agenda of the days that have events.
An agenda: the days that have events, each with its events in order.
Loading the preview…
import { listView } from '@calendar-tsx/core';
listView({ days: 7 });
listView({ period: 'month' });
listView({ period: 'quarter' });
listView({ months: 3 });
listView({ weeks: 1, hiddenDays: [6, 7] });Every view factory takes exactly one of days, weeks, months or period. Counts are positive integers.
| Duration | Range | next() / prev() |
|---|---|---|
days: N | N dates from date; 7 keeps week alignment. | N days. |
weeks: N | N whole weeks from firstDayOfWeek. | N weeks, keeping the weekday. |
months: N | N calendar months from the first of the anchor month. | N months, landing on the first day. |
period | 'month', 'quarter' or 'year', aligned to its calendar boundary. | One period, landing on its first day. |
The list shows only days with at least one event, so a quiet range has no days; render ListViewEmpty for it.
hiddenDays omits weekdays as in the other views (see hidden weekdays).
Resource grouping
groupBy turns the agenda into resource and date sections:
listView({ weeks: 1, groupBy: 'resource' });
listView({ weeks: 1, groupBy: ['resource', 'date'] });
listView({ weeks: 1, groupBy: ['date', 'resource'] });'resource' and ['resource'] mean resources first, then their dates; the ordered pairs choose which comes outside.
Omitting groupBy, or passing 'date' or ['date'], gives the ordinary agenda. Keys cannot repeat, and 'month'
grouping exists only in day grids.
Resources follow their input order and dates are chronological. An event assigned to several known resources appears in each group. Resource agendas leave out unassigned events and unknown resource IDs, as resource grids and timelines do; ordinary agendas include them. Empty dates and resources are omitted, so an agenda with no matching events has one list-wide empty state.
Resources before dates
With groupBy: 'resource' or ['resource', 'date'], each section names a resource and lists its dates.
Loading the preview…
Open the resource-first agenda in the playground.
Dates before resources
With groupBy: ['date', 'resource'], each section shows a date and lists the resources with events on that date.
Loading the preview…
Open the date-first agenda in the playground.
Render layout.sections with ListViewSection and ListViewSectionHeader, then each section's days with the day
and event parts. Day headings show dates in resource-first lists and resource names in date-first lists. Both orders
work with every duration and hiddenDays.
Date headings
The supplied themes place the date beside its event rows. Give ListViewDayHeader a
<time dateTime={day.date.toString()}> holding a <strong> day number and a <span> with the weekday and month or
year, as the React and Solid examples do. The full date stays the heading's accessible name; you format it.
The date column narrows with the list and its labels wrap. --calendar-list-date-width (default 10rem) caps its
width. ListViewDay emits --cal-events so the heading spans the day's event rows; render the header and events as
direct children of the day.
Example
export const Agenda = () => {
const list = useCalendarSelector((state: State) => state.layout);
if (list.kind !== 'list') return null;
return (
<ListView model={list}>
{list.sections.map(section => (
<ListViewSection
key={section.key}
section={section}
aria-label={section.resource?.title ?? section.date?.toLocaleString('en-US', { dateStyle: 'full' })}
>
{(section.resource || section.date) && (
<ListViewSectionHeader section={section}>
{section.resource?.title ?? section.date?.toLocaleString('en-US', { dateStyle: 'full' })}
</ListViewSectionHeader>
)}
{section.days.map(day => (
<ListViewDay key={day.key} day={day}>
<ListViewDayHeader
day={day}
aria-label={
section.date ? day.resource?.title : day.date.toLocaleString('en-US', { dateStyle: 'full' })
}
>
{section.date ? (
day.resource?.title
) : (
<time dateTime={day.date.toString()}>
<strong>{day.date.toLocaleString('en-US', { day: 'numeric' })}</strong>{' '}
<span>
<span>{day.date.toLocaleString('en-US', { weekday: 'short' })}</span>{' '}
<span>{day.date.toLocaleString('en-US', { month: 'short', year: 'numeric' })}</span>
</span>
</time>
)}
</ListViewDayHeader>
{day.events.map(event => (
<ListViewEvent key={event.id} event={event}>
{event.data.title}
</ListViewEvent>
))}
</ListViewDay>
))}
</ListViewSection>
))}
<ListViewEmpty>No events this week</ListViewEmpty>
</ListView>
);
};Model
layout is { kind: 'list', coordinates, sections, days }.
- Each section is
{ key, resource?, date?, days }.resourceidentifies a resource-first section;dateidentifies a date-first section. Ordinary lists have one section with neither field. - Each day is
{ key, date, resource?, events }. Grouped day keys identify both the date and resource. layout.daysis a flat index of the same day objects in section order. Section headings needsections.
Calendar_ListLayout, Calendar_ListSection and Calendar_ListDay take event data, resource data and features as
generic parameters. A feature that decorates days must update the sections and rebuild the flat index from them.
Parts
| Part | Model prop | Element | Notes |
|---|---|---|---|
ListView | model | div | role='region', labelled "Event list". |
ListViewSection | section | section | data-date or data-resource-id; supply an accessible label for grouped sections. |
ListViewSectionHeader | section | h2 | Consumer-supplied date or resource heading. |
ListViewDay | day | section | data-date, optional data-resource-id. |
ListViewDayHeader | day | h3 | |
ListViewEvent | event | button | |
ListViewEmpty | none | div | Renders only when the list has no days. |