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:
@@ -76,13 +76,21 @@ export default function PanelGroups({
|
||||
pos: renderedIds.indexOf(String(id)) + 1,
|
||||
total: renderedIds.length,
|
||||
}));
|
||||
// The stored order, plus any available group it does not hold yet (see above): a move — by drag
|
||||
// or by a group's Up / Down — lands in it, so a group appended after the layout was saved moves too.
|
||||
const fullOrder = [
|
||||
...layout.order,
|
||||
...orderedAvailable.filter((id) => !layout.order.includes(id)),
|
||||
];
|
||||
function move(id: string, overId: string) {
|
||||
const from = fullOrder.indexOf(id);
|
||||
const to = fullOrder.indexOf(overId);
|
||||
if (from < 0 || to < 0 || from === to) return;
|
||||
setLayout({ ...layout, order: arrayMove(fullOrder, from, to) });
|
||||
}
|
||||
function onDragEnd(e: DragEndEvent) {
|
||||
const { active, over } = e;
|
||||
if (!over || active.id === over.id) return;
|
||||
const from = layout.order.indexOf(active.id as string);
|
||||
const to = layout.order.indexOf(over.id as string);
|
||||
if (from < 0 || to < 0) return;
|
||||
setLayout({ ...layout, order: arrayMove(layout.order, from, to) });
|
||||
if (over) move(String(active.id), String(over.id));
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -94,7 +102,7 @@ export default function PanelGroups({
|
||||
>
|
||||
<SortableContext items={renderedIds} strategy={verticalListSortingStrategy}>
|
||||
<div className="space-y-3">
|
||||
{renderedIds.map((id) => (
|
||||
{renderedIds.map((id, i) => (
|
||||
<PanelGroup
|
||||
key={id}
|
||||
id={id}
|
||||
@@ -107,6 +115,11 @@ export default function PanelGroups({
|
||||
onToggleHidden={() => toggleHidden(id)}
|
||||
onTitleClick={byId.get(id)!.onTitleClick}
|
||||
titleActionLabel={byId.get(id)!.titleActionLabel}
|
||||
order={{
|
||||
from: i,
|
||||
count: renderedIds.length,
|
||||
onMove: (to) => move(id, renderedIds[to]!),
|
||||
}}
|
||||
>
|
||||
{byId.get(id)!.body}
|
||||
</PanelGroup>
|
||||
|
||||
Reference in New Issue
Block a user