{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "timeline-3",
  "title": "Activity Feed By Day",
  "description": "Activity timeline grouped by day, with avatar rows for each actor, action, target, and relative timestamp connected by a vertical rail.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "avatar",
    "badge",
    "marker"
  ],
  "files": [
    {
      "path": "registry/blocks/timeline/3/timeline-block.tsx",
      "content": "import { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Marker, MarkerContent } from \"@/components/ui/marker\"\nimport { IconPlaceholder } from \"@/components/icons/icon-placeholder\"\nimport type * as React from \"react\"\n\n/** Props a call site may pass through to an icon. */\ntype IconProps = { className?: string; size?: number | string }\n\n/** An icon held in data and rendered later, e.g. `<item.icon className=\"size-4\" />`. */\ntype IconRenderer = (props: IconProps) => React.ReactNode\n\ntype Event = {\n  actor: string\n  initials: string\n  avatar: string\n  action: string\n  target: string\n  time: string\n  icon: IconRenderer\n}\n\nconst groups: { label: string; events: Event[] }[] = [\n  {\n    label: \"Today\",\n    events: [\n      {\n        actor: \"Mara Ellis\",\n        initials: \"ME\",\n        avatar: \"https://i.pravatar.cc/80?img=47\",\n        action: \"merged pull request\",\n        target: \"feat/auth-refresh\",\n        time: \"12 Min Ago\",\n        icon: (p: IconProps) => (\n          <IconPlaceholder\n            lucide=\"GitMerge\"\n            tabler=\"IconGitMerge\"\n            hugeicons=\"GitMergeIcon\"\n            phosphor=\"GitMerge\"\n            remixicon=\"RiGitMergeLine\"\n            {...p}\n          />\n        ),\n      },\n      {\n        actor: \"Leo Tanaka\",\n        initials: \"LT\",\n        avatar: \"https://i.pravatar.cc/80?img=12\",\n        action: \"deployed to production\",\n        target: \"v2.4.1\",\n        time: \"1 Hour Ago\",\n        icon: (p: IconProps) => (\n          <IconPlaceholder\n            lucide=\"Upload\"\n            tabler=\"IconUpload\"\n            hugeicons=\"UploadIcon\"\n            phosphor=\"Upload\"\n            remixicon=\"RiUploadLine\"\n            {...p}\n          />\n        ),\n      },\n      {\n        actor: \"Priya Nair\",\n        initials: \"PN\",\n        avatar: \"https://i.pravatar.cc/80?img=32\",\n        action: \"resolved a comment on\",\n        target: \"Q3 Roadmap\",\n        time: \"3 Hours Ago\",\n        icon: (p: IconProps) => (\n          <IconPlaceholder\n            lucide=\"MessageCircle\"\n            tabler=\"IconMessageCircle\"\n            hugeicons=\"Message01Icon\"\n            phosphor=\"ChatCircle\"\n            remixicon=\"RiChat3Line\"\n            {...p}\n          />\n        ),\n      },\n    ],\n  },\n  {\n    label: \"Yesterday\",\n    events: [\n      {\n        actor: \"Sasha Kim\",\n        initials: \"SK\",\n        avatar: \"https://i.pravatar.cc/80?img=48\",\n        action: \"completed task\",\n        target: \"Migrate billing service\",\n        time: \"Jun 24\",\n        icon: (p: IconProps) => (\n          <IconPlaceholder\n            lucide=\"Check\"\n            tabler=\"IconCheck\"\n            hugeicons=\"Tick02Icon\"\n            phosphor=\"Check\"\n            remixicon=\"RiCheckLine\"\n            {...p}\n          />\n        ),\n      },\n      {\n        actor: \"Owen Brooks\",\n        initials: \"OB\",\n        avatar: \"https://i.pravatar.cc/80?img=53\",\n        action: \"invited a new member\",\n        target: \"design@acme.com\",\n        time: \"Jun 24\",\n        icon: (p: IconProps) => (\n          <IconPlaceholder\n            lucide=\"UserPlus\"\n            tabler=\"IconUserPlus\"\n            hugeicons=\"UserAddIcon\"\n            phosphor=\"UserPlus\"\n            remixicon=\"RiUserAddLine\"\n            {...p}\n          />\n        ),\n      },\n    ],\n  },\n]\n\nexport default function TimelineBlock() {\n  return (\n    <section className=\"flex w-full items-center justify-center bg-background px-6 py-16 text-foreground\">\n      <div className=\"mx-auto w-full max-w-xl\">\n        <div className=\"mb-8 flex items-center justify-between gap-4\">\n          <div>\n            <h2 className=\"font-heading text-xl font-bold tracking-tight\">\n              Activity\n            </h2>\n            <p className=\"mt-1 text-sm text-muted-foreground\">\n              What your team has been working on lately.\n            </p>\n          </div>\n          <Badge variant=\"secondary\" className=\"shrink-0\">\n            5 Updates\n          </Badge>\n        </div>\n\n        <div className=\"flex flex-col gap-6\">\n          {groups.map((group) => (\n            <div key={group.label} className=\"flex flex-col gap-4\">\n              <Marker variant=\"separator\">\n                <MarkerContent>{group.label}</MarkerContent>\n              </Marker>\n\n              <ol className=\"relative flex flex-col gap-5\">\n                <span\n                  className=\"absolute top-3 bottom-3 left-4 w-px bg-border\"\n                  aria-hidden=\"true\"\n                />\n                {group.events.map((event) => (\n                  <li\n                    key={`${event.actor}-${event.target}`}\n                    className=\"relative flex items-center gap-3\"\n                  >\n                    <span className=\"relative shrink-0\">\n                      <Avatar className=\"size-9 border border-border\">\n                        <AvatarImage\n                          src={event.avatar}\n                          alt={event.actor}\n                          className=\"grayscale\"\n                        />\n                        <AvatarFallback>{event.initials}</AvatarFallback>\n                      </Avatar>\n                      <span className=\"absolute -right-1 -bottom-1 flex size-4 items-center justify-center rounded-full border border-border bg-card text-muted-foreground\">\n                        <event.icon className=\"size-2.5\" aria-hidden=\"true\" />\n                      </span>\n                    </span>\n\n                    <p className=\"flex-1 text-sm text-muted-foreground\">\n                      <span className=\"font-medium text-foreground\">\n                        {event.actor}\n                      </span>{\" \"}\n                      {event.action}{\" \"}\n                      <span className=\"font-medium text-foreground\">\n                        {event.target}\n                      </span>\n                    </p>\n\n                    <span className=\"shrink-0 text-xs text-muted-foreground tabular-nums\">\n                      {event.time}\n                    </span>\n                  </li>\n                ))}\n              </ol>\n            </div>\n          ))}\n        </div>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/blocks/timeline-3.tsx"
    }
  ],
  "meta": {
    "height": "548px",
    "tier": "free"
  },
  "categories": [
    "timeline"
  ],
  "type": "registry:block"
}