feat(tables): a glyph pager with first/last, and tablet-width columns step aside
The pager is four named arrows round the page box (first, previous, next, last). A table hides a tabletHidden column below 64rem of its own width, as narrowHidden does below 42rem, through one shared helper that also hides the column's <col>. The Channels table drops Prio, About and Length there: at 1024 the channel name had 60 px.
This commit is contained in:
@@ -111,27 +111,63 @@ describe("Pager · the page box follows the page without an effect", () => {
|
||||
});
|
||||
});
|
||||
|
||||
// E28 S3f3: on a phone the row ran 18px past a 375 screen. The arrows keep their names (a screen
|
||||
// reader still hears Previous / Next) and only the visible words step aside below `sm`; the size label
|
||||
// stays one line rather than a word per line.
|
||||
describe("Pager · on a phone", () => {
|
||||
it("hides only the visible words of Previous / Next, never their names", () => {
|
||||
// Glyphs only (the owner, 2026-09-27): First / Previous / Next / Last are four arrows that carry their
|
||||
// names as the accessible name and the tooltip, and show no words at any width (the words once pushed
|
||||
// a phone row 18px past a 375 screen). The size label stays one line rather than a word per line.
|
||||
describe("Pager · four named arrows", () => {
|
||||
function renderAt(page: number, onPageChange = vi.fn()) {
|
||||
render(
|
||||
<Pager
|
||||
page={1}
|
||||
page={page}
|
||||
size={10}
|
||||
total={120}
|
||||
pageSizeOptions={[10, 25]}
|
||||
onPageChange={() => {}}
|
||||
onPageChange={onPageChange}
|
||||
onSizeChange={() => {}}
|
||||
sizeLabel="Rows per page"
|
||||
/>,
|
||||
);
|
||||
for (const name of ["datatable.pager.prev", "datatable.pager.next"]) {
|
||||
return onPageChange;
|
||||
}
|
||||
const NAMES = ["first", "prev", "next", "last"].map((k) => `datatable.pager.${k}`);
|
||||
|
||||
it("draws each as a glyph with its name as the tooltip, and no visible word", () => {
|
||||
renderAt(5);
|
||||
for (const name of NAMES) {
|
||||
const btn = screen.getByRole("button", { name });
|
||||
const word = [...btn.querySelectorAll("span")].find((s) => s.textContent === name)!;
|
||||
expect(word.className.split(/\s+/)).toContain("max-sm:sr-only");
|
||||
expect(btn.getAttribute("title")).toBe(name);
|
||||
expect(btn.textContent).toBe("");
|
||||
expect(btn.querySelector("svg")).not.toBeNull();
|
||||
}
|
||||
expect(screen.getByText("Rows per page").className).toContain("whitespace-nowrap");
|
||||
});
|
||||
|
||||
it("jumps to the first, previous, next and last page", () => {
|
||||
const onPageChange = renderAt(5);
|
||||
for (const name of NAMES) fireEvent.click(screen.getByRole("button", { name }));
|
||||
expect(onPageChange.mock.calls).toEqual([[0], [4], [6], [11]]);
|
||||
});
|
||||
|
||||
it("turns off the pair that points past an edge", () => {
|
||||
renderAt(0);
|
||||
const off = (k: string) =>
|
||||
(screen.getByRole("button", { name: `datatable.pager.${k}` }) as HTMLButtonElement)
|
||||
.disabled ||
|
||||
screen.getByRole("button", { name: `datatable.pager.${k}` }).getAttribute("aria-disabled") ===
|
||||
"true";
|
||||
expect([off("first"), off("prev"), off("next"), off("last")]).toEqual([
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
]);
|
||||
cleanup();
|
||||
renderAt(11);
|
||||
expect([off("first"), off("prev"), off("next"), off("last")]).toEqual([
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user