{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "chat-4",
  "title": "Group Chat Panel",
  "description": "Group chat conversation with a member avatar stack header, messages from multiple named senders with per-sender avatars, and an online indicator.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "avatar",
    "bubble",
    "button",
    "input",
    "message",
    "message-scroller"
  ],
  "files": [
    {
      "path": "registry/blocks/chat/4/chat-block.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Bubble, BubbleContent } from \"@/components/ui/bubble\"\nimport { Button } from \"@/components/ui/button\"\nimport { Input } from \"@/components/ui/input\"\nimport {\n  Message,\n  MessageAvatar,\n  MessageContent,\n  MessageHeader,\n} from \"@/components/ui/message\"\nimport {\n  MessageScroller,\n  MessageScrollerButton,\n  MessageScrollerContent,\n  MessageScrollerItem,\n  MessageScrollerProvider,\n  MessageScrollerViewport,\n} from \"@/components/ui/message-scroller\"\nimport { IconPlaceholder } from \"@/components/icons/icon-placeholder\"\n\ntype Member = { id: string; name: string; avatar: string }\n\ntype GroupMessage = {\n  id: number\n  from: string\n  text: string\n  time: string\n}\n\nconst me = \"me\"\n\nconst members: Record<string, Member> = {\n  mara: {\n    id: \"mara\",\n    name: \"Mara Lin\",\n    avatar: \"https://i.pravatar.cc/80?img=32\",\n  },\n  leo: {\n    id: \"leo\",\n    name: \"Leo Tanaka\",\n    avatar: \"https://i.pravatar.cc/80?img=12\",\n  },\n  owen: {\n    id: \"owen\",\n    name: \"Owen Reyes\",\n    avatar: \"https://i.pravatar.cc/80?img=53\",\n  },\n}\n\nconst memberList = Object.values(members)\n\nconst seed: GroupMessage[] = [\n  {\n    id: 1,\n    from: \"mara\",\n    text: \"Morning all. Pushed the new empty states to staging.\",\n    time: \"9:31 AM\",\n  },\n  {\n    id: 2,\n    from: \"leo\",\n    text: \"Nice, the illustrations really tie it together.\",\n    time: \"9:33 AM\",\n  },\n  {\n    id: 3,\n    from: me,\n    text: \"Agreed. Should we ship it behind the beta flag first?\",\n    time: \"9:35 AM\",\n  },\n  {\n    id: 4,\n    from: \"owen\",\n    text: \"Let's do beta. I'll write the release note this afternoon.\",\n    time: \"9:36 AM\",\n  },\n  {\n    id: 5,\n    from: \"mara\",\n    text: \"Perfect. Thanks team.\",\n    time: \"9:37 AM\",\n  },\n]\n\nexport default function ChatBlock() {\n  const [messages, setMessages] = React.useState(seed)\n  const [draft, setDraft] = React.useState(\"\")\n  const nextId = React.useRef(1000)\n\n  const send = (e: React.FormEvent) => {\n    e.preventDefault()\n    const text = draft.trim()\n    if (!text) return\n    setMessages((prev) => [\n      ...prev,\n      { id: nextId.current++, from: me, text, time: \"Now\" },\n    ])\n    setDraft(\"\")\n  }\n\n  return (\n    <section className=\"flex w-full items-center justify-center bg-background px-6 py-16 text-foreground\">\n      <div className=\"flex h-[560px] w-full max-w-md flex-col rounded-lg border border-border bg-background\">\n        <div className=\"flex items-center justify-between gap-3 border-b border-border p-4\">\n          <div className=\"flex min-w-0 items-center gap-3\">\n            <div className=\"flex -space-x-2\">\n              {memberList.map((member) => (\n                <Avatar\n                  key={member.id}\n                  className=\"size-7 ring-2 ring-background\"\n                >\n                  <AvatarImage\n                    src={member.avatar}\n                    alt={member.name}\n                    className=\"grayscale\"\n                  />\n                  <AvatarFallback>{member.name[0]}</AvatarFallback>\n                </Avatar>\n              ))}\n            </div>\n            <div className=\"flex min-w-0 flex-col\">\n              <span className=\"truncate text-sm font-semibold\">\n                Design Guild\n              </span>\n              <span className=\"text-xs text-muted-foreground\">4 Members</span>\n            </div>\n          </div>\n          <span className=\"flex items-center gap-1.5 text-xs text-muted-foreground\">\n            <span className=\"size-1.5 rounded-full bg-success\" />3 Online\n          </span>\n        </div>\n\n        <MessageScrollerProvider autoScroll defaultScrollPosition=\"end\">\n          <MessageScroller className=\"flex-1\">\n            <MessageScrollerViewport>\n              <MessageScrollerContent className=\"gap-3 p-4\">\n                <div className=\"flex items-center justify-center\">\n                  <span className=\"rounded-md bg-muted px-2 py-0.5 text-xs text-muted-foreground\">\n                    Today\n                  </span>\n                </div>\n                {messages.map((message, index) => {\n                  const mine = message.from === me\n                  const prev = messages[index - 1]\n                  const showMeta = !prev || prev.from !== message.from\n                  const member = members[message.from]\n                  return (\n                    <MessageScrollerItem\n                      key={message.id}\n                      messageId={String(message.id)}\n                      scrollAnchor={mine}\n                    >\n                      <Message align={mine ? \"end\" : \"start\"}>\n                        {!mine && (\n                          <MessageAvatar>\n                            {showMeta ? (\n                              <Avatar className=\"size-8\">\n                                <AvatarImage\n                                  src={member?.avatar}\n                                  alt={member?.name}\n                                  className=\"grayscale\"\n                                />\n                                <AvatarFallback>\n                                  {member?.name[0]}\n                                </AvatarFallback>\n                              </Avatar>\n                            ) : (\n                              <span className=\"size-8\" aria-hidden=\"true\" />\n                            )}\n                          </MessageAvatar>\n                        )}\n                        <MessageContent>\n                          {!mine && showMeta && (\n                            <MessageHeader>{member?.name}</MessageHeader>\n                          )}\n                          <Bubble variant={mine ? \"default\" : \"muted\"}>\n                            <BubbleContent>{message.text}</BubbleContent>\n                          </Bubble>\n                        </MessageContent>\n                      </Message>\n                    </MessageScrollerItem>\n                  )\n                })}\n              </MessageScrollerContent>\n            </MessageScrollerViewport>\n            <MessageScrollerButton />\n          </MessageScroller>\n\n          <form\n            onSubmit={send}\n            className=\"flex items-center gap-2 border-t border-border p-3\"\n          >\n            <Input\n              value={draft}\n              onChange={(e) => setDraft(e.target.value)}\n              placeholder=\"Message Design Guild...\"\n              aria-label=\"Message\"\n            />\n            <Button\n              type=\"submit\"\n              size=\"icon\"\n              disabled={!draft.trim()}\n              aria-label=\"Send message\"\n            >\n              <IconPlaceholder\n                lucide=\"Send\"\n                tabler=\"IconSend\"\n                hugeicons=\"SentIcon\"\n                phosphor=\"PaperPlane\"\n                remixicon=\"RiSendPlane2Fill\"\n                className=\"size-4\"\n                aria-hidden=\"true\"\n              />\n            </Button>\n          </form>\n        </MessageScrollerProvider>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/blocks/chat-4.tsx"
    }
  ],
  "cssVars": {
    "light": {
      "success": "oklch(0.432 0.095 166.913)"
    },
    "dark": {
      "success": "oklch(0.765 0.177 163.223)"
    }
  },
  "meta": {
    "height": "696px",
    "tier": "free"
  },
  "categories": [
    "chat"
  ],
  "type": "registry:block"
}