{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "timeline",
  "title": "Timeline",
  "author": "Zubeyr <https://zubeyr.dev>",
  "description": "An activity timeline with a comment box on top and dated events below, newest first. Comments post instantly and call onComment.",
  "files": [
    {
      "path": "registry/dashboard/blocks/timeline/timeline.tsx",
      "content": "'use client'\n\nimport { useState } from 'react'\n\nimport { cn } from '@/lib/utils'\n\nexport type TimelineEvent = { id: string; content: React.ReactNode; time: string }\n\ntype TimelineProps = {\n  events: TimelineEvent[]\n  onComment?: (text: string) => void\n  placeholder?: string\n  className?: string\n}\n\nconst timeFormat = new Intl.DateTimeFormat('en-US', { hour: 'numeric', minute: '2-digit' })\n\nexport function Timeline({\n  events,\n  onComment,\n  placeholder = 'Leave a comment',\n  className,\n}: TimelineProps) {\n  const [draft, setDraft] = useState('')\n  const [posted, setPosted] = useState<TimelineEvent[]>([])\n\n  const post = () => {\n    const text = draft.trim()\n    if (!text) return\n    setPosted([\n      { id: `c-${Date.now()}`, content: text, time: timeFormat.format(new Date()) },\n      ...posted,\n    ])\n    onComment?.(text)\n    setDraft('')\n  }\n\n  return (\n    <div className={cn('flex flex-col gap-4', className)}>\n      <form\n        onSubmit={(e) => {\n          e.preventDefault()\n          post()\n        }}\n        className=\"flex items-center gap-2 rounded-lg border border-input bg-card p-1 pl-3 focus-within:border-ring\"\n      >\n        <input\n          value={draft}\n          onChange={(e) => setDraft(e.target.value)}\n          placeholder={placeholder}\n          aria-label={placeholder}\n          className=\"h-7 min-w-0 flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground\"\n        />\n        {draft.trim() && (\n          <button\n            type=\"submit\"\n            className=\"h-7 rounded-md bg-primary px-2.5 text-xs font-medium text-primary-foreground\"\n          >\n            Post\n          </button>\n        )}\n      </form>\n      <ol className=\"flex flex-col\">\n        {[...posted, ...events].map((event, i, all) => (\n          <li key={event.id} className=\"relative grid grid-cols-[1rem_1fr_auto] gap-2 pb-5\">\n            {i < all.length - 1 && (\n              <span aria-hidden className=\"absolute top-3 bottom-0 left-[3.5px] w-px bg-border\" />\n            )}\n            <span aria-hidden className=\"mt-1.5 size-2 rounded-full bg-muted-foreground/40\" />\n            <span className=\"text-sm\">{event.content}</span>\n            <time className=\"text-xs whitespace-nowrap text-muted-foreground\">{event.time}</time>\n          </li>\n        ))}\n      </ol>\n    </div>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/dashboard/timeline.tsx"
    }
  ],
  "meta": {
    "scenario": "dashboard",
    "kind": "blocks"
  },
  "categories": [
    "dashboard",
    "activity",
    "lists"
  ],
  "type": "registry:block"
}