{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "chat-container",
  "title": "Chat Container",
  "description": "A message list that follows new content while you are at the bottom and lets go when you scroll up.",
  "dependencies": [
    "motion",
    "use-stick-to-bottom"
  ],
  "registryDependencies": [
    "https://ui.ndekocode.dev/r/theme.json",
    "https://ui.ndekocode.dev/r/utils.json"
  ],
  "files": [
    {
      "path": "registry/ndeko/ui/chat-container.tsx",
      "content": "// Adapted from prompt-kit (MIT, Copyright (c) 2025 Julien Thibeaut).\n'use client';\n\nimport { useReducedMotion } from 'motion/react';\nimport {\n  StickToBottom,\n  useStickToBottomContext,\n  type StickToBottomContext,\n} from 'use-stick-to-bottom';\n\nimport { cn } from '@/registry/ndeko/lib/utils';\n\ntype ScrollBehaviour = 'smooth' | 'instant';\n\nfunction scrollBehaviourOf(\n  shouldReduceMotion: boolean | null\n): ScrollBehaviour {\n  if (shouldReduceMotion) {\n    return 'instant';\n  }\n  return 'smooth';\n}\n\ntype ChatContainerRootProps = React.ComponentProps<'div'> & {\n  /** Receives `scrollToBottom`, `isAtBottom` and the rest, for a composer that sits outside the list. */\n  contextRef?: React.Ref<StickToBottomContext>;\n};\n\nfunction ChatContainerRoot({\n  className,\n  children,\n  contextRef,\n  ...props\n}: ChatContainerRootProps) {\n  const shouldReduceMotion = useReducedMotion();\n  const resize = scrollBehaviourOf(shouldReduceMotion);\n\n  return (\n    <StickToBottom\n      data-slot='chat-container'\n      role='log'\n      resize={resize}\n      initial='instant'\n      contextRef={contextRef}\n      className={cn('relative flex min-h-0 flex-col', className)}\n      {...props}\n    >\n      {children}\n    </StickToBottom>\n  );\n}\n\ntype ChatContainerContentProps = Omit<\n  React.ComponentProps<'div'>,\n  'children'\n> & {\n  children: React.ReactNode;\n  /** Classes of the element that scrolls. */\n  scrollClassName?: string;\n};\n\nfunction ChatContainerContent({\n  className,\n  scrollClassName,\n  children,\n  ...props\n}: ChatContainerContentProps) {\n  return (\n    <StickToBottom.Content\n      data-slot='chat-container-content'\n      scrollClassName={cn(\n        'overscroll-contain [scrollbar-color:color-mix(in_oklab,var(--foreground)_20%,transparent)_transparent] [scrollbar-width:thin]',\n        scrollClassName\n      )}\n      className={cn('flex w-full flex-col', className)}\n      {...props}\n    >\n      {children}\n    </StickToBottom.Content>\n  );\n}\n\ntype ChatContainerScrollAnchorProps = React.ComponentProps<'div'>;\n\nfunction ChatContainerScrollAnchor({\n  className,\n  ...props\n}: ChatContainerScrollAnchorProps) {\n  return (\n    <div\n      data-slot='chat-container-scroll-anchor'\n      aria-hidden='true'\n      className={cn('h-px w-full shrink-0 scroll-mt-4', className)}\n      {...props}\n    />\n  );\n}\n\nconst useChatContainer = useStickToBottomContext;\n\nexport {\n  ChatContainerContent,\n  ChatContainerRoot,\n  ChatContainerScrollAnchor,\n  useChatContainer,\n  type StickToBottomContext as ChatContainerContext,\n};\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "primitives",
    "chat"
  ],
  "type": "registry:ui"
}