feat(playlists): drag rows onto a list in the rail
A row's grip carries it, or every selected row with a selected one, onto another list, under a sort or a filter too, and the toast undoes. The rail and the page are separate React trees, so the page reads the rail by what lies under the pointer. An unpinned rail peeks by the drag's own hover and scrolls at its edges. Many rows dropped inside the list stay; a key still moves its own row.
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
import { useRef } from "react";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { cleanup, render, screen, waitFor } from "@testing-library/react";
|
||||
import { navItemAttrs, useListNav, type NavSelection } from "./listNav";
|
||||
import { followRemoval, navItemAttrs, useListNav, type NavSelection } from "./listNav";
|
||||
import { useActiveScopes } from "./keymap";
|
||||
|
||||
afterEach(cleanup);
|
||||
@@ -115,6 +115,27 @@ describe("useListNav · selecting", () => {
|
||||
expect(idle.clear).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("takes the slot of an item that left by other hands, the focus on <body>", async () => {
|
||||
render(<Rows />);
|
||||
const leaving = screen.getByTestId("r1");
|
||||
followRemoval(screen.getByTestId("r1-action"));
|
||||
const list = leaving.parentElement!;
|
||||
list.removeChild(leaving);
|
||||
list.querySelector<HTMLElement>("[data-testid=r2]")!.setAttribute("data-nav-index", "1");
|
||||
await waitFor(() => expect(document.activeElement).toBe(screen.getByTestId("r2")));
|
||||
});
|
||||
|
||||
it("leaves the focus where it is when something else took it meanwhile", async () => {
|
||||
render(<Rows />);
|
||||
const leaving = screen.getByTestId("r1");
|
||||
const other = screen.getByTestId("r0-input");
|
||||
other.focus();
|
||||
followRemoval(screen.getByTestId("r1-action"));
|
||||
leaving.remove();
|
||||
await new Promise((r) => setTimeout(r, 60));
|
||||
expect(document.activeElement).toBe(other);
|
||||
});
|
||||
|
||||
it("has Delete go to the selection first, wherever the focus is", () => {
|
||||
const s = selection();
|
||||
s.removeSelected.mockReturnValue(true);
|
||||
|
||||
Reference in New Issue
Block a user