Phase 1: Dashboard Polish + Theming (#457) (#458)
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

Co-authored-by: Jason Woltje <jason@diversecanvas.com>
Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #458.
This commit is contained in:
2026-02-23 00:16:45 +00:00
committed by jason.woltje
parent 7c55464d54
commit 07f5225a76
17 changed files with 159 additions and 506 deletions

View File

@@ -16,19 +16,21 @@ describe("Button", () => {
it("should apply primary variant styles by default", () => {
render(<Button>Primary</Button>);
const button = screen.getByRole("button");
expect(button.className).toContain("bg-blue-600");
expect(button.style.background).toBe("var(--ms-blue-500)");
});
it("should apply secondary variant styles", () => {
render(<Button variant="secondary">Secondary</Button>);
const button = screen.getByRole("button");
expect(button.className).toContain("bg-gray-200");
expect(button.style.background).toBe("transparent");
expect(button.style.border).toBe("1px solid var(--border)");
});
it("should apply danger variant styles", () => {
render(<Button variant="danger">Delete</Button>);
const button = screen.getByRole("button");
expect(button.className).toContain("bg-red-600");
expect(button.style.background).toBe("rgba(229, 72, 77, 0.12)");
expect(button.style.color).toBe("var(--danger)");
});
});
@@ -81,6 +83,6 @@ describe("Button", () => {
render(<Button className="custom-class">Custom</Button>);
const button = screen.getByRole("button");
expect(button.className).toContain("custom-class");
expect(button.className).toContain("bg-blue-600");
expect(button.style.background).toBe("var(--ms-blue-500)");
});
});

View File

@@ -16,7 +16,7 @@ export interface MetricsStripProps {
className?: string;
}
function MetricCellItem({ cell, isFirst }: { cell: MetricCell; isFirst: boolean }): ReactElement {
function MetricCellItem({ cell }: { cell: MetricCell }): ReactElement {
const [hovered, setHovered] = useState(false);
const trendColor =
@@ -28,6 +28,7 @@ function MetricCellItem({ cell, isFirst }: { cell: MetricCell; isFirst: boolean
return (
<div
className="metric-cell"
onMouseEnter={(): void => {
setHovered(true);
}}
@@ -37,7 +38,6 @@ function MetricCellItem({ cell, isFirst }: { cell: MetricCell; isFirst: boolean
style={{
padding: "14px 16px",
background: hovered ? "var(--surface-2)" : "var(--surface)",
borderLeft: isFirst ? "none" : "1px solid var(--border)",
borderTop: `2px solid ${cell.color}`,
transition: "background 0.15s ease",
}}
@@ -82,17 +82,15 @@ function MetricCellItem({ cell, isFirst }: { cell: MetricCell; isFirst: boolean
export function MetricsStrip({ cells, className = "" }: MetricsStripProps): ReactElement {
return (
<div
className={className}
style={{
display: "grid",
gridTemplateColumns: `repeat(${String(cells.length)}, 1fr)`,
borderRadius: "var(--r-lg)",
overflow: "hidden",
border: "1px solid var(--border)",
}}
className={`metrics-strip ${className}`.trim()}
style={
{
"--ms-cols": String(cells.length),
} as React.CSSProperties
}
>
{cells.map((cell, index) => (
<MetricCellItem key={cell.label} cell={cell} isFirst={index === 0} />
{cells.map((cell) => (
<MetricCellItem key={cell.label} cell={cell} />
))}
</div>
);