Timeline
Vertical timeline for events, order tracking, and activity feeds.
Installation#
npx @aniui/cli add timeline✓
Order confirmedMon 9:00 AM
Your order #4821 has been placed
✓
Payment receivedMon 9:01 AM
Visa ending in 4242
Preparing shipmentTue 11:30 AM
Warehouse is packing your items
In transitPending
Estimated delivery Wed
DeliveredPending
Package will arrive at your door
Web preview — components render natively on iOS & Android
import { Timeline, TimelineItem } from "@/components/ui/timeline";
export function MyScreen() {
return (
<Timeline>
<TimelineItem
title="Order placed"
description="Your order has been confirmed"
time="2:00 PM"
variant="success"
/>
<TimelineItem
title="Processing"
description="Your order is being prepared"
time="2:15 PM"
variant="default"
/>
<TimelineItem
title="Shipping"
description="Waiting for pickup"
time="Pending"
variant="muted"
isLast
/>
</Timeline>
);
}Usage#
app/index.tsx
import { Timeline, TimelineItem } from "@/components/ui/timeline";
export function MyScreen() {
return (
<Timeline>
<TimelineItem
title="Order placed"
description="Your order has been confirmed"
time="2:00 PM"
variant="success"
/>
<TimelineItem
title="Processing"
description="Your order is being prepared"
time="2:15 PM"
variant="default"
/>
<TimelineItem
title="Shipping"
description="Waiting for pickup"
time="Pending"
variant="muted"
isLast
/>
</Timeline>
);
}Props#
Timeline#
PropTypeDefault
classNamestring-childrenReact.ReactNode-TimelineItem#
PropTypeDefault
titlestring-descriptionstring-timestring-variant"default" | "success" | "destructive" | "muted""default"iconReact.ReactNode-isLastbooleanfalseclassNamestring-Accessibility#
- Vertical event timeline with
accessibilityRole="list". - Each timeline item is announced as a list item with its content.
Source#
components/ui/timeline.tsx
import React from "react";
import { View, Text } from "react-native";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
export interface TimelineProps extends React.ComponentPropsWithoutRef<typeof View> {
className?: string;
children?: React.ReactNode;
}
export function Timeline({ className, children, ...props }: TimelineProps) {
return (
<View className={cn("gap-0", className)} accessibilityRole="list" {...props}>
{children}
</View>
);
}
const dotVariants = cva("h-3 w-3 rounded-full z-10", {
variants: {
variant: {
default: "bg-primary",
success: "bg-green-500",
destructive: "bg-destructive",
muted: "bg-muted-foreground",
},
},
defaultVariants: { variant: "default" },
});
export interface TimelineItemProps
extends React.ComponentPropsWithoutRef<typeof View>,
VariantProps<typeof dotVariants> {
className?: string;
title: string;
description?: string;
time?: string;
icon?: React.ReactNode;
isLast?: boolean;
}
export function TimelineItem({
variant,
className,
title,
description,
time,
icon,
isLast,
...props
}: TimelineItemProps) {
return (
<View className={cn("flex-row", className)} accessibilityRole="listitem" {...props}>
<View className="items-center mr-3">
{icon ?? <View className={dotVariants({ variant })} />}
{!isLast && <View className="flex-1 w-0.5 bg-border mt-1" />}
</View>
<View className={cn("flex-1 pb-6", isLast && "pb-0")}>
<View className="flex-row items-center justify-between">
<Text className="text-sm font-medium text-foreground">{title}</Text>
{time && <Text className="text-xs text-muted-foreground">{time}</Text>}
</View>
{description && (
<Text className="text-sm text-muted-foreground mt-1">{description}</Text>
)}
</View>
</View>
);
}