Dots

Status Timeline

Vertical steps of a process with done, current, pending and failed states.

  1. Transfer created, Completed
  2. Money sent, Completed
  3. Bank is processing, In progress
    Usually takes up to 2 hours
    Now
  4. Received by Maya Chen, Not started
import { Card, CardContent } from "@/components/ui/card"
import {
  StatusTimeline,

Use a status timeline to show where a process stands, such as a transfer, a refund, a card order or an identity check. A thin rail with dots is filled up to the last finished step, and each step can carry a time, a detail and an action. Keep it to about five steps on a card or sheet. Pick a progress bar when only the share done matters, and a list of transactions when the steps are separate events.

Installation

pnpm dlx shadcn@latest add @dots/status-timeline

Usage

import {
  StatusTimeline,
  StatusTimelineItem,
} from "@/components/ui/status-timeline"
<StatusTimeline aria-label="Transfer status">
  <StatusTimelineItem status="done" title="Money sent" time="11:44 PM" />
  <StatusTimelineItem status="current" title="Bank is processing" time="Now" />
  <StatusTimelineItem status="pending" title="Received" />
</StatusTimeline>

Composition

StatusTimeline
└── StatusTimelineItem
    ├── title
    ├── description
    ├── children
    └── time

Features

  • Four statuses: done, current, pending and failed
  • A rail filled up to the last finished step
  • A cross on a failed step, so it reads without color
  • A warning tone for a current step that waits on the user
  • The status of each step is read as text by screen readers
  • Times as <time> elements when you pass dateTime
  • A denser sm size for cards and sheets

Waiting for the user

Set tone="warning" on the current step when the user has to act, and say so in statusLabel. Put the action in the step's children.

  1. Documents uploaded, Completed
  2. Selfie needed, Waiting for you
    The photo was blurry. Take a new one in good light.
  3. Review, Not started
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
import {

Failed

Set status="failed" on the step where the process stopped. Use the description for the reason and what to do next.

  1. Refund requested, Completed
    $48.20 from Coffee Point
  2. Merchant declined, Failed
    The merchant says the order was delivered. You can open a dispute.
  3. Money returned, Not started
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
import {

Small

Use size="sm" for a denser list inside a card or sheet.

  1. Ordered, Completed
    Oct 30
  2. Printed, Completed
    Nov 2
  3. On the way, In progress
    Arrives Nov 14 to 16
  4. Activated, Not started
import {
  StatusTimeline,
  StatusTimelineItem,

Accessibility

StatusTimeline is an ordered list, and the current step has aria-current="step". The dot and the rail are decorative. Each title is followed by its status in visually hidden text: "Completed", "In progress", "Not started" or "Failed".

Name the timeline

Give the timeline an aria-label that says what process it tracks.

<StatusTimeline aria-label="Refund status">{/* steps */}</StatusTimeline>

Say what is expected

When a step waits on the user, override the spoken status with statusLabel so it is not just "In progress".

<StatusTimelineItem
  status="current"
  tone="warning"
  statusLabel="Waiting for you"
  title="Selfie needed"
/>

Machine-readable time

Pass dateTime with an ISO date so the short time is rendered as a <time> element.

API Reference

StatusTimeline

The list of steps. Renders an ol and accepts all of its props.

PropTypeDefaultDescription
size"default" | "sm""default"sm is denser, for cards and sheets.
aria-labelstring-What process the timeline tracks.
classNamestring-Additional classes to apply to the list.

StatusTimelineItem

One step. Renders an li and accepts all of its props except title.

PropTypeDefaultDescription
titleReact.ReactNode-What the step is, such as "Payment sent". Required.
status"done" | "current" | "pending" | "failed""pending"Whether the step has passed, is in progress, is ahead or stopped here.
descriptionReact.ReactNode-A detail, how long to wait, or for a failed step the reason.
timeReact.ReactNode-Short time on the right, such as "11:44 PM" or "Now".
dateTimestring-Machine-readable time. When set, time is rendered as a <time> element.
tone"default" | "warning""default"warning marks a current step that waits on the user. Current step only.
statusLabelstring-Overrides the status read by screen readers, such as "Waiting for you".
childrenReact.ReactNode-Extra content under the description, such as a button.
classNamestring-Additional classes to apply to the step.