5
Sponsor

General

Timeline rendered with email-safe, renderer-native components.

import { Timeline } from "@/components/email/timeline";
import { defaultTheme } from "@/components/email/theme-default";

export function TimelineDemo() {
  return (
    <Timeline
      layout="line"
      alignment="left"
      appearance="basic"
      theme={{ ...defaultTheme, containerWidth: "640px" }}
    />
  );
}

Installation

$ pnpm dlx shadcn@latest add @emailcn/react-email/timeline

Usage

import { Timeline } from "@/components/email/timeline";
<Timeline layout="line" alignment="left" appearance="basic" />

Examples

Cards timeline

default

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutCardsVariantDefaultExampleDemo() {
  return <Timeline layout="cards" variant="default" />;
}

with-accent

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutCardsVariantWithAccentExampleDemo() {
  return <Timeline layout="cards" variant="with-accent" />;
}

with-badge

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutCardsVariantWithBadgeExampleDemo() {
  return <Timeline layout="cards" variant="with-badge" />;
}

image-top

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutCardsVariantImageTopExampleDemo() {
  return <Timeline layout="cards" variant="image-top" />;
}

image-bottom

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutCardsVariantImageBottomExampleDemo() {
  return <Timeline layout="cards" variant="image-bottom" />;
}

Changelog

muted-left

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutLineVariantMutedLeftItemsExampleDemo() {
  return (
    <Timeline
      layout="line"
      variant="muted-left"
      items={[{ title: "Initial release", version: "v1.0" }]}
    />
  );
}

muted-right

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutLineVariantMutedRightItemsExampleDemo() {
  return (
    <Timeline
      layout="line"
      variant="muted-right"
      items={[{ title: "Initial release", version: "v1.0" }]}
    />
  );
}

basic-left

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutLineVariantBasicLeftItemsExampleDemo() {
  return (
    <Timeline
      layout="line"
      variant="basic-left"
      items={[{ title: "Initial release", version: "v1.0" }]}
    />
  );
}

basic-right

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutLineVariantBasicRightItemsExampleDemo() {
  return (
    <Timeline
      layout="line"
      variant="basic-right"
      items={[{ title: "Initial release", version: "v1.0" }]}
    />
  );
}

accent-left

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutLineVariantAccentLeftItemsExampleDemo() {
  return (
    <Timeline
      layout="line"
      variant="accent-left"
      items={[{ title: "Initial release", version: "v1.0" }]}
    />
  );
}

accent-right

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutLineVariantAccentRightItemsExampleDemo() {
  return (
    <Timeline
      layout="line"
      variant="accent-right"
      items={[{ title: "Initial release", version: "v1.0" }]}
    />
  );
}

Changelog boxed

muted-left

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutBoxedVariantMutedLeftItemsExampleDemo() {
  return (
    <Timeline
      layout="boxed"
      variant="muted-left"
      items={[{ title: "Initial release", version: "v1.0" }]}
    />
  );
}

muted-right

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutBoxedVariantMutedRightItemsExampleDemo() {
  return (
    <Timeline
      layout="boxed"
      variant="muted-right"
      items={[{ title: "Initial release", version: "v1.0" }]}
    />
  );
}

basic-left

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutBoxedVariantBasicLeftItemsExampleDemo() {
  return (
    <Timeline
      layout="boxed"
      variant="basic-left"
      items={[{ title: "Initial release", version: "v1.0" }]}
    />
  );
}

basic-right

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutBoxedVariantBasicRightItemsExampleDemo() {
  return (
    <Timeline
      layout="boxed"
      variant="basic-right"
      items={[{ title: "Initial release", version: "v1.0" }]}
    />
  );
}

accent-left

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutBoxedVariantAccentLeftItemsExampleDemo() {
  return (
    <Timeline
      layout="boxed"
      variant="accent-left"
      items={[{ title: "Initial release", version: "v1.0" }]}
    />
  );
}

accent-right

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutBoxedVariantAccentRightItemsExampleDemo() {
  return (
    <Timeline
      layout="boxed"
      variant="accent-right"
      items={[{ title: "Initial release", version: "v1.0" }]}
    />
  );
}

Split cards

muted

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutSplitVariantMutedExampleDemo() {
  return <Timeline layout="split" variant="muted" />;
}

muted-reverse

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutSplitVariantMutedReverseExampleDemo() {
  return <Timeline layout="split" variant="muted-reverse" />;
}

boxed

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutSplitVariantBoxedExampleDemo() {
  return <Timeline layout="split" variant="boxed" />;
}

boxed-reverse

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutSplitVariantBoxedReverseExampleDemo() {
  return <Timeline layout="split" variant="boxed-reverse" />;
}

accent

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutSplitVariantAccentExampleDemo() {
  return <Timeline layout="split" variant="accent" />;
}

accent-reverse

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutSplitVariantAccentReverseExampleDemo() {
  return <Timeline layout="split" variant="accent-reverse" />;
}

image-top

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutSplitVariantImageTopExampleDemo() {
  return <Timeline layout="split" variant="image-top" />;
}

image-top-reverse

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutSplitVariantImageTopReverseExampleDemo() {
  return <Timeline layout="split" variant="image-top-reverse" />;
}

image-bottom

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutSplitVariantImageBottomExampleDemo() {
  return <Timeline layout="split" variant="image-bottom" />;
}

image-bottom-reverse

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutSplitVariantImageBottomReverseExampleDemo() {
  return <Timeline layout="split" variant="image-bottom-reverse" />;
}

Stacked timeline

line muted-left

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutLineVariantMutedLeftExampleDemo() {
  return <Timeline layout="line" variant="muted-left" />;
}

line muted-right

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutLineVariantMutedRightExampleDemo() {
  return <Timeline layout="line" variant="muted-right" />;
}

line basic-left

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutLineAlignmentLeftAppearanceBasicExampleDemo() {
  return <Timeline layout="line" alignment="left" appearance="basic" />;
}

line basic-right

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutLineVariantBasicRightExampleDemo() {
  return <Timeline layout="line" variant="basic-right" />;
}

line completed-left

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutLineVariantCompletedLeftExampleDemo() {
  return <Timeline layout="line" variant="completed-left" />;
}

line completed-right

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutLineVariantCompletedRightExampleDemo() {
  return <Timeline layout="line" variant="completed-right" />;
}

boxed muted-left

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutBoxedVariantMutedLeftExampleDemo() {
  return <Timeline layout="boxed" variant="muted-left" />;
}

boxed muted-right

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutBoxedVariantMutedRightExampleDemo() {
  return <Timeline layout="boxed" variant="muted-right" />;
}

boxed basic-left

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutBoxedVariantBasicLeftExampleDemo() {
  return <Timeline layout="boxed" variant="basic-left" />;
}

boxed basic-right

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutBoxedVariantBasicRightExampleDemo() {
  return <Timeline layout="boxed" variant="basic-right" />;
}

boxed accent-left

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutBoxedVariantAccentLeftExampleDemo() {
  return <Timeline layout="boxed" variant="accent-left" />;
}

boxed accent-right

import { Timeline } from "@/components/email/timeline";

export function TimelineLayoutBoxedVariantAccentRightExampleDemo() {
  return <Timeline layout="boxed" variant="accent-right" />;
}

API Reference

PropTypeDefaultDescription
themeEmailThemedefaultThemeRenderer theme configuration.
itemsArray<{ index?: string; label?: string; date?: string; version?: string; category?: string; badge?: string; title: string; description?: string; image?: { src: string; alt?: string }; completed?: boolean }>-Configures the component's items.
layout"line" | "boxed" | "cards" | "split""line"Configures the component's layout.
alignment"left" | "right""left"Configures the component's alignment.
appearance"muted" | "basic" | "accent""basic"Configures the component's appearance.
reversebooleanfalseConfigures the component's reverse.
variant"default" | "with-badge" | "with-accent" | "image-top" | "image-bottom" | "muted-left" | "muted-right" | "basic-left" | "basic-right" | "accent-left" | "accent-right" | "muted" | "muted-reverse" | "boxed" | "boxed-reverse" | "accent" | "accent-reverse" | "image-top-reverse" | "image-bottom-reverse" | "completed-left" | "completed-right"Derived from the other propsSelects an exact legacy composition when needed.