Schedule List
alphav0.2.0Time-anchored agenda list — time or range, title, optional description and icons, per-row links, framed or bare.
Context
Use for conference programs, course curricula, podcast / broadcast schedules, meeting agendas, recipe-step lists with timing — anywhere a time-ordered list of activities renders. Migration origin: kasder kas-social-front-v0 events/[id]/page.tsx Program section. Composes naturally inside event-detail-page-01 (deferred sibling).
Installation
pnpm dlx shadcn@latest init"registries": {
"@ilinxa": "https://ui.ilinxa.com/r/{name}.json"
}pnpm dlx shadcn@latest add @ilinxa/schedule-listAdd -fixtures for dummy data:
pnpm dlx shadcn@latest add @ilinxa/schedule-list-fixturesPreview
Program
- 09:00
Kayıt ve Karşılama Kahvaltısı
Katılımcı kayıtları ve networking
- 10:00
Açılış Konuşması
Dernek Başkanı tarafından açılış
- 11:00
Panel: Geleceğin Şehirleri
Uzman panelimizle interaktif tartışma
- 13:00
Öğle Yemeği
Networking lunch
- 14:30
Çalıştaylar
Paralel çalıştay oturumları
- 17:00
Kapanış ve Networking
Sonuç bildirisi ve kokteyl
Demo source
Usage
When to use
Reach for ScheduleList when you need a vertical time-anchored list of activities — conference programs, course curricula, podcast / broadcast schedules, meeting agendas, recipe steps with timing. Each row is a time + title + optional description triplet, with optional icons and optional per-row links.
Minimal example
import { ScheduleList } from "@/components/schedule-list";
<ScheduleList
heading="Program"
items={[
{ id: "1", time: "09:00", title: "Welcome", description: "Check-in" },
{ id: "2", time: "10:00", endTime: "10:30", title: "Opening Keynote" },
{ id: "3", time: "11:00", title: "Panel: Future Cities" },
]}
/>;Item shape — what's required
id,time,title— required.endTime— optional. When present, time renders as{time}{separator}{endTime}(default separator" - ", configurable vialabels.timeRangeSeparator).description— optional. Description block omitted when missing.icon— optional Lucide-style component (ComponentType<{ className?: string }>). When present, sits left of the time column.href— optional. When present +linkComponentprovided, the entire row becomes clickable via the overlay-link pattern.
Frame toggle
Default framed: true — each row gets card chrome (bg-card rounded-xl border) and rows are spaced space-y-4. Pass framed={false} for bare rows in dense contexts (sidebars, widgets) — chrome dropped, rows tighten to space-y-2.
Custom rendering
renderItem(item)— bypass the default row layout entirely. Useful for embedding speaker avatars, status badges, per-item actions.renderTime(item)— bypass the default time string renderer (e.g. transform "09:00" → "9:00 AM"). Used inside the default row layout whenrenderItemis not supplied.
Polymorphic root
import NextLink from "next/link";
<ScheduleList
heading="Conference Day 1"
items={items.map((item) => ({ ...item, href: `/talks/${item.id}` }))}
linkComponent={NextLink}
/>;Empty state
When items is empty, the component renders emptyState (if provided) OR a <p role="status"> with labels.emptyText(default "No items scheduled.").
Notes
- Renders semantic
<ol role="list">— schedules ARE ordered. - Section
aria-labelledbyresolves to the heading id (computed viauseId) — only whenheadingis supplied. - Decorative icons get
aria-hidden="true"; link's accessible name is the item title. - All hover transitions gated via
motion-safe:— reduced-motion users see static rows.
Features
- Vertical schedule list — time + title + optional description per row
- Optional time range (start - end), separator localizable
- Optional Lucide-style icon per row
- Polymorphic per-row link via linkComponent + per-item href
- Frame toggle (framed=true card chrome / framed=false bare rows)
- Custom renderItem + renderTime slots
- Optional section heading with configurable level (h2/h3/h4)
- Soft-failure on optional fields (description / icon / endTime / href)
- i18n via labels object
- Semantic <ol role='list'> — schedules are ordered
- Empty state slot with labels fallback