Timeline chart

Free · MIT

Mini 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.

MarkdownOpen in v0
Open in v0

Installation

$ npx shadcn@latest add https://goodui.dev/r/timeline-chart.json

The 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

Use it for
  • 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.
Reach for something else
  • 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 needUse
Launch plan over weeksrows with group, from/to spanning the plan, today
This week's sprinta 7-day from/to (day ticks) with rowHeight={32}
A date with no durationmilestone: true (diamond on start)
Progressprogress: 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

PropTypeDefault
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—
rowHeightnumber36
labelWidth
Width of the label column in px.
number128
weekStart
First weekday for week ticks: 1 Monday (default) or 0 Sunday.
0 | 11
localestring"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.
number0.9
labels
Text for built-in controls and screen readers; pass translations here.
Partial<TimelineChartLabels>—

Also accepts every <div> attribute.

Accessibility

TabFocuses the timeline and highlights the first row.
ArrowUp / ArrowDownPrevious or next row (Left/Right work too).
Home / EndFirst or last row.
EscapeClears 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