npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@khaitd0340/react-folder-tree

v5.3.0

Published

customizable react folder tree library

Downloads

31

Readme

React Folder Tree

travis build codecov npm bundle size
npm npm GitHub top language

A versatile and customizable react treeview library. Features:
✅ custom icons
✅ custom event handlers
✅ inline add, modify, and delete tree nodes
✅ checkbox with half check (indeterminate check)
✅ read-only mode

It uses use-tree-state hook internally for convenient state management.

Quick Preview

folder-tree-demo

Live Demos

live demos and code examples can be found here


Basic Usage

🌀 install

$ yarn add react-folder-tree
$ npm install react-folder-tree --save

🌀 basic tree

import FolderTree, { testData } from 'react-folder-tree';
import 'react-folder-tree/dist/style.css';

const BasicTree = () => {
  const onTreeStateChange = (state, event) => console.log(state, event);

  return (
    <FolderTree
      data={ testData }
      onChange={ onTreeStateChange }
    />
  );
};

🌀 custom initial state

Initial tree state is an object that describes a nested tree node structure, which looks like:

{
  // reserved keys, can customize initial value
  name: 'root node',  
  checked (optional): 0 (unchecked, default) | 0.5 (half checked) | 1(checked),
  isOpen (optional): true (default) | false,
  children (optional): [array of treenode],

  // internal keys (auto generated), plz don't include them in the initial data
  path: [],    // path is an array of indexes to this node from root node
  _id: 0,

  // not reserved, can carry any extra info about this node
  nickname (optional): 'pikachu',
  url (optional): 'url of this node',
}

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'.

This example shows how to render a tree with custom initial state

const treeState = {
  name: 'root [half checked and opened]',
  checked: 0.5,   // half check: some children are checked
  isOpen: true,   // this folder is opened, we can see it's children
  children: [
    { name: 'children 1 [not checked]', checked: 0 },
    {
      name: 'children 2 [half checked and not opened]',
      checked: 0.5,
      isOpen: false,
      children: [
        { name: 'children 2-1 [not checked]', checked: 0 },
        { name: 'children 2-2 [checked]', checked: 1 },
      ],
    },
  ],
};

const CustomInitState = () => (
  <FolderTree
    data={ treeState }
    initCheckedStatus='custom'  // default: 0 [unchecked]
    initOpenStatus='custom'     // default: 'open'
  />
);

🌀 hate checkbox?

<FolderTree
  data={ treeState }
  showCheckbox={ false }    // default: true
/>

🌀 love indentation?

<FolderTree
  data={ treeState }
  indentPixels={ 99999 }    // default: 30
/>

🌀 read only?

we can use it as a classical view-only tree

<FolderTree
  data={ treeState }
  showCheckbox={ false }    // hiding checkbox is not required but recommended for better UX
  readOnly                  // <== here!!
/>

Advanced Usage

🔥 sync tree state

In order to perform more complex operations, we can sync and keep track of the current tree state outside.

This example shows how to download all selected files.

const SuperApp = () => {
  const [treeState, setTreeState] = useState(initState);
  const onTreeStateChange = (state, event) => setTreeState(state);

  const onDownload = () => downloadAllSelected(treeState);

  return (
    <>
      <FolderTree
        data={ initState }
        onChange={ onTreeStateChange }
      />
      <DownloadButton onClick={ onDownload } />
    </>
  );
};

🔥 custom icons

There are 9 icons and all of them are customizable.

  • FileIcon
  • FolderIcon
  • FolderOpenIcon
  • EditIcon
  • DeleteIcon
  • CancelIcon
  • CaretRightIcon
  • CaretDownIcon
  • OKIcon

This example shows how to customize the FileIcon (same interface for all other icons).

import { FaBitcoin } from 'react-icons/fa';

const BitcoinApp = () => {
  const FileIcon = ({ onClick: defaultOnClick, nodeData }) => {
    const {
      path,
      name,
      checked,
      isOpen,
      ...restData
    } = nodeData;

    // custom event handler
    const handleClick = () => {   
      doSthBad({ path, name, checked, isOpen, ...restData });

      defaultOnClick();
    };

    // custom Style
    return <FaBitcoin onClick={ handleClick } />;
  };

  return (
    <FolderTree
      data={ initState }
      iconComponents={{
        FileIcon,
        /* other custom icons ... */
      }}
    />
  );
};

🔥 hide icons / disable interaction

This usage is a subset of custom icons.

For example, if we want to disable editing, we can hide EditIcon by passing in a dummy custom icon, so nothing will be rendered.

const EditIcon = (...args) => null;

A little more complex but more flexible way is to have extra node data, say editable, then build a custom icon that utilize this data

const EditIcon = ({ onClick: defaultOnClick, nodeData }) => {
  const { editable } = nodeData;

  // if this node is editable, render an EditIcon, otherwise render air
  return editable ? (<FaEdit onClick={ defaultOnClick } />) : null;

  // or render a 'not editable' icon
  return editable ? (<FaEdit onClick={ defaultOnClick } />) : (<DontEdit />));
};

🔥 custom onClick for node names

This example shows how to download the file when click on the node name.

const dataWithUrl = {
  name: 'secret crypto file',
  url: 'polkadot.network',      // wew can provide any custom data to the FolderTree!
  // ...
};

const onNameClick = ({ defaultOnClick, nodeData }) => {
  defaultOnClick();

  const {
    // internal data
    path, name, checked, isOpen, 
    // custom data
    url, ...whateverRest
  } = nodeData;

  download(url);
};

const Downloader = () => (
  <FolderTree
    data={ dataWithUrl }
    onNameClick={ onNameClick }
  />
);

APIs Summary

| prop | description | type | options | |-------------------|-----------------------------------------|----------|------------------------------------------------| | data | initial tree state data (required) | object | N/A | | initCheckedStatus | initial check status of all nodes | string | 'unchecked' (default) | 'checked' | 'custom' | | initOpenStatus | initial open status of all treenodes | string | 'open' (default) | 'closed' | 'custom' | | iconComponents | custom icon components | object | ant design icons (default) | | onChange | callback when tree state changes | function | console.log (default) | | onNameClick | callback when click treenode name | function | open treenode inline toolbox (default) | | indentPixels | ident pixels of 1x level treenode | number | 30 (default) | | showCheckbox | show check box? | bool | true (default) | false | | readOnly | readOnly mode? can't click/check node | bool | false (default) | true |


Bugs? Questions? Contributions?

Feel free to open an issue, or create a pull request!