{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"inline-citation","type":"registry:component","title":"Inline Citation","description":"AI-powered inline citation component.","files":[{"path":"registry/default/ai-elements/inline-citation.tsx","type":"registry:component","content":"\"use client\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport {\n  Carousel,\n  type CarouselApi,\n  CarouselContent,\n  CarouselItem,\n} from \"@/components/ui/carousel\";\nimport {\n  HoverCard,\n  HoverCardContent,\n  HoverCardTrigger,\n} from \"@/components/ui/hover-card\";\nimport { cn } from \"@/lib/utils\";\nimport { ArrowLeftIcon, ArrowRightIcon } from \"lucide-react\";\nimport {\n  type ComponentProps,\n  createContext,\n  useCallback,\n  useContext,\n  useEffect,\n  useState,\n} from \"react\";\n\nexport type InlineCitationProps = ComponentProps<\"span\">;\n\nexport const InlineCitation = ({\n  className,\n  ...props\n}: InlineCitationProps) => (\n  <span\n    className={cn(\"group inline items-center gap-1\", className)}\n    {...props}\n  />\n);\n\nexport type InlineCitationTextProps = ComponentProps<\"span\">;\n\nexport const InlineCitationText = ({\n  className,\n  ...props\n}: InlineCitationTextProps) => (\n  <span\n    className={cn(\"transition-colors group-hover:bg-accent\", className)}\n    {...props}\n  />\n);\n\nexport type InlineCitationCardProps = ComponentProps<typeof HoverCard>;\n\nexport const InlineCitationCard = (props: InlineCitationCardProps) => (\n  <HoverCard closeDelay={0} openDelay={0} {...props} />\n);\n\nexport type InlineCitationCardTriggerProps = ComponentProps<typeof Badge> & {\n  sources: string[];\n};\n\nexport const InlineCitationCardTrigger = ({\n  sources,\n  className,\n  ...props\n}: InlineCitationCardTriggerProps) => (\n  <HoverCardTrigger asChild>\n    <Badge\n      className={cn(\"ml-1 rounded-full\", className)}\n      variant=\"secondary\"\n      {...props}\n    >\n      {sources[0] ? (\n        <>\n          {new URL(sources[0]).hostname}{\" \"}\n          {sources.length > 1 && `+${sources.length - 1}`}\n        </>\n      ) : (\n        \"unknown\"\n      )}\n    </Badge>\n  </HoverCardTrigger>\n);\n\nexport type InlineCitationCardBodyProps = ComponentProps<\"div\">;\n\nexport const InlineCitationCardBody = ({\n  className,\n  ...props\n}: InlineCitationCardBodyProps) => (\n  <HoverCardContent className={cn(\"relative w-80 p-0\", className)} {...props} />\n);\n\nconst CarouselApiContext = createContext<CarouselApi | undefined>(undefined);\n\nconst useCarouselApi = () => {\n  const context = useContext(CarouselApiContext);\n  return context;\n};\n\nexport type InlineCitationCarouselProps = ComponentProps<typeof Carousel>;\n\nexport const InlineCitationCarousel = ({\n  className,\n  children,\n  ...props\n}: InlineCitationCarouselProps) => {\n  const [api, setApi] = useState<CarouselApi>();\n\n  return (\n    <CarouselApiContext.Provider value={api}>\n      <Carousel className={cn(\"w-full\", className)} setApi={setApi} {...props}>\n        {children}\n      </Carousel>\n    </CarouselApiContext.Provider>\n  );\n};\n\nexport type InlineCitationCarouselContentProps = ComponentProps<\"div\">;\n\nexport const InlineCitationCarouselContent = (\n  props: InlineCitationCarouselContentProps\n) => <CarouselContent {...props} />;\n\nexport type InlineCitationCarouselItemProps = ComponentProps<\"div\">;\n\nexport const InlineCitationCarouselItem = ({\n  className,\n  ...props\n}: InlineCitationCarouselItemProps) => (\n  <CarouselItem\n    className={cn(\"w-full space-y-2 p-4 pl-8\", className)}\n    {...props}\n  />\n);\n\nexport type InlineCitationCarouselHeaderProps = ComponentProps<\"div\">;\n\nexport const InlineCitationCarouselHeader = ({\n  className,\n  ...props\n}: InlineCitationCarouselHeaderProps) => (\n  <div\n    className={cn(\n      \"flex items-center justify-between gap-2 rounded-t-md bg-secondary p-2\",\n      className\n    )}\n    {...props}\n  />\n);\n\nexport type InlineCitationCarouselIndexProps = ComponentProps<\"div\">;\n\nexport const InlineCitationCarouselIndex = ({\n  children,\n  className,\n  ...props\n}: InlineCitationCarouselIndexProps) => {\n  const api = useCarouselApi();\n  const [current, setCurrent] = useState(0);\n  const [count, setCount] = useState(0);\n\n  useEffect(() => {\n    if (!api) {\n      return;\n    }\n\n    setCount(api.scrollSnapList().length);\n    setCurrent(api.selectedScrollSnap() + 1);\n\n    api.on(\"select\", () => {\n      setCurrent(api.selectedScrollSnap() + 1);\n    });\n  }, [api]);\n\n  return (\n    <div\n      className={cn(\n        \"flex flex-1 items-center justify-end px-3 py-1 text-muted-foreground text-xs\",\n        className\n      )}\n      {...props}\n    >\n      {children ?? `${current}/${count}`}\n    </div>\n  );\n};\n\nexport type InlineCitationCarouselPrevProps = ComponentProps<\"button\">;\n\nexport const InlineCitationCarouselPrev = ({\n  className,\n  ...props\n}: InlineCitationCarouselPrevProps) => {\n  const api = useCarouselApi();\n\n  const handleClick = useCallback(() => {\n    if (api) {\n      api.scrollPrev();\n    }\n  }, [api]);\n\n  return (\n    <button\n      aria-label=\"Previous\"\n      className={cn(\"shrink-0\", className)}\n      onClick={handleClick}\n      type=\"button\"\n      {...props}\n    >\n      <ArrowLeftIcon className=\"size-4 text-muted-foreground\" />\n    </button>\n  );\n};\n\nexport type InlineCitationCarouselNextProps = ComponentProps<\"button\">;\n\nexport const InlineCitationCarouselNext = ({\n  className,\n  ...props\n}: InlineCitationCarouselNextProps) => {\n  const api = useCarouselApi();\n\n  const handleClick = useCallback(() => {\n    if (api) {\n      api.scrollNext();\n    }\n  }, [api]);\n\n  return (\n    <button\n      aria-label=\"Next\"\n      className={cn(\"shrink-0\", className)}\n      onClick={handleClick}\n      type=\"button\"\n      {...props}\n    >\n      <ArrowRightIcon className=\"size-4 text-muted-foreground\" />\n    </button>\n  );\n};\n\nexport type InlineCitationSourceProps = ComponentProps<\"div\"> & {\n  title?: string;\n  url?: string;\n  description?: string;\n};\n\nexport const InlineCitationSource = ({\n  title,\n  url,\n  description,\n  className,\n  children,\n  ...props\n}: InlineCitationSourceProps) => (\n  <div className={cn(\"space-y-1\", className)} {...props}>\n    {title && (\n      <h4 className=\"truncate font-medium text-sm leading-tight\">{title}</h4>\n    )}\n    {url && (\n      <p className=\"truncate break-all text-muted-foreground text-xs\">{url}</p>\n    )}\n    {description && (\n      <p className=\"line-clamp-3 text-muted-foreground text-sm leading-relaxed\">\n        {description}\n      </p>\n    )}\n    {children}\n  </div>\n);\n\nexport type InlineCitationQuoteProps = ComponentProps<\"blockquote\">;\n\nexport const InlineCitationQuote = ({\n  children,\n  className,\n  ...props\n}: InlineCitationQuoteProps) => (\n  <blockquote\n    className={cn(\n      \"border-muted border-l-2 pl-3 text-muted-foreground text-sm italic\",\n      className\n    )}\n    {...props}\n  >\n    {children}\n  </blockquote>\n);\n","target":"components/ai-elements/inline-citation.tsx"}],"dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["badge","carousel","hover-card"]}