fix(ui): a removed chip's focus outlives its neighbour; a scroll restore yields to the reader
A chip handed its focus to a Clear all or +N that went in the same removal, and the focus fell to the body. The restore now stops when the reader scrolls, and finishes the way once the Back-to-top spacer brings the saved spot within reach.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
// E28 S3b: the chip family (docs/DESIGN.md "One primitive per button family"). One geometry for a
|
||||
// filter, an applied narrowing, a tag and a suggestion, where five files had five.
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { act, cleanup, fireEvent, render, screen } from "@testing-library/react";
|
||||
import { act, cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react";
|
||||
import { useState } from "react";
|
||||
import { Chip, DismissibleChip } from "./Chip";
|
||||
import { chipClass } from "./chipStyles";
|
||||
@@ -70,6 +70,37 @@ describe("Chip", () => {
|
||||
expect(document.activeElement).toBe(screen.getByRole("button", { name: "Remove News" }));
|
||||
});
|
||||
|
||||
// Round 3: the neighbour it hands the focus to can go in the same removal — the "Clear all" that
|
||||
// only shows beside two filters. The focus then goes to the chip before, not to <body>.
|
||||
it("a removing chip whose neighbour goes with it hands the focus to the chip before", async () => {
|
||||
function Row() {
|
||||
const [chips, setChips] = useState(["Music", "News"]);
|
||||
return (
|
||||
<div>
|
||||
{chips.map((c) => (
|
||||
<Chip
|
||||
key={c}
|
||||
variant="token"
|
||||
removeLabel={`Remove ${c}`}
|
||||
onClick={() => setChips((all) => all.filter((x) => x !== c))}
|
||||
>
|
||||
{c}
|
||||
</Chip>
|
||||
))}
|
||||
{chips.length > 1 && <button onClick={() => setChips([])}>Clear all</button>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
render(<Row />);
|
||||
const news = screen.getByRole("button", { name: "Remove News" });
|
||||
act(() => news.focus());
|
||||
fireEvent.click(news, { detail: 0 });
|
||||
expect(screen.queryByRole("button", { name: "Clear all" })).toBeNull();
|
||||
await waitFor(() =>
|
||||
expect(document.activeElement).toBe(screen.getByRole("button", { name: "Remove Music" })),
|
||||
);
|
||||
});
|
||||
|
||||
it("the measuring mirror lays out exactly like the chip it measures", () => {
|
||||
render(
|
||||
<Chip variant="tag" size="xs">
|
||||
|
||||
Reference in New Issue
Block a user