import { Flex } from "@chakra-ui/react"; import { closestCenter, DndContext, KeyboardSensor, PointerSensor, TouchSensor, useSensor, useSensors, } from "@dnd-kit/core"; import type { DragEndEvent } from "@dnd-kit/core/dist/types/events"; import { restrictToVerticalAxis } from "@dnd-kit/modifiers"; import { arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy, } from "@dnd-kit/sortable"; import { ReactNode, useEffect, useState } from "react"; import { CollapsableText } from "../CollapsableText"; import { SortableItem } from "./SortableItem"; export interface SortableProps { items: ReactNode[]; onChange?: (newSortedIndices: number[]) => void; isDisabled?: boolean; className?: string; } interface SortableItems { id: number; originalIndex: number; item: ReactNode; } export const Sortable = (props: SortableProps) => { const [itemsWithIds, setItemsWithIds] = useState([]); useEffect(() => { setItemsWithIds( props.items.map((item, idx) => ({ item, id: idx + 1, // +1 because dndtoolkit has problem with "falsy" ids originalIndex: idx, })) ); }, [props.items]); const sensors = useSensors( useSensor(PointerSensor), useSensor(TouchSensor), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }) ); const extraClasses = props.className || ""; return ( {itemsWithIds.map(({ id, item }) => ( ))} ); function handleDragEnd(event: DragEndEvent) { const { active, over } = event; if (active.id === over.id) { return; } setItemsWithIds((items) => { const oldIndex = items.findIndex((x) => x.id === active.id); const newIndex = items.findIndex((x) => x.id === over.id); const newArray = arrayMove(items, oldIndex, newIndex); props.onChange && props.onChange(newArray.map((item) => item.originalIndex)); return newArray; }); } };