Timeline chart
Free · MITMini Gantt whose bars grow from their start date on view, with progress fills, milestones, group headers, day / week / month ticks, a today marker and arrow-key rows.
Installation
$ npx shadcn@latest add https://goodui.dev/r/timeline-chart.jsonThe file lands in components/goodui/timeline-chart.tsx and is yours to edit. With the @goodui registry added, npx shadcn@latest add @goodui/timeline-chart works too.
Usage
import { TimelineChart } from "@/components/goodui/timeline-chart"
export function LaunchPlan() {
return (
<TimelineChart
title="Launch plan"
from="2026-10-19"
to="2026-11-30"
today="2026-11-03"
rows={[
{ label: "Booking flow redesign", start: "2026-10-20", end: "2026-11-03", progress: 1, group: "Product" },
{ label: "Deposit payments", start: "2026-10-29", end: "2026-11-12", progress: 0.55, group: "Product" },
{ label: "Launch", start: "2026-11-26", milestone: true, group: "Product" },
{ label: "Landing page", start: "2026-10-26", end: "2026-11-06", progress: 0.8, group: "Marketing" },
]}
/>
)
}When to use
- A plan or roadmap with a handful of tasks: launch plans, sprints, onboarding timelines, campaign calendars.
- Showing progress inside each task bar and where today falls.
- Grouped work (Product / Marketing) with milestones.
- Interactive scheduling (drag to move, dependencies): use a scheduler block.
- Hundreds of rows or many months: a table with dates, or a dedicated Gantt tool.
- Time-of-day bookings: use the scheduler's day view.
| If you need | Use |
|---|---|
| Launch plan over weeks | rows with group, from/to spanning the plan, today |
| This week's sprint | a 7-day from/to (day ticks) with rowHeight={32} |
| A date with no duration | milestone: true (diamond on start) |
| Progress | progress: 0..1 (prints the percentage when the bar is wide enough) |
Examples
One week, day ticks
<TimelineChart title="This week" rows={sprint} from="2026-11-02" to="2026-11-09" today="2026-11-03" rowHeight={32} labelWidth={112} />API reference
| Prop | Type | Default |
|---|---|---|
| rows* | TimelineRow[] | — |
| title Chart name for screen readers and the table caption. | React.ReactNode | — |
| from First day shown (ISO). Defaults to the earliest start, minus a day. | string | — |
| to Last day shown (ISO). Defaults to the latest end, plus a day. | string | — |
| today ISO date of the today marker. Pass it in (no clock is read during render). | string | — |
| rowHeight | number | 36 |
| labelWidth Width of the label column in px. | number | 128 |
| weekStart First weekday for week ticks: 1 Monday (default) or 0 Sunday. | 0 | 1 | 1 |
| locale | string | "en-US" |
| formatDate Formats dates for the tooltip and screen readers. | (date: Date) => string | — |
| duration Seconds a bar takes to grow; bars stagger by 60 ms. | number | 0.9 |
| labels Text for built-in controls and screen readers; pass translations here. | Partial<TimelineChartLabels> | — |
Also accepts every <div> attribute.
Accessibility
| Tab | Focuses the timeline and highlights the first row. |
| ArrowUp / ArrowDown | Previous or next row (Left/Right work too). |
| Home / End | First or last row. |
| Escape | Clears the highlight. |
- The timeline is role="group" with aria-roledescription="timeline" and a summary ("Launch plan: 7 rows from Oct 19 to Nov 30").
- A screen-reader-only table lists task, start, end and progress for every row.
- The highlighted row is announced as "<task>: Oct 29 to Nov 12, 15 days, 55%" through a polite live region and shown in a tooltip.
- Labels live in their own column and are never clipped by the bars; progress percentages print inside bars only when they fit.
- The time axis is always left-to-right (dir="ltr" on the track) while labels and headers follow the page direction.
Motion
- On first view bars scale out from their start date over duration (0.9 s, ease [0.16, 1, 0.3, 1]), 60 ms apart in row order; milestones pop on a spring (stiffness 420, damping 22).
- Hovering or arrowing to a row tints the row with the muted surface.
- Reduced motion: bars and milestones appear at once.
- Plain DOM: one positioned div per bar and per tick line; the only animated properties are transform and opacity.
Notes for AI
Coding agents read these rules through MCP and llms.txt, or paste this page with Copy page.
- Dates are ISO strings parsed in local time; end is inclusive (a Nov 2 to Nov 4 task spans three days). Pass today explicitly; the component never reads the clock during render.
- from/to default to the data range padded by a day; set them to align several timelines.
- Ticks are days (≤ 3 weeks), week starts (≤ ~4 months) or month starts, thinned until labels have 44px.
- Colors default to --chart-1 … --chart-5 per group; set row.color to override.
FAQ
Can bars be dragged?
No; this is a read-only chart. Use the scheduler block for editing.
How are the ticks chosen?
By the span: days up to three weeks, Mondays (or Sundays with weekStart={0}) up to about four months, then the first of each month.
Related
Calendar (GitHub-style) or matrix heatmap on one hue with cells that pop in column by column, a tooltip, arrow-key navigation that scrolls the calendar along, and a Less–More scale.
Grouped, stacked or horizontal bars that grow from the baseline on view and morph when data changes, with a gliding hover band, legend toggles, value labels and 2px surface gaps between segments.
Horizontal or vertical stepper where the connecting line fills between steps, numbers morph into drawn checkmarks, a current-step ring glides to the active step, errors shake, and completed steps are clickable.