Files
wehub-resource-sync e30e75b5d4
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:40:13 +08:00

57 lines
1.3 KiB
TypeScript

import { cn } from "@/lib/utils";
type Props = {
values: number[];
className?: string;
width?: number;
height?: number;
};
export function Sparkline({
values,
className,
width = 64,
height = 18,
}: Props) {
if (values.length < 2) return null;
const max = Math.max(...values);
const min = Math.min(...values);
const range = Math.max(1, max - min);
const stepX = width / (values.length - 1);
const points = values.map((v, i) => {
const x = i * stepX;
const y = height - ((v - min) / range) * (height - 2) - 1;
return [x, y] as const;
});
const linePath = points
.map(([x, y], i) => `${i === 0 ? "M" : "L"}${x.toFixed(2)} ${y.toFixed(2)}`)
.join(" ");
const areaPath = `${linePath} L${width.toFixed(2)} ${height} L0 ${height} Z`;
return (
<svg
width={width}
height={height}
viewBox={`0 0 ${width} ${height}`}
preserveAspectRatio="none"
className={cn("text-foreground/60", className)}
role="img"
>
<title>Weekly downloads trend</title>
<path d={areaPath} fill="currentColor" fillOpacity={0.08} />
<path
d={linePath}
fill="none"
stroke="currentColor"
strokeWidth={1.25}
strokeLinejoin="round"
strokeLinecap="round"
/>
</svg>
);
}