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:
@@ -125,6 +125,67 @@ describe("PageScroller scroll memory", () => {
|
||||
expect(main.scrollTop).toBe(450);
|
||||
});
|
||||
|
||||
// Round 3: landing at the end shows Back to top, whose spacer then brings the spot within reach.
|
||||
it("finishes the way to a spot the spacer brings within reach after it lands", () => {
|
||||
let frames: FrameRequestCallback[] = [];
|
||||
vi.stubGlobal("requestAnimationFrame", (cb: FrameRequestCallback) => frames.push(cb));
|
||||
const flush = (n: number) => {
|
||||
for (let i = 0; i < n; i++) {
|
||||
const run = frames;
|
||||
frames = [];
|
||||
for (const cb of run) cb(0);
|
||||
}
|
||||
};
|
||||
setEntry(1);
|
||||
const { container } = render(<PageScroller scrollKey="e:k1">x</PageScroller>);
|
||||
const main = sizedMain(container);
|
||||
main.scrollTop = 500;
|
||||
fireEvent.scroll(main);
|
||||
setEntry(2);
|
||||
notifyNav();
|
||||
flush(1);
|
||||
Object.defineProperty(main, "scrollHeight", { configurable: true, value: 928 }); // no spacer
|
||||
setEntry(1);
|
||||
notifyNav();
|
||||
flush(12);
|
||||
expect(main.scrollTop).toBe(428);
|
||||
Object.defineProperty(main, "scrollHeight", { configurable: true, value: 1000 }); // spacer up
|
||||
flush(1);
|
||||
expect(main.scrollTop).toBe(500);
|
||||
});
|
||||
|
||||
// Round 3: the give-up put the page at its end 1.5 s in, wherever the reader had scrolled to.
|
||||
it("stops where the reader takes the page over, even for a spot it has not reached", () => {
|
||||
let frames: FrameRequestCallback[] = [];
|
||||
vi.stubGlobal("requestAnimationFrame", (cb: FrameRequestCallback) => frames.push(cb));
|
||||
const flush = (n: number) => {
|
||||
for (let i = 0; i < n; i++) {
|
||||
const run = frames;
|
||||
frames = [];
|
||||
for (const cb of run) cb(0);
|
||||
}
|
||||
};
|
||||
setEntry(1);
|
||||
const { container } = render(<PageScroller scrollKey="e:k1">x</PageScroller>);
|
||||
const main = sizedMain(container);
|
||||
main.scrollTop = 450;
|
||||
fireEvent.scroll(main);
|
||||
setEntry(2);
|
||||
notifyNav();
|
||||
flush(1);
|
||||
Object.defineProperty(main, "scrollHeight", { configurable: true, value: 600 }); // far short
|
||||
setEntry(1);
|
||||
notifyNav();
|
||||
flush(5);
|
||||
fireEvent.wheel(main);
|
||||
main.scrollTop = 30; // where the reader scrolled
|
||||
flush(100);
|
||||
expect(main.scrollTop).toBe(30);
|
||||
Object.defineProperty(main, "scrollHeight", { configurable: true, value: 1000 }); // loaded
|
||||
flush(1);
|
||||
expect(main.scrollTop).toBe(30);
|
||||
});
|
||||
|
||||
it("restores per content key within one entry: a new key resets to top, returning restores", () => {
|
||||
setEntry(10);
|
||||
const { container, rerender } = render(<PageScroller scrollKey="e10:a">x</PageScroller>);
|
||||
|
||||
Reference in New Issue
Block a user