{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "sources",
  "title": "Sources",
  "description": "\"Used N sources\" with stacked tiles, expanding into the list.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils",
    "https://ui.cuelark.com/r/theme.json",
    "https://ui.cuelark.com/r/collapsible.json",
    "https://ui.cuelark.com/r/motion.json"
  ],
  "files": [
    {
      "path": "src/registry/cuelark/ui/sources.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { ArrowUpRightIcon, ChevronDownIcon } from \"lucide-react\";\n\nimport { enterChildren, gsap, motionScale } from \"@/lib/motion\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"@/registry/cuelark/ui/collapsible\";\nimport { cn } from \"@/lib/utils\";\n\ntype Source = { title: string; url: string };\n\nconst host = (url: string) => {\n  try {\n    return new URL(url).hostname.replace(/^www\\./, \"\");\n  } catch {\n    return url;\n  }\n};\n\n/** A letter tile per domain, tinted deterministically: recognizable without loading third-party favicons. */\nfunction SourceTile({ url, className }: { url: string; className?: string }) {\n  const h = host(url);\n  const hue = [...h].reduce((a, c) => (a * 31 + c.charCodeAt(0)) % 360, 11);\n  return (\n    <span className={cn(\"grid size-5 shrink-0 place-items-center rounded-md text-[0.625rem] font-semibold uppercase ring-2 ring-card\", className)} style={{ background: `oklch(0.92 0.05 ${hue})`, color: `oklch(0.38 0.1 ${hue})` }}>\n      {h[0]}\n    </span>\n  );\n}\n\n/** \"Used 5 sources\", with their tiles stacked; expands into the list of links, staggered in. */\nfunction Sources({ sources, className, ...props }: Omit<React.ComponentProps<typeof Collapsible>, \"children\"> & { sources: Source[] }) {\n  const list = React.useRef<HTMLUListElement>(null);\n  return (\n    <Collapsible\n      data-slot=\"sources\"\n      className={cn(\"grid gap-2\", className)}\n      onOpenChange={(o) => o && requestAnimationFrame(() => list.current && motionScale(list.current) && enterChildren(list.current.children, { opacity: 0, y: 4 }, { stagger: 0.03, duration: 0.25 }))}\n      {...props}\n    >\n      <CollapsibleTrigger\n        onPointerEnter={(e) => motionScale(e.currentTarget) && gsap.to(e.currentTarget.querySelectorAll('[data-part=\"tile\"]'), { x: (i) => i * 4, duration: 0.3, ease: \"cue\", overwrite: \"auto\" })}\n        onPointerLeave={(e) => gsap.to(e.currentTarget.querySelectorAll('[data-part=\"tile\"]'), { x: 0, duration: 0.3, ease: \"cue\", overwrite: \"auto\" })}\n        className=\"group/sources flex w-fit items-center gap-2 rounded-full border border-border bg-card py-1 ps-1 pe-2.5 text-xs font-medium outline-none hover:bg-muted focus-visible:ring-3 focus-visible:ring-ring/50\">\n        <span className=\"flex -space-x-1.5\">\n          {sources.slice(0, 4).map((s) => (\n            <span key={s.url} data-part=\"tile\" className=\"grid\">\n              <SourceTile url={s.url} />\n            </span>\n          ))}\n        </span>\n        Used {sources.length} sources\n        <ChevronDownIcon className=\"size-3.5 text-muted-foreground transition-transform duration-200 ease-cue group-data-[state=open]/sources:rotate-180\" />\n      </CollapsibleTrigger>\n      <CollapsibleContent>\n        <ul ref={list} className=\"grid gap-1 sm:grid-cols-2\">\n          {sources.map((s, i) => (\n            <li key={s.url}>\n              <a href={s.url} target=\"_blank\" rel=\"noopener noreferrer\" className=\"group/src flex items-center gap-2.5 rounded-lg border border-border bg-card p-2 text-sm outline-none transition-colors hover:bg-muted/60 focus-visible:ring-3 focus-visible:ring-ring/50\">\n                <span className=\"font-mono text-[0.6875rem] text-muted-foreground tabular-nums\">{i + 1}</span>\n                <SourceTile url={s.url} />\n                <span className=\"grid min-w-0 flex-1\">\n                  <span className=\"truncate font-medium\">{s.title}</span>\n                  <span className=\"truncate font-mono text-[0.6875rem] text-muted-foreground\">{host(s.url)}</span>\n                </span>\n                <ArrowUpRightIcon className=\"size-3.5 shrink-0 text-muted-foreground transition-transform group-hover/src:translate-x-0.5 group-hover/src:-translate-y-0.5\" />\n              </a>\n            </li>\n          ))}\n        </ul>\n      </CollapsibleContent>\n    </Collapsible>\n  );\n}\n\nexport { Sources, SourceTile };\nexport type { Source };\n",
      "type": "registry:ui"
    }
  ],
  "docs": "Docs and examples: https://ui.cuelark.com/components/sources",
  "categories": [
    "agents"
  ],
  "type": "registry:ui"
}