{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "aurora-ai-sources",
  "title": "Aurora AI Sources",
  "author": "jmagar <https://github.com/jmagar>",
  "description": "Aurora-native sources parity surface from AI Elements.",
  "dependencies": [
    "lucide-react@^0.487.0"
  ],
  "registryDependencies": [
    "@aurora/aurora-tokens",
    "@aurora/aurora-ai-elements",
    "@aurora/aurora-badge",
    "@aurora/aurora-button",
    "@aurora/aurora-ai-source"
  ],
  "files": [
    {
      "path": "registry/aurora/blocks/ai/elements/sources.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { ChevronDown, FileText } from \"lucide-react\"\nimport { Badge } from \"@/registry/aurora/ui/badge\"\nimport { Button } from \"@/registry/aurora/ui/button\"\nimport { Source, type SourceItem, type SourceProps } from \"@/registry/aurora/blocks/ai/elements/source\"\n\n// ---------------------------------------------------------------------------\n// Types (architecture source of truth — keep the existing registry API)\n// ---------------------------------------------------------------------------\n\nexport interface SourcesProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n  title?: React.ReactNode\n  /** Render the count badge + chevron and allow the body to collapse. */\n  collapsible?: boolean\n  /** Control the collapsed state (uncontrolled defaults to expanded). */\n  open?: boolean\n  defaultOpen?: boolean\n  onOpenChange?: (open: boolean) => void\n}\n\nexport type { SourceItem, SourceProps }\n\n// ---------------------------------------------------------------------------\n// Shared surface helpers (ported from CD injected CSS)\n// ---------------------------------------------------------------------------\n\nfunction panelStyle(style?: React.CSSProperties): React.CSSProperties {\n  return {\n    background: \"var(--aurora-surface-raised)\",\n    border: \"1px solid var(--aurora-border-strong)\",\n    borderRadius: \"var(--aurora-radius-1)\",\n    boxShadow: \"var(--aurora-shadow-medium), var(--aurora-highlight-medium)\",\n    ...style,\n  }\n}\n\n\n// ---------------------------------------------------------------------------\n// Count badge — small neutral pill next to the title\n// ---------------------------------------------------------------------------\n\nfunction CountBadge({ count }: { count: number }) {\n  return (\n    <Badge\n      tone=\"neutral\"\n      fill=\"outline\"\n      className=\"min-w-[22px] justify-center px-1.5 tabular-nums\"\n    >\n      {count}\n    </Badge>\n  )\n}\n\n// ---------------------------------------------------------------------------\n// Sources — bordered panel with file icon, title, count badge, collapsible body\n// ---------------------------------------------------------------------------\n\nconst Sources = (\n    { ref,\n      className,\n      title = \"Sources\",\n      collapsible = false,\n      open: openProp,\n      defaultOpen = true,\n      onOpenChange,\n      style,\n      children,\n      ...props\n    }: SourcesProps & { ref?: React.Ref<HTMLDivElement> }\n  ) => {\n    const isControlled = openProp !== undefined\n    const [openState, setOpenState] = React.useState(defaultOpen)\n    const open = isControlled ? openProp : openState\n\n    const count = React.Children.toArray(children).filter(React.isValidElement).length\n\n    const toggle = React.useCallback(() => {\n      const next = !open\n      if (!isControlled) setOpenState(next)\n      onOpenChange?.(next)\n    }, [open, isControlled, onOpenChange])\n\n    const headerInner = (\n      <>\n        <FileText className=\"size-[18px] shrink-0\" aria-hidden style={{ color: \"var(--aurora-accent-pink)\" }} />\n        <span\n          className=\"aurora-text-label\"\n          style={{ color: \"var(--aurora-text-primary)\", fontSize: 16, fontWeight: 700 }}\n        >\n          {title}\n        </span>\n        {collapsible ? <CountBadge count={count} /> : null}\n        {collapsible ? (\n          <ChevronDown\n            className=\"ml-auto size-[18px] shrink-0 transition-transform\"\n            aria-hidden\n            style={{\n              color: \"var(--aurora-text-muted)\",\n              transform: open ? \"rotate(180deg)\" : \"rotate(0deg)\",\n            }}\n          />\n        ) : null}\n      </>\n    )\n\n    return (\n      <div\n        ref={ref}\n        className={[\"grid gap-3 p-4\", className].filter(Boolean).join(\" \")}\n        style={panelStyle(style)}\n        {...props}\n      >\n        {collapsible ? (\n          <Button\n            type=\"button\"\n            variant=\"plain\"\n            size=\"unstyled\"\n            onClick={toggle}\n            aria-expanded={open}\n            className=\"flex items-center gap-2.5 bg-transparent p-0 text-left outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--aurora-focus-ring)] focus-visible:ring-offset-0\"\n            style={{ borderRadius: \"var(--aurora-radius-1)\", cursor: \"pointer\", color: \"inherit\" }}\n          >\n            {headerInner}\n          </Button>\n        ) : (\n          <div className=\"flex items-center gap-2.5\">{headerInner}</div>\n        )}\n        {!collapsible || open ? <div className=\"grid gap-2.5\">{children}</div> : null}\n      </div>\n    )\n  }\nSources.displayName = \"Sources\"\n\nexport { Source, Sources }\n",
      "type": "registry:component",
      "target": "@components/aurora/ai/sources.tsx"
    }
  ],
  "meta": {
    "namespace": "@aurora",
    "style": "aurora",
    "family": "block",
    "requiresTokens": true,
    "sourcePath": "registry/aurora/blocks/ai/elements/sources.tsx",
    "installTarget": "@components/aurora/ai/sources.tsx",
    "taxonomy": "ai"
  },
  "docs": "Aurora block that expects its declared dependencies to be installed first.\n\nDefault install target: `@components/aurora/ai/sources.tsx`.\n\nRegistry dependencies: `aurora-tokens`, `aurora-ai-elements`, `aurora-badge`, `aurora-button`, `aurora-ai-source`.",
  "categories": [
    "aurora",
    "block",
    "ai"
  ],
  "type": "registry:block"
}