Skip to content

Commit 4cb045c

Browse files
committed
feat(DatePicker): Add new component
1 parent a7c8e93 commit 4cb045c

File tree

10 files changed

+779
-6
lines changed

10 files changed

+779
-6
lines changed

example/examples/src/routes.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,4 +435,12 @@ export const stackPageData: Routes[] = [
435435
description: 'Picker 解决 ios 与 android 和用户交互方式不同问题',
436436
},
437437
},
438+
{
439+
name: 'DatePicker',
440+
component: require('./routes/DatePicker').default,
441+
params: {
442+
title: 'DatePicker 日期选择器',
443+
description: 'DatePicker 年-月-日-时-分',
444+
},
445+
},
438446
];
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React from 'react';
2+
import {Text, View} from 'react-native';
3+
import {DatePicker, Button} from '@uiw/react-native';
4+
import {ComProps} from '../../routes';
5+
import Layout, {Container} from '../../Layout';
6+
const {Header, Body, Footer} = Layout;
7+
8+
export interface BadgeViewProps extends ComProps {}
9+
10+
export default class BadgeView extends React.Component<BadgeViewProps> {
11+
state = {
12+
visible: false,
13+
};
14+
render() {
15+
const {route, navigation} = this.props;
16+
const description = route.params.description;
17+
const title = route.params.title;
18+
return (
19+
<Container scrollEnabled={false}>
20+
<Layout>
21+
<Header title={title} description={description} />
22+
<Body scrollEnabled={false}>
23+
<Button
24+
onPress={() => {
25+
this.setState({visible: true});
26+
}}>
27+
年月日
28+
</Button>
29+
<DatePicker
30+
visible={this.state.visible}
31+
onClosed={() => this.setState({visible: false})}
32+
precision="second"
33+
max="2021-11-30 23:50:50"
34+
/>
35+
</Body>
36+
<Footer />
37+
</Layout>
38+
</Container>
39+
);
40+
}
41+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export default class BadgeView extends React.Component<BadgeViewProps> {
3030
flexDirection: 'row',
3131
backgroundColor: '#fff',
3232
marginTop: 20,
33+
paddingVertical: 20,
3334
}}>
3435
<View style={{width: '50%'}}>
3536
<Picker data={arr as any} value={17} />
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
Picker 选择器
2+
---
3+
4+
解决 ios 与 android 和用户交互方式不同问题.
5+
6+
> 避免出现样式错乱问题, 请尽量使用统一整数数字高度。
7+
> 激活状态尽量不要改变高度, 只是修改颜色作为标记。
8+
<!--rehype:style=border-left: 8px solid #ffe564;background-color: #ffe56440;padding: 12px 16px;-->
9+
10+
### 基础示例
11+
12+
```jsx
13+
import { View } from 'react-native';
14+
import { Picker } from '@uiw/react-native';
15+
16+
function Demo() {
17+
return (
18+
<View style={{ flex: 1 }}>
19+
<Picker
20+
date={[
21+
{label: '1'},
22+
{label: '2'},
23+
{label: '3'},
24+
{label: '4'},
25+
{label: '5'},
26+
]}
27+
/>
28+
</View>
29+
)
30+
}
31+
```
32+
33+
### 使用自定义元素
34+
35+
```jsx
36+
import { View, Text } from 'react-native';
37+
import { Picker } from '@uiw/react-native';
38+
39+
function Demo() {
40+
return (
41+
<View style={{ flex: 1 }}>
42+
<Picker
43+
date={[
44+
{label: '1'},
45+
{label: '2'},
46+
{label: '3'},
47+
{label: '4'},
48+
{label: '5'},
49+
{label: '5',render: (label, record, index)=><Text>123</Text>},
50+
]}
51+
/>
52+
</View>
53+
)
54+
}
55+
```
56+
57+
58+
59+
### Props
60+
61+
```ts
62+
import { StyleProp, TextStyle, ViewStyle } from 'react-native';
63+
64+
export interface PickerDate {
65+
label?: string,
66+
render?: (key: string, record: PickerDate, index: number)=>React.ReactNode,
67+
[key: string]: any
68+
}
69+
70+
export interface PickerProps {
71+
/** 显示几行, 默认 3 */
72+
lines?: number,
73+
/** 指定需要显示的 key, 默认使用 data 的 label 属性 */
74+
key?: string,
75+
/** 需要渲染的数据 */
76+
date?: Array<PickerDate>,
77+
/** item 容器样式 */
78+
containerStyle?: {
79+
/** 激活的容器样式 */
80+
actived?: StyleProp<ViewStyle>,
81+
/** 未激活的容器样式 */
82+
unactived?: StyleProp<ViewStyle>,
83+
},
84+
/** 容器的文本样式 */
85+
textStyle?: {
86+
/** 激活的文本样式 */
87+
actived?: StyleProp<TextStyle>,
88+
/** 未激活的文本样式 */
89+
unactived?: StyleProp<TextStyle>,
90+
},
91+
/** 选中当前项的下标 */
92+
value?: number,
93+
/** value 改变时触发 */
94+
onChange?: (value: number)=>unknown,
95+
}
96+
```
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import React from 'react';
2+
import { View, StyleSheet, Text, TouchableHighlight } from 'react-native';
3+
4+
export interface ControlProps {
5+
/** 确认时触发 */
6+
onConfirm?: () => void;
7+
/** 关闭模态框 */
8+
onClosed?: () => void;
9+
/** 确定按钮的文字 */
10+
okText?: string | React.ReactNode;
11+
/** 取消按钮的文字 */
12+
cancelText?: string | React.ReactNode;
13+
/** 确定取消按钮 当触摸处于活动状态时将显示的底层颜色 */
14+
underlayColor?: string;
15+
}
16+
17+
const Control = (props: ControlProps) => {
18+
const { onConfirm, onClosed, okText, cancelText, underlayColor } = props;
19+
20+
return (
21+
<View style={styles.container}>
22+
<TouchableHighlight style={styles.touchStyle} onPress={onClosed} underlayColor={underlayColor}>
23+
<Text style={styles.textStyle}>{cancelText}</Text>
24+
</TouchableHighlight>
25+
<TouchableHighlight style={styles.touchStyle} onPress={onConfirm} underlayColor={underlayColor}>
26+
<Text style={styles.textStyle}>{okText}</Text>
27+
</TouchableHighlight>
28+
</View>
29+
);
30+
};
31+
32+
const styles = StyleSheet.create({
33+
container: {
34+
flexDirection: 'row',
35+
justifyContent: 'space-between',
36+
alignItems: 'center',
37+
height: 50,
38+
paddingVertical: 0,
39+
paddingHorizontal: 0,
40+
},
41+
touchStyle: {
42+
paddingHorizontal: 25,
43+
borderRadius: 5,
44+
paddingVertical: 0,
45+
height: 50,
46+
},
47+
textStyle: {
48+
color: '#1677ff',
49+
fontSize: 18,
50+
lineHeight: 50,
51+
},
52+
});
53+
54+
export default Control;
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import React, { useState, useEffect, useRef, useMemo } from 'react';
2+
import { View, StyleSheet, Text, StyleProp, TextStyle } from 'react-native';
3+
import Picker, { PickerProps } from '../../Picker';
4+
5+
// export interface PickerDate {
6+
// label?: string;
7+
// render?: (key: string, record: PickerData, index: number) => React.ReactNode;
8+
// [key: string]: any;
9+
// }
10+
11+
enum DateObject {
12+
year = '年',
13+
month = '月',
14+
day = '日',
15+
hour = '时',
16+
minute = '分',
17+
second = '秒',
18+
}
19+
export type DateKey = keyof typeof DateObject;
20+
21+
export interface PickerViewProps extends PickerProps {
22+
title: DateKey;
23+
showTitle?: boolean;
24+
titleStyle?: StyleProp<TextStyle>;
25+
getTypeDate: (index: number, label: string, title: DateKey) => unknown;
26+
renderTitle?: (text: '年' | '月' | '日' | '时' | '分' | '秒') => React.ReactNode;
27+
}
28+
29+
const PickerView = (props: PickerViewProps) => {
30+
const { title, showTitle, titleStyle, renderTitle, getTypeDate, value, ...other } = props;
31+
const textStyle = StyleSheet.flatten([styles.textStyle, titleStyle]);
32+
const [state, setState] = useState<number>(0);
33+
useEffect(() => {
34+
setState(value || 0);
35+
}, [value]);
36+
useEffect(() => {
37+
getTypeDate(state, other.data?.[state]?.label!, title);
38+
}, [state]);
39+
return (
40+
<View style={{ flex: 1 }}>
41+
{showTitle &&
42+
(renderTitle ? (
43+
renderTitle(DateObject[title as DateKey])
44+
) : (
45+
<View style={styles.viewStyle}>
46+
<Text style={textStyle}>{DateObject[title as DateKey]}</Text>
47+
</View>
48+
))}
49+
<Picker {...other} value={state} onChange={(val) => setState(val)} />
50+
</View>
51+
);
52+
};
53+
54+
const styles = StyleSheet.create({
55+
viewStyle: {
56+
height: 50,
57+
alignItems: 'center',
58+
justifyContent: 'center',
59+
borderTopWidth: 1,
60+
borderTopColor: '#E6E6E6',
61+
},
62+
textStyle: {
63+
fontSize: 18,
64+
color: '#000',
65+
paddingVertical: 0,
66+
paddingHorizontal: 0,
67+
},
68+
});
69+
70+
export default PickerView;

0 commit comments

Comments
 (0)