{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "chat-input",
  "type": "registry:component",
  "title": "Chat Input",
  "description": "A chat input component for a nice chatbot experience. Ready for useChat().",
  "dependencies": [
    "@radix-ui/react-slot",
    "@radix-ui/react-select",
    "class-variance-authority",
    "lucide-react",
    "ai"
  ],
  "files": [
    {
      "path": "registry/new-york/blocks/chat-input/chat-input.tsx",
      "content": "\"use client\";\n\nimport { Button } from \"@/registry/new-york/blocks/button/button\";\nimport { SendIcon, SquareIcon, UploadIcon } from \"lucide-react\";\nimport { cn } from \"@/lib/utils\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/registry/new-york/blocks/select/select\";\nimport { Textarea } from \"@/registry/new-york/blocks/textarea/textarea\";\n\nexport default function ChatInput({\n  title,\n  placeholder = \"Ask anything...\",\n  models,\n  allowFileUpload,\n  loading,\n  handleSubmit,\n  handleInputChange,\n  input = \"\",\n  className,\n  model = \"\",\n  onModelChange,\n  stop,\n}: {\n  handleSubmit?: (e: React.FormEvent<HTMLFormElement>) => void;\n  handleInputChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;\n  input?: string;\n  className?: string;\n  model: string;\n  onModelChange?: (model: string) => void;\n  title?: string;\n  placeholder?: string;\n  models: { id: string; name: string; description: string }[];\n  allowFileUpload?: boolean;\n  loading?: boolean;\n  stop?: () => void;\n}) {\n  return (\n    <form\n      onSubmit={handleSubmit}\n      className={cn(\"w-full relative flex flex-col gap-4 items-center\", className)}\n    >\n      {title && <h2 className=\"text-5xl font-medium tracking-tight\">{title}</h2>}\n      <Textarea\n        name=\"prompt\"\n        value={input}\n        onChange={handleInputChange}\n        disabled={loading}\n        autoComplete=\"off\"\n        placeholder={placeholder}\n        className=\"w-full pb-20 pt-4 px-4 rounded-xl text-md bg-background disabled:opacity-100 disabled:cursor-not-allowed disabled:bg-background\"\n        onKeyDown={(e) => {\n          if (e.key === \"Enter\" && !e.shiftKey && !e.nativeEvent.isComposing) {\n            e.preventDefault();\n            e.currentTarget.form?.requestSubmit();\n          }\n        }}\n      />\n      <Button\n        type={loading ? \"button\" : \"submit\"}\n        onClick={() => {\n          if (stop) {\n            stop();\n          }\n        }}\n        disabled={!stop && loading}\n        variant=\"fancy\"\n        size=\"icon\"\n        className=\"absolute bottom-2 right-2\"\n      >\n        {loading ? <SquareIcon className=\"w-4 h-4\" /> : <SendIcon className=\"w-4 h-4\" />}\n      </Button>\n      {onModelChange && models && (\n        <div className=\"flex items-center gap-2 absolute bottom-0 left-0\">\n          <Select value={model} onValueChange={(value) => onModelChange(value)}>\n            <SelectTrigger className=\"w-[200px] shadow-none pl-4 hover:bg-transparent hover:text-foreground focus-visible:ring-0 border-none bg-transparent text-xs text-muted-foreground dark:bg-transparent\">\n              <SelectValue>\n                {models.find((m) => m.id === model)?.name || \"Select a model\"}\n              </SelectValue>\n            </SelectTrigger>\n            <SelectContent className=\"rounded-xl shadow-shade\">\n              {models.map((model) => (\n                <SelectItem\n                  key={model.id}\n                  value={model.id}\n                  className=\"rounded-lg focus:bg-primary/5\"\n                >\n                  <div className=\"flex flex-col\">\n                    <span>{model.name}</span>\n                    <span className=\"text-xs text-muted-foreground\">{model.description}</span>\n                  </div>\n                </SelectItem>\n              ))}\n            </SelectContent>\n          </Select>\n          {allowFileUpload && (\n            <Button variant=\"outline\" size=\"icon\">\n              <UploadIcon className=\"w-4 h-4\" />\n            </Button>\n          )}\n        </div>\n      )}\n    </form>\n  );\n}\n",
      "type": "registry:component"
    },
    {
      "path": "registry/new-york/blocks/button/button.tsx",
      "content": "import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-1 whitespace-nowrap rounded-xl text-md font-medium disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive duration-200 hover:duration-75 transition-all\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"border border-primary bg-primary/70 bg-linear-to-t from-primary to-primary/30 px-4 py-2 font-medium text-primary-foreground shadow-md inset-shadow-[0px_1px_0px_1px] inset-shadow-white/30 transition-all duration-75 hover:bg-primary/60 active:translate-y-px active:inset-shadow-black/10 dark:bg-primary dark:from-primary dark:to-primary/80 dark:hover:bg-primary/90\",\n        fancy:\n          \"border border-primary bg-primary/30 bg-radial-[at_50%_25%] from-primary/40 to-primary text-primary-foreground shadow-md inset-shadow-sm inset-shadow-white/50 hover:bg-white hover:shadow-lg hover:inset-shadow-white active:bg-primary/30 active:shadow-none active:inset-shadow-primary/80  hover:-translate-y-px active:translate-y-px\",\n        destructive:\n          \"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60\",\n        outline:\n          \"border shadow-lg hover:shadow-none shadow-shade bg-transparent text-primary hover:border-transparent hover:bg-primary/10 active:bg-primary/30\",\n        secondary:\n          \"border border-transparent bg-primary/10 text-primary hover:border-primary/50 hover:bg-transparent  active:border-transparent active:border-primary active:ring-1 active:scale-95\",\n        ghost:\n          \"bg-transparent text-primary hover:border-transparent hover:bg-primary/10 active:bg-primary/30\",\n        link: \"text-foreground underline decoration-primary underline-offset-2 hover:underline-offset-2 active:decoration-4 hover:opacity-70 hover:decoration-2 active:text-foreground\",\n      },\n      size: {\n        default: \"px-4 py-2\",\n        xs: \"px-2 py-1.5 rounded-lg [&_svg:not([class*='size-'])]:size-3 text-xs\",\n        sm: \"px-3 py-1.5 text-sm rounded-lg\",\n        lg: \"px-5 py-2 text-lg\",\n        xl: \"px-6 py-3 [&_svg:not([class*='size-'])]:size-5 text-xl\",\n        icon: \"size-8 rounded-lg [&_svg:not([class*='size-'])]:size-4\",\n        iconSm: \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n        iconLg: \"size-10 rounded-lg [&_svg:not([class*='size-'])]:size-5\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n);\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean;\n  }) {\n  const Comp = asChild ? Slot : \"button\";\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  );\n}\n\nexport { Button, buttonVariants };\n",
      "type": "registry:component",
      "target": "components/ui/button.tsx"
    },
    {
      "path": "registry/new-york/blocks/select/select.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as SelectPrimitive from \"@radix-ui/react-select\";\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {\n  return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nfunction SelectGroup({ ...props }: React.ComponentProps<typeof SelectPrimitive.Group>) {\n  return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />;\n}\n\nfunction SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>) {\n  return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\n\nfunction SelectTrigger({\n  className,\n  size = \"default\",\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n  size?: \"sm\" | \"default\";\n}) {\n  return (\n    <SelectPrimitive.Trigger\n      data-slot=\"select-trigger\"\n      data-size={size}\n      className={cn(\n        \"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-primary focus-visible:ring-primary/30 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex items-center justify-between gap-2 rounded-xl border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-md shadow-shade  transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 data-[size=sm]:rounded-lg *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 w-full\",\n        \"hover:shadow-none hover:bg-muted hover:border-border/0 transition-all duration-150 ease-out hover:duration-75\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <SelectPrimitive.Icon asChild>\n        <ChevronDownIcon className=\"size-4 opacity-50\" />\n      </SelectPrimitive.Icon>\n    </SelectPrimitive.Trigger>\n  );\n}\n\nfunction SelectContent({\n  className,\n  children,\n  position = \"popper\",\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n  return (\n    <SelectPrimitive.Portal>\n      <SelectPrimitive.Content\n        data-slot=\"select-content\"\n        className={cn(\n          \"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2  relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-xl border shadow-lg shadow-shade duration-150 w-full\",\n          position === \"popper\" &&\n            \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n          className\n        )}\n        position={position}\n        {...props}\n      >\n        <SelectScrollUpButton />\n        <SelectPrimitive.Viewport\n          className={cn(\n            \"p-1\",\n            position === \"popper\" &&\n              \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\"\n          )}\n        >\n          {children}\n        </SelectPrimitive.Viewport>\n        <SelectScrollDownButton />\n      </SelectPrimitive.Content>\n    </SelectPrimitive.Portal>\n  );\n}\n\nfunction SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>) {\n  return (\n    <SelectPrimitive.Label\n      data-slot=\"select-label\"\n      className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction SelectItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n  return (\n    <SelectPrimitive.Item\n      data-slot=\"select-item\"\n      className={cn(\n        \"focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-lg py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n        \"transition-all duration-150 ease-out focus:duration-75\",\n        className\n      )}\n      {...props}\n    >\n      <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n        <SelectPrimitive.ItemIndicator>\n          <CheckIcon className=\"size-4\" />\n        </SelectPrimitive.ItemIndicator>\n      </span>\n      <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n    </SelectPrimitive.Item>\n  );\n}\n\nfunction SelectSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n  return (\n    <SelectPrimitive.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"bg-border pointer-events-none -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction SelectScrollUpButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n  return (\n    <SelectPrimitive.ScrollUpButton\n      data-slot=\"select-scroll-up-button\"\n      className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n      {...props}\n    >\n      <ChevronUpIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollUpButton>\n  );\n}\n\nfunction SelectScrollDownButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n  return (\n    <SelectPrimitive.ScrollDownButton\n      data-slot=\"select-scroll-down-button\"\n      className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n      {...props}\n    >\n      <ChevronDownIcon className=\"size-4\" />\n    </SelectPrimitive.ScrollDownButton>\n  );\n}\n\nexport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectScrollDownButton,\n  SelectScrollUpButton,\n  SelectSeparator,\n  SelectTrigger,\n  SelectValue,\n};\n",
      "type": "registry:component",
      "target": "components/ui/select.tsx"
    },
    {
      "path": "registry/new-york/blocks/textarea/textarea.tsx",
      "content": "import * as React from \"react\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction Textarea({\n  className,\n  showHandle = true,\n  ...props\n}: React.ComponentProps<\"textarea\"> & { showHandle?: boolean }) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"border-input placeholder:text-muted-foreground focus-visible:border-primary focus-visible:ring-primary/30 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-xl border bg-transparent p-3 text-base shadow-md shadow-shade transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n        showHandle ? \"resize-y\" : \"resize-none\",\n        \"hover:shadow-none hover:bg-foreground/5 hover:border-border/0 transition-all duration-150 ease-out hover:duration-75\",\n        className\n      )}\n      {...props}\n    />\n  );\n}\n\nexport { Textarea };\n",
      "type": "registry:component",
      "target": "components/ui/textarea.tsx"
    }
  ]
}