Activity Feed
Admin activity feed compound — vertical ordered list of timestamped events for dashboards, audit logs, and notification views. ActivityFeed + ActivityFeedItem with leading, title, description, actor, timestamp, and trailing slots. Default, compact, and timeline variants. Built with CSS Modules and React Context — copy it into your project and own it completely.
Basic
- Profile published
- Profile edited
- Profile archived
With Description and Actor
- Profile publishedJustin
All checks passed and the profile is now live.
- Profile editedAlex
Updated bio and avatar photo.
With Trailing Meta
- Profile publishedJustinLive
- Import failedSystemError
Compact Variant
- user.loginjustin@example.com
- record.updatealex@example.com
- record.deletesystem
Timeline Variant
- Build started
- Tests passed
- Deployed to staging
- Promoted to production
Installation
npx visor add activity-feedThis copies two files into your project:
components/ui/activity-feed/activity-feed.tsx— the componentcomponents/ui/activity-feed/activity-feed.module.css— the styles
Usage
import {
ActivityFeed,
ActivityFeedItem,
} from '@/components/ui/activity-feed/activity-feed';
export default function Example() {
return (
<ActivityFeed aria-label="Recent activity">
<ActivityFeedItem
title="Profile published"
actor="Justin"
timestamp="2m ago"
/>
<ActivityFeedItem
title="Profile edited"
description="Updated bio and avatar"
actor="Justin"
timestamp="5m ago"
/>
</ActivityFeed>
);
}ActivityFeed.Item is also available as a dot-notation alias for
ActivityFeedItem.
API Reference
ActivityFeedProps
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'default' | 'compact' | 'timeline' | 'default' | Display mode. Default is padded rows with borders, compact is denser with smaller text, timeline adds a connecting rail between leading indicators. |
children | React.ReactNode | — | ActivityFeedItem children. |
className | string | — | Additional CSS class names to merge onto the root <ol>. |
...props | React.HTMLAttributes<HTMLOListElement> | — | All standard HTML attributes are forwarded to the root <ol>. |
The component also accepts all standard HTML attributes for the root <ol>.
ActivityFeedItemProps
| Prop | Type | Default | Description |
|---|---|---|---|
title* | React.ReactNode | — | Primary event description. |
timestamp* | React.ReactNode | — | Pre-formatted timestamp. Pass a string, or pass your own <time> element for full control over dateTime semantics. |
leading | React.ReactNode | — | Leading visual — icon, avatar, or colored dot. |
description | React.ReactNode | — | Optional secondary detail beneath the title. |
actor | React.ReactNode | — | Who performed the event — a name string, or an avatar + name cluster. |
trailing | React.ReactNode | — | Right-aligned meta slot — status badge, link, etc. |
className | string | — | Additional CSS class names to merge onto the <li>. |
...props | React.LiHTMLAttributes<HTMLLIElement> | — | All standard HTML attributes are forwarded to the <li>. |
The component also accepts all standard HTML attributes for the <li>.
Source Files
After running npx visor add activity-feed, you'll have:
activity-feed.tsx
A compound component pair. ActivityFeed is a forwardRef <ol> that
exposes a React Context carrying the active variant. ActivityFeedItem
is a forwardRef <li> that reads the context and adapts its layout —
keeping the API ergonomic without forcing consumers to thread the variant
prop through every child. ActivityFeed.Item is attached as a dot-notation
alias for consumers who prefer that style.
activity-feed.module.css
All values reference CSS custom properties from @loworbitstudio/visor-core,
so the feed adapts to your active theme. The timeline variant renders a
connecting rail between leading indicators via a ::before pseudo-element
on the leading slot; the last item's rail is hidden with a :last-child
selector so the line doesn't extend past the final event.
Customization
After copying the component, you own it completely. Common customizations:
- Add a grouped
ActivityFeedGroupsub-component with a date heading for "Today / Yesterday / Last week" sectioning. - Add a
colorprop to items that tints the leading slot and the timeline rail (e.g., success/warning/error). - Make items keyboard-focusable and clickable for drilling into event
detail — wrap the body in an
<a>or<button>and add focus rings viavar(--focus-ring-width)andvar(--focus-ring-offset).
Workspace Switcher
Sidebar-header workspace switcher composing a button trigger and a DropdownMenu of available workspaces. Drop-in for the AdminShell logo slot in multi-tenant admin apps.
Bulk Action Bar
Admin bulk action bar compound — sticky or inline toolbar that appears when rows are selected. Shows a live-announced selection count, an actions slot, and an optional dismiss button. Built with CSS Modules and a reduced-motion-aware entrance animation — copy it into your project and own it completely.