feat(playlists): select rows with a box, Shift for a range, x and Esc

A box first in every row and one over the column for the rows shown, the
selected row tinted. A filter keeps what it hides selected; another list
starts over; a row that left the list drops out. Watch later has none.

A box no longer counts as a typing target: a click on one left the focus
there and the page's keys went dead.
This commit is contained in:
2026-11-01 20:49:59 +01:00
parent cd773e8f33
commit 8cf8c4139c
20 changed files with 710 additions and 29 deletions
+5 -2
View File
@@ -1,5 +1,5 @@
import { useRef, type ReactNode } from "react";
import { useListNav } from "../../lib/listNav";
import { useListNav, type NavSelection } from "../../lib/listNav";
// A plain list of cards or rows the keyboard can walk — `j`/`k`, the arrows, Enter (lib/listNav) — for
// the lists that mount every item (the Plex title, season and episode grids, the download lists, a
@@ -11,16 +11,19 @@ export default function NavGrid({
as: Tag = "div",
className,
onDelete,
selection,
children,
}: {
as?: "div" | "tbody";
className?: string;
/** The Delete key takes the focused item out (lib/listNav): its index among the items. */
onDelete?: (index: number) => void;
/** `x` selects the focused item, Esc clears (lib/listNav). */
selection?: NavSelection;
children: ReactNode;
}) {
const ref = useRef<HTMLDivElement & HTMLTableSectionElement>(null);
useListNav(ref, { enabled: true, onDelete });
useListNav(ref, { enabled: true, onDelete, selection });
return (
<Tag ref={ref} className={className}>
{children}