# ab-dnd-kit-sortable-tree

> [![npm version](https://badge.fury.io/js/dnd-kit-sortable-tree.svg)](https://www.npmjs.org/package/dnd-kit-sortable-tree) [![npm](https://img.shields.io/npm/dt/dnd-kit-sortable-tree.svg)](https://www.npmjs.org/package/dnd-kit-sortable-tree) [![MIT](https:

Latest version **0.1.64** (published 2023-06-20) · MIT license · 0 weekly downloads

## Install

```sh
npm install ab-dnd-kit-sortable-tree
pnpm add ab-dnd-kit-sortable-tree
yarn add ab-dnd-kit-sortable-tree
bun add ab-dnd-kit-sortable-tree
```

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.1.64 |
| Published | 2023-06-20 |
| First published | 2023-06-20 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=10 |
| Dependencies | 2 |
| Unpacked size | 301.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | slb235 |
| Maintainers | slb235 |
| Keywords | tree, dndkit, react, typescript |

## Links

- npm: https://www.npmjs.com/package/ab-dnd-kit-sortable-tree
- Homepage: https://github.com/slb235/dnd-kit-sortable-tree#readme
- npm.io page: https://npm.io/package/ab-dnd-kit-sortable-tree

## Dependencies (2)

- [clsx](https://npm.io/package/clsx.md) ^1.2.1
- [react-merge-refs](https://npm.io/package/react-merge-refs.md) ^2.0.1

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 0.1.64 (latest) — 2023-06-20
- 0.1.63 — 2023-06-20

## README

# dnd-kit-sortable-tree

[![npm version](https://badge.fury.io/js/dnd-kit-sortable-tree.svg)](https://www.npmjs.org/package/dnd-kit-sortable-tree) [![npm](https://img.shields.io/npm/dt/dnd-kit-sortable-tree.svg)](https://www.npmjs.org/package/dnd-kit-sortable-tree) [![MIT](https://img.shields.io/dub/l/vibe-d.svg)](https://opensource.org/licenses/MIT)

This is a Tree component extracted from [dndkit](https://github.com/clauderic/dnd-kit) examples and abstracted a bit.
Here's how it could look like (visuals are completely customizable via css though)
[![img.png](img.png)](https://shaddix.github.io/dnd-kit-sortable-tree)

Play around in [examples](https://shaddix.github.io/dnd-kit-sortable-tree) to check the API and see what it can do.

## Install

    npm install dnd-kit-sortable-tree @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities

## How-to use

Check out the Storybook for code samples and play around. You could also play with it on [playcode](https://playcode.io/1032571)

Shortly, you need to render:

```tsx
<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`:

```tsx
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!

## Examples

1. 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.
   ```jsx
   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' },
   ];
   ```
2. Here's the minimal viable example that you could potentially copy&paste to your project to start from.

   ```tsx
   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 },
   ];
   ```

## API

### Data configuration (each TreeItem element could define them):

- `canHaveChildren` - Default: `true`. If set to `false`, prevents any node from being dragged into the current one
- `disableSorting` - Default: `false`. If set to `true`, prevents node from being dragged (i.e. it can't be sorted or moved to another node)

### Tree configuration (props of `<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
- `disableSorting` - _optional_, you could set this to `true` to completely disable the sorting

### TreeItemWrapper configuration (props of `<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.

# Troubleshooting

1. If your dragged item is shown at the end of a list, make sure you that:
   1. You wrapped your `TreeItem` component in `React.forwardRef` and passing the `ref` to `SimpleTreeItemWrapper`
   1. You pass the `styles` prop from `TreeItem` to `SimpleTreeItemWrapper`

---
_Source: https://npm.io/package/ab-dnd-kit-sortable-tree · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
