diff --git a/apps/app/src/components/template-library/template-card-bar.test.tsx b/apps/app/src/components/template-library/template-card-bar.test.tsx
new file mode 100644
index 0000000..96e4de0
--- /dev/null
+++ b/apps/app/src/components/template-library/template-card-bar.test.tsx
@@ -0,0 +1,27 @@
+import { afterEach, expect, it, vi } from "vitest";
+import { cleanup, render } from "@testing-library/react";
+import { TemplateCard } from "./template-card";
+afterEach(cleanup);
+it.each([1, 6, 40, 300])("keeps %i bars visible within the SVG viewport", (count) => {
+ const data = Array.from({ length: count }, (_, i) => ({ label: String(i), value: i + 1 }));
+ const { container } = render();
+ const svg = container.querySelector("svg")!;
+ const [, , viewportWidth, viewportHeight] = svg.getAttribute("viewBox")!.split(" ").map(Number);
+ const bars = Array.from(svg.querySelectorAll("rect"));
+ expect(bars).toHaveLength(count);
+ let previousRight = -1;
+ for (const bar of bars) {
+ const x = Number(bar.getAttribute("x"));
+ const y = Number(bar.getAttribute("y"));
+ const width = Number(bar.getAttribute("width"));
+ const height = Number(bar.getAttribute("height"));
+ expect(width).toBeGreaterThan(0);
+ expect(height).toBeGreaterThan(0);
+ expect(x).toBeGreaterThanOrEqual(previousRight);
+ expect(x + width).toBeLessThanOrEqual(viewportWidth);
+ expect(y).toBeGreaterThanOrEqual(0);
+ expect(y + height).toBeLessThanOrEqual(viewportHeight);
+ previousRight = x + width;
+ }
+});
diff --git a/apps/app/src/components/template-library/template-card.tsx b/apps/app/src/components/template-library/template-card.tsx
index 23b9824..fc978bd 100644
--- a/apps/app/src/components/template-library/template-card.tsx
+++ b/apps/app/src/components/template-library/template-card.tsx
@@ -25,8 +25,10 @@ interface TemplateCardProps {
function BarChartPreview({ data }: { data: { label: string; value: number }[] }) {
if (!data?.length) return null;
const max = Math.max(...data.map((d) => d.value));
- const barWidth = Math.min(40, Math.floor(280 / data.length) - 8);
- const chartWidth = data.length * (barWidth + 8);
+ const slotWidth = Math.min(48, 280 / data.length);
+ const gap = Math.min(8, slotWidth / 4);
+ const barWidth = slotWidth - gap;
+ const chartWidth = data.length * slotWidth;
const chartHeight = 100;
return (
@@ -42,7 +44,7 @@ function BarChartPreview({ data }: { data: { label: string; value: number }[] })
return (