feat(design): reorder without a drag everywhere a grip drags (WCAG 2.5.7, E28 S3e4a)
One rule, two forms: useOrderItems (Top / Up / Down / Bottom rows of a row menu) and OrderButtons (four buttons with the place, or a compact Up / Down pair). A move that would go nowhere is shown off. - YouTube playlist rows: the four moves now come from useOrderItems. - Plex playlist rows: a block among the blocks, an episode within its show, off while a write is in flight; drag and menu share moveBlock/moveEpisode. - Saved views editor: the selected view's four buttons (owner: A), and the grip's keyboard pick-up (its instructions promised one it did not have). - Side panel groups in edit mode: an Up / Down pair (owner: A); a group the stored order does not hold yet moves too; the name wraps there. - The grip's touch-action: none is now test-held.
This commit is contained in:
@@ -114,7 +114,7 @@ describe("PlexPlaylistView · a row's menu", () => {
|
||||
expect(moreOf("The Show")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("lists the title's own actions, then the removal", async () => {
|
||||
it("lists the title's own actions, its moves, then the removal", async () => {
|
||||
const info = vi.fn();
|
||||
mount([movie("1")], info);
|
||||
await screen.findByText("Movie 1");
|
||||
@@ -126,6 +126,10 @@ describe("PlexPlaylistView · a row's menu", () => {
|
||||
"plex.info.title",
|
||||
"common.copy.title",
|
||||
"home.pin.add",
|
||||
"common.order.top",
|
||||
"common.order.up",
|
||||
"common.order.down",
|
||||
"common.order.bottom",
|
||||
"plex.playlist.removeFromPlaylist",
|
||||
]);
|
||||
expect(moreOf("Movie 1").getAttribute("aria-expanded")).toBe("true");
|
||||
@@ -165,6 +169,10 @@ describe("PlexPlaylistView · a row's menu", () => {
|
||||
expect(menuRows()).toEqual([
|
||||
"plex.playlist.playShow",
|
||||
"common.copy.title",
|
||||
"common.order.top",
|
||||
"common.order.up",
|
||||
"common.order.down",
|
||||
"common.order.bottom",
|
||||
"plex.playlist.removeShow",
|
||||
]);
|
||||
fireEvent.click(
|
||||
@@ -198,6 +206,43 @@ describe("PlexPlaylistView · a row's menu", () => {
|
||||
});
|
||||
});
|
||||
|
||||
const moveRow = (label: string) =>
|
||||
screen.getAllByRole("menuitem", { hidden: true }).find((b) => b.textContent === label)!;
|
||||
|
||||
describe("PlexPlaylistView · reordering without a drag (WCAG 2.5.7)", () => {
|
||||
it("moves a title among the blocks from its menu, the moves that go nowhere held off", async () => {
|
||||
mount([movie("1"), ep("e1", 1, 1), movie("2")]);
|
||||
await screen.findByText("Movie 1");
|
||||
const reorder = vi.spyOn(api, "plexReorderPlaylist").mockResolvedValue({} as never);
|
||||
await openMenu(() => fireEvent.click(moreOf("Movie 1")));
|
||||
expect((moveRow("common.order.top") as HTMLButtonElement).disabled).toBe(true);
|
||||
expect((moveRow("common.order.up") as HTMLButtonElement).disabled).toBe(true);
|
||||
fireEvent.click(moveRow("common.order.bottom"));
|
||||
// The show moves as one block: Movie 1 lands after Movie 2, the episode stays with its show.
|
||||
await waitFor(() => expect(reorder).toHaveBeenCalledWith(5, ["e1", "2", "1"]));
|
||||
});
|
||||
|
||||
it("moves a whole show from its group's menu", async () => {
|
||||
mount([movie("1"), ep("e1", 1, 1), ep("e2", 1, 2)]);
|
||||
await screen.findByText("The Show");
|
||||
const reorder = vi.spyOn(api, "plexReorderPlaylist").mockResolvedValue({} as never);
|
||||
await pick(() => fireEvent.click(moreOf("The Show")), "common.order.up");
|
||||
await waitFor(() => expect(reorder).toHaveBeenCalledWith(5, ["e1", "e2", "1"]));
|
||||
});
|
||||
|
||||
it("moves an episode only within its own show", async () => {
|
||||
mount([movie("1"), ep("e1", 1, 1), ep("e2", 1, 2), ep("e3", 1, 3)]);
|
||||
fireEvent.click(await screen.findByText("The Show")); // open the group
|
||||
await screen.findByText("Ep e3");
|
||||
const reorder = vi.spyOn(api, "plexReorderPlaylist").mockResolvedValue({} as never);
|
||||
await openMenu(() => fireEvent.click(moreOf("Ep e3")));
|
||||
// Last of three in its show: down is off, though a movie sits above the show in the list.
|
||||
expect((moveRow("common.order.down") as HTMLButtonElement).disabled).toBe(true);
|
||||
fireEvent.click(moveRow("common.order.top"));
|
||||
await waitFor(() => expect(reorder).toHaveBeenCalledWith(5, ["1", "e3", "e1", "e2"]));
|
||||
});
|
||||
});
|
||||
|
||||
describe("PlexPlaylistView · the keyboard", () => {
|
||||
it("walks the rows with j and takes out the walked one on Delete", async () => {
|
||||
mount([movie("1"), movie("2"), movie("3")]);
|
||||
|
||||
Reference in New Issue
Block a user