Skip to content

Commit

Permalink
fix(Picker): 增加弹开 & 联动
Browse files Browse the repository at this point in the history
  • Loading branch information
ChenlingasMx committed Apr 6, 2023
1 parent 66e2cf3 commit 87eb1e4
Show file tree
Hide file tree
Showing 10 changed files with 517 additions and 364 deletions.
108 changes: 53 additions & 55 deletions example/examples/src/routes/Picker/index.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,58 @@
import React from 'react';
import {Text, View} from 'react-native';
import {Picker, Button} from '@uiw/react-native';
import {SafeAreaView} from 'react-native';
import {Picker, Button, Spacing} from '@uiw/react-native';
import {ComProps} from '../../routes';
import Layout, {Container} from '../../Layout';
const {Header, Body, Footer} = Layout;

export interface BadgeViewProps extends ComProps {}
export interface PickerViewProps extends ComProps {}

export default class BadgeView extends React.Component<BadgeViewProps> {
state = {
value: 1,
};
render() {
const {route, navigation} = this.props;
const description = route.params.description;
const title = route.params.title;
const arr = [];
for (let i = 0; i < 100; i++) {
arr.push({label: i});
}
return (
<Container scrollEnabled={false}>
<Layout>
<Header title={title} description={description} />
<Body scrollEnabled={false}>
<View
style={{
flex: 1,
flexDirection: 'row',
backgroundColor: '#fff',
marginTop: 20,
paddingVertical: 20,
}}>
<View style={{width: '50%'}}>
<Picker data={arr as any} value={17} />
</View>
<View style={{width: '50%'}}>
<Picker
onChange={val => {
console.log('val: ', val);
}}
data={arr as any}
value={this.state.value}
/>
</View>
</View>
<Button
onPress={() => {
this.setState({value: this.state.value + 1});
}}>
控制第二列value
</Button>
</Body>
<Footer />
</Layout>
</Container>
);
}
export default function (props: PickerViewProps) {
const [value, setValue] = React.useState(['2', '22', '221']);
const [value2, setValue2] = React.useState(['5']);
const [visible, setVisible] = React.useState(false);
const arr = [
{
label: '江苏省',
value: '1',
children: [
{
label: '南京市',
value: '11',
children: [
{label: '宣武区', value: '111'},
{label: '雨花台区', value: '112'},
],
},
{
label: '苏州市',
value: '12',
children: [{label: '苏州区', value: '121'}],
},
],
},
{label: '北京市', value: '2', children: [{label: '北京市', value: '22', children: [{label: '朝阳区', value: '221'}]}]},
];

const arr2 = [
{label: '3', value: '3'},
{label: '4', value: '4'},
{label: '5', value: '5'},
];

return (
<SafeAreaView style={{flex: 1}}>
<Button onPress={() => setVisible(true)}>打开</Button>
<Picker
title="标题"
displayType="modal"
value={value}
onChange={(val: any) => setValue(val)}
visible={visible}
cols={3}
onClosed={() => setVisible(false)}
data={arr as any}
/>
<Spacing />
<Picker cols={1} displayType="view" data={arr2 as any} value={value2} onChange={(val2: any) => setValue2(val2)} />
</SafeAreaView>
);
}
3 changes: 1 addition & 2 deletions packages/core/src/DatePicker/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useState, useEffect, useRef } from 'react';
import { View, StyleSheet, SafeAreaView, StyleProp, TextStyle } from 'react-native';
import Modal, { ModalProps } from '../Modal';
import { PickerProps } from '../Picker';
import PickerView, { DateKey } from './component/PickerView';
import Control from './component/Control';
import {
Expand Down Expand Up @@ -48,7 +47,7 @@ export interface DatePickerProps {
/** modal 属性 */
modalProps?: ModalProps;
/** picker 属性 */
pickerProps?: PickerProps;
pickerProps?: any;
}
interface DateIndex {
year?: number;
Expand Down
33 changes: 18 additions & 15 deletions packages/core/src/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,24 +89,27 @@ const Modal = (props: ModalProps = {}) => {
if (isHorizontal) {
translateStyle.translateX = translateValue;
}
const child = (
<Animated.View
style={[styles.content, placement && styles[placement], { opacity: AnimatedOpacity }, containerStyle]}
>
const child = React.useMemo(
() => (
<Animated.View
onLayout={measureContainer}
style={[
styles.content,
placement && styles[placement],
// !layoutHeight && isVertical ? { display: display } : {},
// !layoutWidth && isHorizontal ? { display: display } : {},
// // getTransformStyle(),
{ transform: [translateStyle], backgroundColor: '#fff', position: 'relative', zIndex: 10000 },
]}
style={[styles.content, placement && styles[placement], { opacity: AnimatedOpacity }, containerStyle]}
>
{children}
<Animated.View
onLayout={measureContainer}
style={[
styles.content,
placement && styles[placement],
// !layoutHeight && isVertical ? { display: display } : {},
// !layoutWidth && isHorizontal ? { display: display } : {},
// // getTransformStyle(),
{ transform: [translateStyle], backgroundColor: '#fff', position: 'relative', zIndex: 10000 },
]}
>
{children}
</Animated.View>
</Animated.View>
</Animated.View>
),
[children],
);
return (
<MaskLayer {...otherProps} visible={visible} onDismiss={onDismiss}>
Expand Down
96 changes: 63 additions & 33 deletions packages/core/src/Picker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ Picker 选择器

解决 ios 与 android 和用户交互方式不同问题.
> 🚧测试版本
> 避免出现样式错乱问题, 请尽量使用统一整数数字高度。
> 激活状态尽量不要改变高度, 只是修改颜色作为标记。
<!--rehype:style=border-left: 8px solid #ffe564;background-color: #ffe56440;padding: 12px 16px;-->
<!-- ![](https://user-images.githubusercontent.com/66067296/139409471-846bdddb-99cc-4b2d-b2da-278da81b0c22.gif) -->
Expand All @@ -14,48 +12,78 @@ Picker 选择器

```jsx mdx:preview&background=#bebebe29
import React from 'react';
import { View } from 'react-native';
import { SafeAreaView } from 'react-native';
import { Picker } from '@uiw/react-native';

function Demo() {
const [value, setValue] = React.useState(['5'])
const arr1 = [
{ label: '3', value: '3' },
{ label: '4', value: '4' },
{ label: '5', value: '5' },
]
return (
<View style={{ flex: 1 }}>
<SafeAreaView style={{ flex: 1 }}>
<Picker
data={[
{label: '1'},
{label: '2'},
{label: '3'},
{label: '4'},
{label: '5'},
]}
cols={1}
value={value}
displayType="view"
data={arr2}
onChange={val => setValue(val)}
/>
</View>
</SafeAreaView>
)
}
export default Demo
```

### 使用自定义元素
### modal弹框 & 联动

```jsx mdx:preview&background=#bebebe29
import React from 'react';
import { View, Text } from 'react-native';
import { Picker } from '@uiw/react-native';
import { SafeAreaView } from 'react-native';
import { Picker,Button } from '@uiw/react-native';

function Demo() {
const [value, setValue] = React.useState(['2', '22', '221'])
const [visible, setVisible] = React.useState(false)
const arr = [
{
label: '江苏省',
value: '1',
children: [
{
label: '南京市', value: '11',
children: [
{ label: '宣武区', value: '111' },
{ label: '雨花台区', value: '112' }
]
},
{
label: '苏州市',
value: '12',
children: [
{ label: '苏州区', value: '121' }
]
}
]
},
{ label: '北京市', value: '2', children: [{ label: '北京市', value: '22', children: [{ label: '朝阳区', value: '221' }] }] }
];
return (
<View style={{ flex: 1 }}>
<SafeAreaView style={{ flex: 1 }}>
<Button onPress={() => setVisible(true)}>打开</Button>
<Picker
data={[
{label: '1'},
{label: '2'},
{label: '3'},
{label: '4'},
{label: '5'},
{label: '5',render: (label, record, index)=><Text>end</Text>},
]}
title="标题"
displayType="modal"
value={value}
onChange={val => setValue(val)}
visible={visible}
cols={3}
onClosed={() => setVisible(false)}
data={arr}
/>
</View>
</SafeAreaView>
)
}
export default Demo
Expand All @@ -65,12 +93,14 @@ export default Demo

属性 | 说明 | 类型 | 默认值
----|-----|------|------
| lines | 显示行数 | number | 3 |
| rowKey | 在开始位置设置图标 | string | - |
| data | 需要渲染的数据 | Array | - |
| containerStyle | item 容器样式 | obj | - |
| textStyle | 容器的文本样式 | TextStyle | - |
| value | 选中当前项的下标 | number | - |
| onChange | value 改变时触发 | fn | - |
| readonly | 是否只读 | fn | - |
| data | 选择项列表 | `CascadePickerItemProps[]` | `Array<CascadePickerItemProps[]>` | [] |
| cols | 展示几列 | `number` | 1 |
| value | 当前值 | `ItemValue[]` | [] |
| displayType | 选择器显示类型。view表示在页面显示;modal表示在弹窗中显示;默认为modal | `view | modal` | view |
| onChange | 修改事件 | `(value?: ItemValue[]) => void` | - |
| title | 选中当前项的下标 | number | - |
| visible | 是否弹窗显示 | boolean | false |
| onClosed | 弹窗关闭事件 | () => void | - |
| cancelText | 取消按钮文本 | string | 取消 |
| okText | 确认按钮文本 | string | 确认 |

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { memo } from 'react';
import { Animated, StyleSheet, Text } from 'react-native';

import { WhellPickerItemProps } from './type';

const opacityFunction = (val: number) => 1 / (1 + Math.abs(val));
const scaleFunction = (val: number) => 1 - 0.1 * Math.abs(val);
const rotationFunction = (val: number) => 20 * val;

function WheelPickerItem({ textStyle, style, visibleRest, height, option, index, currentIndex }: WhellPickerItemProps) {
const relativeScrollIndex = Animated.subtract(index, currentIndex);

const inputRange = [0];
for (let i = 1; i <= visibleRest + 1; i++) {
inputRange.unshift(-i);
inputRange.push(i);
}

const opacityOutputRange = [1];
for (let x = 1; x <= visibleRest + 1; x++) {
const y = opacityFunction(x);
opacityOutputRange.unshift(y);
opacityOutputRange.push(y);
}

const scaleOutputRange = [1.0];
for (let x = 1; x <= visibleRest + 1; x++) {
const y = scaleFunction(x);
scaleOutputRange.unshift(y);
scaleOutputRange.push(y);
}

const rotateXOutputRange = ['0deg'];
for (let x = 1; x <= visibleRest + 1; x++) {
const y = rotationFunction(x);
rotateXOutputRange.unshift(`${y}deg`);
rotateXOutputRange.push(`${y}deg`);
}

const opacity = relativeScrollIndex.interpolate({ inputRange, outputRange: opacityOutputRange });
const scale = relativeScrollIndex.interpolate({ inputRange, outputRange: scaleOutputRange });
const rotateX = relativeScrollIndex.interpolate({ inputRange, outputRange: rotateXOutputRange });

return (
<Animated.View style={[styles.option, style, { height, opacity, transform: [{ rotateX }, { scale }] }]}>
<Text style={textStyle}>{option?.label}</Text>
</Animated.View>
);
}

export default WheelPickerItem;

const styles = StyleSheet.create({
option: {
alignItems: 'center',
justifyContent: 'center',
zIndex: 100,
},
});
Loading

0 comments on commit 87eb1e4

Please sign in to comment.