
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
Tree ui component for react
任何可以利用树形结构来展现事物层级关系的场景
npm install co-tree
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;
gap之间节点变换位置,放置于其他节点上,变成该节点的子节点等)。| 参数 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| autoExpandParent | 是否自动展开父节点 | bool | false |
| className | 根 dom 节点的附加 css 类 | string | ‘’ |
| defaultExpandedKey | 默认展开指定的树节点 | string[] | [] |
| defaultExpandAll | 默认展开所有树节点 | bool | false |
| defaultExpandParent | 默认展开父节点 | bool | true |
| defaultSelectedKeys | 默认选中的树节点 | string[] | [] |
| disabled | 将树禁用 | bool | false |
| draggable | 设置节点可拖拽(IE > 8 & Safari > 5.1) | bool | false |
| expandedKeys | (受控)展开指定的树节点 | string[] | - |
| filterTreeNode | 按需筛选树节点(高亮), 返回true | function (node) | - |
| icon | 自定义图标。可接受组件, props为当前节点props | element/Function(props) | - |
| loadedKeys | (受控)已加载的节点,需要配合loadData使用 | string[] | - |
| loadData | 异步加载数据,返回一个promise | function(node) | - |
| multiple | 支持点选多个节点(节点本身) | bool | false |
| prefixCls | 类名前缀 | string | 'co-tree' |
| selectable | 是否可选中 | bool | true |
| selectedKeys | (受控)设置选中的树节点(若设置了defaultSelectedKeys便不会生效) | string[] | [] |
| showIcon | 是否显示图标 | bool | true |
| showLine | 是否显示连接线 | bool | false |
| treeData | treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点(key 在整个树范围内唯一) | array<{key, title,children,[disabled,selectable]}> | - |
| onExpand | 展开/收起节点时触发 | function(expandedKeys, {expanded: bool, node, nativeEvent}) | - |
| onDragEnd | dragEnd 触发时调用 | function({event, node}) | - |
| onDragEnter | dragEnter触发时调用 | function({event, node, expandedKeys}) | - |
| onDragLeave | dragLeave触发时调用 | function({event, node}) | - |
| onDragStart | dragStart触发时调用 | function({event, node}) | - |
| onDrop | drop触发时调用 | 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 | - |
note: 如果你有很多个树节点,若有超过一千个节点,
建议将父节点设置成默认
收起,这样整体树结构展示便会非常有效迅速,因为藏起来的子节点是不会插入dom中的
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| className | 树节点的附加类 | string | '' |
| style | 为树节点设置样式 | object | - |
| disabled | 禁止响应 | bool | false |
| title | 标题 | string/element/((data:DataNode) => React.ReactNode) | '---' |
| key | 被树的 (default)ExpandedKeys / (default)CheckedKeys / (default)SelectedKeys 属性所用。注意:整个树范围内的所有节点的 key 值不能重复! | string | treeNode's position |
| isLeaf | 设置为叶子节点 | bool | false |
| icon | 自定义图标。可接收组件,props 为当前节点 props | element/Function(props) | - |
| switcherIcon | 切换具体的图标 | ReactNode /(props: TreeNodeAttribute) => ReactNode | - |
npm install
npm start
co-tree is released under the MIT license
FAQs
co-tree React component
We found that co-tree demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
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.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.