{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "chat", "title": "Chat", "description": "A set of composable chat UI components with container query support.", "dependencies": [ "@radix-ui/react-avatar" ], "registryDependencies": [ "avatar", "button", "textarea" ], "files": [ { "path": "registry/new-york/chat/chat.tsx", "content": "/**\n * @module chat\n *\n * Root container for the chat UI. Provides a flex column layout with\n * container query support (`@container/chat`) so child components can\n * adapt to the available width.\n *\n * **Important:** Give `Chat` or its parent a defined height or max-height (e.g. via\n * `className=\"h-screen\"`) to enable proper scrolling in `ChatMessages`.\n *\n * @see {@link ChatHeader} for the sticky top header.\n * @see {@link ChatMessages} for the scrollable message area.\n * @see {@link ChatToolbar} for the sticky bottom input area.\n */\n\nimport { cn } from \"@/lib/utils\";\n\nexport interface ChatProps extends React.ComponentProps<\"div\"> {\n children?: React.ReactNode;\n}\n\n/**\n * Root container component that establishes the chat layout structure\n * with container queries and flex column layout for header, messages,\n * and toolbar sections.\n *\n * Uses container queries (e.g. `@md/chat:`, `@2xl/chat:`) to adapt\n * layout based on available width rather than viewport size.\n *\n * @example\n * ```tsx\n * \n * \n * Header Content\n * \n *\n * \n * Messages Content\n * \n *\n * \n * Toolbar Content\n * \n * \n * ```\n */\nexport function Chat({ children, className, ...props }: ChatProps) {\n return (\n \n {children}\n \n );\n}\n", "type": "registry:file", "target": "components/chat/chat.tsx" }, { "path": "registry/new-york/chat/chat-header.tsx", "content": "/**\n * @module chat-header\n *\n * Sticky header components for the chat UI. Compose `ChatHeaderMain`,\n * `ChatHeaderAddon`, `ChatHeaderAvatar`, and `ChatHeaderButton` inside\n * a `ChatHeader` container to build the header layout.\n *\n * Typical structure:\n * ```\n * ChatHeader\n * ├── ChatHeaderAddon ← left-side items (avatar, back button)\n * ├── ChatHeaderMain ← center content (takes remaining space)\n * └── ChatHeaderAddon ← right-side items (action buttons)\n * ```\n */\n\nimport * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport {\n AvatarFallbackProps,\n AvatarImageProps,\n AvatarProps,\n} from \"@radix-ui/react-avatar\";\nimport {\n Avatar,\n AvatarFallback,\n AvatarImage,\n} from \"@/registry/new-york/ui/avatar\";\nimport { Button } from \"@/registry/new-york/ui/button\";\n\nexport interface ChatHeaderProps extends React.ComponentProps<\"div\"> {\n children?: React.ReactNode;\n}\n\n/**\n * Sticky header container for the chat. Renders as a flex row pinned\n * to the top of the `Chat` container.\n *\n * @example\n * ```tsx\n * \n * \n * \n * \n * \n * Ann Smith\n * \n * \n * \n * \n * \n * \n * ```\n */\nexport function ChatHeader({ children, className, ...props }: ChatHeaderProps) {\n return (\n \n {children}\n \n );\n}\n\nexport interface ChatHeaderMainProps extends React.ComponentProps<\"div\"> {\n children?: React.ReactNode;\n}\n\n/**\n * Primary content area of the header. Uses `flex-1` to take remaining\n * horizontal space between `ChatHeaderAddon` groups.\n *\n * @example\n * ```tsx\n * \n * Ann Smith\n * \n * Front-end developer\n * \n * \n * ```\n */\nexport function ChatHeaderMain({\n children,\n className,\n ...props\n}: ChatHeaderMainProps) {\n return (\n
\n {children}\n
\n );\n}\n\nexport interface ChatHeaderAddonProps extends React.ComponentProps<\"div\"> {\n children?: React.ReactNode;\n}\n\n/**\n * Groups supplementary items (avatars, buttons, inputs) on either side\n * of the header. Place one before `ChatHeaderMain` for the left side\n * and one after for the right side.\n *\n * @example\n * ```tsx\n * // Left side\n * \n * \n * \n *\n * // Right side\n * \n * \n * \n * \n * ```\n */\nexport function ChatHeaderAddon({\n children,\n className,\n ...props\n}: ChatHeaderAddonProps) {\n return (\n
\n {children}\n
\n );\n}\n\nexport interface ChatHeaderAvatarProps extends AvatarProps {\n className?: string;\n /** Image URL for the avatar. */\n src?: AvatarImageProps[\"src\"];\n /** Alt text for the avatar image. */\n alt?: string;\n /** Fallback content shown while the image loads or if it fails (e.g. initials). */\n fallback?: React.ReactNode;\n /** Additional props forwarded to the inner `AvatarImage`. */\n imageProps?: AvatarImageProps;\n /** Additional props forwarded to the inner `AvatarFallback`. */\n fallbackProps?: AvatarFallbackProps;\n}\n\n/**\n * Avatar component sized for the header. Built on Radix UI Avatar\n * primitives with rounded styling.\n *\n * @example\n * ```tsx\n * \n * ```\n */\nexport function ChatHeaderAvatar({\n className,\n src,\n alt,\n fallback,\n imageProps,\n fallbackProps,\n ...props\n}: ChatHeaderAvatarProps) {\n return (\n \n \n {fallback && (\n {fallback}\n )}\n \n );\n}\n\nexport interface ChatHeaderButtonProps extends React.ComponentProps<\n typeof Button\n> {\n children?: React.ReactNode;\n}\n\n/**\n * Pre-styled ghost icon button for header actions (phone, video, menu, etc.).\n * Uses `variant=\"ghost\"` and `size=\"icon-sm\"`.\n *\n * @example\n * ```tsx\n * \n * \n * \n * ```\n */\nexport function ChatHeaderButton({\n children,\n className,\n ...props\n}: ChatHeaderButtonProps) {\n return (\n \n );\n}\n", "type": "registry:file", "target": "components/chat/chat-header.tsx" }, { "path": "registry/new-york/chat/chat-messages.tsx", "content": "/**\n * @module chat-messages\n *\n * Scrollable message container for the chat UI. Uses `flex-col-reverse`\n * to display messages bottom-to-top and automatically scroll to the\n * latest message. Fills all available vertical space between the header\n * and toolbar.\n *\n * **Important:** The parent `Chat` component or its parent must have a defined height\n * for overflow scrolling to work correctly.\n *\n * @see {@link ChatEvent} for rendering individual messages inside this container.\n */\n\nimport { cn } from \"@/lib/utils\";\n\nexport type ChatMessagesProps = React.ComponentProps<\"div\">;\n\n/**\n * Scrollable flex container with reverse column direction that\n * displays chat messages from bottom to top, automatically handling\n * overflow.\n *\n * Render `ChatEvent` items (or custom message components built from\n * them) as direct children. Because of `flex-col-reverse`, the first\n * child in the DOM appears at the **bottom** of the visible area.\n *\n * @example\n * ```tsx\n * \n * {messages.map((msg) => (\n * \n * \n * \n * \n * \n * \n * {msg.sender.name}\n * \n * \n * {msg.content}\n * \n * \n * ))}\n * \n * ```\n */\nexport function ChatMessages({\n children,\n className,\n ...props\n}: ChatMessagesProps) {\n return (\n \n {children}\n \n );\n}\n", "type": "registry:file", "target": "components/chat/chat-messages.tsx" }, { "path": "registry/new-york/chat/chat-toolbar.tsx", "content": "/**\n * @module chat-toolbar\n *\n * Sticky bottom input area for message composition. Compose\n * `ChatToolbarTextarea`, `ChatToolbarAddon`, and `ChatToolbarButton`\n * inside a `ChatToolbar` container.\n *\n * Typical structure:\n * ```\n * ChatToolbar\n * ├── ChatToolbarAddon (align=\"inline-start\") ← left button(s)\n * │ └── ChatToolbarButton\n * ├── ChatToolbarTextarea ← auto-growing input\n * └── ChatToolbarAddon (align=\"inline-end\") ← right button(s)\n * └── ChatToolbarButton (×N)\n * ```\n *\n * The `align` prop on `ChatToolbarAddon` controls position via CSS\n * `order`:\n * - `\"inline-start\"` → left of the textarea\n * - `\"inline-end\"` → right of the textarea\n * - `\"block-start\"` → full-width row above the textarea\n * - `\"block-end\"` → full-width row below the textarea\n */\n\n\"use client\";\n\nimport * as React from \"react\";\nimport { FileTextIcon, PaperclipIcon, XIcon } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport { Textarea } from \"@/registry/new-york/ui/textarea\";\nimport { Button } from \"@/registry/new-york/ui/button\";\n\nexport interface ChatToolbarProps extends React.ComponentProps<\"div\"> {\n children?: React.ReactNode;\n}\n\n/**\n * Sticky bottom container for the message input and action buttons.\n * Renders a bordered, rounded inner wrapper with flex-wrap layout.\n *\n * @example\n * ```tsx\n * \n * \n * \n * \n *\n * setMessage(e.target.value)}\n * onSubmit={() => handleSendMessage()}\n * />\n *\n * \n * \n * \n * \n * \n * ```\n */\nexport function ChatToolbar({\n children,\n className,\n ...props\n}: ChatToolbarProps) {\n return (\n \n \n {children}\n \n \n );\n}\n\n/** Modifier key that allows inserting a new line instead of submitting */\nconst NEWLINE_MODIFIER_KEY = \"shiftKey\" as const;\n\nexport interface ChatToolbarTextareaProps extends React.ComponentProps<\n typeof Textarea\n> {\n /** Called when the user presses Enter (without Shift). Use this to trigger message sending. */\n onSubmit?: () => void;\n}\n\n/**\n * Auto-growing textarea with built-in submit handling.\n *\n * - **Enter** → calls `onSubmit()`\n * - **Shift+Enter** → inserts a new line\n *\n * Accepts all standard `