
Research
NPM targeted by malware campaign mimicking familiar library names
Socket uncovered npm malware campaign mimicking popular Node.js libraries and packages from other ecosystems; packages steal data and execute remote code.
dnd-kit-sortable-tree
Advanced tools
[](https://www.npmjs.org/package/dnd-kit-sortable-tree) [](https://www.npmjs.org/package/dnd-kit-sortable-tree) [
Play around in examples to check the API and see what it can do.
npm install dnd-kit-sortable-tree @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
Check out the Storybook for code samples and play around. You could also play with it on playcode
Shortly, you need to render:
<SortableTree
items={/* array of your tree items */}
onItemsChanged={/* callback when items are reordered */}
TreeItemComponent={/* component that renders a single tree item */}
/>
And TreeItemComponent
is usually your data wrapped in SimpleTreeItemWrapper
or FolderTreeItemWrapper
:
React.forwardRef((props, ref) => (
<SimpleTreeItemWrapper {...props} ref={ref}>
<div>{props.item.value}</div>
</SimpleTreeItemWrapper>
));
Note that wrapping in forwardRef
and passing ref
to SimpleTreeItemWrapper
is very important!
Here's the very minimal code to add a Sortable Tree. You shouldn't use it as is in your project, but it could be easier to grasp what's going on.
export const Minimal = () => {
const [items, setItems] = useState(initialMinimalData);
return (
<SortableTree
items={items}
onItemsChanged={setItems}
{
/*
* You need to pass the component rendering a single item via TreeItemComponent props.
* This component will receive the data via `props.item`.
* In this example we inline the component, but in reality you should extract it into a const.
*/ ...{}
}
TreeItemComponent={React.forwardRef((props, ref) => (
<SimpleTreeItemWrapper {...props} ref={ref}>
{/* HERE GOES THE ACTUAL CONTENT OF YOUR COMPONENT */}
<div>{props.item.id}</div>
</SimpleTreeItemWrapper>
))}
/>
);
};
/*
* Configure the tree data.
*/
const initialMinimalData = [
{ id: '1', children: [{ id: '4' }, { id: '5' }] },
{ id: '2' },
{ id: '3' },
];
Here's the minimal viable example that you could potentially copy&paste to your project to start from.
export const MinimalViable = () => {
const [items, setItems] = useState(initialViableMinimalData);
return (
<SortableTree
items={items}
onItemsChanged={setItems}
TreeItemComponent={MinimalTreeItemComponent}
/>
);
};
type MinimalTreeItemData = {
value: string;
};
/*
* Here's the component that will render a single row of your tree
*/
const MinimalTreeItemComponent = React.forwardRef<
HTMLDivElement,
TreeItemComponentProps<MinimalTreeItemData>
>((props, ref) => (
/* you could also use FolderTreeItemWrapper if you want to show vertical lines. */
<SimpleTreeItemWrapper {...props} ref={ref}>
<div>{props.item.value}</div>
</SimpleTreeItemWrapper>
));
/*
* Configure the tree data.
*/
const initialViableMinimalData: TreeItems<MinimalTreeItemData> = [
{
id: '1',
value: 'Jane',
children: [
{ id: '4', value: 'John' },
{ id: '5', value: 'Sally' },
],
},
{ id: '2', value: 'Fred', children: [{ id: '6', value: 'Eugene' }] },
{ id: '3', value: 'Helen', canHaveChildren: false },
];
canHaveChildren
- Default: true
.
If set to false
, prevents any node from being dragged into the current one.
Also accepts a function: (dragItem) => bool
which could conditionally determine if a certain item could be a children of a node
disableSorting
- Default: false
. If set to true
, prevents node from being dragged (i.e. it can't be sorted or moved to another node)
<SortableTree>
)items
- mandatory, items shown in a tree
onItemsChanged
- mandatory, callback that is called when dragging of certain item is finished. You should preserve new state and adjust the value of items
prop as needed.
TreeItemComponent
- mandatory, component that renders a single tree row.
indentationWidth
- optional, padding used for children
pointerSensorOptions
- optional, configures the condition when item dragging starts. Defaults to:
{
"activationConstraint": {
"distance": 3
}
}
disableSorting
- optional, you could set this to true
to completely disable the sorting
keepGhostInPlace
- optional, you could set this to true
to keep the Node that you are dragging in it's original place in a Tree. Check VSCode sample to see it in action.
dndContextProps
- optional, override any prop of underlying DndContext.
sortableProps
- optional, override any prop that is passed to underlying useSortable hook.
<SimpleTreeItemWrapper>
and <FolderTreeItemWrapper>
)manualDrag
- Default: false
. Set to true
if you want tree item to be draggable ONLY from dragHandle.showDragHandle
- optional, set to false
if you want to hide default dragHandle and show your own instead. Use <div {...props.handleProps}>DRAG_ME</div>
for your own drag handle.null
as dropAnimation
prop (this disables the actual 'drop' animation for the Node that was dragged).{ animateLayoutChanges: () => false }
to sortableProps
(this disables the animation of all other nodes that were not dragged)TreeItem
component in React.forwardRef
and passing the ref
to SimpleTreeItemWrapper
styles
prop from TreeItem
to SimpleTreeItemWrapper
FAQs
[](https://www.npmjs.org/package/dnd-kit-sortable-tree) [](https://www.npmjs.org/package/dnd-kit-sortable-tree) [ to exfiltrate data and execute commands.