{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "spark-line", "title": "Spark Line", "description": "Dependency-free sparkline glyph: line, filled area, or line with local maxima marked.", "dependencies": [ "class-variance-authority" ], "registryDependencies": [ "http://localhost:5173/r/liquid-theme.json", "http://localhost:5173/r/liquid-path.json" ], "files": [ { "path": "src/components/ui/spark-line.tsx", "content": "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\nimport { areaPath, linePath, scale, smoothPath } from \"@/lib/liquid-path\"\n\nconst spark = cva(\"block max-w-full overflow-visible\", {\n variants: {\n tone: {\n ink: \"text-ink dark:text-white\",\n current: \"text-current\",\n volt: \"text-volt\",\n flare: \"text-flare\",\n muted: \"text-current opacity-40\",\n },\n },\n defaultVariants: { tone: \"ink\" },\n})\n\nexport interface SparkLineProps\n extends Omit, \"values\">,\n VariantProps {\n values: number[]\n /**\n * `line` is the Credit Age glyph. `area` fills to the baseline.\n * `peaks` marks local maxima with dots, as the reference tile does.\n */\n variant?: \"line\" | \"area\" | \"peaks\"\n width?: number\n height?: number\n strokeWidth?: number\n /** 0 is a polyline; ~0.5 matches the reference curvature. */\n tension?: number\n}\n\nexport function SparkLine({\n values,\n variant = \"line\",\n width = 120,\n height = 40,\n strokeWidth = 1.5,\n tension = 0.55,\n tone,\n className,\n style,\n ...props\n}: SparkLineProps) {\n const pad = strokeWidth + 2\n const points = React.useMemo(\n () => scale(values, width, height, { pad }),\n [values, width, height, pad],\n )\n const d = tension > 0 ? smoothPath(points, tension) : linePath(points)\n\n // Local maxima only — marking every point would turn a glyph into a table.\n const peaks = React.useMemo(\n () =>\n variant === \"peaks\"\n ? points.filter(\n (p, i) =>\n i > 0 &&\n i < points.length - 1 &&\n p.y <= points[i - 1].y &&\n p.y < points[i + 1].y,\n )\n : [],\n [points, variant],\n )\n\n return (\n \n {variant === \"area\" ? (\n \n ) : null}\n \n {peaks.map((p, i) => (\n \n ))}\n \n )\n}\n", "type": "registry:ui" } ], "type": "registry:ui" }