@mpxjs/webpack-plugin 2.9.62 → 2.9.65

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 (95) hide show
  1. package/lib/config.js +38 -10
  2. package/lib/index.js +1 -3
  3. package/lib/platform/style/wx/index.js +115 -66
  4. package/lib/platform/template/wx/index.js +12 -8
  5. package/lib/react/processStyles.js +1 -0
  6. package/lib/react/processTemplate.js +2 -3
  7. package/lib/react/style-helper.js +9 -7
  8. package/lib/runtime/components/react/context.ts +9 -7
  9. package/lib/runtime/components/react/dist/context.js +1 -0
  10. package/lib/runtime/components/react/dist/getInnerListeners.js +12 -1
  11. package/lib/runtime/components/react/dist/mpx-button.jsx +53 -74
  12. package/lib/runtime/components/react/dist/mpx-checkbox-group.jsx +20 -18
  13. package/lib/runtime/components/react/dist/mpx-checkbox.jsx +30 -42
  14. package/lib/runtime/components/react/dist/mpx-form.jsx +18 -15
  15. package/lib/runtime/components/react/dist/mpx-icon.jsx +15 -17
  16. package/lib/runtime/components/react/dist/mpx-image/index.jsx +36 -34
  17. package/lib/runtime/components/react/dist/mpx-image/svg.jsx +3 -1
  18. package/lib/runtime/components/react/dist/mpx-input.jsx +36 -31
  19. package/lib/runtime/components/react/dist/mpx-label.jsx +30 -37
  20. package/lib/runtime/components/react/dist/mpx-movable-area.jsx +15 -19
  21. package/lib/runtime/components/react/dist/mpx-movable-view.jsx +10 -9
  22. package/lib/runtime/components/react/dist/mpx-picker/date.jsx +2 -1
  23. package/lib/runtime/components/react/dist/mpx-picker/index.jsx +11 -10
  24. package/lib/runtime/components/react/dist/mpx-picker/multiSelector.jsx +9 -5
  25. package/lib/runtime/components/react/dist/mpx-picker/region.jsx +13 -8
  26. package/lib/runtime/components/react/dist/mpx-picker/selector.jsx +3 -2
  27. package/lib/runtime/components/react/dist/mpx-picker/time.jsx +22 -20
  28. package/lib/runtime/components/react/dist/mpx-picker-view-column.jsx +103 -10
  29. package/lib/runtime/components/react/dist/mpx-picker-view.jsx +149 -54
  30. package/lib/runtime/components/react/dist/mpx-radio-group.jsx +20 -18
  31. package/lib/runtime/components/react/dist/mpx-radio.jsx +29 -43
  32. package/lib/runtime/components/react/dist/mpx-root-portal.jsx +8 -4
  33. package/lib/runtime/components/react/dist/mpx-scroll-view.jsx +36 -27
  34. package/lib/runtime/components/react/dist/mpx-swiper/carouse.jsx +141 -75
  35. package/lib/runtime/components/react/dist/mpx-swiper/index.jsx +16 -7
  36. package/lib/runtime/components/react/dist/mpx-swiper-item.jsx +20 -11
  37. package/lib/runtime/components/react/dist/mpx-switch.jsx +18 -14
  38. package/lib/runtime/components/react/dist/mpx-text.jsx +20 -35
  39. package/lib/runtime/components/react/dist/mpx-textarea.jsx +1 -1
  40. package/lib/runtime/components/react/dist/mpx-view.jsx +296 -210
  41. package/lib/runtime/components/react/dist/mpx-web-view.jsx +11 -7
  42. package/lib/runtime/components/react/dist/parser.js +218 -0
  43. package/lib/runtime/components/react/dist/useNodesRef.js +1 -5
  44. package/lib/runtime/components/react/dist/utils.jsx +445 -0
  45. package/lib/runtime/components/react/getInnerListeners.ts +18 -8
  46. package/lib/runtime/components/react/mpx-button.tsx +83 -91
  47. package/lib/runtime/components/react/mpx-checkbox-group.tsx +50 -43
  48. package/lib/runtime/components/react/mpx-checkbox.tsx +56 -64
  49. package/lib/runtime/components/react/mpx-form.tsx +51 -22
  50. package/lib/runtime/components/react/mpx-icon.tsx +31 -27
  51. package/lib/runtime/components/react/mpx-image/index.tsx +54 -47
  52. package/lib/runtime/components/react/mpx-image/svg.tsx +5 -3
  53. package/lib/runtime/components/react/mpx-input.tsx +59 -38
  54. package/lib/runtime/components/react/mpx-label.tsx +55 -59
  55. package/lib/runtime/components/react/mpx-movable-area.tsx +40 -25
  56. package/lib/runtime/components/react/mpx-movable-view.tsx +29 -29
  57. package/lib/runtime/components/react/mpx-navigator.tsx +2 -2
  58. package/lib/runtime/components/react/mpx-picker/date.tsx +4 -4
  59. package/lib/runtime/components/react/mpx-picker/index.tsx +12 -11
  60. package/lib/runtime/components/react/mpx-picker/multiSelector.tsx +17 -13
  61. package/lib/runtime/components/react/mpx-picker/region.tsx +23 -19
  62. package/lib/runtime/components/react/mpx-picker/selector.tsx +7 -7
  63. package/lib/runtime/components/react/mpx-picker/time.tsx +29 -31
  64. package/lib/runtime/components/react/mpx-picker/type.ts +1 -1
  65. package/lib/runtime/components/react/mpx-picker-view-column.tsx +149 -20
  66. package/lib/runtime/components/react/mpx-picker-view.tsx +180 -63
  67. package/lib/runtime/components/react/mpx-radio-group.tsx +51 -47
  68. package/lib/runtime/components/react/mpx-radio.tsx +57 -72
  69. package/lib/runtime/components/react/mpx-root-portal.tsx +10 -8
  70. package/lib/runtime/components/react/mpx-scroll-view.tsx +136 -104
  71. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +175 -96
  72. package/lib/runtime/components/react/mpx-swiper/index.tsx +21 -9
  73. package/lib/runtime/components/react/mpx-swiper/type.ts +16 -5
  74. package/lib/runtime/components/react/mpx-swiper-item.tsx +48 -14
  75. package/lib/runtime/components/react/mpx-switch.tsx +46 -24
  76. package/lib/runtime/components/react/mpx-text.tsx +38 -45
  77. package/lib/runtime/components/react/mpx-textarea.tsx +1 -1
  78. package/lib/runtime/components/react/mpx-view.tsx +401 -241
  79. package/lib/runtime/components/react/mpx-web-view.tsx +22 -22
  80. package/lib/runtime/components/react/parser.ts +245 -0
  81. package/lib/runtime/components/react/types/common.ts +4 -4
  82. package/lib/runtime/components/react/types/global.d.ts +24 -2
  83. package/lib/runtime/components/react/useNodesRef.ts +1 -7
  84. package/lib/runtime/components/react/utils.tsx +524 -0
  85. package/lib/runtime/components/web/mpx-scroll-view.vue +25 -5
  86. package/lib/style-compiler/index.js +5 -4
  87. package/lib/template-compiler/compiler.js +133 -161
  88. package/lib/template-compiler/gen-node-react.js +1 -3
  89. package/lib/utils/const.js +2 -1
  90. package/lib/web/processStyles.js +2 -1
  91. package/lib/web/processTemplate.js +2 -3
  92. package/lib/wxml/loader.js +1 -1
  93. package/package.json +7 -4
  94. package/lib/runtime/components/react/dist/utils.js +0 -148
  95. package/lib/runtime/components/react/utils.ts +0 -170
@@ -1,5 +1,6 @@
1
1
  import { View } from 'react-native';
2
2
  import React, { forwardRef, useRef, useContext, useState } from 'react';
3
+ import { warn } from '@mpxjs/utils';
3
4
  import useInnerProps, { getCustomEvent } from '../getInnerListeners';
4
5
  import useNodesRef from '../useNodesRef'; // 引入辅助函数
5
6
  import Selector from './selector';
@@ -8,7 +9,6 @@ import DateSelector from './date';
8
9
  import MultiSelector from './multiSelector';
9
10
  import RegionSelector from './region';
10
11
  import { FormContext } from '../context';
11
- import { throwReactWarning } from '../utils';
12
12
  /**
13
13
  * ✔ mode
14
14
  * ✔ disabled
@@ -29,8 +29,9 @@ import { throwReactWarning } from '../utils';
29
29
  */
30
30
  const _Picker = forwardRef((props, ref) => {
31
31
  const { mode = 'selector', value, bindcancel, bindchange, children, bindcolumnchange } = props;
32
- let innerLayout = useRef({});
33
- const { nodeRef } = useNodesRef(props, ref, {});
32
+ const innerLayout = useRef({});
33
+ const nodeRef = useRef(null);
34
+ useNodesRef(props, ref, nodeRef, {});
34
35
  const innerProps = useInnerProps(props, {
35
36
  ref: nodeRef
36
37
  }, [], { layoutRef: innerLayout });
@@ -57,7 +58,7 @@ const _Picker = forwardRef((props, ref) => {
57
58
  };
58
59
  if (formValuesMap) {
59
60
  if (!props.name) {
60
- throwReactWarning('[Mpx runtime warn]: If a form component is used, the name attribute is required.');
61
+ warn('If a form component is used, the name attribute is required.');
61
62
  }
62
63
  else {
63
64
  formValuesMap.set(props.name, { getValue, resetValue });
@@ -88,26 +89,26 @@ const _Picker = forwardRef((props, ref) => {
88
89
  const selectorProps = {
89
90
  ...commonProps,
90
91
  value: pickerValue,
91
- range: props['range'],
92
+ range: props.range,
92
93
  'range-key': props['range-key']
93
94
  };
94
95
  const multiProps = {
95
96
  ...commonProps,
96
97
  value: pickerValue,
97
- range: props['range'],
98
+ range: props.range,
98
99
  'range-key': props['range-key']
99
100
  };
100
101
  const timeProps = {
101
102
  ...commonProps,
102
103
  value: pickerValue,
103
- start: props['start'],
104
- end: props['end']
104
+ start: props.start,
105
+ end: props.end
105
106
  };
106
107
  const dateProps = {
107
108
  ...commonProps,
108
109
  value: pickerValue,
109
- start: props['start'],
110
- end: props['end'],
110
+ start: props.start,
111
+ end: props.end,
111
112
  fileds: props.fields || 'day'
112
113
  };
113
114
  const regionProps = {
@@ -17,7 +17,7 @@ function formatRangeFun(range = [], rangeKey) {
17
17
  });
18
18
  let tmp = result;
19
19
  for (let i = 1; i < range.length; i++) {
20
- let child = Array.isArray(range[i]) ? range[i] : [];
20
+ const child = Array.isArray(range[i]) ? range[i] : [];
21
21
  const nextColData = child.map(item => {
22
22
  return convertToObj(item, rangeKey);
23
23
  });
@@ -44,7 +44,7 @@ function getIndexByValues(range = [], value = []) {
44
44
  function getInnerValueByIndex(range = [], value = []) {
45
45
  let tmp = range;
46
46
  return value.map(v => {
47
- let current = tmp[v].value;
47
+ const current = tmp[v].value;
48
48
  tmp = tmp[v].children;
49
49
  return current;
50
50
  });
@@ -60,6 +60,7 @@ function getColumnIndexByValue(range = [], column, value = []) {
60
60
  if (ritem.value === item) {
61
61
  changeIndex = rindex;
62
62
  }
63
+ return ritem;
63
64
  });
64
65
  }
65
66
  else {
@@ -67,23 +68,26 @@ function getColumnIndexByValue(range = [], column, value = []) {
67
68
  if (citem.value === item) {
68
69
  tmpRange = citem.children;
69
70
  }
71
+ return citem;
70
72
  });
71
73
  curRange = tmpRange;
72
74
  }
75
+ return item;
73
76
  });
74
77
  return changeIndex;
75
78
  }
76
79
  const _MultiSelectorPicker = forwardRef((props, ref) => {
77
80
  const { range, value, disabled, bindchange, bindcancel, children, bindcolumnchange } = props;
78
- let formatRange = formatRangeFun(range, props['range-key']);
79
- let initValue = getInnerValueByIndex(formatRange, value);
81
+ const formatRange = formatRangeFun(range, props['range-key']);
82
+ const initValue = getInnerValueByIndex(formatRange, value);
80
83
  // 选中的索引值
81
84
  const [selected, setSelected] = useState(initValue);
82
85
  // range数据源
83
86
  const [data, setData] = useState(formatRange || []);
84
87
  // 存储layout布局信息
85
88
  const layoutRef = useRef({});
86
- const { nodeRef: viewRef } = useNodesRef(props, ref, {});
89
+ const viewRef = useRef(null);
90
+ useNodesRef(props, ref, viewRef, {});
87
91
  useEffect(() => {
88
92
  if (range) {
89
93
  const newFormatRange = formatRangeFun(range, props['range-key']);
@@ -5,6 +5,8 @@ import React, { forwardRef, useState, useRef } from 'react';
5
5
  import useNodesRef from '../useNodesRef'; // 引入辅助函数
6
6
  function formateRegionData(clObj = [], customItem, depth = 2) {
7
7
  const l = depth;
8
+ // 'PickerData[]' is not assignable to type 'PickerColumn | PickerColumn[]'.
9
+ // const obj: PickerColumnItem[] = []
8
10
  const obj = [];
9
11
  if (customItem) {
10
12
  const objClone = {
@@ -23,7 +25,7 @@ function formateRegionData(clObj = [], customItem, depth = 2) {
23
25
  for (let i = 0; i < clObj.length; i++) {
24
26
  const region = {
25
27
  value: clObj[i].value,
26
- label: clObj[i].value,
28
+ label: clObj[i].value
27
29
  };
28
30
  if (clObj[i].children) {
29
31
  region.children = formateRegionData(clObj[i].children, customItem, l - 1);
@@ -34,11 +36,12 @@ function formateRegionData(clObj = [], customItem, depth = 2) {
34
36
  }
35
37
  const _RegionPicker = forwardRef((props, ref) => {
36
38
  const { children, value, bindchange, bindcancel, disabled } = props;
37
- let formatRegionData = formateRegionData(regionData, props['custom-item']);
39
+ const formatRegionData = formateRegionData(regionData, props['custom-item']);
38
40
  const [regionvalue, setRegionValue] = useState(value);
39
41
  // 存储layout布局信息
40
42
  const layoutRef = useRef({});
41
- const { nodeRef: viewRef } = useNodesRef(props, ref, {});
43
+ const viewRef = useRef(null);
44
+ useNodesRef(props, ref, viewRef, {});
42
45
  const onChange = (value) => {
43
46
  // 通过 value 查找 code
44
47
  let tmp = regionData;
@@ -52,6 +55,7 @@ const _RegionPicker = forwardRef((props, ref) => {
52
55
  return code;
53
56
  }
54
57
  }
58
+ return item;
55
59
  }).filter(code => !!code);
56
60
  const detail = { value, code };
57
61
  if (postcode[2])
@@ -67,24 +71,25 @@ const _RegionPicker = forwardRef((props, ref) => {
67
71
  props.getInnerLayout && props.getInnerLayout(layoutRef);
68
72
  });
69
73
  };
74
+ const onDismiss = () => {
75
+ bindcancel && bindcancel();
76
+ };
70
77
  const regionProps = {
71
78
  data: formatRegionData,
72
79
  value: regionvalue,
73
80
  onChange,
74
81
  disabled,
75
- onDismiss: bindcancel && bindcancel
82
+ onDismiss
76
83
  };
77
84
  const touchProps = {
78
85
  onLayout: onElementLayout,
79
86
  ref: viewRef
80
87
  };
81
- return (
82
- // @ts-ignore
83
- <Picker {...regionProps}>
88
+ return (<Picker {...regionProps}>
84
89
  <TouchableWithoutFeedback>
85
90
  <View {...touchProps}>{children}</View>
86
91
  </TouchableWithoutFeedback>
87
92
  </Picker>);
88
93
  });
89
- _RegionPicker.displayName === 'mpx-picker-region';
94
+ _RegionPicker.displayName = 'mpx-picker-region';
90
95
  export default _RegionPicker;
@@ -20,14 +20,15 @@ const formatRangeFun = (range, rangeKey = '') => {
20
20
  const _SelectorPicker = forwardRef((props, ref) => {
21
21
  const { range, children, value, disabled, bindchange, bindcancel } = props;
22
22
  // 格式化数据为Array<*>
23
- let formatRange = formatRangeFun(range, props['range-key']);
23
+ const formatRange = formatRangeFun(range, props['range-key']);
24
24
  // 选中的索引值
25
25
  const [selected, setSelected] = useState(value || 0);
26
26
  // range数据源
27
27
  const [data, setData] = useState(formatRange || []);
28
28
  // 存储layout布局信息
29
29
  const layoutRef = useRef({});
30
- const { nodeRef: viewRef } = useNodesRef(props, ref, {});
30
+ const viewRef = useRef(null);
31
+ useNodesRef(props, ref, viewRef, {});
31
32
  useEffect(() => {
32
33
  if (range) {
33
34
  const newFormatRange = formatRangeFun(range, props['range-key']);
@@ -6,47 +6,47 @@ import useNodesRef from '../useNodesRef'; // 引入辅助函数
6
6
  // const { height: dHeight, width: dWidth } = Dimensions.get('window');
7
7
  // modal属性: {"height": 298.33331298828125, "offsetLeft": 0, "offsetTop": 513.6666870117188, "width": 375, "x": 0, "y": 513.6666870117188}
8
8
  // const { height: sHeight, width: sWidth } = Dimensions.get('screen');
9
- // 设备屏幕的大小。 screen
9
+ // 设备屏幕的大小。 screen
10
10
  const styles = {
11
11
  showModal: {
12
- backgroundColor: "black",
12
+ backgroundColor: 'black',
13
13
  opacity: 0.5,
14
- position: "absolute",
15
- width: "100%"
14
+ position: 'absolute',
15
+ width: '100%'
16
16
  },
17
17
  hideModal: {
18
18
  opacity: 1,
19
19
  height: 0
20
20
  },
21
21
  modal: {
22
- backgroundColor: "black",
22
+ backgroundColor: 'black',
23
23
  opacity: 0.5
24
24
  },
25
25
  centeredView: {
26
26
  position: 'absolute',
27
27
  bottom: 0,
28
- width: "100%",
28
+ width: '100%',
29
29
  overflow: 'scroll'
30
30
  },
31
31
  btnLine: {
32
- width: "100%",
32
+ width: '100%',
33
33
  flex: 1,
34
- flexDirection: "row",
35
- justifyContent: "space-between",
34
+ flexDirection: 'row',
35
+ justifyContent: 'space-between',
36
36
  borderColor: 20,
37
37
  borderBottomWidth: 1,
38
- backgroundColor: "white",
38
+ backgroundColor: 'white',
39
39
  paddingLeft: 40,
40
40
  paddingRight: 40
41
41
  },
42
42
  cancel: {
43
43
  height: 50,
44
- display: "flex",
44
+ display: 'flex',
45
45
  justifyContent: 'center'
46
46
  },
47
47
  ok: {
48
48
  height: 50,
49
- display: "flex",
49
+ display: 'flex',
50
50
  justifyContent: 'center'
51
51
  },
52
52
  btntext: {
@@ -55,7 +55,7 @@ const styles = {
55
55
  }
56
56
  };
57
57
  function formatStrToInt(timestr) {
58
- let [start, end] = timestr.split(':');
58
+ const [start, end] = timestr.split(':');
59
59
  return [parseInt(start), parseInt(end)];
60
60
  }
61
61
  // [9, 59] to 09:59
@@ -70,9 +70,9 @@ function formatStr(arr) {
70
70
  return hour + ':' + minute;
71
71
  }
72
72
  function generateMinute() {
73
- let arrMinute = [];
73
+ const arrMinute = [];
74
74
  for (let i = 0; i <= 59; i++) {
75
- let obj = {
75
+ const obj = {
76
76
  label: toSingleStr(i),
77
77
  value: i,
78
78
  children: []
@@ -82,9 +82,9 @@ function generateMinute() {
82
82
  return arrMinute;
83
83
  }
84
84
  function generateColumns() {
85
- let pickData = [];
85
+ const pickData = [];
86
86
  for (let i = 0; i <= 23; i++) {
87
- let obj = {
87
+ const obj = {
88
88
  label: toSingleStr(i),
89
89
  value: i,
90
90
  children: generateMinute()
@@ -126,10 +126,12 @@ const _TimePicker = forwardRef((props, ref) => {
126
126
  const [timevalue, setTimeValue] = useState(defaultValue);
127
127
  // 存储layout布局信息
128
128
  const layoutRef = useRef({});
129
- const { nodeRef: viewRef } = useNodesRef(props, ref, {});
129
+ const viewRef = useRef(null);
130
+ useNodesRef(props, ref, viewRef, {});
130
131
  // 存储modal的布局信息
131
132
  const modalLayoutRef = useRef({});
132
- const { nodeRef: modalRef } = useNodesRef(props, ref, {});
133
+ const modalRef = useRef(null);
134
+ useNodesRef(props, ref, modalRef, {});
133
135
  const [visible, setVisible] = useState(false);
134
136
  const columnData = generateColumns();
135
137
  const [data, setData] = useState(columnData);
@@ -228,7 +230,7 @@ const _TimePicker = forwardRef((props, ref) => {
228
230
  </TouchableWithoutFeedback>
229
231
  </View>;
230
232
  };
231
- const strStyle = visible ? styles['showModal'] : styles['hideModal'];
233
+ const strStyle = visible ? styles.showModal : styles.hideModal;
232
234
  const mheight = Math.floor(offsetTop);
233
235
  // Animated.View
234
236
  return (<>
@@ -1,15 +1,108 @@
1
- import { View } from 'react-native';
2
- import React, { forwardRef, useRef } from 'react';
3
- import useInnerProps from './getInnerListeners';
1
+ import { View, Animated, SafeAreaView } from 'react-native';
2
+ import React, { forwardRef, useRef, useState, useEffect } from 'react';
3
+ import { useTransformStyle, splitStyle, splitProps, wrapChildren, useLayout } from './utils';
4
4
  import useNodesRef from './useNodesRef'; // 引入辅助函数
5
+ const defaultItemHeight = 36;
6
+ // 每个Column 都有个外层的高度, 内部的元素高度
7
+ // 默认的高度
5
8
  const _PickerViewColumn = forwardRef((props, ref) => {
6
- const { children } = props;
7
- const layoutRef = useRef({});
8
- const { nodeRef } = useNodesRef(props, ref, {});
9
- const innerProps = useInnerProps(props, {}, [], { layoutRef });
10
- return (<View ref={nodeRef} {...innerProps}>
11
- {children}
12
- </View>);
9
+ const { children, selectedIndex, onColumnLayoutChange, onSelectChange, getInnerLayout, style, wrapperStyle, 'enable-var': enableVar, 'external-var-context': externalVarContext } = props;
10
+ // PickerViewColumn
11
+ const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext });
12
+ const { textStyle } = splitStyle(normalStyle);
13
+ const { textProps } = splitProps(props);
14
+ // const { innerStyle } = splitStyle(normalStyle)
15
+ // scrollView的ref
16
+ const scrollViewRef = useRef(null);
17
+ useNodesRef(props, ref, scrollViewRef, {});
18
+ // 每个元素的高度
19
+ let [itemH, setItemH] = useState(0);
20
+ useEffect(() => {
21
+ if (selectedIndex && itemH) {
22
+ const offsetY = selectedIndex * itemH;
23
+ scrollViewRef.current?.scrollTo({ x: 0, y: offsetY, animated: true });
24
+ }
25
+ }, [selectedIndex, itemH]);
26
+ const onScrollViewLayout = () => {
27
+ getInnerLayout && getInnerLayout(layoutRef);
28
+ };
29
+ const {
30
+ // 存储layout布局信息
31
+ layoutRef, layoutProps } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: scrollViewRef, onLayout: onScrollViewLayout });
32
+ const onItemLayout = (e) => {
33
+ const layout = e.nativeEvent.layout;
34
+ if (layout.height && itemH !== layout.height) {
35
+ itemH = layout.height;
36
+ setItemH(layout.height);
37
+ onColumnLayoutChange && onColumnLayoutChange({ height: layout.height * 5 });
38
+ }
39
+ };
40
+ const onMomentumScrollEnd = (e) => {
41
+ if (scrollViewRef && itemH) {
42
+ const { y: scrollY } = e.nativeEvent.contentOffset;
43
+ const selIndex = Math.floor(scrollY / itemH);
44
+ onSelectChange(selIndex);
45
+ }
46
+ };
47
+ const renderInnerchild = () => {
48
+ // Fragment 节点
49
+ let realElement = [];
50
+ const getRealChilds = () => {
51
+ if (Array.isArray(children)) {
52
+ realElement = children;
53
+ }
54
+ else {
55
+ const tempChild = children;
56
+ if (tempChild.props.children && tempChild.props.children) {
57
+ realElement = tempChild.props.children;
58
+ }
59
+ else {
60
+ realElement = [children];
61
+ }
62
+ }
63
+ return realElement;
64
+ };
65
+ const realChilds = getRealChilds();
66
+ const arrChild = realChilds.map((item, index) => {
67
+ const InnerProps = index === 0 ? { onLayout: onItemLayout } : {};
68
+ const strKey = 'picker' + props.prefix + '-column' + index;
69
+ const arrHeight = (wrapperStyle.itemHeight + '').match(/\d+/g) || [];
70
+ const iHeight = (arrHeight[0] || defaultItemHeight);
71
+ return <View key={strKey} {...InnerProps} style={[{ height: iHeight, width: '100%' }]}>
72
+ {wrapChildren({
73
+ children: item
74
+ }, {
75
+ hasVarDec,
76
+ varContext: varContextRef.current,
77
+ textStyle,
78
+ textProps
79
+ })}
80
+ </View>;
81
+ });
82
+ const totalHeight = itemH * 5;
83
+ if (wrapperStyle.height && totalHeight !== wrapperStyle.height) {
84
+ const fix = Math.ceil((totalHeight - wrapperStyle.height) / 2);
85
+ arrChild.unshift(<View key="picker-column-0" style={[{ height: itemH - fix }]}></View>);
86
+ arrChild.unshift(<View key="picker-column-1" style={[{ height: itemH }]}></View>);
87
+ arrChild.push(<View key="picker-column-2" style={[{ height: itemH }]}></View>);
88
+ arrChild.push(<View key="picker-column-3" style={[{ height: itemH - fix }]}></View>);
89
+ }
90
+ else {
91
+ arrChild.unshift(<View key="picker-column-0" style={[{ height: itemH }]}></View>);
92
+ arrChild.unshift(<View key="picker-column-1" style={[{ height: itemH }]}></View>);
93
+ arrChild.push(<View key="picker-column-2" style={[{ height: itemH }]}></View>);
94
+ arrChild.push(<View key="picker-column-3" style={[{ height: itemH }]}></View>);
95
+ }
96
+ return arrChild;
97
+ };
98
+ const renderScollView = () => {
99
+ return (<Animated.ScrollView horizontal={false} ref={scrollViewRef} bounces={false} scrollsToTop={false} removeClippedSubviews={true} showsHorizontalScrollIndicator={false} showsVerticalScrollIndicator={false} pagingEnabled={false} snapToInterval={itemH} automaticallyAdjustContentInsets={false} {...layoutProps} onMomentumScrollEnd={onMomentumScrollEnd}>
100
+ {renderInnerchild()}
101
+ </Animated.ScrollView>);
102
+ };
103
+ return (<SafeAreaView style={[{ display: 'flex', flex: 1 }]}>
104
+ {renderScollView()}
105
+ </SafeAreaView>);
13
106
  });
14
107
  _PickerViewColumn.displayName = 'mpx-picker-view-column';
15
108
  export default _PickerViewColumn;
@@ -1,68 +1,163 @@
1
- import React, { forwardRef, useState, useRef, useEffect } from 'react';
2
- import { PickerView } from '@ant-design/react-native';
3
- import useInnerProps from './getInnerListeners';
4
- import { getCustomEvent } from './getInnerListeners';
1
+ import { View } from 'react-native';
2
+ import { LinearGradient } from 'react-native-linear-gradient';
3
+ import React, { forwardRef, useState, useRef } from 'react';
4
+ import useInnerProps, { getCustomEvent } from './getInnerListeners';
5
5
  import useNodesRef from './useNodesRef'; // 引入辅助函数
6
+ import { parseInlineStyle, useTransformStyle, splitStyle, splitProps, useLayout, wrapChildren } from './utils';
7
+ const styles = {
8
+ wrapper: {
9
+ display: 'flex',
10
+ flex: 1,
11
+ flexDirection: 'row',
12
+ justifyContent: 'space-around',
13
+ overflow: 'hidden',
14
+ alignItems: 'center'
15
+ },
16
+ maskTop: {
17
+ position: 'absolute',
18
+ width: 1000,
19
+ zIndex: 100
20
+ },
21
+ maskBottom: {
22
+ position: 'absolute',
23
+ width: 1000,
24
+ zIndex: 100
25
+ }
26
+ };
6
27
  const _PickerView = forwardRef((props, ref) => {
7
- const { children, ...restProps } = props;
8
- const layoutRef = useRef({});
9
- const { nodeRef } = useNodesRef(props, ref, {});
10
- const [value, setValue] = useState(props.value);
11
- useEffect(() => {
12
- // 确认这个是变化的props变化的时候才执行,还是初始化的时候就执行
13
- setValue(props.value);
14
- }, [props.value]);
15
- const onLayout = () => {
16
- nodeRef.current?.measure((x, y, width, height, offsetLeft, offsetTop) => {
17
- layoutRef.current = { x, y, width, height, offsetLeft, offsetTop };
18
- });
28
+ const { children, value = [], bindchange, style, 'enable-var': enableVar, 'external-var-context': externalVarContext } = props;
29
+ // indicatorStyle 需要转换为rn的style
30
+ // 微信设置到pick-view上上设置的normalStyle如border等需要转换成RN的style然后进行透传
31
+ const indicatorStyle = parseInlineStyle(props['indicator-style']);
32
+ const { height: indicatorH, width: indicatorW } = indicatorStyle;
33
+ const nodeRef = useRef(null);
34
+ useNodesRef(props, ref, nodeRef, {});
35
+ // picker-view 设置的color等textStyle,在小程序上的表现是可以继承到最内层的text样式, 但是RN内部column是slot无法设置, 需要业务自己在column内的元素上设置
36
+ const { normalStyle, hasVarDec, varContextRef, hasSelfPercent, setWidth, setHeight } = useTransformStyle(style, { enableVar, externalVarContext });
37
+ const { textStyle } = splitStyle(normalStyle);
38
+ const { textProps } = splitProps(props);
39
+ const {
40
+ // 存储layout布局信息
41
+ layoutRef, layoutProps, layoutStyle } = useLayout({ props, hasSelfPercent, setWidth, setHeight, nodeRef: nodeRef });
42
+ const isSetW = indicatorW !== undefined ? 1 : 0;
43
+ const cloneRef = useRef(null);
44
+ const maskPos = {};
45
+ let [pickH, setPickH] = useState(0);
46
+ const itemH = pickH / 5;
47
+ if (normalStyle?.height && pickH && pickH !== normalStyle?.height) {
48
+ maskPos.height = itemH * 2 + Math.ceil((normalStyle.height - pickH) / 2);
49
+ }
50
+ else {
51
+ maskPos.height = itemH * 2;
52
+ }
53
+ const onColumnLayoutChange = (layoutConfig) => {
54
+ pickH = layoutConfig.height;
55
+ setPickH(layoutConfig.height);
19
56
  };
20
- const innerProps = useInnerProps(props, {}, [], { layoutRef });
21
- const onChange = (val) => {
22
- const eventData = getCustomEvent('change', {}, { detail: { value: val, source: 'touch' }, layoutRef: layoutRef });
23
- setValue(val);
24
- props.bindchange && props.bindchange(eventData);
57
+ const onSelectChange = (columnIndex, selIndex) => {
58
+ const changeValue = value.slice();
59
+ changeValue[columnIndex] = selIndex;
60
+ const eventData = getCustomEvent('change', {}, { detail: { value: changeValue, source: 'change' }, layoutRef });
61
+ bindchange && bindchange(eventData);
25
62
  };
26
- const joinString = (data) => {
27
- return (Array.isArray(data) ? data : [data]).join('');
63
+ const innerProps = useInnerProps(props, {
64
+ ref: nodeRef,
65
+ style: {
66
+ ...normalStyle,
67
+ ...layoutStyle,
68
+ position: 'relative',
69
+ overflow: 'hidden'
70
+ },
71
+ ...layoutProps
72
+ }, [
73
+ 'enable-offset'
74
+ ], { layoutRef });
75
+ const cloneChild = (child, index) => {
76
+ // const extraProps = index === 0 ? { getInnerLayout: getInnerLayout, innerProps } : {}
77
+ const extraProps = {};
78
+ const childProps = {
79
+ ...child?.props,
80
+ ref: cloneRef,
81
+ prefix: index,
82
+ key: 'pick-view' + index,
83
+ wrapperStyle: {
84
+ height: normalStyle?.height || 0,
85
+ itemHeight: indicatorH || 0
86
+ },
87
+ onColumnLayoutChange,
88
+ onSelectChange: onSelectChange.bind(null, index),
89
+ selectedIndex: value?.[index] || 0,
90
+ ...extraProps
91
+ };
92
+ const realElement = React.cloneElement(child, childProps);
93
+ return wrapChildren({
94
+ children: realElement
95
+ }, {
96
+ hasVarDec,
97
+ varContext: varContextRef.current,
98
+ textStyle,
99
+ textProps
100
+ });
28
101
  };
29
- const getLabelFromChildren = (child) => {
30
- return child.props && child.props.children ? getLabelFromChildren(child.props.children) : joinString(child);
102
+ const renderTopMask = () => {
103
+ const linearProps = {
104
+ colors: ['rgba(255,255,255,0.8)', 'rgba(255,255,255,0.2)'],
105
+ style: [
106
+ styles.maskTop,
107
+ {
108
+ height: maskPos.height,
109
+ top: 0,
110
+ pointerEvents: 'none'
111
+ }
112
+ ]
113
+ };
114
+ return (<LinearGradient {...linearProps}/>);
31
115
  };
32
- const handleChildren = (children) => {
33
- return children.map((child, index) => {
34
- return {
35
- label: getLabelFromChildren(child),
36
- value: index
37
- };
38
- });
116
+ const renderBottomMask = () => {
117
+ const linearProps = {
118
+ colors: ['rgba(255,255,255,0.2)', 'rgba(255,255,255,0.8)'],
119
+ style: [
120
+ styles.maskBottom,
121
+ {
122
+ height: maskPos.height,
123
+ bottom: 0,
124
+ pointerEvents: 'none'
125
+ }
126
+ ]
127
+ };
128
+ return <LinearGradient {...linearProps}></LinearGradient>;
39
129
  };
40
- const getDataFromChildren = (children) => {
41
- return (Array.isArray(children) ? children : [children]).map((child) => {
42
- return handleChildren(child.props && child.props.children ? child.props.children : [child]);
43
- });
130
+ const renderLine = () => {
131
+ return <View style={[{
132
+ position: 'absolute',
133
+ top: '50%',
134
+ transform: [{ translateY: -(itemH / 2) }],
135
+ height: itemH,
136
+ borderTopWidth: 1,
137
+ borderBottomWidth: 1,
138
+ borderColor: '#f0f0f0',
139
+ width: '100%',
140
+ zIndex: 101
141
+ }]}></View>;
44
142
  };
45
- const columns = Array.isArray(children) ? children.length : 1;
46
- const originData = getDataFromChildren(children);
47
- // 子节点默认的序号,这里是更新默认值的
48
- const subChildLength = originData.map((item) => {
49
- return item.length;
50
- });
51
- const defaultValue = (props.value || []).map((item, index) => {
52
- if (item > subChildLength[index]) {
53
- return subChildLength[index] - 1;
143
+ const renderSubChild = () => {
144
+ if (Array.isArray(children)) {
145
+ return children.map((item, index) => {
146
+ return cloneChild(item, index);
147
+ });
54
148
  }
55
149
  else {
56
- return item;
150
+ return cloneChild(children, 0);
57
151
  }
58
- });
59
- return (<PickerView {...restProps} cols={columns}
60
- // 默认选中项
61
- defaultValue={defaultValue}
62
- // 内部维护选中项
63
- value={value}
64
- // data数据源column
65
- data={originData} onChange={onChange} cascade={false}/>);
152
+ };
153
+ return (<View {...innerProps}>
154
+ {renderTopMask()}
155
+ <View style={[styles.wrapper]}>
156
+ {renderSubChild()}
157
+ </View>
158
+ {renderBottomMask()}
159
+ {!isSetW && renderLine()}
160
+ </View>);
66
161
  });
67
162
  _PickerView.displayName = 'mpx-picker-view';
68
163
  export default _PickerView;