60 lines
1.5 KiB
TypeScript
60 lines
1.5 KiB
TypeScript
import React, { CSSProperties, ReactNode } from "react";
|
|
import { useSortable } from "@dnd-kit/sortable";
|
|
import { CSS } from "@dnd-kit/utilities";
|
|
import DragHandle from "./DragHandle";
|
|
|
|
type Props = {
|
|
id: number | string;
|
|
renderItem: (renderDraggable?: () => ReactNode) => ReactNode;
|
|
renderDraggable?: () => ReactNode; // if not passed - the whole item renders as draggable
|
|
disabled?: boolean;
|
|
dragHandleStyle?: CSSProperties;
|
|
};
|
|
|
|
const SortableItem = ({
|
|
renderItem,
|
|
dragHandleStyle,
|
|
renderDraggable,
|
|
id,
|
|
disabled = false,
|
|
}: Props) => {
|
|
const { isDragging, setNodeRef, transform, transition } = useSortable({
|
|
id,
|
|
animateLayoutChanges: () => false,
|
|
});
|
|
|
|
const style: CSSProperties = {
|
|
opacity: isDragging ? 0.4 : undefined,
|
|
transform: CSS.Translate.toString(transform),
|
|
transition,
|
|
};
|
|
|
|
const renderDragHandle = () => (
|
|
<DragHandle
|
|
id={id}
|
|
style={dragHandleStyle}
|
|
disabled={disabled}>
|
|
{renderDraggable && renderDraggable()}
|
|
</DragHandle>
|
|
);
|
|
|
|
return (
|
|
<div
|
|
ref={setNodeRef}
|
|
style={style}>
|
|
{renderDraggable ? (
|
|
renderItem(renderDragHandle)
|
|
) : (
|
|
<DragHandle
|
|
id={id}
|
|
style={dragHandleStyle}
|
|
disabled={disabled}>
|
|
{renderItem()}
|
|
</DragHandle>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default SortableItem;
|