mirror of
https://github.com/vector-im/element-web.git
synced 2026-05-11 15:16:35 +02:00
Fix inadvertant scrolling of the timeline when using pageUp/pageDown
This commit is contained in:
parent
a09197dd76
commit
4fecf1413c
@ -30,7 +30,7 @@ test.describe("Lazy Loading", () => {
|
||||
});
|
||||
|
||||
test.beforeEach(async ({ page, homeserver, user, bot, app }) => {
|
||||
// The charlies were running off the bottom of the screen.
|
||||
// The charlies were running off the bottom of the screen.
|
||||
// We no longer overscan the member list so the result is they are not in the dom.
|
||||
// Increase the viewport size to ensure they are.
|
||||
await page.setViewportSize({ width: 1000, height: 1000 });
|
||||
|
||||
@ -89,6 +89,8 @@ export function ListView<Item, Context = any>(props: IListViewProps<Item, Contex
|
||||
// Extract our custom props to avoid conflicts with Virtuoso props
|
||||
const { items, onSelectItem, getItemComponent, isItemFocusable, getItemKey, context, ...virtuosoProps } = props;
|
||||
|
||||
const isScrollingToItem = useRef<boolean>(false);
|
||||
|
||||
// Update the key-to-index mapping whenever items change
|
||||
React.useEffect(() => {
|
||||
const newKeyToIndexMap = new Map<string, number>();
|
||||
@ -125,15 +127,21 @@ export function ListView<Item, Context = any>(props: IListViewProps<Item, Contex
|
||||
(index: number, align?: "center" | "end" | "start"): void => {
|
||||
// Ensure index is within bounds
|
||||
const clampedIndex = Math.max(0, Math.min(index, items.length - 1));
|
||||
|
||||
if (isScrollingToItem.current) {
|
||||
// If already scrolling to an item drop this request. Adding further requests
|
||||
// causes the event to bubble up and be handled by other components(unintentional timeline scrolling was observed).
|
||||
return;
|
||||
}
|
||||
if (items[clampedIndex]) {
|
||||
const key = getItemKey(items[clampedIndex]);
|
||||
setfocusKey(key);
|
||||
isScrollingToItem.current = true;
|
||||
virtuosoHandleRef?.current?.scrollIntoView({
|
||||
index: clampedIndex,
|
||||
align: align,
|
||||
behavior: "auto",
|
||||
done: () => {
|
||||
setfocusKey(key);
|
||||
isScrollingToItem.current = false;
|
||||
},
|
||||
});
|
||||
}
|
||||
@ -195,11 +203,11 @@ export function ListView<Item, Context = any>(props: IListViewProps<Item, Contex
|
||||
handled = true;
|
||||
} else if (e.code === "PageDown" && visibleRange && currentIndex !== undefined) {
|
||||
const numberDisplayed = visibleRange.endIndex - visibleRange.startIndex;
|
||||
scrollToItem(currentIndex + numberDisplayed, true, `start`);
|
||||
scrollToItem(Math.min(currentIndex + numberDisplayed, items.length - 1), true, `start`);
|
||||
handled = true;
|
||||
} else if (e.code === "PageUp" && visibleRange && currentIndex !== undefined) {
|
||||
const numberDisplayed = visibleRange.endIndex - visibleRange.startIndex;
|
||||
scrollToItem(currentIndex - numberDisplayed, false, `start`);
|
||||
scrollToItem(Math.max(currentIndex - numberDisplayed, 0), false, `start`);
|
||||
handled = true;
|
||||
}
|
||||
|
||||
|
||||
@ -227,38 +227,6 @@ describe("ListView", () => {
|
||||
expect(items[lastIndex]).toHaveAttribute("tabindex", "-1");
|
||||
});
|
||||
|
||||
it("should prevent default and stop propagation for handled keys", () => {
|
||||
render(<ListView {...defaultProps} />);
|
||||
const container = screen.getByRole("grid");
|
||||
|
||||
// Focus the container first to establish initial focus
|
||||
fireEvent.focus(container);
|
||||
|
||||
// Create a spy to monitor the event
|
||||
const keyDownSpy = jest.fn();
|
||||
container.addEventListener("keydown", keyDownSpy);
|
||||
|
||||
fireEvent.keyDown(container, { code: "ArrowDown" });
|
||||
|
||||
// Check that the event was prevented and stopped
|
||||
expect(keyDownSpy).toHaveBeenCalled();
|
||||
const event = keyDownSpy.mock.calls[0][0];
|
||||
expect(event.defaultPrevented).toBe(true);
|
||||
});
|
||||
|
||||
it("should not prevent default for unhandled keys", () => {
|
||||
render(<ListView {...defaultProps} />);
|
||||
const container = screen.getByRole("grid");
|
||||
const event = new KeyboardEvent("keydown", { code: "KeyA", bubbles: true, cancelable: true });
|
||||
const preventDefault = jest.spyOn(event, "preventDefault");
|
||||
const stopPropagation = jest.spyOn(event, "stopPropagation");
|
||||
|
||||
fireEvent(container, event);
|
||||
|
||||
expect(preventDefault).not.toHaveBeenCalled();
|
||||
expect(stopPropagation).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should skip non-focusable items when navigating down", async () => {
|
||||
// Create items where every other item is not focusable
|
||||
const mixedItems = [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user