Socket
Socket
Sign inDemoInstall

react-hyper-tree

Package Overview
Dependencies
6
Maintainers
1
Versions
35
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    react-hyper-tree

Fully customizable react tree component


Version published
Weekly downloads
976
decreased by-20%
Maintainers
1
Install size
144 kB
Created
Weekly downloads
 

Readme

Source

React hyper tree

Fully customizable tree view react component

Welcome to the react hyper tree component 😄 I want to introduce you to an awesome react component for displaying tree data structure

dependecies license min minzip

Features

  • render tree-like data structure
  • show/hide lines
  • fully custom component by providing render functions (node and drag zone) or custom class names
  • tree management by global utility (treeHandlers)
  • single/multiple node selection
  • async loading of children
  • drag and drop using 3 types of insertion (before, children, after)

Table of contents

  • Installation
  • Usage
  • Properties
  • API
  • Road map
  • Contributing
  • License

Live demo is available!

Check also react-hyper-modal library

Installation

You can use npm or yarn package managers
$ npm i --save react-hyper-tree

or

$ yarn add react-hyper-tree

Usage

Simple Usage

import React from 'react'
import Tree, { useTreeState } from 'react-hyper-tree'

const data = {
  id: 1,
  name: 'Parent 1',
  children: [
    {
      id: 2,
      name: 'Child 1',
      children: [
        {
          id: 5,
          name: 'Child 1__1',
        },
        {
          id: 6,
          name: 'Child 1__2',
        },
        {
          id: 7,
          name: 'Child 1__3',
        },
      ],
    },
  ],
}

...

const MyTreeComponent = () => {
  const { required, handlers } = useTreeState({
    data,
    id: 'your_tree_id',
  })

  return (
    <Tree
      {...required}
      {...handlers}
    />
  )
}

Properties

PropsDescription
classes?object with elements class names
datanodes data, provided by required prop
depthGap?children indentation related to parent
disableHorizontalLines?disable horizontal lines
disableLines?disable all lines
disableVerticalLines?disable vertical lines
disableTransitions?disable transitions (improves performance)
displayedName?format node content, if you use default node renderer
draggable?:enable draggable mode
gapMode?indentation mode
horizontalLineStyles?horizontal line styles, SVG properties
renderDragZone?function to render your custom drag zone
renderNode?function to render your custom node
setOpen?open node children, provided by handlers prop
setSelected?select node, provided by handlers prop
staticNodeHeight?set static height of node, otherwise dynamic height will be used
verticalLineOffset?vertical line offset related to parent
verticalLineStyles?vertical line styles, SVG properties
verticalLineTopOffset?vertical line top offset

useTreeState API

useTreeState React hook includes the state management functionality. It prepares and transforms the data to use all functionality of the Node API.

useTreeState input

PropertyDescription
childrenKey?set the children key, e.g. 'children'
datatree-like data
defaultOpened?if true, all parent will be opened
filter?function to filter tree nodes
idtree id, required
idKey?set the data id key, e.g. 'id'
multipleSelect?if true, a several nodes can be selected
sort?function to sort tree nodes
refreshAsyncNodes?load async children every time when open node

useTreeState output

PropertyDescription
handlershandlers to manipulate node state. setOpen, setLoading, setSelected, setChildren, setRawChildren
instancetree view instance including all tree methods
requiredincludes enhanced tree structure

Actually TreeView component is a renderer. It hasn't any functionality to manipulate of tree state.

Node API

MethodDescriptionTypings
getChildrenreturns node children or empty array() => TreeNode[]
getDatareturns raw node data() => any
getFirstChildreturns the first child() => TreeNode `
getLastChildreturns the last child() => TreeNode `
getPathget node path(array?: boolean) => string
hasChildrenreturns true if node has atleast one child() => boolean
isLoadingreturns true if node is loading() => boolean
isOpenedreturns true if node is opened() => boolean
isSelectedreturns true if node is selected() => boolean
setChildrena simple equivalent of setNodeChildren(children: TreeNode[]) => void
setDatasets node data(data?: any) => void
setLoadingset node loading(loading?: boolean) => void
setNodeChildreninsert node children(children: TreeNode[], type?: InsertChildType, reset?: boolean) => TreeNode[]
setOpenedset node opened(opened?: boolean) => void
setParentset node parent(parent?: TreeNode) => void
setSelectedset node selected(selected?: boolean) => void
getPathget node path(array?: boolean) => string | string[]
getReactKeyreturns calculated property for react key() => string

Global state manager

The main goal to implement the tree view library was a simple usage and global tree manager.

Actually, global state manager (GSM) is represented as treeHandlers object. It has all instances of trees in the project.

Every time you use useTreeState hook. It will create a new TreeView instance and add the instance to treeHandlers object.

The GSM structure

The GSM object has the one property trees.

type Handler = (...args: any[]) => any

interface IHandlers {
    [key: string]: Handler
}

interface ITreeItem {
    instance: TreeView
    handlers: IHandlers
}

interface ITrees {
    [key: string]: ITreeItem
}

trees: ITrees

When you use useTreeState with the tree id, it will add tree instance to GSM. To access to tree instance you should do the next:

import { treeHandlers } from 'react-hyper-tree'

treeHandlers.trees[your - tree - id].instance

You can use the full tree instance functionality from the GSM. Also the GSM has the handlers property for every tree instance.

Every tree has a default set of methods to manipulate the data

MethodDescriptipnTypings
rerenderrerender the tree component(callback? () => void) => void
setLoadingset loading property(node: TreeNode | string | number, loading?: boolean) => void
setOpenset opened property(node: TreeNode | string | number, toggle?: boolean) => void
setOpenByPathset opened by path(path: string) => void
setRawChildrenset node children, use it if you have a raw children data(parent: TreeNode | string | number, children: IData[], type?: InsertChildType, reset?: boolean) => void
setChildrenset node children, use it if you have an enhanced children data(parent: TreeNode | string | number, children: TreeNode[], type?: InsertChildType, reset?: boolean) => void
setSelectedset selected property(node: TreeNode | string | number, selected?: boolean) => void
setSelectedByPathset selected by path(path: string, all?: boolean, toggle?: boolean) => void
setSiblingsset node siblings(node: TreeNode | string | number, siblings: TreeNode[], type: InsertSiblingType) => void
getNodeDatareturns node data(node: TreeNode | string | number, siblings: TreeNode[]) => void
getNodereturns node(node: TreeNode | string | number, siblings: TreeNode[]) => void
selectAllselect all nodes (if multipleSelect is true)() => void
unselectAllunselect all nodes() => void

To call any method you should do the next:

import { treeHandlers } from 'react-hyper-tree'

treeHandlers.trees[your-tree-id].handlers.setOpen(...)

treeHandlers API

MethodDescriptionTypings
getIdsget trees ids() => string[]
removeremove tree from the GSM(id: string): TreeHandlers
removeHandlerremove handler from the treeremoveHandler(treeId: string, handlerName: string): TreeHandlers
safeUpdateadd or update tree in the GSMsafeUpdate(id: string, tree: TreeView) => TreeHandlers
safeUpdateHandleradd or update tree handlersafeUpdateHandler(treeId: string, handlerName: string, handler: Handler): TreeHandlers

You can also use treeHandlers like call chain

treeHandlers
    .safeUpdateHandler(id, 'setLoading', setLoading)
    .safeUpdateHandler(id, 'setSelected', setSelected)
    .safeUpdateHandler(id, 'setRawChildren', setRawChildren)
    .safeUpdateHandler(id, 'setChildren', setChildren)

Async children

You also can use loadable children. To enable the feature you should provide getChildren function to node data

const getChildren = ({ node }) => {
    return getChildrenByParentId(node.id)
}

const data = {
    id: 1,
    name: 'Parent 1',
    getChildren
}

getChildren function can return Promise and resolve the children data in format like this:

const getChildren = () =>
    new Promise(resolve =>
        setTimeout(
            () =>
                resolve([
                    {
                        id: 2,
                        name: 'Child'
                    }
                ]),
            1000
        )
    )

You can also fire any events like redux-actions in the getChildren function. In this case you can set the children by the GSM

Default properties

export const defaultProps = {
    childrenKey: 'children',
    classes: {} as ClassesType,
    depthGap: 20,
    displayedName: (node: TreeNode) => node.data.name,
    filter: () => true,
    gapMode: 'margin' as const,
    horizontalLineStyles: { stroke: 'black', strokeWidth: 1, strokeDasharray: '1 1' },
    idKey: 'id',
    opened: [],
    verticalLineOffset: 5,
    verticalLineStyles: { stroke: 'black', strokeWidth: 1, strokeDasharray: '1 1' },
    verticalLineTopOffset: 0
}

Road map

  • Coverage by tests
  • Inner improvements and extending functionality
  • Documentation improvements

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

License

MIT

Keywords

FAQs

Last updated on 13 Apr 2022

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc