{"id":25232947,"url":"https://github.com/minop1205/react-dnd-treeview","last_synced_at":"2025-04-09T02:18:24.535Z","repository":{"id":37876758,"uuid":"293962244","full_name":"minop1205/react-dnd-treeview","owner":"minop1205","description":"A draggable / droppable React-based treeview component. You can use render props to create each node freely.","archived":false,"fork":false,"pushed_at":"2025-01-14T03:13:09.000Z","size":9465,"stargazers_count":558,"open_issues_count":39,"forks_count":71,"subscribers_count":11,"default_branch":"next","last_synced_at":"2025-04-02T01:15:39.811Z","etag":null,"topics":["component","dnd","drag-and-drop","headress-component","react","touch-support","treeview"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/minop1205.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-09T00:44:53.000Z","updated_at":"2025-04-01T15:38:10.000Z","dependencies_parsed_at":"2024-04-19T04:21:57.469Z","dependency_job_id":"6c85609b-2000-4759-9e9d-cd879d3a63e7","html_url":"https://github.com/minop1205/react-dnd-treeview","commit_stats":{"total_commits":485,"total_committers":10,"mean_commits":48.5,"dds":0.07628865979381438,"last_synced_commit":"c76f4e131320383b562a07b4e4ca98d758f8b82c"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minop1205%2Freact-dnd-treeview","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minop1205%2Freact-dnd-treeview/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minop1205%2Freact-dnd-treeview/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minop1205%2Freact-dnd-treeview/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/minop1205","download_url":"https://codeload.github.com/minop1205/react-dnd-treeview/tar.gz/refs/heads/next","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247962605,"owners_count":21024871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["component","dnd","drag-and-drop","headress-component","react","touch-support","treeview"],"created_at":"2025-02-11T13:37:24.621Z","updated_at":"2025-04-09T02:18:24.513Z","avatar_url":"https://github.com/minop1205.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React DnD TreeView\n\nA draggable and droppable React treeview component.  \nYou can use render props to create each node freely.\n\n![react-dnd-treeview](https://user-images.githubusercontent.com/3772820/204380436-4c501e28-6c0a-43ea-a317-6620d6dc1ca0.gif)\n\n## Demo and Examples\n\nSome of the examples below use [MUI(Material-UI)](https://mui.com) components, but TreeView does not depend on MUI, so you can use other libraries or your own custom components.\n\n[https://minop1205.github.io/react-dnd-treeview/](https://minop1205.github.io/react-dnd-treeview/?path=/docs/basic-examples-minimum-configuration--minimum-configuration-story)\n\n## Breaking changes and migration\n\nSee [Migration Guide](MIGRATION.md) for information on breaking changes and migrations between major versions.\n\n## Getting Started\n\n### Installation\n\n```shell\n$ npm i react-dnd @minoru/react-dnd-treeview\n```\n\n### Usage\n\n```jsx\nimport { useState } from \"react\";\nimport {\n  Tree,\n  getBackendOptions,\n  MultiBackend,\n} from \"@minoru/react-dnd-treeview\";\nimport { DndProvider } from \"react-dnd\";\nimport initialData from \"./sample-default.json\";\n\nfunction App() {\n  const [treeData, setTreeData] = useState(initialData);\n  const handleDrop = (newTreeData) =\u003e setTreeData(newTreeData);\n\n  return (\n    \u003cDndProvider backend={MultiBackend} options={getBackendOptions()}\u003e\n      \u003cTree\n        tree={treeData}\n        rootId={0}\n        onDrop={handleDrop}\n        render={(node, { depth, isOpen, onToggle }) =\u003e (\n          \u003cdiv style={{ marginLeft: depth * 10 }}\u003e\n            {node.droppable \u0026\u0026 (\n              \u003cspan onClick={onToggle}\u003e{isOpen ? \"[-]\" : \"[+]\"}\u003c/span\u003e\n            )}\n            {node.text}\n          \u003c/div\u003e\n        )}\n      /\u003e\n    \u003c/DndProvider\u003e\n  );\n}\n```\n\n### Backends\n\n`MultiBackend` is a backend to support both touch and pointer devices. If you only need support for one or the other, you can also use the backend provided by [react-dnd-html5-backend](https://react-dnd.github.io/react-dnd/docs/backends/html5) or [react-dnd-touch-backend](https://react-dnd.github.io/react-dnd/docs/backends/touch).\n\n```jsx\nimport { DndProvider } from \"react-dnd\";\nimport { HTML5Backend } from \"react-dnd-html5-backend\";\n\nfunction App() {\n  return (\n    \u003cDndProvider backend={HTML5Backend}\u003e\n      \u003cTree {...someProps}\u003e /\u003e\n    \u003c/DndProvider\u003e\n  );\n}\n```\n\n```jsx\nimport { DndProvider } from \"react-dnd\";\nimport { TouchBackend } from \"react-dnd-touch-backend\";\n\nfunction App() {\n  return (\n    \u003cDndProvider backend={TouchBackend}\u003e\n      \u003cTree {...someProps}\u003e /\u003e\n    \u003c/DndProvider\u003e\n  );\n}\n```\n\n### Backend options\n\n`HTML5Backend`, `TouchBackend` and `MultiBackend` allow setting the BackendOptions defined in `react-dnd`.\n\nFor more information on `TouchBackend`, please see [here](https://react-dnd.github.io/react-dnd/docs/backends/touch#options). (For the HTML5Backend option, only the `rootElement` option is available.)\n\n```jsx\nimport { DndProvider } from \"react-dnd\";\nimport { HTML5Backend, HTML5BackendOptions } from \"react-dnd-html5-backend\";\nimport {TouchBackend, TouchBackendOptions} from \"react-dnd-touch-backend\"\nimport {Tree, MultiBackend, getBackendOptions} from \"@minoru/react-dnd-treeview\"\n\nconst touchOptions: Partial\u003cTouchBackendOptions\u003e = {\n  // some options\n};\n\nconst html5Options: Partial\u003cHTML5BackendOptions\u003e = {\n  rootElement: document.body,\n  // some options\n};\n\nconst multiOptions = {\n  touch: touchOptions,\n  html5: html5Options,\n}\n\nfunction App() {\n  return (\n    \u003cDndProvider\n      backend={MultiBackend}\n      options={getBackendOptions(multiOptions)}\n\n      // or\n      // backend={HTML5Backend}\n      // options={html5Options}\n\n      // or\n      // backend={TouchBackend}\n      // options={touchOptions}\n    \u003e\n      \u003cTree {...someProps}\u003e /\u003e\n    \u003c/DndProvider\u003e\n  );\n}\n```\n\n## Data Structure\n\nTo display the treeview, pass data with the following structure to the `tree` property of the Tree component.\n\n### Basic example\n\nThe minimal data structure for representing the tree is shown in the following example\n\n```json\n[\n  {\n    \"id\": 1,\n    \"parent\": 0,\n    \"droppable\": true,\n    \"text\": \"Folder 1\"\n  },\n  {\n    \"id\": 2,\n    \"parent\": 1,\n    \"text\": \"File 1-1\"\n  },\n  {\n    \"id\": 3,\n    \"parent\": 1,\n    \"text\": \"File 1-2\"\n  },\n  {\n    \"id\": 4,\n    \"parent\": 0,\n    \"droppable\": true,\n    \"text\": \"Folder 2\"\n  },\n  {\n    \"id\": 5,\n    \"parent\": 4,\n    \"droppable\": true,\n    \"text\": \"Folder 2-1\"\n  },\n  {\n    \"id\": 6,\n    \"parent\": 5,\n    \"text\": \"File 2-1-1\"\n  }\n]\n```\n\n### Optional data\n\nIf you want to pass custom properties to each node's rendering,  \nyou can use the `data` property.\n\n```json\n[\n  {\n    \"id\": 1,\n    \"parent\": 0,\n    \"droppable\": true,\n    \"text\": \"Folder 1\"\n  },\n  {\n    \"id\": 2,\n    \"parent\": 1,\n    \"text\": \"File 1-1\",\n    \"data\": {\n      \"fileType\": \"csv\",\n      \"fileSize\": \"0.5MB\"\n    }\n  },\n  {\n    \"id\": 3,\n    \"parent\": 1,\n    \"text\": \"File 1-2\",\n    \"data\": {\n      \"fileType\": \"pdf\",\n      \"fileSize\": \"4.8MB\"\n    }\n  },\n  {\n    \"id\": 4,\n    \"parent\": 0,\n    \"droppable\": true,\n    \"text\": \"Folder 2\"\n  },\n  {\n    \"id\": 5,\n    \"parent\": 4,\n    \"droppable\": true,\n    \"text\": \"Folder 2-1\"\n  },\n  {\n    \"id\": 6,\n    \"parent\": 5,\n    \"text\": \"File 2-1-1\",\n    \"data\": {\n      \"fileType\": \"image\",\n      \"fileSize\": \"2.1MB\"\n    }\n  }\n]\n```\n\n### Node properties\n\n| Key       | Type                 | Required | Default     | Description                                                                                     |\n| --------- | -------------------- | -------- | ----------- | ----------------------------------------------------------------------------------------------- |\n| id        | `number` \\| `string` | ✅       | -           | Identifier of each node                                                                         |\n| parent    | `number` \\| `string` | ✅       | -           | Parent id of each node                                                                          |\n| text      | `string`             | ✅       | -           | Node label                                                                                      |\n| droppable | `boolean`            |          | `false`     | If `true`, child nodes will be accepted and it will be able to drop other node                  |\n| data      | `any`                |          | `undefined` | Additional data to be injected into each node.\u003cbr\u003eThese data are available in the render props. |\n\n## Component API\n\n| Props                | Type                    | Required | Default     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |\n| -------------------- | ----------------------- | -------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| tree                 | `array`                 | ✅       |             | The data representing the tree structure. An array of node data.                                                                                                                                                                                                                                                                                                                                                                                                                                           |\n| rootId               | `number` \\| `string`    | ✅       |             | The id of the root node. It is the parent id of the shallowest node displayed in the tree view.                                                                                                                                                                                                                                                                                                                                                                                                            |\n| extraAcceptTypes     | `array`                 |          | `[]`        | If allowing drop from outside the tree, the [drag type](https://react-dnd.github.io/react-dnd/docs/api/use-drag#specification-object-members) of the drag source.                                                                                                                                                                                                                                                                                                                                          |\n| classes              | `object`                |          | `undefined` | A set of CSS class names to be applied to a specific area in the tree view.\u003cbr\u003eSee the [Component Styling](#Component-Styling) section for more information.                                                                                                                                                                                                                                                                                                                                               |\n| listComponent        | `string`                |          | `ul`        | HTML tag for list.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |\n| listItemComponent    | `string`                |          | `li`        | HTML tag for list items.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |\n| render               | `function`              | ✅       |             | The render function of each node.\u003cbr\u003ePlease refer to the [Render prop](#Render-prop) section for more details about the render functions.                                                                                                                                                                                                                                                                                                                                                                  |\n| dragPreviewRender    | `function`              |          | `undefined` | Render function for customizing the drag preview.\u003cbr\u003eSee the [Dragging Preview](#Dragging-Preview) section for more information on customizing the drag preview\u003cbr\u003e\u003cbr\u003e**NOTE**:\u003cbr\u003eThe default preview is not displayed on touch devices. Therefore, if you want to support touch devices, please define a custom preview in `dragPreviewRender`.                                                                                                                                                         |\n| onDrop               | `function`              | ✅       |             | Callback function for when the state of the tree is changed.\u003cbr\u003eThe new data is passed as the argument.\u003cbr\u003eSee the [onDrop callback](#onDrop-callback) section for more information.                                                                                                                                                                                                                                                                                                                       |\n| onDragStart          | `function`              |          | `undefined` | This event is fired when a node in the tree is started to be dragged. The event handler is passed the target node and a [DragSourceMonitor](https://react-dnd.github.io/react-dnd/docs/api/drag-source-monitor) object.                                                                                                                                                                                                                                                                                    |\n| onDragEnd            | `function`              |          | `undefined` | This event is fired when a node in the tree is finished being dragged. The event handler is passed the target node and a [DragSourceMonitor](https://react-dnd.github.io/react-dnd/docs/api/drag-source-monitor) object.                                                                                                                                                                                                                                                                                   |\n| onChangeOpen         | `function`              |          | `undefined` | Callback function to be called after the open/close state of a node is changed.\u003cbr\u003eThe function is passed an array of node IDs in the open state.                                                                                                                                                                                                                                                                                                                                                          |\n| canDrop              | `function`              |          | `undefined` | A callback function to determine if a given node can be dropped to another node.\u003cbr\u003eIf nothing is returned (or if undefined is returned), the default rules are followed.\u003cbr\u003eIf it returns true or false, the default rules will be overridden and the `droppable` properties of each node will not be referenced.\u003cbr\u003eThis callback takes the current tree and the same option object that is passed to the onDrop callback.\u003cbr\u003eSee the [canDrop callback](#canDrop-callback) section for more information. |\n| canDrag              | `function`              |          | `undefined` | Callback function which should return true or false depending on if a give node should be draggable.\u003cbr\u003eBy default, all nodes are draggable.                                                                                                                                                                                                                                                                                                                                                               |\n| sort                 | `function` \\| `boolean` |          | `true`      | This property controls the order of the child nodes.\u003cbr\u003e By default (`true`), they are sorted by the `text` property of each node.\u003cbr\u003e If `false`, sorting is disabled. In this case, the nodes will follow the order of the array passed to the `tree` property.\u003cbr\u003eIt is also possible to customize the sorting by passing a callback function.                                                                                                                                                          |\n| insertDroppableFirst | `boolean`               |          | `true`      | Specifies whether droppable nodes should be placed first in the list of child nodes.                                                                                                                                                                                                                                                                                                                                                                                                                       |\n| enableAnimateExpand  | `boolean`               |          | `false`     | Specifies whether use animation when toggle expanding the node.                                                                                                                                                                                                                                                                                                                                                                                                                                            |\n| placeholderRender    | `function`              |          | `undefined` | Render function for the drop destination placeholder. By default, placeholder is not displayed.\u003cbr\u003eSee the [Manual sort with placeholder](#Manual-sort-with-placeholder) section for more information on using placeholder.                                                                                                                                                                                                                                                                                |\n| placeholderComponent | `string`                |          | `li`        | HTML tag for placeholder.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |\n| dropTargetOffset     | `number`                |          | `0`         | Effective drop range of a droppable node. It is specified in pixels from the top or bottom of the node.\u003cbr\u003eUsed to insert a node anywhere using placeholders.\u003cbr\u003e\u003cbr\u003eSee the [Manual sort with placeholder placeholder](#Manual-sort-with-placeholder) section for more information on using placeholder.                                                                                                                                                                                                   |\n| initialOpen          | `boolean` \\| `array`    |          | `false`     | If true, all parent nodes will be initialized to the open state.\u003cbr\u003eIf an array of node IDs is passed instead of the boolean value, only the specified node will be initialized in the open state. When this prop is updated the open state of the tree is also reset.                                                                                                                                                                                                                                     |\n| rootProps            | `object`                |          | `undefined` | Properties to be passed to the root element (by default, `ul` tag), excluding the `ref` and `role` property.                                                                                                                                                                                                                                                                                                                                                                                               |\n\n### Render prop\n\nTo render each tree node, please pass a render function to the `render` property.\n\n```jsx\n\u003cTree\n  {...props}\n  render={(node, { depth, isOpen, draggable, onToggle }) =\u003e (\n    \u003cdiv style={{ marginLeft: depth * 10 }}\u003e\n      {node.droppable \u0026\u0026 (\n        \u003cspan onClick={onToggle}\u003e{isOpen ? \"[-]\" : \"[+]\"}\u003c/span\u003e\n      )}\n      {node.text}\n    \u003c/div\u003e\n  )}\n/\u003e\n```\n\nThe arguments passed to the render function are as follows\n\n| Name                 | Type              | Description                                                                                                                                                                                                                                                                 |\n| -------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| data                 | `object`          | Node data. (an element in the tree data array)                                                                                                                                                                                                                              |\n| options.depth        | `number`          | The depth of the node hierarchy.                                                                                                                                                                                                                                            |\n| options.isOpen       | `boolean`         | The open and closed state of the node.\u003cbr\u003eIf `droppable` is not `true`, isOpen is always false.                                                                                                                                                                             |\n| options.draggable    | `boolean`         | Indicates whether this node is draggable or not.                                                                                                                                                                                                                            |\n| options.hasChild     | `boolean`         | Flag indicating whether or not the node has children. It is true if the node has children, false otherwise.                                                                                                                                                                 |\n| options.isDragging   | `boolean`         | Flag indicating whether this node is being dragged or not.                                                                                                                                                                                                                  |\n| options.isDropTarget | `boolean`         | Flag indicating whether or not this node is a drop target.                                                                                                                                                                                                                  |\n| options.containerRef | `React.RefObject` | Reference to the HTML element (default: `li` tag) that wraps the custom node.                                                                                                                                                                                               |\n| options.handleRef    | `React.RefObject` | Reference to the HTML element you wish to set as a drag handle. It is used by assigning it to the `ref` attribute of the element you want to set as a handle.By default, no handle is set and the entire node is draggable.\u003cbr\u003eSee [Drag handle](#Drag-handle) for details. |\n| options.onToggle     | `function`        | An event handler for the open/close button of a node.                                                                                                                                                                                                                       |\n\n### Drag handle\n\nBy default, the entire node is draggable, but the `handleRef` render option allows the node to be dragged only by the specified handle, as in the following example.\n\n```jsx\n\u003cTree\n  {...props}\n  render={(node, { handleRef }) =\u003e (\n    \u003cdiv\u003e\n      \u003cspan ref={handleRef}\u003e[Drag me]\u003c/span\u003e\n      {node.text}\n    \u003c/div\u003e\n  )}\n/\u003e\n```\n\n### Dragging preview\n\nBy default, the drag preview is a screenshot of a DOM node.  \nThe `dragPreviewRender` property allows you to display a custom React component instead of a screenshot.\n\nNOTE:  \nThe default preview is not displayed on touch devices.  \nTherefore, if you want to support touch devices, please define a custom preview in `dragPreviewRender`.\n\n```jsx\n\u003cTree\n  {...props}\n  dragPreviewRender={(monitorProps) =\u003e {\n    const item = monitorProps.item;\n\n    return (\n      \u003cdiv\u003e\n        \u003cp\u003e{item.text}\u003c/p\u003e\n      \u003c/div\u003e\n    );\n  }}\n/\u003e\n```\n\nThe data passed to `dragPreviewRender` contains the following properties\n\n| Name         | Type     | Description                                                                                                                                                                   |\n| ------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| item         | `object` | Node data. (an element in the tree data array)\u003cbr\u003eIt also includes the `ref` property, which is a reference to the HTML element to be dragged.                                |\n| clientOffset | `object` | The client offset of the pointer during the dragging operation.\u003cbr\u003eIt is in the format of `{x: number, y: number}`.\u003cbr\u003eIf the item is not being dragged, it is set to `null`. |\n\n### onDrop callback\n\nIf the tree is modified by drag-and-drop, the changes can be retrieved by the `onDrop` callback.\n\n```jsx\nconst [treeData, setTreeData] = useState(initialTreeData);\nconst handleDrop = (\n  newTree,\n  { dragSourceId, dropTargetId, dragSource, dropTarget }\n) =\u003e {\n  // Do something\n\n  setTreeData(newTree);\n};\n\nreturn \u003cTree {...props} tree={treeData} onDrop={handleDrop} /\u003e;\n```\n\nThe arguments passed to the onDrop callback function are as follows\n\n| Name                     | Type                                | Description                                                                                                                                                                                                                                                                                      |\n| ------------------------ | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| newTree                  | `array`                             | This data represents the updated TreeView.\u003cbr\u003eTo redraw the modified TreeView, you need to set this data to the `tree` property.                                                                                                                                                                 |\n| options.dragSourceId     | `number` \\| `string` \\| `undefined` | node id of the dragging source.\u003cbr\u003eIf the drag source is an element external to `DndProvider` or a file or selected text, these will be `undefined`.                                                                                                                                             |\n| options.dropTargetId     | `number` \\| `string`                | node id of the drop destination.\u003cbr\u003eIf the drop destination is the root node, it will be the value of the `rootId` property.                                                                                                                                                                     |\n| options.dragSource       | `object`                            | node item of the dragging source.\u003cbr\u003eIf the drag source is an element external to `DndProvider` or a file or selected text, these will be `undefined`.                                                                                                                                           |\n| options.dropTarget       | `object` \\| `undefined`             | node item of the drop destination.\u003cbr\u003eIf the drop destination is the root node, it will be `undefined`                                                                                                                                                                                           |\n| options.destinationIndex | `number` \\| `undefined`             | When the `sort` property is `false`, it indicates the index to which the drag source in the tree data array should be moved.\u003cbr\u003eWhen the `sort` property is `true`, it will be `undefined`.                                                                                                      |\n| options.relativeIndex    | `number` \\| `undefined`             | When the `sort` property is `false`, it indicates the relative index of the drop destination with respect to the parent node.\u003cbr\u003eWhen the `sort` property is `true`, it will be `undefined`.                                                                                                     |\n| options.monitor          | `object`                            | Provides various methods for accessing react-dnd's internal state, e.g. for accessing drag sources from outside DndProvider.\u003cbr\u003eSee this [definition](https://github.com/react-dnd/react-dnd/blob/f835e26d81094b4aebc9d5b5f7b172beaeddf4b0/packages/dnd-core/src/interfaces.ts#L26) for details. |\n\n### canDrop callback\n\nBy default, it allows dropping to any droppable node (or root node) except its own descendants.\nThis callback can override the default rules.\n\nIf it returns nothing or returns `undefined`, the default rules will be applied. If it returns a boolean value, it will override the default rules and the droppable property of each node will no longer be referenced.\n\nIf it returns false and the user drops the dragged node, no action will be taken and the onDrop callback will not be fired.\n\nThis callback takes the same parameters as the [onDrop callback](#onDrop-callback), but the first parameter specifies the current tree.\n\n```jsx\nconst canDrop = (\n  currentTree,\n  { dragSourceId, dropTargetId, dragSource, dropTarget }\n) =\u003e {\n  return true;\n\n  // or\n\n  return false;\n\n  // or\n\n  return;\n\n  // or\n\n  return undefined;\n};\n\nreturn \u003cTree {...props} tree={treeData} canDrop={canDrop} /\u003e;\n```\n\nNOTE:  \nWhen overriding the default rules by returning true or false, be careful of inconsistencies in the tree structure.  \nFor example, if you allow dropping from a parent node to a child node as shown in the figure below, inconsistency will occur and the tree will collapse.\n\n![malformed tree](https://user-images.githubusercontent.com/3772820/114326837-9d717400-9b71-11eb-91cf-c762c4ab7461.gif)\n\n### Manual sort with placeholder\n\nBy default, nodes are automatically sorted and cannot be sorted manually, but by combining some APIs, you can sort them manually and display placeholders as follows.\n\n![placeholder_sample](https://user-images.githubusercontent.com/3772820/129397312-9501e164-d413-4a06-b023-1713d206004e.gif)\n\nThe following is an example (excerpt) of the implementation of manual sort of nodes and placeholder display.\n\n```jsx\nimport { CustomPlaceholder } from \"./CustomPlaceholder\";\nimport styles from \"./App.module.css\";\n\nfunction App() {\n  const [treeData, setTreeData] = useState(SampleData);\n  const handleDrop = (newTree) =\u003e setTreeData(newTree);\n\n  return (\n    \u003cTree\n      {...props}\n      tree={treData}\n      onDrop={handleDrop}\n      classes={{\n        placeholder: styles.placeholder,\n      }}\n      sort={false}\n      insertDroppableFirst={false}\n      canDrop={(tree, { dragSource, dropTargetId }) =\u003e {\n        if (dragSource?.parent === dropTargetId) {\n          return true;\n        }\n      }}\n      dropTargetOffset={5}\n      placeholderRender={(node, { depth }) =\u003e (\n        \u003cCustomPlaceholder node={node} depth={depth} /\u003e\n      )}\n    /\u003e;\n  );\n}\n```\n\n### External drag source\n\nTo drop elements outside the tree into the tree, `extraAcceptTypes` must be set.\n\nIf the external drag source is under a `DndProvider`, set the `type` and `item` using [useDrag](https://react-dnd.github.io/react-dnd/docs/api/use-drag) in react-dnd for that element. add the external drag source `type` to `extraAcceptTypes` so it can be dropped in the tree.\n\nIf the external drag source is an element or file external to `DndProvider`, adding the `type` defined in react-dnd-html5-backend to `extraAcceptTypes` will allow dropping into the tree.\n\nIn this case, the `onDrop` callback will access the dropped element via `options.monitor` and add the new node to the data array of tree, as in the following example.\n\n```jsx\nimport { NativeTypes } from \"react-dnd-html5-backend\";\n\nfunction App() {\n  const [treeData, setTreeData] = useState(SampleData);\n  const [lastId, setLastId] = useState(100);\n\n  const handleDrop = (tree, options) =\u003e {\n    const { dropTargetId, monitor } = options;\n    const itemType = monitor.getItemType();\n\n    if (itemType === NativeTypes.FILE) {\n      const files = monitor.getItem().files;\n      const nodes = files.map((file, index) =\u003e ({\n        id: lastId + index,\n        parent: dropTargetId,\n        text: file.name,\n      }));\n\n      const mergedTree = [...tree, ...nodes];\n      setTree(mergedTree);\n      setLastId(lastId + files.length);\n    } else {\n      setTree(tree);\n    }\n  };\n\n  return (\n    \u003cTree\n      {...someProps}\n      tree={treeData}\n      extraAcceptTypes={[NativeTypes.FILE]}\n\n      {/*\n        extraAcceptTypes={[NativeTypes.URL]}\n        extraAcceptTypes={[NativeTypes.TEXT]}\n        extraAcceptTypes={[NativeTypes.HTML]}\n      */}\n\n      onDrop={handleDrop}\n    /\u003e;\n  );\n}\n```\n\n### Component styling\n\nYou are free to define the styling of individual nodes in the tree in your Render props, but the rest of the tree can be styled by specifying the CSS class name for the `classes` property.\n\n```jsx\n\u003cTree\n  {...props}\n  classes={{\n    root: \"my-root-classname\",\n    dragOver: \"my-dragover-classname\",\n    // listItem: \"my-listitem-classname\",\n    // You can use callback function for listItem class name.\n    listItem: (node, options) =\u003e {\n      return options.depth === 0\n        ? \"my-listitem-root-classname\"\n        : \"my-listitem-classname\";\n    },\n  }}\n/\u003e\n```\n\nYou can use the following keys for the objects you pass to the `classes` property. Neither key is required.\n\n| Name           | type                   | Description                                                                                                                                                               |\n| -------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| root           | `string`               | CSS class name to give to the top-level container element (by default, `ul` tag) that wraps all nodes.                                                                    |\n| container      | `string`               | CSS class name to give to the element wrapping the list of nodes of the same hierarchy (by default, `ul` tag).                                                            |\n| listItem       | `string` \\| `function` | CSS class name to give to the element that wraps each node item (by default, `li` tag).\u003cbr\u003eIt is also possible to dynamically create class names using callback function. |\n| dropTarget     | `string`               | CSS class name to give to the area that can be dropped during a node dragging operation.                                                                                  |\n| draggingSource | `string`               | CSS class name to give to the node during the dragging operation.                                                                                                         |\n| placeholder    | `string`               | CSS class name to give to the element wrapping the placeholder (by default, `li` tag).                                                                                    |\n\n### Usage to open / close methods\n\nThe open/close status of a node is managed within the Tree component, but the methods for opening and closing nodes are public, so they can be controlled from outside the Tree component.\n\n```jsx\nconst ref = useRef(null);\n\nconst handleOpenAll = () =\u003e ref.current.openAll();\nconst handleCloseAll = () =\u003e ref.current.closeAll();\n\n// open /close method can be passed a node ID or an array of node IDs\nconst handleOpen = (nodeId) =\u003e ref.current.open(nodeId);\nconst handleClose = (nodeId) =\u003e ref.current.close(nodeId);\n\n\u003cTree\n  ref={ref}\n  {...props}\n\u003e\n\n\u003cbutton onClick={handleOpenAll}\u003eOpen All Folders\u003c/button\u003e\n\u003cbutton onClick={handleCloseAll}\u003eClose All Folders\u003c/button\u003e\n\u003cbutton onClick={handleOpen}\u003eOpen specific folder(s)\u003c/button\u003e\n\u003cbutton onClick={handleClose}\u003eClose specific folder(s)\u003c/button\u003e\n\n```\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminop1205%2Freact-dnd-treeview","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fminop1205%2Freact-dnd-treeview","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminop1205%2Freact-dnd-treeview/lists"}