Activity Feed
Show recent events by people with avatars, times and attachments.
This example installs with a Siteplane UI Pro license key.
Get a license on the Pro page.
pnpm dlx shadcn@4.18.0 add @siteplane-pro/activity-feed-demoThis Pattern is part of Siteplane UI Pro, and its source comes with a Pro license. Its previews are free to view and try.
Installation
pnpm dlx shadcn@4.18.0 add @siteplane-pro/activity-feedUsage
import {
ActivityFeed,
ActivityFeedItem,
} from "@/siteplane/components/activity-feed";
<ActivityFeed aria-label="Project activity">
<ActivityFeedItem
actor={{ name: "Mara Ellis" }}
description="Added a file to Website redesign"
timestamp="Just now"
/>
</ActivityFeed>;Composition
ActivityFeed
└── ActivityFeedItem
├── ActivityFeedLink (in the description)
├── ActivityFeedAttachment
├── ActivityFeedMessage
└── your own content, such as labelsThe feed separates its items with a divider by default. Each item shows the portrait, the name and the time, then the description. An actor.href links the name and, for pointer users, the portrait to the same destination; the portrait stays out of the tab order, so keyboard and screen-reader users meet one link per person. Without avatarUrl the portrait shows initials taken from the name.
status adds the presence dot of Avatar to the portrait, as online, away, busy or offline. The dot is named for assistive technology by statusLabel, or else by the English status name. unreadLabel adds an unread marker with that text as its accessible name. Anything passed as children appears below the description, such as attachments, a message or your own content.
Connected layout
Set variant="connected" to draw a line through the portraits. It suits events that follow one another, such as the history of a task.
This example installs with a Siteplane UI Pro license key.
Get a license on the Pro page.
pnpm dlx shadcn@4.18.0 add @siteplane-pro/activity-feed-connected-exampleSpaced layout
Set variant="spaced" to separate the items with space only, for a lighter feed inside a card or a sheet.
This example installs with a Siteplane UI Pro license key.
Get a license on the Pro page.
pnpm dlx shadcn@4.18.0 add @siteplane-pro/activity-feed-spaced-exampleMessages
ActivityFeedMessage sets what a person wrote in a bordered message surface below the name. Use the description for a short line such as a handle. Messages work in all three layouts, and an attachment can follow a message.
This example installs with a Siteplane UI Pro license key.
Get a license on the Pro page.
pnpm dlx shadcn@4.18.0 add @siteplane-pro/activity-feed-messages-exampleAPI reference
| Prop | Type | Default | Description |
|---|---|---|---|
Activity | ActivityFeedVariant: divided | connected | spaced | divided | Layout of the items: a divider between them, a line through the portraits, or space only. |
Activity | string | Activity feed | Accessible name of the list. Replace it with a name that fits the feed. |
Activity | { name, href?, avatarUrl?, initials? } | required | The person. name is shown before the time, href links the name and the portrait, avatarUrl sets the portrait image and initials replace the ones taken from the name. |
Activity | ReactNode | required | Visible time of the event. |
Activity | string | unset | Machine-readable time. With it the timestamp is a time element; without it, a plain span. |
Activity | ReactNode | unset | What happened, such as a sentence with an ActivityFeedLink. |
Activity | online | away | busy | offline | unset | Avatar's presence dot on the portrait. |
Activity | string | English status name | Accessible name of the dot. |
Activity | { state: online | offline; label: string } | unset | Deprecated: the earlier form of status and statusLabel, which it maps to. Use status and statusLabel. |
Activity | string | unset | Shows an unread marker. The text is its accessible name. |
Activity | ReactNode | unset | Content below the description, such as attachments, labels or a message. |
Activity | string | required | File name, also used to choose the file type icon. |
Activity | string | from fileName | Extension for the icon when it differs from the file name, for example for files without a suffix. |
Activity | ReactNode | unset | Secondary line, such as the file size. |
ActivityFeedProps extends native ol props, ActivityFeedItemProps native li props except the animation and drag handlers, which belong to the motion, ActivityFeedLink native anchor props, ActivityFeedMessage native div props and ActivityFeedAttachmentProps native figure props. All accept refs and string className, and all but ActivityFeedAttachment take children: the attachment renders its file icon, name and metadata itself. ActivityFeedLink renders an inline link button and ActivityFeedMessage sets its children in a Card with the message variant.
Usage notes
The feed is an ordered list of articles. Pass the items newest first and give the list an aria-label that names it. Pass dateTime so the timestamp becomes a time element with a machine-readable value; without it, the timestamp is plain text.
The feed does not sort, group by day, paginate, virtualize or announce new items. For a long or live feed, add these in the application and announce new entries with your own live region.
Entries that are added or removed animate on their own. A new entry expands and fades in, and a removed one fades out and collapses; the divider or the connecting line opens and closes with it while the other entries glide. Give every ActivityFeedItem a stable key, because an index as the key makes a removed entry leave as its neighbor, and pass the entries as direct children of the feed, not inside a fragment. A leaving entry is inert, so move focus before you remove one that holds it. With reduced motion, from the system setting or SiteplaneMotionProvider preset="reduced", every change is instant.
Status dots and unread markers are indicators only. An attachment shows the file and does not link or download it, so add a link or a button beside it when people need to open the file.