fix(filters): the year dialog fits a tablet, walks by arrow keys, names one year once
- a decade cell is a 36-high box with its count under the year (owner A) - arrow keys walk the cells: along a decade, then to the nearest year below - clearing the kept older year hands the focus on instead of dropping it - More... shows while a year with titles is hidden, as a plain chip - the decade caption is not read twice; the Plex range fields have names - one Plex year is labelled 1999, not 1999-1999, via oneYear/singleYear - tests for the Plex wiring and the feed year clearing the upload date
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// @vitest-environment jsdom
|
||||
import { describe, it, expect, vi, afterEach } from "vitest";
|
||||
import { render, screen, fireEvent, cleanup, within } from "@testing-library/react";
|
||||
import { render, screen, fireEvent, cleanup, within, act } from "@testing-library/react";
|
||||
|
||||
vi.mock("react-i18next", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("react-i18next")>();
|
||||
@@ -9,6 +9,7 @@ vi.mock("react-i18next", async (importOriginal) => {
|
||||
useTranslation: () => ({
|
||||
t: (k: string, o?: Record<string, unknown>) =>
|
||||
o && "from" in o ? `${k}:${String(o.from)}-${String(o.to)}` : k,
|
||||
i18n: { language: "en" },
|
||||
}),
|
||||
};
|
||||
});
|
||||
@@ -80,4 +81,60 @@ describe("YearPicker", () => {
|
||||
fireEvent.click(screen.getByRole("button", { pressed: true }));
|
||||
expect(onPick).toHaveBeenLastCalledWith(undefined);
|
||||
});
|
||||
|
||||
it("offers More… while a year with titles is not among the chips, the kept selection aside", () => {
|
||||
// Seven years, and a selected year with no titles kept beside the six newest: 2013 is hidden.
|
||||
render(<YearPicker years={YEARS.slice(0, 7)} selected={1999} onPick={() => {}} />);
|
||||
expect(screen.getByRole("button", { name: "sidebar.year.more" })).toBeTruthy();
|
||||
});
|
||||
|
||||
it("More… is a plain chip: the ellipsis says a dialog follows, no chevron", () => {
|
||||
render(<YearPicker years={YEARS} onPick={() => {}} />);
|
||||
expect(
|
||||
screen.getByRole("button", { name: "sidebar.year.more" }).querySelector("svg"),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it("clearing the kept older year hands the focus on, not to <body>", () => {
|
||||
const { rerender } = render(<YearPicker years={YEARS} selected={1985} onPick={() => {}} />);
|
||||
const kept = screen.getByRole("button", { pressed: true });
|
||||
kept.focus();
|
||||
fireEvent.click(kept);
|
||||
rerender(<YearPicker years={YEARS} onPick={() => {}} />);
|
||||
expect(document.activeElement).toBe(screen.getByRole("button", { name: "sidebar.year.more" }));
|
||||
});
|
||||
|
||||
it("a decade row is named once: its caption is not read again", () => {
|
||||
render(<YearPicker years={YEARS} onPick={() => {}} />);
|
||||
open();
|
||||
const row = screen.getAllByRole("group", { name: /sidebar\.year\.decade/ })[0]!;
|
||||
expect(row.firstElementChild?.getAttribute("aria-hidden")).toBe("true");
|
||||
});
|
||||
|
||||
it("a cell carries its count under the year, compact", () => {
|
||||
render(<YearPicker years={[...YEARS, { year: 2025, count: 17243 }]} onPick={() => {}} />);
|
||||
open();
|
||||
const cell = screen.getByRole("dialog").querySelector<HTMLElement>('[data-year="2025"]')!;
|
||||
expect(cell.textContent).toBe("202517.2K");
|
||||
});
|
||||
|
||||
it("the arrows walk the cells: along a decade, then down to the next one", () => {
|
||||
render(<YearPicker years={YEARS} onPick={() => {}} />);
|
||||
open();
|
||||
const dialog = screen.getByRole("dialog");
|
||||
dialog.querySelector<HTMLElement>('[data-year="2020"]')!.focus();
|
||||
press("ArrowRight");
|
||||
expect((document.activeElement as HTMLElement).dataset.year).toBe("2021");
|
||||
press("ArrowDown");
|
||||
expect((document.activeElement as HTMLElement).dataset.year).toMatch(/^201/);
|
||||
});
|
||||
});
|
||||
|
||||
/** A keydown where a real one starts: on whatever holds focus, bubbling to the window listener. */
|
||||
function press(key: string): void {
|
||||
act(() => {
|
||||
(document.activeElement ?? document.body).dispatchEvent(
|
||||
new KeyboardEvent("keydown", { key, bubbles: true, cancelable: true }),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user