New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

co-tree

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

co-tree

co-tree React component

latest
npmnpm
Version
0.2.73
Version published
Maintainers
1
Created
Source

co-tree

Tree ui component for react

特性

  • 支持所有流行的浏览器,包括IE9及以上版本
  • 用于多层次结构列表展示
  • 具有展开收起选择等交互功能

使用场景

任何可以利用树形结构来展现事物层级关系的场景

Example

http://localhost:3333/

Usage

npm install co-tree

Draggable Demo

Based on the toolkit nwb

You can based on some toolkit or framework, whatever create-react-app etc...

npm install nwb -g;
nwb new react-component test;
cd test;
npm install co-tree
import React from 'react';
import Tree from 'co-tree';

//Some very simple styles, just embed the js code
const STYLE = `
.draggable-demo {
	width: 20%;
	margin-left: 30px;
}
.wrapper {
	background-color: #f5f7f9;
}
.node-motion {
	transition: all .3s;
	overflow-y: hidden;
}
`;

//Basic animation setting.
const motion = {
  motionName: "node-motion",
  motionAppear: false,
  onAppearStart: () => ({ height: 0 }),
  onAppearActive: node => ({ height: node.scrollHeight }),
  onLeaveStart: node => ({ height: node.offsetHeight }),
  onLeaveActive: () => ({ height: 0 })
};

//Generate Data Function
const gData = (x = 3, y = 2, z = 1, data = []) => {
  //x: 每一级下的节点总数。y: 每一级节点里有y个节点、存在子节点
  //y: 树的level层级(0代表一级)
  const loop = (_level, _prevKey, _tns) => {
    const preKey = _prevKey || '0';
    const tns = _tns || data;
    
    const children = [];
    for(let i = 0; i < x; i++){
      const key = `${preKey}-${i}`;
      tns.push({title: `${key}`, key: `${key}-key`});
      if(i < y){
        children.push(key);
      }
    }
    if(_level < 0){
      return tns;
    }
    const __level = _level - 1;
    children.forEach((key, index) => {
      tns[index].children = [];
      return loop(__level, key, tns[index].children);
    });
    return null;
  };
  loop(z);
  return data;
};

//By the way, we can also just simply hard code data like the //following way in the component
//const gData = [
//	{ title: '0-0', key: '0-0' },
//	{ title: '0-1', key: '0-1' },
//	{ title: '0-2', key: '0-2', children: [{ title: '0-2-0', key: //	'0-2-0' }] },
//];

const DragTree = () => {
  const [_gData, setGData] = React.useState(gData);
  const [autoExpandParent, setAutoExpandParent] = React.useState(true);
  const [expandedKeys, setExpandedKeys] = React.useState([
    "0-0-key",
    "0-0-0-key",
    "0-0-0-0-key"
  ]);

  const onDragEnter = ({ expandedKeys }) => {
    setExpandedKeys(expandedKeys);
  };

  const onDrop = info => {
    const dropKey = info.node.props.eventKey;
    const dragKey = info.dragNode.props.eventKey;
    const dropPos = info.node.props.pos.split("-");

    const dropPosition =
      info.dropPosition - Number(dropPos[dropPos.length - 1]);

    //Traverse the whole tree node structure
    const loop = (data, key, callback) => {
      data.forEach((item, index, arr) => {
        if (item.key === key) {
          callback(item, index, arr);
          return;
        }
        if (item.children) {
          loop(item.children, key, callback);
        }
      });
    };

    //获取原始节点数据结构
    const data = [..._gData];
    //被拖拽的节点对象
    let dragObj;
    loop(data, dragKey, (item, index, arr) => {
      arr.splice(index, 1);
      dragObj = item;
    });

    if (!info.dropToGap) {
      // Drop on the content 释放在其他节点上
      loop(data, dropKey, item => {
        item.children = item.children || [];
        // where to insert 示例添加到尾部,可以是随意位置
        item.children.push(dragObj);
      });
    } else if (
      (info.node.props.children || []).length > 0 && // Has children
      info.node.props.expanded && // Is expanded
      dropPosition === 1 // On the bottom gap
    ) {
      loop(data, dropKey, item => {
        item.children = item.children || [];
        // where to insert 示例添加到尾部,可以是随意位置
        item.children.unshift(dragObj);
      });
    } else {
      // Drop on the gap 释放在节点间的gap上
      let ar;
      let i;
      loop(data, dropKey, (_item, index, arr) => {
        ar = arr;
        i = index;
      });
      if (dropPosition === -1) {
        ar.splice(i, 0, dragObj);
      } else {
        ar.splice(i + 1, 0, dragObj);
      }
    }
    setGData(data);
  };

  const onExpand = expandedKeys => {
    setExpandedKeys(expandedKeys);
    setAutoExpandParent(false);
  };

  return (
    <div className="draggable-demo">
      <style dangerouslySetInnerHTML={{ __html: STYLE }} />
      <h2>Draggable</h2>
      <p>drag a node into another node</p>
			<div className='wrapper'>
        <Tree
          expandedKeys={expandedKeys}
          onExpand={onExpand}
          autoExpandParent={autoExpandParent}
          draggable
          onDragEnter={onDragEnter}
          onDrop={onDrop}
          treeData={_gData}
          motion={motion}
        />
      </div>
    </div>
  );
};

export default DragTree;

效果图

image-20200316122231392

Draggable Demo使用的api解析

  • expandedKeys: 用于展开指定的树节点,决定树形结构数据最初呈现(展开/收起)的样子,也可以作为其他函数的参数,用来设定节点最初的展开状态。
  • onExpand: 将expandedKeys作为参数的函数,来决定哪些节点最初呈现展开状态,并且用于控制节点的开合状态。
  • autoExpandParent:是否自动展开父节点。配合前两个api一起使用,来决定ui呈现时,哪些父节点自动展开。
  • draggable:用于决定组件的节点是否能被拖拽。
  • onDragEnter:当被拖拽的节点进入另外的父节点时,该节点自动展开。
  • onDrop: 处理被拖拽节点释放位置的具体情况(放置于gap之间节点变换位置,放置于其他节点上,变成该节点的子节点等)。
  • treeData:决定组件的数据结构,具体收到怎样的数据,最终节点便会有怎样的ui呈现。
  • motion:处理运用于组件的简单动画设置。

组件其他部分常用api解析

  • disabled: 禁用某节点,主要用于禁止节点的拖拽、选中等功能,并不影响父节点的展开/收起以及图标的更换。
  • icon:用于自定义图标,可直接用在数据中,在json数据中添加icon的选项信息,也可以设置更换图标的函数,配合switcherIcon一起使用。
  • multiple:通过点击可以选中多个节点(配合selectable一起使用)。
  • selectable:是否可以选中节点,默认值为true。
  • title:用于设置节点标题信息的API,可直接放置于json信息中,也可具体设置。
  • showIcon: 是否显示节点图标,默认值为true,我们也可以将其手动设置成false;

API

Tree Props

参数描述类型默认值
autoExpandParent是否自动展开父节点boolfalse
className根 dom 节点的附加 css 类string‘’
defaultExpandedKey默认展开指定的树节点string[][]
defaultExpandAll默认展开所有树节点boolfalse
defaultExpandParent默认展开父节点booltrue
defaultSelectedKeys默认选中的树节点string[][]
disabled将树禁用boolfalse
draggable设置节点可拖拽(IE > 8 & Safari > 5.1)boolfalse
expandedKeys(受控)展开指定的树节点string[]-
filterTreeNode按需筛选树节点(高亮), 返回truefunction (node)-
icon自定义图标。可接受组件, props为当前节点propselement/Function(props)-
loadedKeys(受控)已加载的节点,需要配合loadData使用string[]-
loadData异步加载数据,返回一个promisefunction(node)-
multiple支持点选多个节点(节点本身)boolfalse
prefixCls类名前缀string'co-tree'
selectable是否可选中booltrue
selectedKeys(受控)设置选中的树节点(若设置了defaultSelectedKeys便不会生效)string[][]
showIcon是否显示图标booltrue
showLine是否显示连接线boolfalse
treeDatatreeNodes 数据,如果设置则不需要手动构造 TreeNode 节点(key 在整个树范围内唯一)array<{key, title,children,[disabled,selectable]}>-
onExpand展开/收起节点时触发function(expandedKeys, {expanded: bool, node, nativeEvent})-
onDragEnddragEnd 触发时调用function({event, node})-
onDragEnterdragEnter触发时调用function({event, node, expandedKeys})-
onDragLeavedragLeave触发时调用function({event, node})-
onDragStartdragStart触发时调用function({event, node})-
onDropdrop触发时调用function({event, node, dragNode, dragNodesKeys})-
onLoad节点加载完毕时触发, 如果设置了loadedKeys, 便必需设置onLoad来避免无限循环function(loadedKeys, {event, node})-
onMouseEnter当光标进入树节点时响应function({event, node})-
onMouseLeave当光标离开树节点时响应function({event, node})-
onRightClick响应右键点击显示自定义的内容菜单function({event, node})-
onSelect点击树节点时触发function(selectedKeys, e: {selected: bool, selectedNodes, node, event, nativeEvent})-
switcherIcon切换具体图标ReactNode / (props: TreeNodeAttribute) => ReactNode-

TreeNode Props

note: 如果你有很多个树节点,若有超过一千个节点,

建议将父节点设置成默认收起,这样整体树结构展示便会非常有效迅速,

因为藏起来的子节点是不会插入dom中的

属性描述类型默认值
className树节点的附加类string''
style为树节点设置样式object-
disabled禁止响应boolfalse
title标题string/element/((data:DataNode) => React.ReactNode)'---'
key被树的 (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys 属性所用。注意:整个树范围内的所有节点的 key 值不能重复!stringtreeNode's position
isLeaf设置为叶子节点boolfalse
icon自定义图标。可接收组件,props 为当前节点 propselement/Function(props)-
switcherIcon切换具体的图标ReactNode /(props: TreeNodeAttribute) => ReactNode-

Development

npm install
npm start

License

co-tree is released under the MIT license

Keywords

react-component

FAQs

Package last updated on 25 Mar 2020

Did you know?

Socket

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