"use client"; import { ArrowIcon, GripIcon } from "../ui/icons.tsx"; import { useReducedMotion } from "../motion/Preferences.tsx"; import { Reorder, useDragControls } from "motion/react"; export type ReorderEntry = { id: string; label: string; description?: string }; function Entry({ item, index, total, move, }: { item: ReorderEntry; index: number; total: number; move: (from: number, to: number) => void; }) { const controls = useDragControls(), reduced = useReducedMotion(); return (
{item.label} {item.description && {item.description}}
); } export function ReorderList({ items, onReorder, label = "Reorder items", className = "", }: { items: readonly T[]; onReorder: (items: T[]) => void; label?: string; className?: string; }) { const move = (from: number, to: number) => { if (to < 0 || to >= items.length || from === to) return; const next = [...items]; next.splice(to, 0, next.splice(from, 1)[0]!); onReorder(next); }; return (

{label}

i.id)} aria-label={label} onReorder={(ids) => onReorder(ids.map((id) => items.find((i) => i.id === id)!)) } > {items.map((item, index) => ( ))} {!items.length &&

No items to reorder.

}

Drag a handle, use its arrow keys, or use the move buttons.

); }