Skip to content

Commit 4d64649

Browse files
committed
Merge branch 'dev' of https://github.com/uiwjs/react-native-uiw into dev
2 parents 1913d84 + d094352 commit 4d64649

File tree

12 files changed

+827
-0
lines changed

12 files changed

+827
-0
lines changed

example/examples/src/routes.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,14 @@ export const stackPageData: Routes[] = [
450450
description: '可自定义拖曳抽屉高度',
451451
},
452452
},
453+
{
454+
name: 'Tree',
455+
component: require('./routes/Tree').default,
456+
params: {
457+
title: 'Tree 树形展示',
458+
description: '树形展示',
459+
},
460+
},
453461
{
454462
name: 'TreeSelect',
455463
component: require('./routes/TreeSelect').default,
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import React from 'react';
2+
import {Tree, DragDrawer, Icon} from '@uiw/react-native';
3+
import {ComProps} from '../../routes';
4+
import Layout, {Container} from '../../Layout';
5+
const {Header, Body} = Layout;
6+
7+
export interface TreeViewProps extends ComProps {}
8+
9+
export default class TreeDemo extends React.Component<TreeViewProps> {
10+
render() {
11+
const {route} = this.props;
12+
const description = route.params.description;
13+
const title = route.params.title;
14+
const option: any = [
15+
{
16+
label: '一栋',
17+
value: '01',
18+
children: [
19+
{
20+
label: '一单元',
21+
value: '01-1',
22+
children: [{label: '一层', value: '01-1-1', children: [{label: '101', value: '01-1-1-1'}]}],
23+
},
24+
{
25+
label: '一单元1',
26+
value: '01-2',
27+
},
28+
{
29+
label: '一单元2',
30+
value: '01-3',
31+
},
32+
],
33+
},
34+
{
35+
label: '二栋',
36+
value: '02',
37+
children: [
38+
{
39+
label: '二单元',
40+
value: '02-1',
41+
},
42+
{
43+
label: '二单元1',
44+
value: '02-2',
45+
},
46+
{
47+
label: '二单元2',
48+
value: '02-3',
49+
},
50+
],
51+
},
52+
];
53+
54+
return (
55+
<Container>
56+
<Layout>
57+
<Header title={title} description={description} />
58+
<React.Fragment>
59+
<Body style={{paddingLeft: 16, paddingRight: 16}}>
60+
<Tree
61+
treeData={option}
62+
defaultExpandAll
63+
onCheck={e => {
64+
console.log(e);
65+
}}
66+
/>
67+
</Body>
68+
</React.Fragment>
69+
</Layout>
70+
</Container>
71+
);
72+
}
73+
}
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.value, {
25+
expandedKeys,
26+
checkedKeys: checkedKeys,
27+
});
28+
const level = keyEntities?.[item.value].level;
29+
const itemIcon = keyEntities?.[item.value].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: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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+
label,
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, value: data.value, label, 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+
{label}
77+
</Text>
78+
</View>
79+
{!!data.children && !!showIcon && <Icon name={expanded ? 'up' : 'down'} color="#999999" size={18} />}
80+
</Flex>
81+
</View>
82+
</TouchableOpacity>
83+
</Animated.View>
84+
);
85+
};
86+
TreeNode.displayName = 'TreeNode';
87+
88+
export default TreeNode;

0 commit comments

Comments
 (0)