{"_id":"@aqaurius1910/react-folder-tree","name":"@aqaurius1910/react-folder-tree","dist-tags":{"latest":"5.0.3"},"versions":{"5.0.3":{"name":"@aqaurius1910/react-folder-tree","version":"5.0.3","description":"customizable react folder tree library","main":"dist/react-folder-tree.bundle.js","typings":"index.d.ts","author":{"name":"Shunji Zhan","email":"shunhahaha@live.com"},"keywords":["react","npm","reactjs","npm-package","folder","recursion","npm-module","folders","tree-structure","treeview","folder-picker","folder-viewer","recursion-problem","folder-structure","folder-tooling","folder-tree","recursion-tree","recursion-tree-visualiser","recursion-tree-visualizer","recursions"],"homepage":"https://shunjizhan.github.io/react-folder-tree-demos/","repository":{"type":"git","url":"https://github.com/shunjizhan/react-folder-tree.git"},"bugs":{"url":"https://github.com/shunjizhan/react-folder-tree/issues"},"license":"MIT","private":false,"scripts":{"prebuild":"rm -rf dist/","build":"webpack --config config/webpack.prod.config.js","start":"NODE_ENV=development node scripts/dev-server.js","lint":"eslint src/ --ext .js,.jsx","test":"jest --collect-coverage","prepublish":"yarn build"},"husky":{"hooks":{"pre-commit":"lint-staged","pre-push":"yarn test"}},"lint-staged":{"*.[tj]s?(x)":["eslint"]},"devDependencies":{"@babel/core":"^7.11.6","@babel/plugin-proposal-optional-chaining":"^7.12.7","@babel/preset-env":"^7.11.5","@babel/preset-react":"^7.10.4","@wojtekmaj/enzyme-adapter-react-17":"^0.6.1","babel-eslint":"^10.1.0","babel-loader":"^8.1.0","clean-terminal-webpack-plugin":"^3.0.0","css-loader":"^5.0.1","enzyme":"^3.11.0","enzyme-adapter-react-16":"^1.15.5","eslint":"7.2.0","eslint-config-airbnb":"18.2.1","eslint-plugin-import":"^2.22.1","eslint-plugin-jsx-a11y":"^6.4.1","eslint-plugin-react":"^7.21.5","eslint-plugin-react-hooks":"^4.2.0","html-loader":"^1.3.2","html-webpack-plugin":"^4.5.0","husky":"^4.3.0","identity-obj-proxy":"^3.0.0","jest":"^26.6.3","lint-staged":"^10.5.1","mini-css-extract-plugin":"^1.6.0","node-sass":"^6.0.0","react":"^16.8.0 || ^17","react-dom":"^16.8.0 || ^17","sass-loader":"^10.1.0","style-loader":"^2.0.0","webpack":"^5.1.0","webpack-bundle-analyzer":"^4.4.0","webpack-cli":"^4.0.0","webpack-dev-server":"^3.11.0"},"peerDependencies":{"react":"^16.8.0 || ^17","react-dom":"^16.8.0 || ^17"},"dependencies":{"prop-types":"^15.7.2","react-icons":"^4.1.0","use-tree-state":"1.0.0"},"_id":"@aqaurius1910/react-folder-tree@5.0.3","dist":{"shasum":"f508dc04000d489a390d85a02d8a2c3f1106da3e","integrity":"sha512-IaRRSZufpp2ETXrKgW8KrozekbaHVmekrfAEulEScA4o6kwtFE29Qv39MZpsuGo1e9sfaLdXDLbj3Rn/G+YOow==","tarball":"https://registry.npmjs.org/@aqaurius1910/react-folder-tree/-/react-folder-tree-5.0.3.tgz","fileCount":8,"unpackedSize":40130,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD7kqm1Dg1nLxP/CyJmqfVfTLhH+CNuBFEt7NXAz3gfOgIhAO0qjGo3zXclifSoN4z7Wzekq3F0TbkXx6iTTRmAeGdx"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkBAJ9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrghA/9E3yL7VCDOZ7fn08DUJiW6iqNlcH0gwmCGVrr/Mpib8Z45GE9\r\nZE9sh5ltXsjVifE2GVjx1fOfTlK6KbjJ9zYA/n+qUAtgUVh5xyhmRLjG02L2\r\nyqvu3NicXFyNpR5DO6sCZUcLBsJ/bzgAP2CI1uQFalkTl8E4gdSeZSP4zlI8\r\nayPXv7EPQ+/jBvLVm6wTdYiK8lZCKn4hM41OoltdDn0IeCkvOweaiOvVg726\r\nkWmdbHC9eTAeCB/KBZiH5G26lzNhy1IET7agza0mhnG/1wBFfxWmFUgrnRdB\r\n7aKs98Am/r2eBqQFLnYaM7c8vBuaV18y7aGMwYEvOqhOcmY7gErqmcy2NfPV\r\n7brY7uTLcxqpgnSifea11mvW6y7InHS2b+a9epdmistc1MAJ0q2lHPVVZSVr\r\nqhUN5TFZAOtN52iDpT/r6fGv9JVzdz4FALxI2bXISW6uRy9NxXxEMUsU+EDH\r\ncqQhevh9RY9hpOAIHq8rYytZwbXhbibNjWY6JbbppPyRnnEJtf8TJVFsllxB\r\nTPtucydCXi52FGO8vQak9kpvVpimT2tyDKITI/Wf03rdQp2x/D0nq9ZPrRGh\r\nbCaACB/10RZjmY/f7OL2mbnYKRN95lgarzHDkx91cGu96hTztba9VWsz36sZ\r\nlEz/Nx3/Y8Yakq1O99MfZCGD2V5V+Oeh4sE=\r\n=46pk\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"aqaurius1910","email":"aqaurius1910@gmail.com"},"directories":{},"maintainers":[{"name":"aqaurius1910","email":"aqaurius1910@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/react-folder-tree_5.0.3_1677984381284_0.6094492931690252"},"_hasShrinkwrap":false}},"time":{"created":"2023-03-05T02:46:21.211Z","5.0.3":"2023-03-05T02:46:21.518Z","modified":"2023-03-05T02:46:21.667Z"},"maintainers":[{"name":"aqaurius1910","email":"aqaurius1910@gmail.com"}],"description":"customizable react folder tree library","homepage":"https://shunjizhan.github.io/react-folder-tree-demos/","keywords":["react","npm","reactjs","npm-package","folder","recursion","npm-module","folders","tree-structure","treeview","folder-picker","folder-viewer","recursion-problem","folder-structure","folder-tooling","folder-tree","recursion-tree","recursion-tree-visualiser","recursion-tree-visualizer","recursions"],"repository":{"type":"git","url":"https://github.com/shunjizhan/react-folder-tree.git"},"author":{"name":"Shunji Zhan","email":"shunhahaha@live.com"},"bugs":{"url":"https://github.com/shunjizhan/react-folder-tree/issues"},"license":"MIT","readme":"# React Folder Tree\n[![travis build](https://img.shields.io/travis/com/shunjizhan/react-folder-tree?logo=travis)](https://travis-ci.com/shunjizhan/react-folder-tree) [![codecov](https://codecov.io/gh/shunjizhan/react-folder-tree/branch/master/graph/badge.svg?token=26EEM3JIUY)](https://codecov.io/gh/shunjizhan/react-folder-tree) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/react-folder-tree?color=light%20green&label=zipped%20only&logo=webpack)  \n[![npm](https://img.shields.io/npm/v/react-folder-tree?logo=npm)](https://www.npmjs.com/package/react-folder-tree) [![npm](https://img.shields.io/npm/dm/react-folder-tree?logo=DocuSign&color=blue)](https://www.npmjs.com/package/react-folder-tree) ![GitHub top language](https://img.shields.io/github/languages/top/shunjizhan/react-folder-tree?logo=react)\n\nA versatile and customizable react treeview library. Features:  \n✅ custom icons  \n✅ custom event handlers  \n✅ inline add, modify, and delete tree nodes  \n✅ checkbox with half check (indeterminate check)  \n✅ read-only mode\n\nIt uses [use-tree-state](https://www.npmjs.com/package/use-tree-state) hook internally for convenient state management.\n### Quick Preview\n![folder-tree-demo](/assets/folder-tree-demo.gif)\n\n### Live Demos\nlive demos and code examples can be found [here](https://shunjizhan.github.io/react-folder-tree-demos/)\n\n---\n## Basic Usage\n### 🌀 install\n```bash\n$ yarn add react-folder-tree\n$ npm install react-folder-tree --save\n```\n### 🌀 basic tree\n```tsx\nimport FolderTree, { testData } from 'react-folder-tree';\nimport 'react-folder-tree/dist/style.css';\n\nconst BasicTree = () => {\n  const onTreeStateChange = (state, event) => console.log(state, event);\n\n  return (\n    <FolderTree\n      data={ testData }\n      onChange={ onTreeStateChange }\n    />\n  );\n};\n```\n\n### 🌀 custom initial state\nInitial tree state is an object that describes a nested tree node structure, which looks like:\n```jsx\n{\n  // reserved keys, can customize initial value\n  name: 'root node',  \n  checked (optional): 0 (unchecked, default) | 0.5 (half checked) | 1(checked),\n  isOpen (optional): true (default) | false,\n  children (optional): [array of treenode],\n\n  // internal keys (auto generated), plz don't include them in the initial data\n  path: [],    // path is an array of indexes to this node from root node\n  _id: 0,\n\n  // not reserved, can carry any extra info about this node\n  nickname (optional): 'pikachu',\n  url (optional): 'url of this node',\n}\n```\n`checked` and `isOpen` status could be auto initialized by props `initCheckedStatus` and `initOpenStatus`. We can also provide data with custom `checked` and `isOpen` status, and set `initCheckedStatus` and `initOpenStatus` to `'custom'`.\n\nThis example shows how to render a tree with custom initial state\n```tsx\nconst treeState = {\n  name: 'root [half checked and opened]',\n  checked: 0.5,   // half check: some children are checked\n  isOpen: true,   // this folder is opened, we can see it's children\n  children: [\n    { name: 'children 1 [not checked]', checked: 0 },\n    {\n      name: 'children 2 [half checked and not opened]',\n      checked: 0.5,\n      isOpen: false,\n      children: [\n        { name: 'children 2-1 [not checked]', checked: 0 },\n        { name: 'children 2-2 [checked]', checked: 1 },\n      ],\n    },\n  ],\n};\n\nconst CustomInitState = () => (\n  <FolderTree\n    data={ treeState }\n    initCheckedStatus='custom'  // default: 0 [unchecked]\n    initOpenStatus='custom'     // default: 'open'\n  />\n);\n```\n\n### 🌀 hate checkbox?\n```jsx\n<FolderTree\n  data={ treeState }\n  showCheckbox={ false }    // default: true\n/>\n```\n\n### 🌀 love indentation?\n```jsx\n<FolderTree\n  data={ treeState }\n  indentPixels={ 99999 }    // default: 30\n/>\n```\n\n### 🌀 read only?\nwe can use it as a classical view-only tree\n```jsx\n<FolderTree\n  data={ treeState }\n  showCheckbox={ false }    // hiding checkbox is not required but recommended for better UX\n  readOnly                  // <== here!!\n/>\n```\n---\n## Advanced Usage\n### 🔥 sync tree state\nIn order to perform more complex operations, we can sync and keep track of the current tree state outside.\n\nThis example shows how to download all selected files.\n```jsx\nconst SuperApp = () => {\n  const [treeState, setTreeState] = useState(initState);\n  const onTreeStateChange = (state, event) => setTreeState(state);\n\n  const onDownload = () => downloadAllSelected(treeState);\n\n  return (\n    <>\n      <FolderTree\n        data={ initState }\n        onChange={ onTreeStateChange }\n      />\n      <DownloadButton onClick={ onDownload } />\n    </>\n  );\n};\n```\n\n### 🔥 custom icons \nThere are 9 icons and all of them are customizable.\n- FileIcon\n- FolderIcon\n- FolderOpenIcon\n- EditIcon\n- DeleteIcon\n- CancelIcon\n- CaretRightIcon\n- CaretDownIcon\n- OKIcon\n\nThis example shows how to customize the FileIcon (same interface for all other icons).\n```jsx\nimport { FaBitcoin } from 'react-icons/fa';\n\nconst BitcoinApp = () => {\n  const FileIcon = ({ onClick: defaultOnClick, nodeData }) => {\n    const {\n      path,\n      name,\n      checked,\n      isOpen,\n      ...restData\n    } = nodeData;\n\n    // custom event handler\n    const handleClick = () => {   \n      doSthBad({ path, name, checked, isOpen, ...restData });\n\n      defaultOnClick();\n    };\n\n    // custom Style\n    return <FaBitcoin onClick={ handleClick } />;\n  };\n\n  return (\n    <FolderTree\n      data={ initState }\n      iconComponents={{\n        FileIcon,\n        /* other custom icons ... */\n      }}\n    />\n  );\n};\n```\n\n### 🔥 hide icons / disable interaction\nThis usage is a subset of custom icons.\n\nFor example, if we want to disable editing, we can hide `EditIcon` by passing in a dummy custom icon, so nothing will be rendered.\n```tsx\nconst EditIcon = (...args) => null;\n```\n\nA little more complex but more flexible way is to have extra node data, say `editable`, then build a custom icon that utilize this data\n```ts\nconst EditIcon = ({ onClick: defaultOnClick, nodeData }) => {\n  const { editable } = nodeData;\n\n  // if this node is editable, render an EditIcon, otherwise render air\n  return editable ? (<FaEdit onClick={ defaultOnClick } />) : null;\n\n  // or render a 'not editable' icon\n  return editable ? (<FaEdit onClick={ defaultOnClick } />) : (<DontEdit />));\n};\n```\n\n### 🔥 custom `onClick` for node names\nThis example shows how to download the file when click on the node name.\n```tsx\nconst dataWithUrl = {\n  name: 'secret crypto file',\n  url: 'polkadot.network',      // wew can provide any custom data to the FolderTree!\n  // ...\n};\n\nconst onNameClick = ({ defaultOnClick, nodeData }) => {\n  defaultOnClick();\n\n  const {\n    // internal data\n    path, name, checked, isOpen, \n    // custom data\n    url, ...whateverRest\n  } = nodeData;\n\n  download(url);\n};\n\nconst Downloader = () => (\n  <FolderTree\n    data={ dataWithUrl }\n    onNameClick={ onNameClick }\n  />\n);\n```\n\n---\n## APIs Summary\n\n| prop              | description                             | type     | options                                        |\n|-------------------|-----------------------------------------|----------|------------------------------------------------|\n| data              | initial tree state data (required)      | object   | N/A                                            |\n| initCheckedStatus | initial check status of all nodes       | string   | 'unchecked' (default) \\| 'checked' \\| 'custom' |\n| initOpenStatus    | initial open status of all treenodes    | string   | 'open' (default) \\| 'closed' \\| 'custom'        |\n| iconComponents    | custom icon components                  | object   | ant design icons (default)                     |\n| onChange          | callback when tree state changes        | function | console.log (default)                          |\n| onNameClick       | callback when click treenode name       | function | open treenode inline toolbox (default)         |\n| indentPixels      | ident pixels of 1x level treenode       | number   | 30 (default)                                   |\n| showCheckbox      | show check box?                         | bool     | true (default) | false                         |\n| readOnly          | readOnly mode? can't click/check node   | bool     | false (default) | true                       |\n\n---\n## Bugs? Questions? Contributions?\nFeel free to [open an issue](https://github.com/shunjizhan/react-folder-tree/issues), or create a pull request!\n","readmeFilename":"README.md"}