ipanel-rnapp-ajb-base 1.0.13 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/app/App.js +3 -0
  2. package/app/components/common/PickerV1/index.js +93 -0
  3. package/app/components/common/PickerV2/index.js +96 -0
  4. package/app/components/common/PickerV2Base/_util/devWarning.tsx +5 -0
  5. package/app/components/common/PickerV2Base/_util/getLocale.tsx +42 -0
  6. package/app/components/common/PickerV2Base/_util/hooks/useAnimations.tsx +57 -0
  7. package/app/components/common/PickerV2Base/_util/hooks/useClickAway.ts +30 -0
  8. package/app/components/common/PickerV2Base/_util/isPromise.ts +5 -0
  9. package/app/components/common/PickerV2Base/_util/reactNode.ts +27 -0
  10. package/app/components/common/PickerV2Base/_util/version.json +1 -0
  11. package/app/components/common/PickerV2Base/_util/with-default-props.tsx +15 -0
  12. package/app/components/common/PickerV2Base/config-provider/DisabledContext.tsx +24 -0
  13. package/app/components/common/PickerV2Base/config-provider/index.tsx +7 -0
  14. package/app/components/common/PickerV2Base/locale-provider/en_US.tsx +22 -0
  15. package/app/components/common/PickerV2Base/locale-provider/es_ES.tsx +22 -0
  16. package/app/components/common/PickerV2Base/locale-provider/fa_IR.tsx +22 -0
  17. package/app/components/common/PickerV2Base/locale-provider/index.en-US.md +37 -0
  18. package/app/components/common/PickerV2Base/locale-provider/index.tsx +126 -0
  19. package/app/components/common/PickerV2Base/locale-provider/index.zh-CN.md +38 -0
  20. package/app/components/common/PickerV2Base/locale-provider/ko_KR.tsx +22 -0
  21. package/app/components/common/PickerV2Base/locale-provider/pt_BR.tsx +22 -0
  22. package/app/components/common/PickerV2Base/locale-provider/ru_RU.tsx +22 -0
  23. package/app/components/common/PickerV2Base/locale-provider/sv_SE.tsx +22 -0
  24. package/app/components/common/PickerV2Base/locale-provider/useLocale.tsx +36 -0
  25. package/app/components/common/PickerV2Base/locale-provider/zh_CN.tsx +22 -0
  26. package/app/components/common/PickerV2Base/picker/Picker.tsx +216 -0
  27. package/app/components/common/PickerV2Base/picker/Popup.tsx +77 -0
  28. package/app/components/common/PickerV2Base/picker/PopupPickerTypes.tsx +16 -0
  29. package/app/components/common/PickerV2Base/picker/PropsType.tsx +26 -0
  30. package/app/components/common/PickerV2Base/picker/index.en-US.md +98 -0
  31. package/app/components/common/PickerV2Base/picker/index.tsx +85 -0
  32. package/app/components/common/PickerV2Base/picker/index.zh-CN.md +97 -0
  33. package/app/components/common/PickerV2Base/picker/locale/en_US.tsx +5 -0
  34. package/app/components/common/PickerV2Base/picker/locale/es_ES.tsx +5 -0
  35. package/app/components/common/PickerV2Base/picker/locale/fa_IR.tsx +5 -0
  36. package/app/components/common/PickerV2Base/picker/locale/id_ID.tsx +5 -0
  37. package/app/components/common/PickerV2Base/picker/locale/ko_KR.tsx +5 -0
  38. package/app/components/common/PickerV2Base/picker/locale/pt_BR.tsx +5 -0
  39. package/app/components/common/PickerV2Base/picker/locale/ru_RU.tsx +5 -0
  40. package/app/components/common/PickerV2Base/picker/locale/sv_SE.tsx +5 -0
  41. package/app/components/common/PickerV2Base/picker/locale/zh_CN.tsx +5 -0
  42. package/app/components/common/PickerV2Base/picker/style/index.tsx +57 -0
  43. package/app/components/common/PickerV2Base/picker-view/PropsType.tsx +37 -0
  44. package/app/components/common/PickerV2Base/picker-view/Wheel.tsx +200 -0
  45. package/app/components/common/PickerV2Base/picker-view/columns-extend.tsx +86 -0
  46. package/app/components/common/PickerV2Base/picker-view/index.en-US.md +71 -0
  47. package/app/components/common/PickerV2Base/picker-view/index.tsx +69 -0
  48. package/app/components/common/PickerV2Base/picker-view/index.zh-CN.md +72 -0
  49. package/app/components/common/PickerV2Base/picker-view/picker-view.tsx +166 -0
  50. package/app/components/common/PickerV2Base/picker-view/style/index.tsx +51 -0
  51. package/app/components/common/PickerV2Base/style/index.tsx +96 -0
  52. package/app/components/common/PickerV2Base/style/themes/default.tsx +203 -0
  53. package/app/components/index.js +2 -0
  54. package/app/eventBus/index.js +1 -0
  55. package/app/hooks/shopMessageManager.js +5 -3
  56. package/app/screens/LoginScreen/OpenLogSheet.js +6 -1
  57. package/app/utils/common.js +0 -1
  58. package/package.json +19 -19
@@ -0,0 +1,85 @@
1
+ import React, {
2
+ forwardRef,
3
+ useCallback,
4
+ useEffect,
5
+ useImperativeHandle,
6
+ useMemo,
7
+ useState,
8
+ } from 'react'
9
+ import { mergeProps } from '../_util/with-default-props'
10
+ import {
11
+ PickerColumn,
12
+ PickerColumnItem,
13
+ PickerValue,
14
+ PickerValueExtend,
15
+ } from '../picker-view/PropsType'
16
+ import { getColumns, getValueExtend } from '../picker-view/columns-extend'
17
+ import RMCPicker, { PickerRef } from './Picker'
18
+ import { PickerPropsType } from './PropsType'
19
+
20
+ export interface PickerProps extends PickerPropsType {}
21
+ export { PickerColumn, PickerColumnItem, PickerValue, PickerValueExtend }
22
+
23
+ const defaultProps = {
24
+ defaultValue: [],
25
+ cols: 3,
26
+ cascade: true,
27
+ }
28
+
29
+ const Picker = forwardRef<PickerRef, PickerProps>((props, ref) => {
30
+ const p = mergeProps(defaultProps, props)
31
+
32
+ const [innerValue, setInnerValue] = useState<PickerValue[]>(
33
+ p.value === undefined ? p.defaultValue : p.value,
34
+ )
35
+
36
+ const pickerRef = React.useRef<PickerRef>(null)
37
+
38
+ useImperativeHandle(ref, () => pickerRef.current as PickerRef)
39
+
40
+ const columns = useMemo(
41
+ () => getColumns(p.data, innerValue, p.cols, p.cascade),
42
+ [p.data, innerValue, p.cols, p.cascade],
43
+ )
44
+
45
+ const handleSelect = useCallback(
46
+ (val: PickerValue, index: number) => {
47
+ const value = innerValue?.slice?.(0) || []
48
+ value[index] = val
49
+ const { nextValue } = getValueExtend(p.data, value, p.cols, p.cascade)
50
+ setInnerValue(nextValue)
51
+ p.onPickerChange?.(nextValue, index)
52
+ },
53
+ [p, innerValue, setInnerValue],
54
+ )
55
+
56
+ const onVisibleChange = useCallback(
57
+ (visible) => {
58
+ p.onVisibleChange?.(visible)
59
+ if (!visible && p.value !== innerValue) {
60
+ // 关闭时,如果选中值不同步,恢复为原选中值
61
+ setInnerValue(p.value || [])
62
+ }
63
+ },
64
+ [innerValue, p],
65
+ )
66
+
67
+ useEffect(() => {
68
+ setInnerValue(p.value || [])
69
+ }, [p.value])
70
+
71
+ return (
72
+ <RMCPicker
73
+ {...p}
74
+ innerValue={innerValue}
75
+ columns={columns}
76
+ handleSelect={handleSelect}
77
+ onVisibleChange={onVisibleChange}
78
+ ref={pickerRef}
79
+ />
80
+ )
81
+ })
82
+
83
+ Picker.displayName = 'AntmPicker'
84
+
85
+ export default Picker
@@ -0,0 +1,97 @@
1
+ ---
2
+ category: Components
3
+ type: Data Entry
4
+ title: Picker
5
+ subtitle: 选择器
6
+ ---
7
+
8
+ 在一组预设数据中进行选择,e.g. 省市区选择。
9
+
10
+ ### 规则
11
+ - 尽量使用 Picker 来帮助用户完成输入,避免用户通过键盘直接输入。
12
+ - DatePicker 是 Picker 的特定模式。
13
+
14
+ ## API
15
+
16
+ ### 属性
17
+
18
+ ```ts
19
+ type PickerColumnItem = {
20
+ label: string | ReactNode
21
+ value: string | number
22
+ key?: string | number
23
+ children?: PickerColumnItem[]
24
+ }
25
+
26
+ type PickerColumn = PickerColumnItem[]
27
+
28
+ type PickerValue = string | number
29
+
30
+ type PickerValueExtend = {
31
+ columns: PickerColumn[]
32
+ items: (PickerColumnItem | undefined)[]
33
+ }
34
+ ```
35
+
36
+ 属性 | 说明 | 类型 | 默认值 | 版本
37
+ ----|-----|------|-------|------
38
+ | data | 数据源 | `PickerColumn` / `PickerColumn[]` | - | |
39
+ | value | 选中项 | `PickerValue[]` | - | |
40
+ | defaultValue | 默认选中项 | `PickerValue[]` | - | |
41
+ | cascade | 是否级联。<br/>子级来自`data`参数内的`children` | Boolean | `true` | |
42
+ | cols | 列数 | Number | `3` | |
43
+ | onChange | 选中后的回调,可使用[rc-form](https://github.com/react-component/form) | `(value: PickerValue[], extend: PickerValueExtend) => void` | - | |
44
+ | onPickerChange | 每列数据选择变化后的回调函数 | `(value: PickerValue[], index: number) => void` | - | |
45
+ | onVisibleChange | 当显隐状态变化时回调函数 | `(visible: bool): void` | - | |
46
+ | renderLabel | 自定义渲染每列展示的内容 | `(item: PickerColumnItem, index: number) => ReactNode` | `(item) => item.label` | |
47
+ | locale | 国际化,可覆盖全局[LocaleProvider](/components/locale-provider-cn)的配置 | Object: {okText, dismissText, extra} | - | |
48
+ | title | 大标题 | ReactNode | - | |
49
+ | okText | 选中的文案 | String | `确定` | |
50
+ | dismissText | 取消选中的文案 | String | `取消` | |
51
+ | onOk | 点击选中时执行的回调 | `(value: PickerValue[], extend: PickerValueExtend) => void` | - | |
52
+ | onDismiss | 点击取消时执行的回调 | (): void | - | |
53
+ | okButtonProps | ok 按钮 props | [TouchableHighlightProps](https://reactnative.dev/docs/touchablehighlight) | `{ activeOpacity:1, underlayColor:'#ddd' }` | `5.1.3` |
54
+ | dismissButtonProps | dismiss 按钮 props | [TouchableHighlightProps](https://reactnative.dev/docs/touchablehighlight) | `{ activeOpacity:1, underlayColor:'#ddd' }` | `5.1.3` |
55
+ | visible | 是否显示选择器 | Boolean | - | |
56
+ | loading | 是否处于加载状态 | Boolean | - | |
57
+ | loadingContent | 加载状态下展示的内容 | ReactNode | - | |
58
+ | indicatorStyle | 默认Indicator的样式 | Object | - | |
59
+
60
+ ### 自定义样式
61
+
62
+ 属性 | 说明 | 类型 | 默认值
63
+ ----|-----|------|------
64
+ | style | 外部样式 | `StyleProp<ViewStyle>` | - |
65
+ | styles | 内部组件样式集 | 同 [PickerViewStyle](/components//picker-view-cn/#pickerviewstyle-语义化样式) | - |
66
+ | itemStyle| 每列样式 | `StyleProp<TextStyle>` | - |
67
+ | itemHeight | 每列固定高度,未设值时会根据`numberOfLines`动态计算;`itemStyle`属性设置`{height}`值是无效的 | Number | - |
68
+ | numberOfLines | 允许每列显示行数 | Number | `1` |
69
+
70
+ #### 遮罩层
71
+ 还支持自定义遮罩样式,如使用渐变组件`<LinearGradient />`。当前默认为白色半透明。
72
+
73
+ 属性 | 说明 | 类型 | 默认值
74
+ ----|-----|------|------
75
+ | renderMaskTop | 自定义渲染上半部分遮罩层 | `()=> ReactNode` | `<View style={{ flex: 1, backgroundColor: 'rgba(255,255,255,0.8)' }} />` |
76
+ | renderMaskBottom | 自定义渲染下半部分遮罩层 | `()=> ReactNode` | `<View style={{ flex: 1, backgroundColor: 'rgba(255,255,255,0.8)' }} />` |
77
+
78
+ ### 自定义Children
79
+ 通常是 [List.Item](/components/list-cn/#List.Item) ,以下属性也是围绕着`List.Item`展开:
80
+
81
+ 属性 | 说明 | 类型 | 默认值 | 版本
82
+ ----|-----|------|------|------
83
+ | children| Picker占位组件,通常是`List.Item` | `ReactNode` / `({extra, value, toggle})=>ReactNode` | - | `5.2.0`新增函数作为Children |
84
+ | extra | Picker children的`extra`属性,无选中项时展示 | String | `请选择` | |
85
+ | format | 格式化选中值的函数,用于回显在`extra`属性上 | (labels: string[]): any | `(labels) => { return labels.join(','); } ` | |
86
+ | triggerType | 按钮事件名称 | String | `onPress` | |
87
+ | disabled | 是否不可用 | Boolean | `false` | |
88
+
89
+ ### PickerActions
90
+ 属性 | 说明 | 类型
91
+ ----|-----|------
92
+ | close |关闭 Picker|`() => void`|
93
+ | open |显示 Picker|`() => void`|
94
+ | toggle|切换 Picker 的显示和隐藏状态|`() => void`|
95
+
96
+ ### Ref
97
+ 同 PickerActions
@@ -0,0 +1,5 @@
1
+ export default {
2
+ okText: 'Ok',
3
+ dismissText: 'Cancel',
4
+ extra: 'please select',
5
+ }
@@ -0,0 +1,5 @@
1
+ export default {
2
+ okText: 'OK',
3
+ dismissText: 'Cancelar',
4
+ extra: 'Seleccione',
5
+ }
@@ -0,0 +1,5 @@
1
+ export default {
2
+ okText: 'تایید',
3
+ dismissText: 'لغو',
4
+ extra: 'لطفا انتخاب کنید',
5
+ }
@@ -0,0 +1,5 @@
1
+ export default {
2
+ okText: 'Ok',
3
+ dismissText: 'Cancel',
4
+ extra: 'please select',
5
+ }
@@ -0,0 +1,5 @@
1
+ export default {
2
+ okText: '확인',
3
+ dismissText: '취소',
4
+ extra: '선택해주세요',
5
+ }
@@ -0,0 +1,5 @@
1
+ export default {
2
+ okText: 'Ok',
3
+ dismissText: 'Cancelar',
4
+ extra: 'Selecione',
5
+ }
@@ -0,0 +1,5 @@
1
+ export default {
2
+ okText: 'Ок',
3
+ dismissText: 'Отмена',
4
+ extra: '',
5
+ }
@@ -0,0 +1,5 @@
1
+ export default {
2
+ okText: 'Ok',
3
+ dismissText: 'Avbryt',
4
+ extra: 'vänligen välj',
5
+ }
@@ -0,0 +1,5 @@
1
+ export default {
2
+ okText: '确定',
3
+ dismissText: '取消',
4
+ extra: '请选择',
5
+ }
@@ -0,0 +1,57 @@
1
+ import { StyleSheet, TextStyle, ViewStyle } from 'react-native'
2
+
3
+ export interface PickerStyle {
4
+ modal: ViewStyle
5
+ container: ViewStyle
6
+ header: ViewStyle
7
+ headerItem: ViewStyle
8
+ actionText: TextStyle
9
+ title: TextStyle
10
+ okText: TextStyle
11
+ dismissText: TextStyle
12
+ maskColor:ViewStyle
13
+ okView:ViewStyle
14
+ dismissView:ViewStyle
15
+ }
16
+
17
+ export default () =>
18
+ StyleSheet.create<PickerStyle>({
19
+ modal: {
20
+ flex: 1,
21
+ flexDirection: 'column',
22
+ justifyContent: 'flex-end',
23
+ // backgroundColor: 'rgba(0,0,0,.6)'
24
+ },
25
+ container: {},
26
+ header: {
27
+ height: 44,
28
+ alignItems: 'center',
29
+ flexDirection: 'row',
30
+ justifyContent: 'center',
31
+ borderBottomWidth: 1,
32
+ borderBottomColor: '#e7e7e7',
33
+ },
34
+ headerItem: {
35
+ height: 44,
36
+ flex: 1,
37
+ alignItems: 'center',
38
+ justifyContent: 'center',
39
+ },
40
+ actionText: {
41
+ color: '#0ae',
42
+ fontSize: 18,
43
+ textAlign: 'center',
44
+ },
45
+ okText: {},
46
+ okView:{},
47
+ dismissText: {},
48
+ dismissView:{},
49
+ title: {
50
+ color: '#666',
51
+ fontSize: 18,
52
+ textAlign: 'center',
53
+ },
54
+ maskColor:{
55
+ backgroundColor: 'rgba(0,0,0,.6)'
56
+ }
57
+ })
@@ -0,0 +1,37 @@
1
+ import type { ReactNode } from 'react'
2
+ import { StyleProp, TextStyle, ViewStyle } from 'react-native'
3
+
4
+ export type PickerValue = string | number
5
+
6
+ export type PickerValueExtend = {
7
+ columns: PickerColumn[]
8
+ items: (PickerColumnItem | undefined)[]
9
+ }
10
+
11
+ export type PickerColumnItem = {
12
+ label: string | ReactNode
13
+ value: string | number
14
+ key?: string | number
15
+ children?: PickerColumnItem[]
16
+ }
17
+
18
+ export type PickerColumn = PickerColumnItem[]
19
+
20
+ export interface PickerViewPropsType {
21
+ value?: PickerValue[]
22
+ defaultValue?: PickerValue[]
23
+ data: PickerColumn | PickerColumn[]
24
+ cols?: number
25
+ cascade?: boolean
26
+ loading?: boolean
27
+ loadingContent?: ReactNode
28
+ numberOfLines?: number
29
+ style?: StyleProp<ViewStyle>
30
+ itemStyle?: StyleProp<TextStyle>
31
+ itemHeight?: number
32
+ indicatorStyle?: StyleProp<ViewStyle>
33
+ onChange?: (value: PickerValue[], extend: PickerValueExtend) => void
34
+ renderLabel?: (item: PickerColumnItem, index: number) => ReactNode
35
+ renderMaskTop?: () => ReactNode
36
+ renderMaskBottom?: () => ReactNode
37
+ }
@@ -0,0 +1,200 @@
1
+ import type { ReactNode } from 'react'
2
+ import React from 'react'
3
+ import {
4
+ NativeScrollEvent,
5
+ NativeSyntheticEvent,
6
+ Platform,
7
+ ScrollView,
8
+ View,
9
+ } from 'react-native'
10
+
11
+ type ColumnItem = {
12
+ label: string | ReactNode
13
+ value: string | number
14
+ }
15
+ type Value = string | number
16
+
17
+ type Props = {
18
+ index: number
19
+ column: ColumnItem[]
20
+ value?: Value
21
+ onSelect: (value: Value, index: number) => void
22
+ renderLabel: (item: ColumnItem, index: number) => ReactNode
23
+ itemHeight: number
24
+ wheelHeight: number
25
+ }
26
+
27
+ class Wheel extends React.Component<Props> {
28
+ scrollerRef: any
29
+
30
+ scrollBuffer: number
31
+
32
+ selectValue: any
33
+ isScrolling: boolean
34
+
35
+ componentDidMount() {
36
+ const { value, column, itemHeight } = this.props
37
+ setTimeout(() => {
38
+ this.scrollTo(this.getSelectIndex(column, value) * itemHeight)
39
+ })
40
+ }
41
+
42
+ shouldComponentUpdate(nextProps: Props) {
43
+ const { value, column, itemHeight, wheelHeight } = nextProps
44
+ if (
45
+ value !== this.props.value ||
46
+ itemHeight !== this.props.itemHeight ||
47
+ wheelHeight !== this.props.wheelHeight
48
+ ) {
49
+ this.scrollTo(this.getSelectIndex(column, value) * itemHeight)
50
+ return true
51
+ }
52
+ return column !== this.props.column
53
+ }
54
+
55
+ componentDidUpdate(prevProps: Props) {
56
+ const { column } = prevProps
57
+ if (column !== this.props.column) {
58
+ this.scrollTo(
59
+ this.getSelectIndex(this.props.column, this.props.value) *
60
+ this.props.itemHeight,
61
+ )
62
+ }
63
+ }
64
+
65
+ scrollTo = (y: any) => {
66
+ this.scrollerRef?.scrollTo?.({
67
+ y,
68
+ animated: false,
69
+ })
70
+ }
71
+
72
+ getSelectIndex(column: ColumnItem[], value?: Value) {
73
+ return Math.max(
74
+ column.findIndex((item) => item.value === value),
75
+ 0,
76
+ )
77
+ }
78
+
79
+ handleSelect = () => {
80
+ if (this.props.value !== this.selectValue && this.props.onSelect) {
81
+ this.props.onSelect(this.selectValue, this.props.index)
82
+ }
83
+
84
+ setTimeout(() => {
85
+ this.scrollTo(
86
+ this.getSelectIndex(this.props.column, this.props.value) *
87
+ this.props.itemHeight,
88
+ )
89
+ })
90
+ }
91
+
92
+ onScrollEndForWeb = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
93
+ e.persist?.()
94
+ let contentOffset = e.nativeEvent.contentOffset
95
+ // android/web hack
96
+ if (!contentOffset) {
97
+ //@ts-ignore
98
+ const { position } = e.nativeEvent
99
+ contentOffset = {
100
+ x: 0,
101
+ y: position * this.props.itemHeight,
102
+ }
103
+ }
104
+
105
+ const selectIndex = Math.round(contentOffset.y / this.props.itemHeight)
106
+ if (this.props.column[selectIndex]) {
107
+ this.selectValue = this.props.column[selectIndex].value
108
+ if (!this.isScrolling) {
109
+ this.updateSelectThrottle()
110
+ }
111
+ }
112
+ }
113
+
114
+ /*** for web event ***/
115
+ onTouchStartForWeb = () => {
116
+ this.isScrolling = true
117
+ }
118
+ onTouchEndForWeb = () => {
119
+ this.isScrolling = false
120
+ this.updateSelectThrottle()
121
+ }
122
+ onScrollForWeb = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
123
+ this.onScrollEndForWeb(e)
124
+ }
125
+ updateSelectThrottle = () => {
126
+ clearTimeout(this.scrollBuffer)
127
+ this.scrollBuffer = setTimeout(() => {
128
+ this.handleSelect()
129
+ }, 100) //idle time
130
+ }
131
+
132
+ onMomentumScrollBegin = () => {
133
+ this.isScrolling = true
134
+ }
135
+ onMomentumScrollEnd = (e: NativeSyntheticEvent<NativeScrollEvent>) => {
136
+ e.persist?.()
137
+ if (this.isScrolling) {
138
+ let contentOffset = e.nativeEvent.contentOffset
139
+ // android/web hack
140
+ if (!contentOffset) {
141
+ //@ts-ignore
142
+ const { position } = e.nativeEvent
143
+ contentOffset = {
144
+ x: 0,
145
+ y: position * this.props.itemHeight,
146
+ }
147
+ }
148
+ const selectIndex = Math.round(contentOffset.y / this.props.itemHeight)
149
+ if (this.props.column[selectIndex]) {
150
+ this.selectValue = this.props.column[selectIndex].value
151
+ this.handleSelect()
152
+ }
153
+ }
154
+ this.isScrolling = false
155
+ }
156
+
157
+ renderItems = () => {
158
+ const { column, renderLabel, itemHeight, wheelHeight } = this.props
159
+ return (
160
+ <View
161
+ style={{
162
+ paddingVertical: (wheelHeight - itemHeight) / 2,
163
+ }}>
164
+ {column.map((item, index) => renderLabel(item, index))}
165
+ </View>
166
+ )
167
+ }
168
+
169
+ render() {
170
+ return (
171
+ <ScrollView
172
+ style={{ flex: 1 }}
173
+ nestedScrollEnabled
174
+ horizontal={false}
175
+ ref={(el: any) => (this.scrollerRef = el)}
176
+ showsHorizontalScrollIndicator={false}
177
+ showsVerticalScrollIndicator={false}
178
+ pagingEnabled={false}
179
+ automaticallyAdjustContentInsets={false}
180
+ directionalLockEnabled={true}
181
+ decelerationRate="fast"
182
+ snapToInterval={this.props.itemHeight}
183
+ {...(Platform.OS === 'web'
184
+ ? {
185
+ onTouchStart: this.onTouchStartForWeb,
186
+ onTouchEnd: this.onTouchEndForWeb,
187
+ onScroll: this.onScrollForWeb,
188
+ scrollEventThrottle: 16,
189
+ }
190
+ : {
191
+ onMomentumScrollBegin: this.onMomentumScrollBegin,
192
+ onMomentumScrollEnd: this.onMomentumScrollEnd,
193
+ })}>
194
+ {this.renderItems()}
195
+ </ScrollView>
196
+ )
197
+ }
198
+ }
199
+
200
+ export default Wheel
@@ -0,0 +1,86 @@
1
+ import { PickerColumn, PickerValue } from './PropsType'
2
+
3
+ export function getColumns(
4
+ d: PickerColumn | PickerColumn[],
5
+ val: PickerValue[],
6
+ cols: number,
7
+ cascade: boolean,
8
+ ): PickerColumn[] {
9
+ if (!d || d.length === 0) {
10
+ return []
11
+ }
12
+
13
+ if (!cascade) {
14
+ // when d is PickerColumn
15
+ if (!Array.isArray(d[0])) {
16
+ return [d as PickerColumn]
17
+ }
18
+ // when d is PickerColumn[]
19
+ return (d as PickerColumn[]).slice(0, cols!)
20
+ }
21
+
22
+ // cascade data
23
+ const columns = []
24
+ let currentOptions = (d as PickerColumn).slice()
25
+ let selected = val || []
26
+ let i = 0
27
+ while (i < cols!) {
28
+ columns.push(
29
+ currentOptions.map((option: any) => ({
30
+ label: option.label,
31
+ value: option.value,
32
+ })),
33
+ )
34
+ const x = selected[i]
35
+ const targetOptions =
36
+ currentOptions.find((option: any) => option.value === x) ||
37
+ currentOptions[0]
38
+ if (!targetOptions.children) {
39
+ break
40
+ }
41
+ currentOptions = targetOptions.children
42
+ i++
43
+ }
44
+ return columns
45
+ }
46
+
47
+ export function getValueExtend(
48
+ d: PickerColumn | PickerColumn[],
49
+ val: PickerValue[],
50
+ cols: number,
51
+ cascade: boolean,
52
+ ) {
53
+ if (!d || d.length === 0) {
54
+ return { nextValue: [], extend: [] }
55
+ }
56
+
57
+ if (!cascade) {
58
+ const columns = getColumns(d, val, cols, false).map(
59
+ (column: PickerColumn, index: number) =>
60
+ column.find((item) => item.value === val[index]) ?? column[0],
61
+ )
62
+
63
+ return { nextValue: columns.map((item) => item.value), extend: columns }
64
+ }
65
+
66
+ // cascade data
67
+ let currentOptions = (d as PickerColumn).slice()
68
+ const nextValue = []
69
+ const extend = []
70
+ let selected = val || []
71
+ let i = 0
72
+ while (i < cols!) {
73
+ const x = selected[i]
74
+ const targetOptions =
75
+ currentOptions.find((option: any) => option.value === x) ||
76
+ currentOptions[0]
77
+ nextValue[i] = targetOptions.value
78
+ extend[i] = targetOptions
79
+ if (!targetOptions.children) {
80
+ break
81
+ }
82
+ currentOptions = targetOptions.children
83
+ i++
84
+ }
85
+ return { nextValue, extend }
86
+ }
@@ -0,0 +1,71 @@
1
+ ---
2
+ category: Components
3
+ type: Data Entry
4
+ title: PickerView
5
+ ---
6
+
7
+ PickerView's functions like Picker, but it is rendered directly in the area instead of the pop-up window.
8
+
9
+ ## API
10
+
11
+ ### Props
12
+
13
+ Properties | Descrition | Type | Default
14
+ -----------|------------|------|--------
15
+ | data | data source | `PickerColumn` / `PickerColumn[]` | - |
16
+ | value | Selected options | `PickerValue[]` | - |
17
+ | defaultValue | Default selected options | `PickerValue[]` | - |
18
+ | cascade | whether cascade <br/>child cascade get from `data[].children` | Boolean | `true` |
19
+ | cols | col numbers | Number | `3` |
20
+ | onChange | selected callback function, can use [rc-form](https://github.com/react-component/form) | `(value: PickerValue[], extend: PickerValueExtend) => void` | - |
21
+ | renderLabel | The function to custom rendering the label shown on a column | `(item: PickerColumnItem, index: number) => ReactNode` | `(item) => item.label` |
22
+ | loading | Should the Picker displays as loading state | Boolean | - |
23
+ | loadingContent | The loading content displayed in loading state | ReactNode | `<ActivityIndicator/>` |
24
+ | indicatorStyle | style of default Indicator | Object | - |
25
+
26
+ For the type definition of `PickerColumnItem` `PickerColumn` `PickerValue` `PickerValueExtend`, please refer to the document of [Picker](/components/picker/).
27
+
28
+ ### Custom Style
29
+
30
+ Properties | Descrition | Type | Default
31
+ -----------|------------|------|--------
32
+ | style | style | `StyleProp<ViewStyle>` | - |
33
+ | styles | Semantic DOM style | [PickerViewStyle](#pickerviewstyle-interface) | - |
34
+ | itemStyle| style to apply to each of the item labels | `StyleProp<TextStyle>` | - |
35
+ | itemHeight | Height of option item, calculated by `numberOfLines` when without value; `itemStyle` was not allowed to set `{height}` | Number | - |
36
+ | numberOfLines | Used to truncate the text with an ellipsis after computing the text layout, including line wrapping, such that the total number of lines does not exceed this number | Number | `1` |
37
+
38
+ #### PickerViewStyle interface
39
+
40
+ ```jsx
41
+ interface PickerViewStyle {
42
+ wrappper: ViewStyle
43
+ wheelWrapper: ViewStyle
44
+ mask: ViewStyle
45
+ maskTop: ViewStyle
46
+ maskMiddle: ViewStyle
47
+ maskBottom: ViewStyle
48
+ }
49
+ ```
50
+
51
+ #### Mask View
52
+
53
+ Support custom mask style, such as using the gradient component `<LinearGradient />`. Default is white translucency.
54
+
55
+ Properties | Descrition | Type | Default
56
+ -----------|------------|------|--------
57
+ | renderMaskTop | The function to custom rendering the mask top half view | `()=> ReactNode` | `<View style={{ flex: 1, backgroundColor: 'rgba(255,255,255,0.8)' }} />` |
58
+ | renderMaskBottom | The function to custom rendering the mask bottom half view | `()=> ReactNode` | `<View style={{ flex: 1, backgroundColor: 'rgba(255,255,255,0.8)' }} />` |
59
+
60
+ ## FAQ
61
+
62
+ ### On the Android platform, when using `PickerView` nested in `ScrollView`, the Picker Item cannot slide. What should I do?
63
+
64
+ Support in `5.1.3`. Set the `nestedScrollEnabled` property of `ScrollView` to `true`.
65
+
66
+ ```jsx
67
+ <ScrollView nestedScrollEnabled={true}>
68
+ ...
69
+ <PickerView />
70
+ </ScrollView>
71
+ ```