import React, { CSSProperties, HTMLAttributes, useMemo } from 'react';
import {
AnimateLayoutChanges,
UseSortableArguments,
useSortable,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { getIsOverParent, iOS } from './utilities';
import type { FlattenedItem, TreeItem, TreeItemComponentType } from './types';
import { UniqueIdentifier } from '@dnd-kit/core';
export interface TreeItemProps extends HTMLAttributes {
childCount?: number;
clone?: boolean;
collapsed?: boolean;
depth: number;
disableInteraction?: boolean;
disableSelection?: boolean;
ghost?: boolean;
handleProps?: any;
indicator?: boolean;
indentationWidth: number;
item: TreeItem;
isLast: boolean;
parent: FlattenedItem | null;
onCollapse?(id: UniqueIdentifier): void;
onRemove?(id: UniqueIdentifier): void;
wrapperRef?(node: HTMLLIElement): void;
}
const animateLayoutChanges: AnimateLayoutChanges = ({
isSorting,
isDragging,
}) => (isSorting || isDragging ? false : true);
type SortableTreeItemProps<
T,
TElement extends HTMLElement
> = TreeItemProps & {
id: string;
TreeItemComponent: TreeItemComponentType;
disableSorting?: boolean;
sortableProps?: Omit;
keepGhostInPlace?: boolean;
};
const SortableTreeItemNotMemoized = function SortableTreeItem<
T,
TElement extends HTMLElement
>({
id,
depth,
isLast,
TreeItemComponent,
parent,
disableSorting,
sortableProps,
keepGhostInPlace,
...props
}: SortableTreeItemProps) {
const {
attributes,
isDragging,
isSorting,
listeners,
setDraggableNodeRef,
setDroppableNodeRef,
transform,
transition,
isOver,
over,
} = useSortable({
id,
animateLayoutChanges,
disabled: disableSorting,
...sortableProps,
});
const isOverParent = useMemo(
() => !!over?.id && getIsOverParent(parent, over.id),
[over?.id]
);
const style: CSSProperties = {
transform: CSS.Translate.toString(transform),
transition: transition ?? undefined,
};
const localCollapse = useMemo(() => {
if (!props.onCollapse) return undefined;
return () => props.onCollapse?.(props.item.id);
}, [props.item.id, props.onCollapse]);
const localRemove = useMemo(() => {
if (!props.onRemove) return undefined;
return () => props.onRemove?.(props.item.id);
}, [props.item.id, props.onRemove]);
return (
);
};
export const SortableTreeItem = React.memo(
SortableTreeItemNotMemoized
) as typeof SortableTreeItemNotMemoized;