Skip to content

Commit b0d7f35

Browse files
panbibihy
authored andcommitted
fix(Tree):添加Tree树桩展示组件
1 parent b2a7d83 commit b0d7f35

File tree

11 files changed

+776
-334
lines changed

11 files changed

+776
-334
lines changed

example/examples/src/routes/Tree/index.tsx

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,57 +11,65 @@ export default class TreeDemo extends React.Component<TreeViewProps> {
1111
const {route} = this.props;
1212
const description = route.params.description;
1313
const title = route.params.title;
14-
const option = [
14+
const option: any = [
1515
{
16-
label: '一栋',
17-
value: '01',
16+
title: '一栋',
17+
key: '01',
1818
children: [
1919
{
20-
label: '一单元',
21-
value: '01-1',
22-
children: [{label: '一层', value: '01-1-1', children: [{label: '101', value: '01-1-1-1'}]}],
20+
title: '一单元',
21+
key: '01-1',
22+
children: [{title: '一层', key: '01-1-1', children: [{title: '101', key: '01-1-1-1'}]}],
2323
},
2424
{
25-
label: '一单元1',
26-
value: '01-2',
25+
title: '一单元1',
26+
key: '01-2',
2727
},
2828
{
29-
label: '一单元2',
30-
value: '01-3',
29+
title: '一单元2',
30+
key: '01-3',
3131
},
3232
],
3333
},
3434
{
35-
label: '二栋',
36-
value: '02',
35+
title: '二栋',
36+
key: '02',
3737
children: [
3838
{
39-
label: '二单元',
40-
value: '02-1',
39+
title: '二单元',
40+
key: '02-1',
4141
},
4242
{
43-
label: '二单元1',
44-
value: '02-2',
43+
title: '二单元1',
44+
key: '02-2',
4545
},
4646
{
47-
label: '二单元2',
48-
value: '02-3',
47+
title: '二单元2',
48+
key: '02-3',
4949
},
5050
],
5151
},
5252
];
53+
5354
return (
5455
<Container>
5556
<Layout>
5657
<Header title={title} description={description} />
5758
<React.Fragment>
5859
<Body style={{paddingLeft: 16, paddingRight: 16}}>
59-
<Tree
60+
{/* <Tree
6061
defaultValue={['01', '01-1', '01-1-1', '01-1-1-1']}
6162
// activeColor="red"
6263
options={option}
63-
onChange={(value: any, nodes: any) => {
64-
console.log(value, nodes);
64+
onChange={(key: any, nodes: any) => {
65+
// console.log(key, nodes);
66+
}}
67+
/> */}
68+
<Tree
69+
treeData={option}
70+
defaultExpandAll
71+
onCheck={e => {
72+
console.log(e);
6573
}}
6674
/>
6775
</Body>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React, { FC, PropsWithChildren } from 'react';
2+
import { StyleSheet, Animated } from 'react-native';
3+
4+
const Chevron: FC<
5+
PropsWithChildren<{
6+
progress: any;
7+
}>
8+
> = ({ progress, children }) => {
9+
const value = 0 * (1 - progress.value) + Math.PI * progress.value;
10+
const style = {
11+
transform: [{ rotateZ: `${value}rad` }],
12+
};
13+
14+
return <Animated.View style={[styles.container, style]}>{children}</Animated.View>;
15+
};
16+
17+
export default Chevron;
18+
19+
const size = 30;
20+
const styles = StyleSheet.create({
21+
container: {
22+
height: size,
23+
width: size,
24+
borderRadius: size / 2,
25+
justifyContent: 'center',
26+
alignItems: 'center',
27+
},
28+
});
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import React, { FC } from 'react';
2+
import { ScrollView } from 'react-native';
3+
import { FlattenNode, TreeProps } from '../type';
4+
import { getTreeNodeProps } from '../util';
5+
import TreeNode from './TreeNode';
6+
import { useTree } from './useTree';
7+
8+
const Tree: FC<TreeProps> = (props) => {
9+
const {
10+
flattenNodes,
11+
handleNodeExpand,
12+
handlerCheck,
13+
containerStyle,
14+
expandedKeys,
15+
checkedKeys,
16+
keyEntities,
17+
icon,
18+
checkable,
19+
disabled,
20+
showIcon,
21+
} = useTree(props);
22+
23+
const treeRender = (item: FlattenNode) => {
24+
const treeNodeProps = getTreeNodeProps(item.key, {
25+
expandedKeys,
26+
checkedKeys: checkedKeys,
27+
});
28+
const level = keyEntities?.[item.key].level;
29+
const itemIcon = keyEntities?.[item.key].data.icon || icon;
30+
return (
31+
<TreeNode
32+
icon={itemIcon}
33+
checkable={checkable}
34+
disabled={disabled}
35+
{...treeNodeProps}
36+
{...item}
37+
showIcon={showIcon}
38+
onClick={handleNodeExpand}
39+
onCheck={handlerCheck}
40+
level={!!level || level == 0 ? level : 1}
41+
/>
42+
);
43+
};
44+
return <ScrollView style={containerStyle}>{flattenNodes.map((item: any) => treeRender(item))}</ScrollView>;
45+
};
46+
Tree.displayName = 'Tree';
47+
48+
export default React.memo(Tree);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React, { FC, useState } from 'react';
2+
import Modal from '../../Modal';
3+
import { TreeProps } from '../type';
4+
import Tree from './Tree';
5+
6+
const TreeModal: FC<TreeProps> = (props) => {
7+
const [visible, setVisible] = useState(true);
8+
9+
return (
10+
<Modal visible={visible} maskClosable={true} placement="bottom" onClosed={() => setVisible(false)}>
11+
<Tree {...props} />
12+
</Modal>
13+
);
14+
};
15+
TreeModal.displayName = 'TreeModal';
16+
17+
export default TreeModal;
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import React, { FC } from 'react';
2+
import { TouchableOpacity, View, StyleSheet, Animated } from 'react-native';
3+
import { useTheme } from '@shopify/restyle';
4+
import Flex from '../../Flex';
5+
import { px } from '../util';
6+
import Icon from '../../Icon';
7+
import Text from '../../Typography/Text';
8+
import { Theme } from '../../theme';
9+
import { TreeNodeProps } from '../type';
10+
import Chevron from './Chevron';
11+
import { useTreeNode } from './useTreeNode';
12+
import CheckBox from '../../CheckBox';
13+
14+
const TreeNode: FC<TreeNodeProps> = (props) => {
15+
const theme = useTheme<Theme>();
16+
const {
17+
icon: customIcon,
18+
level,
19+
disabled,
20+
checkable,
21+
expanded = false,
22+
title,
23+
checked = false,
24+
data,
25+
showIcon,
26+
} = props;
27+
const { progress, style, handlerCheck, onClick } = useTreeNode(props);
28+
29+
const iconRender = (checked: boolean) => {
30+
if (customIcon) {
31+
return customIcon(checked);
32+
}
33+
// return (
34+
// <Icon
35+
// name={checked ? 'up' : 'down'}
36+
// color={checked ? theme.colors.primary200 : '#999999'}
37+
// />
38+
// );
39+
return (
40+
<CheckBox
41+
checked={checked}
42+
onChange={(checked) => {
43+
console.log(checked);
44+
}}
45+
/>
46+
);
47+
};
48+
49+
return (
50+
<Animated.View style={[{ overflow: 'hidden' }, style()]}>
51+
<TouchableOpacity
52+
disabled={disabled}
53+
onPress={() => {
54+
onClick?.({ expanded, key: data.key, title, checked, disabled });
55+
}}
56+
>
57+
<View
58+
style={{
59+
height: px(55),
60+
backgroundColor: '#F5F5F5',
61+
borderBottomWidth: StyleSheet.hairlineWidth,
62+
borderBottomColor: '#CCCCCC',
63+
paddingHorizontal: px(12),
64+
}}
65+
>
66+
<Flex style={{ marginLeft: level * px(16), alignItems: 'center', flex: 1 }}>
67+
<TouchableOpacity disabled={disabled} onPress={handlerCheck}>
68+
{checkable && iconRender(checked)}
69+
</TouchableOpacity>
70+
71+
<View style={{ flex: 1, marginLeft: px(4) }}>
72+
<Text
73+
style={{ fontSize: px(14), lineHeight: px(19) }}
74+
color={disabled ? 'rgba(255, 255, 255, 0.25)' : 'rgba(255, 255, 255, 0.8)'}
75+
>
76+
{title}
77+
</Text>
78+
</View>
79+
{!!data.children && !!showIcon && (
80+
<Chevron {...{ progress }}>
81+
<Icon name={checked ? 'up' : 'down'} color="#999999" />
82+
</Chevron>
83+
)}
84+
</Flex>
85+
</View>
86+
</TouchableOpacity>
87+
</Animated.View>
88+
);
89+
};
90+
TreeNode.displayName = 'TreeNode';
91+
92+
export default TreeNode;

0 commit comments

Comments
 (0)