0.2.73 • Published 4 years ago

co-tree v0.2.73

Weekly downloads
-
License
MIT
Repository
-
Last release
4 years ago

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;

效果图

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

0.2.73

4 years ago

0.2.72

4 years ago

0.2.71

4 years ago

0.2.7

4 years ago

0.2.6-x

4 years ago

0.2.5-x

4 years ago

0.2.6

4 years ago

0.2.4-x

4 years ago

0.2.5

4 years ago

0.2.4

4 years ago

0.2.3

4 years ago

0.2.2

4 years ago

0.2.1-x

4 years ago

0.2.1

4 years ago

0.2.0-x

4 years ago

0.2.0

4 years ago

0.1.9-x

4 years ago

0.1.9-xx

4 years ago

0.1.9

4 years ago

0.1.8-x

4 years ago

0.1.8

4 years ago

0.1.7

4 years ago

0.1.6

4 years ago

0.1.5

4 years ago

0.1.4-x

4 years ago

0.1.4

4 years ago

0.1.3-x

4 years ago

0.1.2

4 years ago

0.1.1

4 years ago

0.1.0

4 years ago

0.0.8

4 years ago

0.0.7

4 years ago

0.0.6

4 years ago

0.0.5

4 years ago

0.0.4

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago