Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions e2e/smoke.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,36 @@ test("switching tabs changes active tab indicator", async ({ page }) => {
await expect(actionsTab).toHaveAttribute("aria-selected", "true");
});

test("fixed elements compensate for scrollbar width when scroll is locked", async ({ page }) => {
await setupAuth(page);
await page.goto("/dashboard");

const navbar = page.locator(".navbar");
const footer = page.locator(".app-footer");
await expect(navbar).toBeVisible();
await expect(footer).toBeVisible();

// Baseline: navbar 0.5rem (8px) from daisyUI, footer 0px (no base padding)
expect(parseFloat(await navbar.evaluate((el) => getComputedStyle(el).paddingRight))).toBeCloseTo(8, 0);
expect(parseFloat(await footer.evaluate((el) => getComputedStyle(el).paddingRight))).toBeCloseTo(0, 0);

// Simulate solid-prevent-scroll setting --scrollbar-width on body
await page.evaluate(() => {
document.body.style.setProperty("--scrollbar-width", "15px");
});

// Navbar: 8px + 15px = 23px, footer: 0px + 15px = 15px
expect(parseFloat(await navbar.evaluate((el) => getComputedStyle(el).paddingRight))).toBeCloseTo(23, 0);
expect(parseFloat(await footer.evaluate((el) => getComputedStyle(el).paddingRight))).toBeCloseTo(15, 0);

// Clear — both return to baseline
await page.evaluate(() => {
document.body.style.removeProperty("--scrollbar-width");
});
expect(parseFloat(await navbar.evaluate((el) => getComputedStyle(el).paddingRight))).toBeCloseTo(8, 0);
expect(parseFloat(await footer.evaluate((el) => getComputedStyle(el).paddingRight))).toBeCloseTo(0, 0);
});

test("dashboard shows empty state with no data", async ({ page }) => {
await setupAuth(page);
await page.goto("/dashboard");
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/dashboard/DashboardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ export default function DashboardPage() {
</main>
</div>

<footer class="fixed bottom-0 left-0 right-0 z-30 border-t border-base-300 bg-base-100 py-3 text-xs text-base-content/50">
<footer class="app-footer fixed bottom-0 left-0 right-0 z-30 border-t border-base-300 bg-base-100 py-3 text-xs text-base-content/50">
<div class="max-w-6xl mx-auto w-full px-4 grid grid-cols-3 items-center">
<div />
<div class="flex items-center justify-center gap-3">
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/dashboard/WorkflowRunRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export default function WorkflowRunRow(props: WorkflowRunRowProps) {

return (
<div
class={`flex items-center gap-3 ${paddingClass()} hover:bg-base-200 group ${props.isFlashing ? "animate-flash" : props.isPolling ? "animate-shimmer" : ""}`}
class={`flex items-center gap-3 ${paddingClass()} group ${props.run.conclusion === "failure" ? "bg-error/5 hover:bg-error/10" : "hover:bg-base-200"} ${props.isFlashing ? "animate-flash" : props.isPolling ? "animate-shimmer" : ""}`}
>
<StatusIcon status={props.run.status} conclusion={props.run.conclusion} />

Expand Down
4 changes: 2 additions & 2 deletions src/app/components/shared/StatusDot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ const STATUS_CONFIG = {
pulse: true,
},
failure: {
bg: "bg-error",
bg: "bg-red-500",
label: "Checks failing",
pulse: false,
},
error: {
bg: "bg-error",
bg: "bg-red-500",
label: "Checks failing",
pulse: false,
},
Expand Down
11 changes: 11 additions & 0 deletions src/app/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@
animation: overlay-fade-in 0.3s ease-out forwards;
}

/* ── Fixed-element scrollbar compensation ────────────────────────────────── */
/* solid-prevent-scroll sets --scrollbar-width on body when scroll is locked;
fixed elements don't inherit body padding-right, so compensate explicitly.
0.5rem matches daisyUI .navbar padding (padding: .5rem) */
.navbar {
padding-right: calc(0.5rem + var(--scrollbar-width, 0px));
}
.app-footer {
padding-right: var(--scrollbar-width, 0px);
}

/* ── Kobalte → daisyUI bridges ───────────────────────────────────────────── */

/* Kobalte Tabs: data-selected → daisyUI tab-active */
Expand Down