Files
stack/packages/ui/src/components/MetricsStrip.tsx
Jason Woltje 07f5225a76
All checks were successful
ci/woodpecker/push/orchestrator Pipeline was successful
ci/woodpecker/push/api Pipeline was successful
ci/woodpecker/push/web Pipeline was successful
Phase 1: Dashboard Polish + Theming (#457) (#458)
Co-authored-by: Jason Woltje <jason@diversecanvas.com>
Co-committed-by: Jason Woltje <jason@diversecanvas.com>
2026-02-23 00:16:45 +00:00

98 lines
2.1 KiB
TypeScript

import { useState } from "react";
import type { ReactElement } from "react";
export interface MetricCell {
label: string;
value: string;
color: string; // CSS color, e.g., "var(--ms-blue-400)"
trend?: {
direction: "up" | "down" | "neutral";
text: string;
};
}
export interface MetricsStripProps {
cells: MetricCell[];
className?: string;
}
function MetricCellItem({ cell }: { cell: MetricCell }): ReactElement {
const [hovered, setHovered] = useState(false);
const trendColor =
cell.trend?.direction === "up"
? "var(--success)"
: cell.trend?.direction === "down"
? "var(--danger)"
: "var(--muted)";
return (
<div
className="metric-cell"
onMouseEnter={(): void => {
setHovered(true);
}}
onMouseLeave={(): void => {
setHovered(false);
}}
style={{
padding: "14px 16px",
background: hovered ? "var(--surface-2)" : "var(--surface)",
borderTop: `2px solid ${cell.color}`,
transition: "background 0.15s ease",
}}
>
<div
style={{
fontSize: "1.4rem",
fontWeight: 800,
fontFamily: "var(--mono)",
lineHeight: 1.1,
color: cell.color,
}}
>
{cell.value}
</div>
<div
style={{
fontSize: "0.72rem",
color: "var(--muted)",
marginTop: 3,
whiteSpace: "nowrap",
}}
>
{cell.label}
</div>
{cell.trend && (
<div
style={{
fontSize: "0.68rem",
fontFamily: "var(--mono)",
marginTop: 4,
color: trendColor,
}}
>
{cell.trend.text}
</div>
)}
</div>
);
}
export function MetricsStrip({ cells, className = "" }: MetricsStripProps): ReactElement {
return (
<div
className={`metrics-strip ${className}`.trim()}
style={
{
"--ms-cols": String(cells.length),
} as React.CSSProperties
}
>
{cells.map((cell) => (
<MetricCellItem key={cell.label} cell={cell} />
))}
</div>
);
}