import React, { useRef, useState } from 'react';
import Tree from '../index';
import AutoSizer from '../autoSizer';
import { Button, ButtonGroup, Input, Popover, Toast } from '../../index';
import BigTree from './BigData';
import testData from './data';
import { cloneDeep, difference, isEqual } from 'lodash';
import { IconEdit, IconMapPin, IconMore } from '@douyinfe/semi-icons';
const TreeNode = Tree.TreeNode;
export default {
title: 'Tree'
}
const treeChildren = [
{
label: '北京',
value: 'beijing',
key: 'beijing',
},
{
label: '上海',
value: 'shanghai',
key: 'shanghai',
},
];
const treeData1 = [
{
label: '亚洲',
value: 'yazhou',
key: 'yazhou',
children: [
{
label: '中国',
value: 'zhongguo',
key: 'zhongguo',
disabled: true,
children: treeChildren,
},
{
label: '日本',
value: 'riben',
key: 'riben',
children: [
{
label: '东京',
value: 'dongjing',
key: 'dongjing',
},
{
label: '大阪',
value: 'daban',
key: 'daban',
},
],
},
],
},
{
label: '北美洲',
value: 'beimeizhou',
key: 'beimeizhou',
children: [
{
label: '美国',
value: 'meiguo',
key: 'meiguo',
},
{
label: '加拿大',
value: 'jianada',
key: 'jianada',
},
],
},
];
const treeDataWithoutValue = [
{
label: '亚洲',
key: 'yazhou',
children: [
{
label: '中国',
key: 'zhongguo',
disabled: true,
children: treeChildren,
},
{
label: '日本',
key: 'riben',
children: [
{
label: '东京',
key: 'dongjing',
},
{
label: '大阪',
key: 'daban',
},
],
},
],
},
{
label: '北美洲',
key: 'beimeizhou',
children: [
{
label: '美国',
key: 'meiguo',
},
{
label: '加拿大',
key: 'jianada',
},
],
},
];
const treeDataWithIcon = [
{
label: 'Asia',
value: 'Asia',
key: '0',
icon: ,
children: [
{
label: 'China',
value: 'China',
key: '0-0',
icon: ,
},
{
label: 'Japan',
value: 'Japan',
key: '0-1',
icon: ,
},
],
},
];
let opts = {
content: 'Hi, Bytedance dance dance',
duration: 3,
};
const treeDataWithNode = [
{
label: (
亚洲
),
value: 'yazhou',
key: 'yazhou',
children: [
{
label: '中国',
value: 'zhongguo',
key: 'zhongguo',
children: [
{
label: '北京',
value: 'beijing',
key: 'beijing',
},
{
label: '上海',
value: 'shanghai',
key: 'shanghai',
},
],
},
{
label: '日本',
value: 'riben',
key: 'riben',
},
],
},
{
label: '北美洲',
value: 'beimeizhou',
key: 'beimeizhou',
children: [
{
label: '美国',
value: 'meiguo',
key: 'meiguo',
},
{
label: '加拿大',
value: 'jianada',
key: 'jianada',
},
],
},
];
const treeJson = {
Node1: {
Child1: '0-0-1',
Child2: '0-0-2',
},
Node2: '0-1',
};
const benchmarkSet = size => {
console.time('benchmarkSet');
var set = new Set();
for (var i = 0; i < size; i++) set.add(i);
for (var i = 0; i < size; i++) set.has(i);
console.timeEnd('benchmarkSet');
};
const benchmarkArr = size => {
console.time('benchmarkArr');
var arr = [];
for (var i = 0; i < size; i++) arr.push(i);
for (var i = 0; i < size; i++) arr.indexOf(i);
console.timeEnd('benchmarkArr');
};
export const BenchMark = () => {
const size = 100000;
benchmarkSet(size);
benchmarkArr(size);
return
check console please
;
};
BenchMark.story = {
name: 'bench mark',
};
export const SimpleTree = () => (
console.log('expand', e, expanded, node)}
// onSelect={(e, bool, node) => console.log('select', e, bool, node)}
// onChange={e => console.log('change', e)}
onContextMenu={(e, node) => console.log(e.currentTarget, node)}
onDoubleClick={(e, node) => console.log(e, node)}
motion={true}
/>
);
SimpleTree.story = {
name: 'simple tree',
};
export const MultipleTree = () => (
console.log('expand', e, expanded, node)}
// onSelect={(e, bool) => console.log('select', e, bool)}
onContextMenu={(e, node) => console.log(e, node)}
onDoubleClick={(e, node) => console.log(e, node)}
onChange={e => console.log('change', e)}
/>
);
MultipleTree.story = {
name: 'multiple tree',
};
export const SearchableTree = () => (
);
SearchableTree.story = {
name: 'searchable tree',
};
export const DisabledTree = () => (
);
DisabledTree.story = {
name: 'disabled tree',
};
export const DefaultTree = () => (
console.log(e)}
onSelect={e => console.log(e)}
/>
);
DefaultTree.story = {
name: 'default tree',
};
export const ExpandAction = () => (
console.log(e.detail)}
/>
);
ExpandAction.story = {
name: 'expandAction',
};
class Demo extends React.Component {
constructor() {
super();
this.state = {
value: 'shanghai',
};
}
onChange(value) {
this.setState({ value });
}
render() {
return (
this.onChange(e)}
/>
);
}
}
export const ControlledComponentSingle = () => ;
ControlledComponentSingle.story = {
name: 'controlled Component single',
};
class Demo2 extends React.Component {
constructor() {
super();
this.state = {
value: ['shanghai', 'beijing', 'zhongguo'],
};
}
onChange(value) {
console.log(value);
this.setState({ value });
}
render() {
console.log(this.state.value);
return (
this.onChange(e)}
/>
);
}
}
export const ControlledComponentMultiple = () => ;
ControlledComponentMultiple.story = {
name: 'controlled Component multiple',
};
export const JsonTree = () => (
console.log('change', e)}
onSelect={e => console.log('select', e)}
/>
console.log(e)}
onSelect={e => console.log(e)}
/>
);
JsonTree.story = {
name: 'json tree',
};
export const IconTree = () => (
);
IconTree.story = {
name: 'icon tree',
};
export const DirectoryTree = () => ;
DirectoryTree.story = {
name: 'directory tree',
};
const button = (
);
const style = {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
};
const treeDataWithNode2 = [
{
label: (
亚洲
{button}
),
value: 'yazhou',
key: 'yazhou',
children: [
{
label: (
中国
{button}
),
value: 'zhongguo',
key: 'zhongguo',
children: [
{
label: (
test
{button}
),
value: 'test',
key: 'test',
},
],
},
{
label: (
日本
{button}
),
value: 'riben',
key: 'riben',
},
],
},
];
export const TreeLabelUsingNode = () => (
);
TreeLabelUsingNode.story = {
name: 'tree label using node',
};
const treeDataTest = [
{
value: '一级标签1',
label: '一级标签1',
id: 1,
key: '1',
},
];
class TagSideSheet2 extends React.Component {
constructor() {
super();
this.state = {
tagList: [],
visibles: false,
};
this.onVisible = this.onVisible.bind(this);
this.renderLabel = this.renderLabel.bind(this);
this.transLabel = this.transLabel.bind(this);
}
componentDidMount() {
let tagList = [...treeDataTest];
this.setState({
tagList,
});
}
onVisible(visibles) {
this.setState({
visibles,
});
}
renderLabel(item) {
const { visibles } = this.state;
console.log('rendering label', visibles);
return (
}
onClick={e => {
e.stopPropagation();
this.onVisible(!visibles);
}}
>
{item.label}
);
}
transLabel(list) {
// list = cloneDeep(list);
list.forEach(item => {
item.label = this.renderLabel(item);
// item.key += Math.random().toString().slice(0, 5);
});
return list;
}
render() {
const { tagList = [] } = this.state;
const transformedTags = this.transLabel(cloneDeep(tagList));
console.log('transformedTags', transformedTags, treeDataTest);
return ;
}
}
export const TreeLabelUsingPopover = () => ;
TreeLabelUsingPopover.story = {
name: 'tree label using popover',
};
export const DefaultExpandKeysTree = () => (
<>
>
);
DefaultExpandKeysTree.story = {
name: 'defaultExpandKeys tree',
};
export const LabelInValueTree = () => (
<>
console.log(e)} />
console.log(e)} multiple />
console.log(e)} multiple />
>
);
LabelInValueTree.story = {
name: 'labelInValue tree',
};
class Test extends React.Component {
constructor() {
super();
this.state = {
loading: false,
};
}
componentDidMount() {
setTimeout(() => {
console.log('set loading');
this.setState({ loading: true });
}, 5000);
}
render() {
const treeDataWithNode2 = [
{
label: (
亚洲
{button}
),
value: 'yazhou',
key: 'yazhou',
children: [
{
label: (
中国
{button}
),
value: 'zhongguo',
key: 'zhongguo',
children: [
{
label: (
test
{button}
),
value: 'test',
key: 'test',
},
],
},
{
label: (
日本
{button}
),
value: 'riben',
key: 'riben',
},
],
},
];
return ;
}
}
export const SetStateAfter5S = () => ;
SetStateAfter5S.story = {
name: 'setState after 5s',
};
class DemoExpandedKeys extends React.Component {
constructor() {
super();
this.state = {
expand: ['zhongguo', 'beimeizhou'],
};
}
onExpand(expand) {
console.log(expand);
this.setState({ expand });
}
render() {
return (
this.onExpand(e, rest)}
/>
);
}
}
class DemoExpandeKeysMulti extends React.Component {
constructor() {
super();
this.state = {
expand: ['zhongguo'],
};
}
onExpand(expand) {
console.log(expand);
this.setState({ expand });
}
render() {
return (
this.onExpand(e)}
/>
);
}
}
export const ExpandedKeys = () => (
<>
>
);
ExpandedKeys.story = {
name: 'expandedKeys',
};
class DmExpandedKeys extends React.Component {
constructor() {
super();
this.state = {
treeData: [
{
key: '0',
label: 'item-0',
value: '0',
},
],
};
this.add = this.add.bind(this);
}
add() {
let itemLength = Math.floor(Math.random() * 5) + 1;
let treeData = new Array(itemLength).fill(0).map((v, i) => {
let length = Math.floor(Math.random() * 3);
let children = new Array(length).fill(0).map((cv, ci) => {
let child = {
key: `${i}-${ci}`,
label: `Leaf-${i}-${ci}`,
value: `${i}-${ci}`,
};
return child;
});
let item = {
key: `${i}`,
label: `Item-${i}`,
value: `${i}`,
children,
};
return item;
});
this.setState({ treeData });
}
render() {
const { treeData } = this.state;
return (
<>
>
);
}
}
export const DynamicExpandKeys = () => (
<>
>
);
DynamicExpandKeys.story = {
name: 'dynamic expandKeys',
};
class DmSelectedKeys extends React.Component {
constructor() {
super();
this.state = {
treeData: [
{
key: '0',
label: 'item-0',
value: '0',
},
],
};
this.add = this.add.bind(this);
}
add() {
let itemLength = Math.floor(Math.random() * 5) + 1;
let treeData = new Array(itemLength).fill(0).map((v, i) => {
let length = Math.floor(Math.random() * 3);
let children = new Array(length).fill(0).map((cv, ci) => {
let child = {
key: `${i}-${ci}`,
label: `Leaf-${i}-${ci}`,
value: `${i}-${ci}`,
};
return child;
});
let item = {
key: `${i}`,
label: `Item-${i}`,
value: `${i}`,
children,
};
return item;
});
this.setState({ treeData });
}
render() {
const { treeData } = this.state;
return (
<>
console.log(e)} />
>
);
}
}
export const DynamicSelectedKey = () => (
<>
>
);
DynamicSelectedKey.story = {
name: 'dynamic selectedKey',
};
export const LargeAmountOfData = () => (
<>
>
);
LargeAmountOfData.story = {
name: 'large amount of data',
};
export const Autosizer = () => (
{({ height, width }) => (
{`width:${width}, height:${height}`}
)}
);
Autosizer.story = {
name: 'autosizer',
};
const MotionCustomLabelDemo = () => {
const treeData = [
{
label: '亚洲',
value: 'Asia',
key: '0',
children: [
{
label: '中国',
value: 'China',
key: '0-0',
children: [
{
label: '北京',
value: 'Beijing',
key: '0-0-0',
},
{
label: '上海',
value: 'Shanghai',
key: '0-0-1',
},
],
},
],
},
{
label: '北美洲',
value: 'North America',
key: '1',
},
];
const [hoverKey, setHoverKey] = useState();
const cusLabel = (list = []) => {
const recusive = (list = []) => {
if (!list.length) {
return;
}
list.forEach(item => {
const { type, label, key } = item;
item.label = (
setHoverKey(key)}>
{label}
{hoverKey === key ? : null}
);
recusive(item.children);
});
};
recusive(list);
return list;
};
return ;
};
export const MotionCustomLabel = () => ;
MotionCustomLabel.story = {
name: 'motion custom label',
};
const AutoParentDemo = () => {
const [expandedKeys, setExpandedKeys] = useState(['beimeizhou']);
const [selectedKeys, setSelectedKeys] = useState(['beimeizhou']);
const [autoExpandParent, setAutoExpandParent] = useState(true);
const onExpand = expandedKeys => {
console.log('onExpand', expandedKeys);
// if not set autoExpandParent to false, if children expanded, parent can not collapse.
// or, you can remove all expanded children keys.
setExpandedKeys(expandedKeys);
setAutoExpandParent(false);
};
const onSelect = (selectedKeys, info) => {
console.log('onSelect:', info);
setSelectedKeys(selectedKeys);
};
return (
);
};
export const AutoExpandParent = () => (
<>
>
);
AutoExpandParent.story = {
name: 'autoExpandParent',
};
const findDescendantKeys = node => {
let res = [node.key];
const findChild = item => {
if (!item) return;
const { children } = item;
if (children && children.length) {
children.forEach(child => {
res.push(child.key);
findChild(child);
});
}
};
findChild(node);
return res;
};
class DyTreeWithExpandControlled extends React.Component {
constructor() {
super();
this.state = {
treeData: [
{
key: '0',
label: 'item-0',
value: '0',
},
],
expandedKeys: [],
autoExpandParent: false,
inputValue: '',
collapsedKeys: new Set([]),
};
}
componentDidUpdate(prevProps, prevState) {
if (
!isEqual(prevState.treeData, this.state.treeData) ||
!isEqual(prevState.inputValue, this.state.inputValue)
) {
const { treeData, inputValue, collapsedKeys } = this.state;
let filteredKeys = [];
const findFilteredKey = arr => {
arr.forEach(item => {
if (item.label.indexOf(inputValue) > -1) {
filteredKeys.push(item.key);
}
if (item.children) {
findFilteredKey(item.children);
}
});
};
findFilteredKey(treeData);
const expanded = difference(filteredKeys, [...collapsedKeys]);
this.setState({
expandedKeys: expanded,
autoExpandParent: true,
});
}
}
add = () => {
let itemLength = Math.floor(Math.random() * 5) + 1;
let treeData = new Array(itemLength).fill(0).map((v, i) => {
let length = Math.floor(Math.random() * 3) + 1;
let children = new Array(length).fill(0).map((cv, ci) => {
let child = {
key: `${i}-${ci}`,
label: `Leaf-${i}-${ci}`,
value: `${i}-${ci}`,
};
return child;
});
let item = {
key: `${i}`,
label: `Item-${i}`,
value: `${i}`,
children,
};
return item;
});
this.setState({ treeData });
};
search = val => {
this.setState({ inputValue: val });
};
onExpand = (keys, { expanded, node }) => {
let collapsed = this.state.collapsedKeys;
let desKeys = findDescendantKeys(node);
if (!expanded) {
desKeys.forEach(key => collapsed.add(key));
} else {
desKeys.forEach(key => collapsed.has(key) && collapsed.delete(key));
}
this.setState({
expandedKeys: keys,
autoExpandParent: false,
collapsedKeys: collapsed,
});
};
render() {
const { treeData, expandedKeys, autoExpandParent } = this.state;
return (
);
}
}
export const DynamicTreeDataWithSearchValueAndControlledExpand = () => (
);
DynamicTreeDataWithSearchValueAndControlledExpand.story = {
name: 'dynamic treeData with searchValue and controlled expand',
};
const CusSearchRender = () => {
const [inputValue, setInputValue] = useState('');
const ref = useRef();
const setValue = value => {
setInputValue(value);
ref.current.search(value);
};
return (
(
setValue(value)}
/>
)}
/>
);
};
export const _CusSearchRender = () => (
<>
>
);
_CusSearchRender.story = {
name: 'CusSearchRender',
};
const RefSearch = () => {
const ref = useRef();
const treeData = [
{
label: 'Asia',
value: 'Asia',
key: '0',
children: [
{
label: 'China',
value: 'China',
key: '0-0',
children: [
{
label: 'Beijing',
value: 'Beijing',
key: '0-0-0',
},
{
label: 'Shanghai',
value: 'Shanghai',
key: '0-0-1',
},
],
},
{
label: 'Japan',
value: 'Japan',
key: '0-1',
children: [
{
label: 'Osaka',
value: 'Osaka',
key: '0-1-0',
},
],
},
],
},
{
label: 'North America',
value: 'North America',
key: '1',
children: [
{
label: 'United States',
value: 'United States',
key: '1-0',
},
{
label: 'Canada',
value: 'Canada',
key: '1-1',
},
],
},
];
return (
ref.current.search(v)} />
null}
/>
);
};
export const _RefSearch = () => (
<>
>
);
_RefSearch.story = {
name: 'RefSearch',
};
const initTreeDate = [
{
label: 'Expand to load',
key: '0',
},
{
label: 'Expand to load',
key: '1',
},
{
label: 'Tree Node',
key: '2',
isLeaf: true,
},
];
function updateTreeData(list, key, children) {
return list.map(node => {
if (node.key === key) {
return { ...node, children };
}
if (node.children) {
return { ...node, children: updateTreeData(node.children, key, children) };
}
return node;
});
}
const LoadingTreeDemo = () => {
const [treeData, setTreeData] = useState(initTreeDate);
function onLoadData({ key, children }) {
return new Promise(resolve => {
if (children) {
resolve();
return;
}
setTimeout(() => {
setTreeData(origin =>
updateTreeData(origin, key, [
{
label: 'Child Node',
key: `${key}-0`,
},
{
label: 'Child Node',
key: `${key}-1`,
},
])
);
resolve();
}, 1000);
});
}
return ;
};
export const Loading = () => (
<>
>
);
Loading.story = {
name: 'loading',
};
const LoadingWithSearch = () => {
const [treeData, setTreeData] = useState(initTreeDate);
function onLoadData({ key, children }) {
return new Promise(resolve => {
if (children) {
resolve();
return;
}
setTimeout(() => {
setTreeData(origin =>
updateTreeData(origin, key, [
{
label: 'Child Node',
key: `${key}-0`,
},
{
label: 'Child Node',
key: `${key}-1`,
},
])
);
resolve();
}, 1000);
});
}
return ;
};
export const _LoadingWithSearch = () => (
<>
>
);
_LoadingWithSearch.story = {
name: 'Loading with search',
};
const DisabledStrictly = () => {
return (
<>
disable shanghai(checked), China
disable shanghai(checked), beijing(checked)
disable shanghai(checked)
disable shanghai
disable China(checked) - Shanghai
disable China
>
);
};
export const DisableStrictly = () => ;
DisableStrictly.story = {
name: 'disableStrictly',
};
const ActionTree = () => {
let initData = [
{
label: 'Asia',
value: 'Asia',
key: 'asia',
children: [
{
label: 0,
value: `${0}`,
key: `${0}`,
},
{
label: 1,
value: `${1}`,
key: `${1}`,
},
{
label: 2,
value: `${2}`,
key: `${2}`,
},
{
label: 3,
value: `${3}`,
key: `${3}`,
},
{
label: 4,
value: `${4}`,
key: `${4}`,
},
],
},
];
const [data, setData] = useState(initData);
const remove = key => {
let ind = data[0].children.findIndex(item => item.key === key);
if (ind >= 0) {
let items = cloneDeep(data);
items[0].children.splice(ind, 1);
setData(items);
}
};
return (
(
{label}
)}
/>
);
};
export const DeleteOrAddChildNode = () => ;
DeleteOrAddChildNode.story = {
name: 'Delete or Add Child Node',
};
const MutipleHLTree = () => {
const [selected, setSelected] = useState(new Set());
const [selectedThroughParent, setSelectedThroughParent] = useState(new Set());
const findDescendantKeys = node => {
let res = [node.key];
const findChild = item => {
if (!item) return;
const { children } = item;
if (children && children.length) {
children.forEach(child => {
res.push(child.key);
findChild(child);
});
}
};
findChild(node);
return res;
};
const handleSelect = (key, bool, node) => {
setSelected(new Set([key]));
const descendantKeys = findDescendantKeys(node);
setSelectedThroughParent(new Set(descendantKeys));
};
const renderLabel = ({ className, data, onClick, expandIcon }) => {
const { label, icon, key } = data;
const isLeaf = !(data.children && data.children.length);
const style = {
backgroundColor: selected.has(key)
? 'rgba(var(--semi-blue-0), 1)'
: selectedThroughParent.has(key)
? 'rgba(var(--semi-blue-0), .5)'
: 'transparent',
};
return (
{isLeaf ? null : expandIcon}
{icon ? icon : null}
{label}
);
};
const treeStyle = {
width: 260,
height: 420,
border: '1px solid var(--semi-color-border)',
};
return (
);
};
export const RenderOuterLable = () => ;
RenderOuterLable.story = {
name: 'renderOuterLable',
};
export const TreeWithoutValueProps = () => (
console.log(args)}
/>
);
TreeWithoutValueProps.story = {
name: 'tree without value props',
};
const DnDTree = () => {
const initialData = [
{
label: 'Asia',
value: 'Asia',
key: '0',
children: [
{
label: 'China',
value: 'China',
key: '0-0',
children: [
{
label: 'Beijing',
value: 'Beijing',
key: '0-0-0',
},
{
label: 'Shanghai',
value: 'Shanghai',
key: '0-0-1',
},
],
},
{
label: 'Japan',
value: 'Japan',
key: '0-1',
children: [
{
label: 'Osaka',
value: 'Osaka',
key: '0-1-0',
},
],
},
],
},
{
label: 'North America',
value: 'North America',
key: '1',
children: [
{
label: 'United States',
value: 'United States',
key: '1-0',
},
{
label: 'Canada',
value: 'Canada',
key: '1-1',
},
],
},
{
label: 'Europe',
value: 'Europe',
key: '2',
},
];
const [treeData, setTreeData] = useState(initialData);
// const [expandedKeys, setExpandedKeys] = useState(['zhongguo']);
function onDragEnter(info) {
console.log(info);
// if in controlled expandedKeys mode
// setExpandedKeys(info.expandedKeys)
}
function onDrop(info) {
const { dropToGap, node, dragNode } = info;
const dropKey = node.key;
const dragKey = dragNode.key;
const dropPos = node.pos.split('-');
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
const data = [...treeData];
const loop = (data, key, callback) => {
data.forEach((item, ind, arr) => {
if (item.key === key) return callback(item, ind, arr);
if (item.children) return loop(item.children, key, callback);
});
};
let dragObj;
loop(data, dragKey, (item, ind, arr) => {
arr.splice(ind, 1);
dragObj = item;
});
if (!dropToGap) {
// inset into the dropPosition
loop(data, dropKey, (item, ind, arr) => {
item.children = item.children || [];
item.children.push(dragObj);
});
} else if (dropPosition === 1 && node.children && node.expanded) {
// has children && expanded and drop into the node bottom gap
// insert to the top 这里我们添加在头部,可以是任意位置
loop(data, dropKey, item => {
item.children = item.children || [];
item.children.unshift(dragObj);
});
} else {
let dropNodeInd;
let dropNodePosArr;
loop(data, dropKey, (item, ind, arr) => {
dropNodePosArr = arr;
dropNodeInd = ind;
});
if (dropPosition === -1) {
// insert to top
dropNodePosArr.splice(dropNodeInd, 0, dragObj);
} else {
// insert to bottom
dropNodePosArr.splice(dropNodeInd + 1, 0, dragObj);
}
}
setTreeData(data);
}
return (
);
};
export const DraggableTree = () => ;
DraggableTree.story = {
name: 'draggable Tree',
};
const TestTree = () => {
return (
);
};
export const Draggable = () => ;
Draggable.story = {
name: 'draggable',
};
export const RenderFullLabelWithDraggable = () => {
const [selected, setSelected] = useState(new Set());
const [selectedThroughParent, setSelectedThroughParent] = useState(new Set());
const defaultTreeData = [
{
label: '黑色固定按钮',
key: 'fix-btn-0',
},
{
label: '模块',
key: 'module-0',
children: [
{
label: '可自由摆放的组件',
key: 'free-compo-0',
},
{
label: '分栏容器',
key: 'split-col-0',
children: [
{
label: '按钮组件',
key: 'btn-0',
},
{
label: '按钮组件',
key: 'btn-1',
},
],
},
],
},
{
label: '模块',
key: 'module-1',
children: [
{
label: '自定义组件',
key: 'cus-0',
},
],
},
];
const [treeData, setTreeData] = useState(defaultTreeData);
const onDrop = info => {
const { dropToGap, node, dragNode } = info;
const dropKey = node.key;
const dragKey = dragNode.key;
const dropPos = node.pos.split('-');
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
const data = [...treeData];
const loop = (data, key, callback) => {
data.forEach((item, ind, arr) => {
if (item.key === key) return callback(item, ind, arr);
if (item.children) return loop(item.children, key, callback);
});
};
let dragObj;
loop(data, dragKey, (item, ind, arr) => {
arr.splice(ind, 1);
dragObj = item;
});
if (!dropToGap) {
loop(data, dropKey, (item, ind, arr) => {
item.children = item.children || [];
item.children.push(dragObj);
});
} else if (dropPosition === 1 && node.children && node.expanded) {
loop(data, dropKey, item => {
item.children = item.children || [];
item.children.unshift(dragObj);
});
} else {
let dropNodeInd;
let dropNodePosArr;
loop(data, dropKey, (item, ind, arr) => {
dropNodePosArr = arr;
dropNodeInd = ind;
});
if (dropPosition === -1) {
dropNodePosArr.splice(dropNodeInd, 0, dragObj);
} else {
dropNodePosArr.splice(dropNodeInd + 1, 0, dragObj);
}
}
setTreeData(data);
};
const findDescendantKeys = node => {
let res = [node.key];
const findChild = item => {
if (!item) return;
const { children } = item;
if (children && children.length) {
children.forEach(child => {
res.push(child.key);
findChild(child);
});
}
};
findChild(node);
return res;
};
const handleSelect = (key, bool, node) => {
setSelected(new Set([key]));
const descendantKeys = findDescendantKeys(node);
setSelectedThroughParent(new Set(descendantKeys));
};
const renderLabel = ({ className, data, onClick, expandIcon }) => {
const { label, icon, key } = data;
const isLeaf = !(data.children && data.children.length);
const style = {
backgroundColor: selected.has(key)
? 'rgba(var(--semi-blue-0), 1)'
: selectedThroughParent.has(key)
? 'rgba(var(--semi-blue-0), .5)'
: 'transparent',
};
return (
{isLeaf ? : expandIcon}
{icon ? icon : null}
{label}
);
};
const treeStyle = {
height: 420,
border: '1px solid var(--semi-color-border)',
};
return (
);
};
RenderFullLabelWithDraggable.story = {
name: 'renderFullLabel with draggable',
};
export const CheckRelationDemo = () => {
const treeData = [
{
label: 'Asia',
value: 'Asia',
key: '0',
children: [
{
label: 'China',
value: 'China',
key: '0-0',
children: [
{
label: 'Beijing',
value: 'Beijing',
key: '0-0-0',
},
{
label: 'Shanghai',
value: 'Shanghai',
key: '0-0-1',
},
{
label: 'Chengdu',
value: 'Chengdu',
key: '0-0-2',
},
],
},
{
label: 'Japan',
value: 'Japan',
key: '0-1',
children: [
{
label: 'Osaka',
value: 'Osaka',
key: '0-1-0'
}
]
},
],
},
{
label: 'North America',
value: 'North America',
key: '1',
children: [
{
label: 'United States',
value: 'United States',
key: '1-0'
},
{
label: 'Canada',
value: 'Canada',
key: '1-1'
}
]
}
];
const [value, setValue] = useState('China');
const [value2, setValue2] = useState();
const [value3, setValue3] = useState();
const style = {
width: 260,
height: 420,
border: '1px solid var(--semi-color-border)'
};
const handleChange = value => {
console.log(value);
setValue(value);
};
const handleChange2 = value => {
console.log(value);
setValue2(value);
};
const handleChange3 = value => {
console.log(value);
setValue3(value);
};
return (
<>
checkRelation='unRelated'
checkRelation='unRelated' + 中国节点为 disabled
checkRelation='unRelated' + 中国节点为 disabled + 严格禁用
checkRelation='unRelated' + defaultValue 为 China
checkRelation='unRelated' + 受控 + value 初始为 China
checkRelation='unRelated' + 受控 + onChangeWithObject
checkRelation='unRelated' + 受控 + leafOnly,此时 leafOnly 失效
checkRelation='unRelated' + onSelect
console.log('select', value, status, node)}
/>
>
);
};