Fade sidebar pinned chrome edges (#1423)

This commit is contained in:
klopez4212
2026-07-01 07:51:05 -07:00
committed by GitHub
parent 2fc8b9cf5f
commit 3e4e9dda94
3 changed files with 157 additions and 1 deletions
@@ -780,7 +780,7 @@ export function AppSidebar({
/>
) : null}
<SidebarFooter className="bg-sidebar/55 backdrop-blur-xl supports-[backdrop-filter]:bg-sidebar/45 dark:bg-sidebar/45 dark:supports-[backdrop-filter]:bg-sidebar/35">
<SidebarFooter>
<AnimatePresence>
{sidebarRelayConnectionCard.showSidebarRelayConnectionCard ? (
<SidebarRelayConnectionCard
@@ -1,4 +1,57 @@
@layer components {
[data-testid="app-sidebar"] [data-testid="sidebar-pinned-header"],
[data-testid="app-sidebar"] [data-sidebar="footer"] {
--buzz-sidebar-edge-fade-size: 0.5rem;
--buzz-sidebar-edge-fade-surface: hsl(var(--sidebar-background));
--buzz-sidebar-edge-fade-transparent: hsl(var(--sidebar-background) / 0);
background: var(--buzz-sidebar-edge-fade-surface);
box-shadow: none;
isolation: isolate;
position: relative;
z-index: 30;
}
[data-testid="app-sidebar"] [data-testid="sidebar-pinned-header"]::before,
[data-testid="app-sidebar"] [data-sidebar="footer"]::before {
box-shadow: none;
content: "";
filter: none;
pointer-events: none;
position: absolute;
z-index: 5;
}
[data-testid="app-sidebar"] [data-testid="sidebar-pinned-header"] > *,
[data-testid="app-sidebar"] [data-sidebar="footer"] > * {
position: relative;
z-index: 10;
}
[data-testid="app-sidebar"] [data-testid="sidebar-pinned-header"]::before {
background: linear-gradient(
to bottom,
var(--buzz-sidebar-edge-fade-surface) 0%,
var(--buzz-sidebar-edge-fade-transparent) 100%
);
bottom: calc(var(--buzz-sidebar-edge-fade-size) * -1);
height: var(--buzz-sidebar-edge-fade-size);
left: 0;
right: 0;
}
[data-testid="app-sidebar"] [data-sidebar="footer"]::before {
background: linear-gradient(
to top,
var(--buzz-sidebar-edge-fade-surface) 0%,
var(--buzz-sidebar-edge-fade-transparent) 100%
);
height: var(--buzz-sidebar-edge-fade-size);
left: 0;
right: 0;
top: calc(var(--buzz-sidebar-edge-fade-size) * -1);
}
.buzz-side-panel-enter {
animation: buzz-side-panel-enter 260ms cubic-bezier(0.32, 0.72, 0, 1) both;
transform-origin: right center;
+103
View File
@@ -41,6 +41,109 @@ async function dragSidebarRail(page: Page, deltaX: number) {
await page.mouse.up();
}
test("fades the pinned sidebar chrome edges", async ({ page }) => {
await page.goto("/");
const pinnedHeader = page.getByTestId("sidebar-pinned-header");
const footer = page.locator(
'[data-testid="app-sidebar"] [data-sidebar="footer"]',
);
const channelContent = page.getByTestId("sidebar-channel-content");
await expect(pinnedHeader).toBeVisible();
await expect(footer).toBeVisible();
await expect(channelContent).toBeVisible();
const fadeStyles = await page.evaluate(() => {
const header = document.querySelector<HTMLElement>(
'[data-testid="app-sidebar"] [data-testid="sidebar-pinned-header"]',
);
const footerElement = document.querySelector<HTMLElement>(
'[data-testid="app-sidebar"] [data-sidebar="footer"]',
);
const channelElement = document.querySelector<HTMLElement>(
'[data-testid="sidebar-channel-content"]',
);
if (!header || !footerElement || !channelElement) {
throw new Error("Expected sidebar chrome elements to be rendered");
}
const headerBefore = getComputedStyle(header, "::before");
const headerStyle = getComputedStyle(header);
const sidebarElement = header.closest<HTMLElement>(
'[data-sidebar="sidebar"]',
);
const sidebarStyle = sidebarElement
? getComputedStyle(sidebarElement)
: null;
const footerStyle = getComputedStyle(footerElement);
const footerBefore = getComputedStyle(footerElement, "::before");
const channelBefore = getComputedStyle(channelElement, "::before");
const channelAfter = getComputedStyle(channelElement, "::after");
const headerRect = header.getBoundingClientRect();
const footerRect = footerElement.getBoundingClientRect();
return {
channelAfterBackground: channelAfter.backgroundImage,
channelBeforeBackground: channelBefore.backgroundImage,
footerBackgroundColor: footerStyle.backgroundColor,
footerBackdropFilter: footerBefore.backdropFilter,
footerBackground: footerBefore.backgroundImage,
footerBoxShadow: footerStyle.boxShadow,
footerFadeBoxShadow: footerBefore.boxShadow,
footerFadeHeight: Number.parseFloat(footerBefore.height),
footerHeight: footerRect.height,
footerPointerEvents: footerBefore.pointerEvents,
footerPosition: footerBefore.position,
footerTopPx: Number.parseFloat(footerBefore.top),
footerZIndex: footerBefore.zIndex,
headerBackground: headerBefore.backgroundImage,
headerBackdropFilter: headerBefore.backdropFilter,
headerBackgroundColor: headerStyle.backgroundColor,
headerBottomPx: Number.parseFloat(headerBefore.bottom),
headerBoxShadow: headerStyle.boxShadow,
headerFadeBoxShadow: headerBefore.boxShadow,
headerFadeHeight: Number.parseFloat(headerBefore.height),
headerHeight: headerRect.height,
headerPointerEvents: headerBefore.pointerEvents,
headerPosition: headerBefore.position,
headerZIndex: headerBefore.zIndex,
sidebarBackgroundColor: sidebarStyle?.backgroundColor ?? null,
};
});
expect(fadeStyles.headerBackground).toContain("gradient");
expect(fadeStyles.headerBackgroundColor).toBe(
fadeStyles.sidebarBackgroundColor,
);
expect(fadeStyles.headerBackground).toContain("rgba");
expect(fadeStyles.headerBackground).toContain("0) 100%");
expect(fadeStyles.headerBackdropFilter).toBe("none");
expect(fadeStyles.headerBottomPx).toBeLessThan(0);
expect(fadeStyles.headerBoxShadow).toBe("none");
expect(fadeStyles.headerFadeBoxShadow).toBe("none");
expect(fadeStyles.headerFadeHeight).toBeLessThanOrEqual(10);
expect(fadeStyles.headerPointerEvents).toBe("none");
expect(fadeStyles.headerPosition).toBe("absolute");
expect(fadeStyles.headerZIndex).toBe("5");
expect(fadeStyles.footerBackground).toContain("gradient");
expect(fadeStyles.footerBackgroundColor).toBe(
fadeStyles.sidebarBackgroundColor,
);
expect(fadeStyles.footerBackground).toContain("rgba");
expect(fadeStyles.footerBackground).toContain("0) 100%");
expect(fadeStyles.footerBackdropFilter).toBe("none");
expect(fadeStyles.footerBoxShadow).toBe("none");
expect(fadeStyles.footerFadeBoxShadow).toBe("none");
expect(fadeStyles.footerFadeHeight).toBeLessThanOrEqual(10);
expect(fadeStyles.footerPointerEvents).toBe("none");
expect(fadeStyles.footerPosition).toBe("absolute");
expect(fadeStyles.footerTopPx).toBeLessThan(0);
expect(fadeStyles.footerZIndex).toBe("5");
expect(fadeStyles.channelBeforeBackground).toBe("none");
expect(fadeStyles.channelAfterBackground).toBe("none");
});
test("resizes, persists, and snaps to the default sidebar width", async ({
page,
}) => {