commit 2aa903a3c6a19c9247be9fa6338dbeb2bb3cd887
parent a3a8276a06c025e9c0a34d48bf2208873937f43c
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Thu, 24 Sep 2026 19:05:29 -0400
channels: an opened Advanced panel scrolls itself into view
Audit finding (desktop/mobile popover-open, and the layers spec's own
failure at 1280x720): the Tier cell's Advanced panel is absolute so it
never moves the rack — which lets the scroll region clip it. Opened on a
row near the bottom (below md, near the right edge too) its overrides
hung off the region, out of reach.
Opening now scrolls the panel into view with block/inline "nearest", so
a panel already on screen stays exactly where it is. The layers spec
opens the last row's panel and checks it lands inside the region and
owns its bottom edge.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat:
2 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/editor/app/channels/components/ChannelTierSelect.tsx b/editor/app/channels/components/ChannelTierSelect.tsx
@@ -199,8 +199,26 @@ export default function ChannelTierSelect({
{/* OPENING THIS MUST NOT MOVE THE RACK. In a 40px row an inline panel
would push every row below it down by 150px, so the panel is absolute
- and overlays them instead. */}
- <details className="text-[11px]">
+ and overlays them instead.
+ ...WHICH MEANS THE SCROLL REGION CLIPS IT. Opened on a row near the
+ rack's bottom (or, below md, its right edge) the panel hung off the
+ region with its selects out of reach, and nothing said it was there.
+ Opening scrolls the region — and the document, below md — just far
+ enough to show the whole panel; `nearest` leaves an already-visible
+ one exactly where it is. */}
+ <details
+ className="text-[11px]"
+ onToggle={(e) => {
+ const details = e.currentTarget;
+ if (!details.open) return;
+ requestAnimationFrame(() =>
+ details.lastElementChild?.scrollIntoView({
+ block: "nearest",
+ inline: "nearest",
+ }),
+ );
+ }}
+ >
<summary
aria-label={`advanced priority for ${slug}`}
className="cursor-pointer text-muted-foreground hover:text-foreground"
diff --git a/editor/e2e/channels-rack-layers.spec.ts b/editor/e2e/channels-rack-layers.spec.ts
@@ -159,3 +159,28 @@ test("the Advanced priority popover paints over the rows, pins and headers aroun
await hitsInside(page, popover, box.x + box.width / 2, box.y + box.height - 4),
).toBe(true);
});
+
+test("an Advanced popover opened on the last row scrolls itself into view", async ({
+ page,
+}) => {
+ await seed();
+ await page.goto("/channels?site=alpha");
+ const region = page.getByTestId("channels-rack");
+ // slow-a sorts last: its panel opens past the region's bottom edge.
+ await page.getByLabel("advanced priority for slow-a").click();
+ const popover = page
+ .getByLabel("advanced priority for slow-a")
+ .locator("xpath=following-sibling::div[1]");
+ await expect(popover).toBeVisible();
+ await expect
+ .poll(async () => {
+ const r = (await region.boundingBox())!;
+ const p = (await popover.boundingBox())!;
+ return p.y + p.height <= r.y + r.height + 1;
+ })
+ .toBe(true);
+ const box = (await popover.boundingBox())!;
+ expect(
+ await hitsInside(page, popover, box.x + box.width / 2, box.y + box.height - 4),
+ ).toBe(true);
+});