{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "ai-inline-citation",
  "title": "AI: Inline Citation",
  "description": "Inline citation badges with a hover-card carousel of source cards and quotes.",
  "dependencies": [
    "@untitledui/icons@^0.0.22"
  ],
  "registryDependencies": [
    "@nx-ui/utils",
    "@nx-ui/badge",
    "@nx-ui/carousel",
    "@nx-ui/hover-card"
  ],
  "files": [
    {
      "path": "components/ai/inline-citation.tsx",
      "content": "\"use client\"\n\nimport {\n  type ComponentProps,\n  createContext,\n  useCallback,\n  useContext,\n  useEffect,\n  useState,\n} from \"react\"\nimport { ArrowLeft, ArrowRight } from \"@untitledui/icons\"\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\"\n\nexport type InlineCitationProps = ComponentProps<\"span\">\n\nexport const InlineCitation = ({ className, ...props }: InlineCitationProps) => (\n  <span className={cn(\"group inline items-center gap-1\", className)} {...props} />\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 {...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\n    render={\n      <Badge className={cn(\"ml-1 rounded-full\", className)} variant=\"secondary\" {...props}>\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    }\n  />\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 className={cn(\"w-full space-y-2 p-4 pl-8\", className)} {...props} />\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-lg 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      <ArrowLeft 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      <ArrowRight 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",
      "type": "registry:ui",
      "target": "components/ai/inline-citation.tsx"
    }
  ],
  "type": "registry:ui"
}