{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "aurora-ai-schema-display",
  "title": "Aurora AI Schema Display",
  "author": "jmagar <https://github.com/jmagar>",
  "description": "Aurora-native schema display parity surface from AI Elements.",
  "dependencies": [
    "lucide-react@^0.487.0"
  ],
  "registryDependencies": [
    "@aurora/aurora-tokens",
    "@aurora/aurora-ai-elements"
  ],
  "files": [
    {
      "path": "registry/aurora/blocks/ai/elements/schema-display.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Code } from \"lucide-react\"\nimport { cn } from \"@/lib/utils\"\nimport { Badge } from \"@/registry/aurora/ui/badge\"\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface JsonSchemaProperty {\n  type?: string\n  description?: string\n  items?: { type?: string }\n  [key: string]: unknown\n}\n\nexport interface JsonSchema {\n  type?: string\n  required?: string[]\n  properties?: Record<string, JsonSchemaProperty>\n  [key: string]: unknown\n}\n\nexport interface SchemaDisplayProps extends React.HTMLAttributes<HTMLDivElement> {\n  /** JSON Schema object to render. */\n  schema: JsonSchema | unknown\n  /** Header title shown beside the code glyph. */\n  title?: string\n  /** Initial view tab. Defaults to \"fields\". */\n  defaultView?: \"fields\" | \"json\"\n}\n\n// ---------------------------------------------------------------------------\n// Type-tone mapping — each JSON-schema scalar maps to an Aurora status tone.\n// Array/string -> success, integer/number -> warn, boolean -> rose.\n// ---------------------------------------------------------------------------\n\ntype TypeTone = {\n  badge: \"info\" | \"success\" | \"warn\" | \"rose\"\n}\n\nfunction toneForType(type: string): TypeTone {\n  const base = type.replace(/\\[\\]$/, \"\")\n  switch (base) {\n    case \"integer\":\n    case \"number\":\n      return {\n        badge: \"warn\",\n      }\n    case \"boolean\":\n      return {\n        badge: \"rose\",\n      }\n    case \"object\":\n      return {\n        badge: \"info\",\n      }\n    // string, array (string[]), and anything else → success teal\n    default:\n      return {\n        badge: \"success\",\n      }\n  }\n}\n\nfunction displayType(prop: JsonSchemaProperty): string {\n  if (prop.type === \"array\") {\n    const itemType = prop.items?.type ?? \"any\"\n    return `${itemType}[]`\n  }\n  return prop.type ?? \"any\"\n}\n\n// ---------------------------------------------------------------------------\n// Raw JSON renderer (token-colored, mono).\n// ---------------------------------------------------------------------------\n\nfunction renderJsonValue(value: unknown, depth = 0): React.ReactNode {\n  const indent = \"  \".repeat(depth)\n\n  if (Array.isArray(value)) {\n    if (value.length === 0) return <span style={{ color: \"var(--aurora-text-muted)\" }}>[]</span>\n    return (\n      <>\n        <span style={{ color: \"var(--aurora-text-muted)\" }}>[</span>\n        {\"\\n\"}\n        {value.map((item, index) => (\n          <React.Fragment key={index}>\n            {indent}\n            {\"  \"}\n            {renderJsonValue(item, depth + 1)}\n            {index < value.length - 1 ? <span style={{ color: \"var(--aurora-text-muted)\" }}>,</span> : null}\n            {\"\\n\"}\n          </React.Fragment>\n        ))}\n        {indent}\n        <span style={{ color: \"var(--aurora-text-muted)\" }}>]</span>\n      </>\n    )\n  }\n\n  if (value && typeof value === \"object\") {\n    const entries = Object.entries(value)\n    if (entries.length === 0) return <span style={{ color: \"var(--aurora-text-muted)\" }}>{`{}`}</span>\n    return (\n      <>\n        <span style={{ color: \"var(--aurora-text-muted)\" }}>{`{`}</span>\n        {\"\\n\"}\n        {entries.map(([key, entryValue], index) => (\n          <React.Fragment key={key}>\n            {indent}\n            {\"  \"}\n            <span style={{ color: \"var(--aurora-accent-primary)\" }}>{`\"${key}\"`}</span>\n            <span style={{ color: \"var(--aurora-text-muted)\" }}>: </span>\n            {renderJsonValue(entryValue, depth + 1)}\n            {index < entries.length - 1 ? <span style={{ color: \"var(--aurora-text-muted)\" }}>,</span> : null}\n            {\"\\n\"}\n          </React.Fragment>\n        ))}\n        {indent}\n        <span style={{ color: \"var(--aurora-text-muted)\" }}>{`}`}</span>\n      </>\n    )\n  }\n\n  if (typeof value === \"string\") return <span style={{ color: \"var(--aurora-accent-pink)\" }}>{`\"${value}\"`}</span>\n  if (typeof value === \"number\") return <span style={{ color: \"var(--aurora-warn)\" }}>{value}</span>\n  if (typeof value === \"boolean\") return <span style={{ color: \"var(--aurora-success)\" }}>{String(value)}</span>\n  if (value === null) return <span style={{ color: \"var(--aurora-text-muted)\" }}>null</span>\n  return <span style={{ color: \"var(--aurora-text-primary)\" }}>{String(value)}</span>\n}\n\n// ---------------------------------------------------------------------------\n// SchemaDisplay\n// ---------------------------------------------------------------------------\n\nconst SchemaDisplay = ({ ref, schema, title = \"Schema\", defaultView = \"fields\", className, style, ...props }: SchemaDisplayProps & { ref?: React.Ref<HTMLDivElement> }) => {\n    const [view, setView] = React.useState<\"fields\" | \"json\">(defaultView)\n\n    const typed = (schema ?? {}) as JsonSchema\n    const properties = typed.properties ?? {}\n    const required = new Set(typed.required ?? [])\n    const fieldNames = Object.keys(properties)\n\n    const tabBase =\n      \"rounded-[8px] px-3 py-1.5 aurora-text-control transition-colors focus-visible:outline-none focus-visible:ring-2\"\n\n    return (\n      <div\n        ref={ref}\n        className={cn(\"overflow-hidden rounded-[var(--aurora-radius-1)] border\", className)}\n        style={{\n          borderColor: \"var(--aurora-border-strong)\",\n          background: \"var(--aurora-surface-raised)\",\n          boxShadow: \"var(--aurora-shadow-medium), var(--aurora-highlight-medium)\",\n          fontFamily: \"var(--aurora-font-sans)\",\n          ...style,\n        }}\n        {...props}\n      >\n        {/* Header */}\n        <div\n          className=\"flex items-center justify-between gap-3 px-5 py-4\"\n          style={{ borderBottom: \"1px solid var(--aurora-border-default)\" }}\n        >\n          <div className=\"flex min-w-0 items-center gap-2.5\">\n            <Code\n              className=\"size-[18px] shrink-0\"\n              style={{ color: \"var(--axon-orange)\" }}\n              aria-hidden\n            />\n            <span\n              className=\"truncate text-[16px] font-bold\"\n              style={{ color: \"var(--aurora-text-primary)\" }}\n            >\n              {title}\n            </span>\n          </div>\n          <div\n            role=\"tablist\"\n            aria-label=\"Schema view\"\n            className=\"flex shrink-0 items-center gap-1 rounded-[10px] p-1\"\n            style={{\n              border: \"1px solid var(--aurora-border-default)\",\n              background: \"var(--aurora-control-surface)\",\n            }}\n          >\n            <button\n              type=\"button\"\n              role=\"tab\"\n              aria-selected={view === \"fields\"}\n              onClick={() => setView(\"fields\")}\n              className={tabBase}\n              style={\n                view === \"fields\"\n                  ? {\n                      color: \"var(--aurora-accent-primary)\",\n                      background: \"var(--aurora-accent-primary-surface)\",\n                      border: \"1px solid var(--aurora-accent-primary-border)\",\n                      boxShadow: \"var(--aurora-active-glow)\",\n                    }\n                  : {\n                      color: \"var(--aurora-text-muted)\",\n                      background: \"transparent\",\n                      border: \"1px solid transparent\",\n                    }\n              }\n            >\n              Fields\n            </button>\n            <button\n              type=\"button\"\n              role=\"tab\"\n              aria-selected={view === \"json\"}\n              onClick={() => setView(\"json\")}\n              className={tabBase}\n              style={\n                view === \"json\"\n                  ? {\n                      color: \"var(--aurora-accent-primary)\",\n                      background: \"var(--aurora-accent-primary-surface)\",\n                      border: \"1px solid var(--aurora-accent-primary-border)\",\n                      boxShadow: \"var(--aurora-active-glow)\",\n                    }\n                  : {\n                      color: \"var(--aurora-text-muted)\",\n                      background: \"transparent\",\n                      border: \"1px solid transparent\",\n                    }\n              }\n            >\n              JSON\n            </button>\n          </div>\n        </div>\n\n        {/* Body */}\n        {view === \"fields\" ? (\n          <div role=\"tabpanel\" aria-label=\"Fields\">\n            {fieldNames.length === 0 ? (\n              <div\n                className=\"px-5 py-4 text-[13px]\"\n                style={{ color: \"var(--aurora-text-muted)\" }}\n              >\n                No fields defined.\n              </div>\n            ) : (\n              fieldNames.map((name, index) => {\n                const prop = properties[name]\n                const type = displayType(prop)\n                const tone = toneForType(type)\n                const isRequired = required.has(name)\n                return (\n                  <div\n                    key={name}\n                    className=\"grid grid-cols-[minmax(0,1fr)_auto] items-start gap-4 px-5 py-4\"\n                    style={\n                      index < fieldNames.length - 1\n                        ? { borderBottom: \"1px solid var(--aurora-border-default)\" }\n                        : undefined\n                    }\n                  >\n                    <div className=\"min-w-0\">\n                      <div className=\"flex items-center gap-2.5\">\n                        <span\n                          className=\"text-[16px] font-bold\"\n                          style={{ color: \"var(--aurora-text-primary)\", fontFamily: \"var(--aurora-font-mono)\" }}\n                        >\n                          {name}\n                        </span>\n                        {isRequired ? (\n                          <Badge tone=\"warn\" size=\"sm\" shape=\"label\">\n                            Required\n                          </Badge>\n                        ) : null}\n                      </div>\n                      {prop.description ? (\n                        <p\n                          className=\"mt-1.5 text-[14px]\"\n                          style={{ color: \"var(--aurora-text-muted)\" }}\n                        >\n                          {prop.description}\n                        </p>\n                      ) : null}\n                    </div>\n                    <Badge tone={tone.badge} size=\"sm\" shape=\"tag\">\n                      {type}\n                    </Badge>\n                  </div>\n                )\n              })\n            )}\n          </div>\n        ) : (\n          <div role=\"tabpanel\" aria-label=\"JSON\">\n            <pre\n              className=\"aurora-text-code m-0 overflow-auto px-5 py-4\"\n              style={{ background: \"transparent\" }}\n            >\n              {renderJsonValue(schema)}\n            </pre>\n          </div>\n        )}\n      </div>\n    )\n  }\nSchemaDisplay.displayName = \"SchemaDisplay\"\n\nexport { SchemaDisplay }\nexport default SchemaDisplay\n",
      "type": "registry:component",
      "target": "@components/aurora/ai/schema-display.tsx"
    }
  ],
  "meta": {
    "namespace": "@aurora",
    "style": "aurora",
    "family": "block",
    "requiresTokens": true,
    "sourcePath": "registry/aurora/blocks/ai/elements/schema-display.tsx",
    "installTarget": "@components/aurora/ai/schema-display.tsx",
    "taxonomy": "ai"
  },
  "docs": "Aurora block that expects `aurora-tokens` to be installed first.\n\nDefault install target: `@components/aurora/ai/schema-display.tsx`.\n\nRegistry dependencies: `aurora-tokens`, `aurora-ai-elements`.",
  "categories": [
    "aurora",
    "block",
    "ai"
  ],
  "type": "registry:block"
}