{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "elements-chart",
  "type": "registry:component",
  "title": "Chart",
  "description": "Area, line, and bars, with points landing one at a time as the series streams in.",
  "registryDependencies": [
    "https://r.assistant-ui.com/elements-surfaces.json",
    "https://r.assistant-ui.com/elements-range.json"
  ],
  "files": [
    {
      "type": "registry:component",
      "path": "components/assistant-ui/elements/chart.tsx",
      "sourcePath": "packages/ui/src/components/react/assistant-ui/elements/chart.tsx",
      "content": "\"use client\";\n\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { mono, paper } from \"./surfaces\";\nimport { clamp, take } from \"../utils/range\";\n\nexport type ChartVariant = \"area\" | \"line\" | \"bars\";\n\nconst W = 300;\nconst H = 88;\nconst PAD = 6;\n\nconst scale = (points: readonly number[]) => {\n  const max = Math.max(...points, 1);\n  const min = Math.min(...points, 0);\n  const span = max - min || 1;\n  return (value: number) => H - PAD - ((value - min) / span) * (H - PAD * 2);\n};\n\nexport function Chart({\n  label,\n  value,\n  delta,\n  points,\n  visibleCount,\n  variant = \"area\",\n  className,\n  ...props\n}: Omit<\n  ComponentProps<\"div\">,\n  | \"children\"\n  | \"label\"\n  | \"value\"\n  | \"delta\"\n  | \"points\"\n  | \"visibleCount\"\n  | \"variant\"\n> & {\n  label: string;\n  value: string;\n  delta?: string;\n  points: readonly number[];\n  visibleCount: number;\n  variant?: ChartVariant;\n}) {\n  const shown = take(points, clamp(visibleCount, 1, points.length));\n  const y = scale(points);\n  const step = points.length > 1 ? (W - PAD * 2) / (points.length - 1) : 0;\n  const x = (i: number) => PAD + i * step;\n\n  const coords = shown.map((p, i) => ({ x: x(i), y: y(p) }));\n  const line = coords.map((c) => `${c.x},${c.y}`).join(\" \");\n  const last = coords.at(-1);\n  const area = last\n    ? `M ${PAD},${H - PAD} ${coords.map((c) => `L ${c.x},${c.y}`).join(\" \")} L ${last.x},${H - PAD} Z`\n    : \"\";\n  const lastIndex = shown.length - 1;\n  const falling = delta !== undefined && /^\\s*[-−–]/.test(delta);\n  const rising = delta !== undefined && !falling;\n\n  return (\n    <div\n      data-slot=\"chart\"\n      className={cn(\n        paper,\n        \"flex w-full max-w-sm flex-col gap-3 rounded-2xl p-4\",\n        className,\n      )}\n\n      {...props}\n    >\n      <div className=\"flex items-baseline justify-between\">\n        <span className={cn(mono, \"text-foreground/35\")}>{label}</span>\n        {delta !== undefined && (\n          <span\n            className={cn(\n              mono,\n              \"tabular-nums\",\n              rising\n                ? \"text-emerald-600 dark:text-emerald-400\"\n                : \"text-red-600 dark:text-red-400\",\n            )}\n          >\n            {delta}\n          </span>\n        )}\n      </div>\n\n      <span className=\"text-2xl font-medium tracking-tight tabular-nums\">\n        {value}\n      </span>\n\n      <svg\n        viewBox={`0 0 ${W} ${H}`}\n        role=\"img\"\n        aria-label={`${label}: ${value}`}\n        className=\"h-[88px] w-full overflow-visible\"\n        preserveAspectRatio=\"none\"\n      >\n        <line\n          x1=\"0\"\n          x2={W}\n          y1={H - PAD}\n          y2={H - PAD}\n          className=\"stroke-foreground/[0.08]\"\n          strokeWidth=\"1\"\n          vectorEffect=\"non-scaling-stroke\"\n        />\n        {variant === \"bars\" ? (\n          shown.map((p, i) => {\n            const top = y(p);\n            const barWidth = Math.max(2, step * 0.55);\n            return (\n              <rect\n                key={i}\n                x={x(i) - barWidth / 2}\n                y={top}\n                width={barWidth}\n                height={Math.max(1, H - PAD - top)}\n                rx=\"1.5\"\n                className={cn(\n                  \"fade-in animate-in fill-mode-both duration-300\",\n                  i === lastIndex\n                    ? \"fill-blue-500 dark:fill-blue-400\"\n                    : \"fill-foreground/25\",\n                )}\n                style={{ animationDelay: `${i * 40}ms` }}\n              />\n            );\n          })\n        ) : (\n          <>\n            {variant === \"area\" && shown.length > 1 && (\n              <path\n                d={area}\n                className=\"fill-blue-500/12 dark:fill-blue-400/15\"\n              />\n            )}\n            <polyline\n              points={line}\n              fill=\"none\"\n              strokeWidth=\"1.75\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n              vectorEffect=\"non-scaling-stroke\"\n              className=\"stroke-blue-500 dark:stroke-blue-400\"\n            />\n            {last && (\n              <circle\n                cx={last.x}\n                cy={last.y}\n                r=\"3\"\n                className=\"fill-blue-500 dark:fill-blue-400\"\n              />\n            )}\n          </>\n        )}\n      </svg>\n    </div>\n  );\n}\n"
    }
  ]
}