Skip to content
View as Markdown

Timeline ​

Timeline provides composable primitives for building time-based layouts such as Gantt charts, schedules, and project timelines. It is a compound component with five sub-components: Root, Viewport, Row, Interval, and Link.

Import ​

tsx
import { Timeline } from "@tailor-platform/app-shell";

Basic Usage ​

tsx
import { Timeline } from "@tailor-platform/app-shell";

<Timeline.Root start={0} end={100}>
  <Timeline.Viewport
    axis={{
      guides: [{ at: 0 }, { at: 50 }, { at: 100 }],
      levels: [
        {
          kind: "spans",
          items: [
            { start: 0, end: 50, label: "Phase 1" },
            { start: 50, end: 100, label: "Phase 2" },
          ],
        },
      ],
    }}
  >
    <Timeline.Row height={40}>
      <Timeline.Interval start={10} end={35}>
        <div className="h-full rounded-md bg-primary" />
      </Timeline.Interval>
    </Timeline.Row>
  </Timeline.Viewport>
</Timeline.Root>;

Sub-components ​

Sub-componentDescription
Timeline.RootProvides the shared time range for all nested timeline primitives
Timeline.ViewportRenders the axis, decorations, scrolling area, and link overlay layer
Timeline.RowDefines one horizontal lane with a fixed height and optional background
Timeline.IntervalPositions content across a time range inside a row
Timeline.LinkDraws an orthogonal dependency connector between two named Interval elements

TimeValue ​

All time position props (start, end, at) accept either a Date object or a millisecond-precision number timestamp.

tsx
// Using Date objects
<Timeline.Root start={new Date("2024-01-01")} end={new Date("2024-12-31")}>

// Using numeric timestamps
<Timeline.Root start={0} end={100}>

Props ​

Timeline.Root Props ​

PropTypeDefaultDescription
startDate | number—Inclusive start of the overall timeline range
endDate | number—Inclusive end of the overall timeline range
childrenReact.ReactNode—Timeline subtree, usually a Timeline.Viewport
classNamestring—Additional CSS classes applied to the root element
styleCSSProperties—Inline style applied to the root element

Timeline.Viewport Props ​

PropTypeDefaultDescription
childrenReact.ReactNode—Rows and links, in any order
axisTimelineAxis—Axis configuration: guides and stacked header levels
decorationsTimelineDecorations—Decorative layers: bands and markers
linkDefaultsTimelineLinkDefaults—Shared defaults applied to all Timeline.Link nodes in this viewport
canvasWidthnumber—Fixed canvas width in pixels for horizontally scrollable timelines
stickyAxisbooleanfalsePins the axis to the top of the viewport during vertical scrolling
classNamestring—Additional CSS classes applied to the scroll viewport
styleCSSProperties—Inline style applied to the scroll viewport

Timeline.Row Props ​

PropTypeDefaultDescription
childrenReact.ReactNode—Row contents, typically Timeline.Interval elements
heightnumber32Row height in pixels
backgroundTimelineRowBackground | null—Optional background rendered in a dedicated layer, in front of bands but behind guide lines
classNamestring—Additional CSS classes applied to the row content container
styleCSSProperties—Inline style applied to the row content container

Timeline.Interval Props ​

PropTypeDefaultDescription
startDate | number—Start of the interval
endDate | number—End of the interval
childrenReact.ReactNode—Rendered content for the interval
idstring—Stable id used by Timeline.Link to reference this interval
insetYnumber0Top and bottom inset in pixels within the row
classNamestring—Additional CSS classes applied to the positioned interval container
styleCSSProperties—Inline style applied to the positioned interval container
PropTypeDefaultDescription
fromstring—Source Timeline.Interval id
tostring—Target Timeline.Interval id
fromAnchor"start" | "center" | "end""end"Source anchor used for routing
toAnchor"start" | "center" | "end""start"Target anchor used for routing
arrowboolean—Overrides the viewport-level linkDefaults.arrow
gapnumber—Overrides the viewport-level linkDefaults.gap
strokeWidthnumber—Optional stroke width for the link path
classNamestring—Additional CSS classes applied to the link SVG
styleCSSProperties—Inline style applied to the link SVG

Type Reference ​

TimelineAxis ​

Axis configuration for Timeline.Viewport.

FieldTypeDescription
guidesTimelineGuide[]Vertical boundary lines rendered in the axis and body
levelsTimelineAxisLevel[]Stacked header levels rendered above the body
classNamestringOptional class applied to the axis container

TimelineAxisLevel ​

A stacked axis level. Has a discriminated union kind field:

  • kind: "spans" — renders labeled time ranges (TimelineAxisSpan[])
  • kind: "ticks" — renders labeled point-in-time markers (TimelineAxisTick[])
FieldTypeDefaultDescription
kind"spans" | "ticks"—Level rendering mode
itemsTimelineAxisSpan[] | TimelineAxisTick[]—Items to render in this level
heightnumber28Height of this axis level in pixels
classNamestring—Optional class applied to the level container

TimelineGuide ​

A vertical guide line rendered in both the axis and the body.

FieldTypeDescription
atDate | numberTime position for the guide line
keyReact.KeyOptional stable React key
axisClassNamestringOptional class for the axis portion of the guide
axisStyleCSSPropertiesOptional style for the axis portion of the guide
bodyClassNamestringOptional class for the body portion of the guide
bodyStyleCSSPropertiesOptional style for the body portion of the guide

TimelineDecorations ​

Decorative layers rendered by Timeline.Viewport.

FieldTypeDescription
bandsTimelineBand[]Background range highlights rendered behind rows
markersTimelineMarker[]Vertical markers rendered in the axis and/or body

TimelineBand ​

A decorative horizontal band rendered behind rows.

FieldTypeDescription
startDate | numberStart of the band
endDate | numberEnd of the band
keyReact.KeyOptional stable React key
colorstringOptional background color convenience prop
classNamestringOptional class applied to the band element
styleCSSPropertiesOptional inline style applied to the band

TimelineMarker ​

A decorative vertical marker line.

FieldTypeDefaultDescription
atDate | number—Time position for the marker
keyReact.Key—Optional stable React key
colorstring—Optional line color convenience prop
labelReact.ReactNode—Optional marker label
placement"axis" | "body" | "both""body"Controls where the marker is rendered
classNamestring—Optional class applied to the outer marker wrapper
lineClassNamestring—Optional class applied to the marker line
labelClassNamestring—Optional class applied to the marker label

TimelineLinkDefaults ​

Shared defaults for all Timeline.Link nodes inside one viewport.

FieldTypeDefaultDescription
routing"orthogonal""orthogonal"Link routing strategy
arrowbooleantrueWhether links end with an arrow marker
gapnumber16Horizontal gap in px used when routing out of/into items
strokeWidthnumber—Optional default stroke width for link paths
classNamestring—Optional class applied to each link SVG
styleCSSProperties—Optional style applied to each link SVG

TimelineRowBackground ​

Background content for a row rendered in a dedicated layer (in front of bands, behind guides).

FieldTypeDescription
classNamestringOptional class applied to the background layer element
styleCSSPropertiesOptional style applied to the background layer element

Examples ​

Horizontal Scrolling ​

Use canvasWidth on Timeline.Viewport to enable horizontal scrolling:

tsx
<Timeline.Root start={projectStart} end={projectEnd}>
  <Timeline.Viewport canvasWidth={2400} axis={axis}>
    {rows}
  </Timeline.Viewport>
</Timeline.Root>

Sticky Axis ​

Pin the axis to the top during vertical scrolling with stickyAxis:

tsx
<Timeline.Root start={0} end={100}>
  <Timeline.Viewport stickyAxis axis={axis}>
    {rows}
  </Timeline.Viewport>
</Timeline.Root>

Use id on Timeline.Interval and Timeline.Link to draw dependency connectors:

tsx
<Timeline.Root start={0} end={100}>
  <Timeline.Viewport
    linkDefaults={{ style: { color: "var(--muted-foreground)" }, strokeWidth: 1.5 }}
  >
    <Timeline.Row height={40}>
      <Timeline.Interval id="task-a" start={10} end={40}>
        <div className="h-full rounded-md bg-primary" />
      </Timeline.Interval>
    </Timeline.Row>
    <Timeline.Row height={40}>
      <Timeline.Interval id="task-b" start={50} end={80}>
        <div className="h-full rounded-md bg-secondary" />
      </Timeline.Interval>
    </Timeline.Row>
    <Timeline.Link from="task-a" to="task-b" />
  </Timeline.Viewport>
</Timeline.Root>

Background Bands and Markers ​

Use decorations to add background highlights and vertical marker lines:

tsx
<Timeline.Viewport
  axis={axis}
  decorations={{
    bands: [
      {
        start: freezeStart,
        end: freezeEnd,
        color: "var(--destructive/10)",
        className: "border-x border-destructive/30",
      },
    ],
    markers: [
      {
        at: today,
        color: "var(--primary)",
        label: <span className="text-xs text-primary">Today</span>,
      },
    ],
  }}
>
  {rows}
</Timeline.Viewport>

Row Background ​

Use background on Timeline.Row to apply a background that respects guide lines:

tsx
<Timeline.Row height={40} background={{ style: { background: "var(--muted)" } }}>
  <Timeline.Interval start={10} end={35}>
    <div className="h-full rounded-md bg-primary" />
  </Timeline.Interval>
</Timeline.Row>