fix(layout): keep region picker right-anchored on desktop (#47)

This commit is contained in:
MrAlders0n
2026-09-18 06:12:14 -04:00
committed by GitHub
parent 2264b3be35
commit d5d9c0870c
4 changed files with 32 additions and 3 deletions
+1 -1
View File
@@ -114,7 +114,7 @@ function RegionSelector() {
return (
<Dropdown
align="left"
align="left-below-md"
width="w-60"
renderTrigger={({ toggle }) => (
<button
+5 -2
View File
@@ -1,9 +1,12 @@
import { useState, useRef, useCallback, useEffect, type ReactNode } from "react";
import { useClickOutside } from "../hooks/useClickOutside";
const ALIGN_CLASS = { left: "left-0", right: "right-0", "left-below-md": "left-0 md:left-auto md:right-0" } as const;
export function Dropdown({ renderTrigger, align = "right", width = "w-48", fullWidth = false, children }: {
renderTrigger: (props: { open: boolean; toggle: () => void }) => ReactNode;
align?: "left" | "right";
// left-below-md: the trigger sits at the left edge of a phone row but mid-row on desktop
align?: "left" | "right" | "left-below-md";
width?: string;
// stretch + render the panel inline (accordion) for the mobile filter sheet
fullWidth?: boolean;
@@ -33,7 +36,7 @@ export function Dropdown({ renderTrigger, align = "right", width = "w-48", fullW
<div className={
fullWidth
? "mt-1 w-full bg-bg-raised border border-border rounded-md py-1 max-h-72 overflow-y-auto"
: `absolute top-full mt-1 ${align === "left" ? "left-0" : "right-0"} ${width} max-w-[calc(100vw-1.5rem)] bg-bg-raised border border-border rounded-md shadow-lg z-50 py-1 max-h-80 overflow-y-auto`
: `absolute top-full mt-1 ${ALIGN_CLASS[align]} ${width} max-w-[calc(100vw-1.5rem)] bg-bg-raised border border-border rounded-md shadow-lg z-50 py-1 max-h-80 overflow-y-auto`
}>
{children(close)}
</div>
+11
View File
@@ -260,3 +260,14 @@ describe("rate limit badge", () => {
expect(screen.queryByText(/RATE LIMITED/)).not.toBeInTheDocument();
});
});
describe("AppShell region picker alignment", () => {
it("opens rightward only below md so the desktop row's controls stay visible", async () => {
vi.mocked(getIatas).mockResolvedValue([]);
renderShell();
fireEvent.click(screen.getByRole("button", { name: /REGION/ }));
const panel = screen.getByPlaceholderText("Filter IATA or name…").closest(".absolute")!;
expect(panel.className).toContain("left-0");
expect(panel.className).toContain("md:right-0");
});
});
+15
View File
@@ -45,3 +45,18 @@ describe("Dropdown", () => {
expect(onClose).toHaveBeenCalledTimes(1);
});
});
describe("Dropdown align", () => {
it("left-below-md anchors left on phones and flips to right at md", () => {
render(
<Dropdown align="left-below-md" renderTrigger={({ toggle }) => <button type="button" onClick={toggle}>trigger</button>}>
{() => <div data-testid="dropdown-panel">option</div>}
</Dropdown>,
);
fireEvent.click(screen.getByText("trigger"));
const panel = screen.getByTestId("dropdown-panel").parentElement!;
expect(panel.className).toContain("left-0");
expect(panel.className).toContain("md:left-auto");
expect(panel.className).toContain("md:right-0");
});
});