Feed

Activity Feed

Workspace activity card built on ActivityFeedCard: a large event count, a timeline of deploys, merges and comments with one highlighted event, a 48-hour summary row and a full-width View all link.

Free, MIT licenseOpen in Browse
import { cn } from "cn"

import {
  ActivityFeedCard,
  type ActivityFeedEvent,
} from "@/components/activity/activity-feed-card"
import { buttonVariants } from "@/components/ui/button"

// The copy: change text here, not in the markup.
const COPY = {
  title: "Activity",
  body: "What changed across the workspace.",
  count: "events",
  window: "Last 48 hours",
  latest: "Latest",
  cta: "View all activity",
} as const

const EVENTS: ActivityFeedEvent[] = [
  {
    id: 1,
    actor: "Lena Orvik",
    action: "deployed",
    target: "api-gateway",
    time: "2h",
    featured: true,
  },
  {
    id: 2,
    actor: "Tomas Vey",
    action: "commented on",
    target: "#482",
    time: "3h",
    comment:
      "Looks right to me. One small note on the error handling, then merge.",
  },
  {
    id: 3,
    actor: "Ines Halloran",
    action: "merged",
    target: "rate-limiter",
    time: "5h",
  },
  {
    id: 4,
    actor: "Kofi Brandt",
    action: "tagged",
    target: "v2.4.0",
    time: "1d",
  },
  {
    id: 5,
    actor: "Mira Sato",
    action: "closed",
    target: "#311",
    time: "1d",
    comment: "Fixed by the latest deploy. It no longer happens on staging.",
  },
  {
    id: 6,
    actor: "Elias Quill",
    action: "joined the workspace",
    time: "2d",
  },
]

export default function ActivityFeed() {
  return (
    <ActivityFeedCard
      className="mx-auto w-full max-w-sm"
      title={COPY.title}
      description={COPY.body}
      events={EVENTS}
      countLabel={COPY.count}
      summary={{
        period: COPY.window,
        latest: (
          <>
            {COPY.latest} {EVENTS[0].time}
          </>
        ),
      }}
      actions={
        <a
          href="#"
          data-slot="button"
          className={cn(
            buttonVariants({ variant: "secondary", size: "lg" }),
            "w-full"
          )}
        >
          {COPY.cta}
        </a>
      }
    />
  )
}

Installation

pnpm dlx shadcn add @01orbital/activity-feed
npx shadcn add @01orbital/activity-feed
yarn shadcn add @01orbital/activity-feed
bunx --bun shadcn add @01orbital/activity-feed

Free under the MIT license. Add the @01orbital registry to components.json once (install guide), then run the command.

It lands at components/blocks/feed/activity-feed/index.tsx, as source you own and edit.

Usage

import ActivityFeed from "@/components/blocks/feed/activity-feed"

export default function Example() {
  return <ActivityFeed />
}

Dependencies

npm: cn. The CLI installs them for you.

Registry pieces it installs with it:

  • activity-feed-card
  • button