{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "spark-chart",
  "type": "registry:ui",
  "title": "Spark Chart",
  "description": "Inline mini line/area/bar chart. Pure SVG, no recharts. Tucks inside metric cards.",
  "dependencies": [
    "@saasflare/ui"
  ],
  "files": [
    {
      "path": "components/ui/spark-chart.tsx",
      "type": "registry:ui",
      "content": "// @draft\n\"use client\"\n\n/**\n * @fileoverview Saasflare SparkChart — inline mini line/area/bar visualization.\n * @author Saasflare™\n *\n * Compact (~64×24 px by default) chart for tucking inside metric cards,\n * table cells, or KPI tiles. Pure SVG — no recharts dependency, no axes,\n * no tooltip overhead. For full charts use the `Chart` subpath\n * (`@saasflare/ui/chart`).\n *\n * @module packages/ui/components/ui/spark-chart\n * @package ui\n * @layer core\n *\n * @example\n * <SparkChart data={[3, 5, 4, 8, 6, 9, 11]} variant=\"area\" />\n *\n * @example\n * <MetricCard\n *   title=\"MRR\"\n *   value=\"$24,180\"\n *   chart={<SparkChart data={mrrSeries} variant=\"line\" />}\n * />\n */\n\nimport { cn } from \"@saasflare/ui\"\nimport { useSaasflareProps, type SaasflareComponentProps } from \"@saasflare/ui\"\n\n/** Visual variant of the spark chart. */\nexport type SparkChartVariant = \"line\" | \"area\" | \"bar\"\n\n/** Props for the SparkChart component. */\nexport interface SparkChartProps extends SaasflareComponentProps {\n    /** Series of numeric points (length ≥ 2). */\n    data: number[]\n    /** Visual treatment. Default: `\"area\"`. */\n    variant?: SparkChartVariant\n    /** Stroke / fill color (any CSS color). Default: `var(--primary)`. */\n    color?: string\n    /** SVG width in pixels. Default: `64`. */\n    width?: number\n    /** SVG height in pixels. Default: `24`. */\n    height?: number\n    /** Line stroke width in pixels. Default: `1.5`. */\n    strokeWidth?: number\n    /** Additional class names. */\n    className?: string\n    /** Accessible label. */\n    \"aria-label\"?: string\n}\n\nfunction buildPath(data: number[], width: number, height: number, sw: number) {\n    const min = Math.min(...data)\n    const max = Math.max(...data)\n    const span = max - min || 1\n    const innerW = width - sw\n    const innerH = height - sw\n    const offset = sw / 2\n\n    return data\n        .map((v, i) => {\n            const x = offset + (i / (data.length - 1)) * innerW\n            const y = offset + innerH - ((v - min) / span) * innerH\n            return `${i === 0 ? \"M\" : \"L\"} ${x.toFixed(2)} ${y.toFixed(2)}`\n        })\n        .join(\" \")\n}\n\n/**\n * Inline mini chart for KPI tiles, table cells, and metric cards.\n *\n * @component\n * @layer core\n */\nexport function SparkChart({\n    data,\n    variant = \"area\",\n    color,\n    width = 64,\n    height = 24,\n    strokeWidth = 1.5,\n    className,\n    surface,\n    radius,\n    animated,\n    iconWeight,\n    \"aria-label\": ariaLabel,\n}: SparkChartProps) {\n    const sf = useSaasflareProps({ surface, radius, animated, iconWeight })\n\n    const points = data.filter((v) => Number.isFinite(v))\n    if (points.length < 2) return null\n\n    const stroke = color ?? \"var(--primary)\"\n    const linePath = buildPath(points, width, height, strokeWidth)\n    const areaPath = `${linePath} L ${width - strokeWidth / 2} ${height - strokeWidth / 2} L ${strokeWidth / 2} ${height - strokeWidth / 2} Z`\n\n    const min = Math.min(...points)\n    const max = Math.max(...points)\n    const span = max - min || 1\n    const innerH = height - strokeWidth\n    const offset = strokeWidth / 2\n    // Proportional slot layout: each bar gets an equal slice of the width with a\n    // ~30% gap. Scales to any point count (the old fixed-gap formula went\n    // negative past ~40 points and the bars vanished).\n    const slot = width / points.length\n    const barW = Math.max(slot * 0.7, 0.5)\n\n    return (\n        <svg\n            data-slot=\"spark-chart\"\n            data-variant={variant}\n            data-surface={sf.surface}\n            data-radius={sf.radius}\n            data-animated={String(sf.animated)}\n            width={width}\n            height={height}\n            viewBox={`0 0 ${width} ${height}`}\n            role=\"img\"\n            aria-label={ariaLabel ?? `Sparkline ${variant}`}\n            className={cn(\"inline-block align-middle\", className)}\n        >\n            {variant === \"bar\" ? (\n                points.map((v, i) => {\n                    const h = Math.max(((v - min) / span) * innerH, 1)\n                    const x = i * slot + (slot - barW) / 2\n                    const y = offset + innerH - h\n                    return (\n                        <rect\n                            key={i}\n                            data-slot=\"spark-chart-bar\"\n                            x={x}\n                            y={y}\n                            width={barW}\n                            height={h}\n                            fill={stroke}\n                            rx={1}\n                        />\n                    )\n                })\n            ) : (\n                <>\n                    {variant === \"area\" && (\n                        <path\n                            data-slot=\"spark-chart-area\"\n                            d={areaPath}\n                            fill={stroke}\n                            fillOpacity={0.18}\n                        />\n                    )}\n                    <path\n                        data-slot=\"spark-chart-line\"\n                        d={linePath}\n                        fill=\"none\"\n                        stroke={stroke}\n                        strokeWidth={strokeWidth}\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                </>\n            )}\n        </svg>\n    )\n}\n",
      "target": "components/ui/spark-chart.tsx"
    }
  ],
  "$meta": {
    "source": "https://ui.saasflare.io/r/spark-chart.json"
  }
}
