@tarojs/components-react 4.1.9-beta.1 → 4.1.9-beta.1-patch.2
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.
- package/dist/components/picker/index.js +22 -3
- package/dist/components/picker/index.js.map +1 -1
- package/dist/components/picker/picker-group.js +187 -81
- package/dist/components/picker/picker-group.js.map +1 -1
- package/dist/components/scroll-view/index.js +104 -30
- package/dist/components/scroll-view/index.js.map +1 -1
- package/dist/contexts/ScrollElementContext.js +6 -0
- package/dist/contexts/ScrollElementContext.js.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/original/components/picker/index.js +22 -3
- package/dist/original/components/picker/index.js.map +1 -1
- package/dist/original/components/picker/picker-group.js +187 -81
- package/dist/original/components/picker/picker-group.js.map +1 -1
- package/dist/original/components/picker/style/index.scss +146 -46
- package/dist/original/components/scroll-view/index.js +104 -30
- package/dist/original/components/scroll-view/index.js.map +1 -1
- package/dist/original/contexts/ScrollElementContext.js +6 -0
- package/dist/original/contexts/ScrollElementContext.js.map +1 -0
- package/dist/original/index.js +1 -0
- package/dist/original/index.js.map +1 -1
- package/dist/solid/components/picker/index.js +33 -14
- package/dist/solid/components/picker/index.js.map +1 -1
- package/dist/solid/components/picker/picker-group.js +188 -86
- package/dist/solid/components/picker/picker-group.js.map +1 -1
- package/dist/solid/components/scroll-view/index.js +109 -35
- package/dist/solid/components/scroll-view/index.js.map +1 -1
- package/dist/solid/contexts/ScrollElementContext.js +6 -0
- package/dist/solid/contexts/ScrollElementContext.js.map +1 -0
- package/dist/solid/index.css +1 -1
- package/package.json +6 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createComponent } from 'solid-js/web';
|
|
1
|
+
import { createComponent, mergeProps } from 'solid-js/web';
|
|
2
2
|
import { View, ScrollView } from '@tarojs/components';
|
|
3
3
|
import Taro from '@tarojs/taro';
|
|
4
4
|
import * as React from 'react';
|
|
@@ -7,27 +7,91 @@ import * as React from 'react';
|
|
|
7
7
|
const PICKER_LINE_HEIGHT = 34; // px
|
|
8
8
|
const PICKER_VISIBLE_ITEMS = 7; // 可见行数
|
|
9
9
|
const PICKER_BLANK_ITEMS = 3; // 空白行数
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
10
|
+
const getIndicatorStyle = lineColor => {
|
|
11
|
+
return {
|
|
12
|
+
borderTopColor: lineColor,
|
|
13
|
+
borderBottomColor: lineColor
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
// 大屏方案版本要求
|
|
17
|
+
const MIN_DESIGN_APP_VERSION = 16;
|
|
18
|
+
// 判断是否启用测量值缩放适配(true=启用, false=使用系统侧缩放)
|
|
19
|
+
const resolveUseMeasuredScale = res => {
|
|
20
|
+
// H5/weapp 不参与大屏系数
|
|
21
|
+
if (process.env.TARO_ENV === 'h5' || process.env.TARO_ENV === 'weapp') {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
const designAppVersionRaw = res.designAppVersion;
|
|
25
|
+
const designAppVersionMajor = designAppVersionRaw != null ? parseInt(String(designAppVersionRaw).trim(), 10) : Number.NaN;
|
|
26
|
+
if (!Number.isFinite(designAppVersionMajor) || designAppVersionMajor < MIN_DESIGN_APP_VERSION) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
const platform = String(res.platform || '').toLowerCase();
|
|
30
|
+
if (platform === 'harmony' || platform === 'android' || platform === 'ios') {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
};
|
|
35
|
+
// 辅助函数:计算 lengthScaleRatio
|
|
36
|
+
const calculateLengthScaleRatio = res => {
|
|
37
|
+
let lengthScaleRatio = res === null || res === void 0 ? void 0 : res.lengthScaleRatio;
|
|
38
|
+
if (lengthScaleRatio == null || lengthScaleRatio === 0) {
|
|
39
|
+
console.warn('Taro.getSystemInfo: lengthScaleRatio 不存在,使用计算值');
|
|
40
|
+
lengthScaleRatio = 1;
|
|
41
|
+
if (res.windowWidth < 320) {
|
|
42
|
+
lengthScaleRatio = res.windowWidth / 320;
|
|
43
|
+
} else if (res.windowWidth >= 400 && res.windowWidth < 600) {
|
|
44
|
+
lengthScaleRatio = res.windowWidth / 400;
|
|
45
|
+
}
|
|
46
|
+
const shortSide = res.windowWidth < res.windowHeight ? res.windowWidth : res.windowHeight;
|
|
47
|
+
const isBigScreen = shortSide >= 600;
|
|
48
|
+
if (isBigScreen) {
|
|
49
|
+
lengthScaleRatio = shortSide / 720;
|
|
29
50
|
}
|
|
30
|
-
}
|
|
51
|
+
}
|
|
52
|
+
return lengthScaleRatio;
|
|
53
|
+
};
|
|
54
|
+
// 辅助函数:获取系统信息的 lengthScaleRatio 并设置 targetScrollTop
|
|
55
|
+
const setTargetScrollTopWithScale = function (setTargetScrollTop, baseValue, randomOffset) {
|
|
56
|
+
let lengthScaleRatio = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
|
|
57
|
+
// H5 和 weapp 不参与放大计算,直接使用 baseValue
|
|
58
|
+
if (process.env.TARO_ENV === 'h5' || process.env.TARO_ENV === 'weapp') {
|
|
59
|
+
const finalValue = randomOffset !== undefined ? baseValue + randomOffset : baseValue;
|
|
60
|
+
setTargetScrollTop(finalValue);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (process.env.TARO_PLATFORM === 'harmony') {
|
|
64
|
+
const scaledValue = baseValue;
|
|
65
|
+
const finalValue = randomOffset !== undefined ? scaledValue + randomOffset : scaledValue;
|
|
66
|
+
setTargetScrollTop(finalValue);
|
|
67
|
+
} else {
|
|
68
|
+
const scaledValue = baseValue * lengthScaleRatio;
|
|
69
|
+
const finalValue = randomOffset !== undefined ? scaledValue + randomOffset : scaledValue;
|
|
70
|
+
setTargetScrollTop(finalValue);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
// 根据 scrollTop 计算选中索引
|
|
74
|
+
// 系统侧缩放模式:scrollHeight 已被系统缩放,直接相除即可
|
|
75
|
+
// 自行缩放模式:需要除以 ratio 换算(harmony 特殊处理,ratio 已内嵌在 itemHeight 中)
|
|
76
|
+
const getSelectedIndex = function (scrollTop, itemHeight) {
|
|
77
|
+
let lengthScaleRatio = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
|
|
78
|
+
let useMeasuredScale = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
79
|
+
if (!useMeasuredScale || process.env.TARO_PLATFORM === 'harmony') {
|
|
80
|
+
return Math.round(scrollTop / itemHeight);
|
|
81
|
+
}
|
|
82
|
+
return Math.round(scrollTop / lengthScaleRatio / itemHeight);
|
|
83
|
+
};
|
|
84
|
+
// 计算单项高度(返回设计稿值)
|
|
85
|
+
const calculateItemHeight = function (scrollView, lengthScaleRatio) {
|
|
86
|
+
let useMeasuredScale = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
87
|
+
if (process.env.TARO_PLATFORM === 'harmony') {
|
|
88
|
+
return useMeasuredScale ? PICKER_LINE_HEIGHT * lengthScaleRatio : PICKER_LINE_HEIGHT;
|
|
89
|
+
}
|
|
90
|
+
if (scrollView && (scrollView === null || scrollView === void 0 ? void 0 : scrollView.scrollHeight)) {
|
|
91
|
+
return useMeasuredScale ? scrollView.scrollHeight / lengthScaleRatio / scrollView.childNodes.length : scrollView.scrollHeight / scrollView.childNodes.length;
|
|
92
|
+
}
|
|
93
|
+
console.warn('Height measurement anomaly');
|
|
94
|
+
return PICKER_LINE_HEIGHT;
|
|
31
95
|
};
|
|
32
96
|
function PickerGroupBasic(props) {
|
|
33
97
|
const {
|
|
@@ -40,6 +104,7 @@ function PickerGroupBasic(props) {
|
|
|
40
104
|
// 使用selectedIndex参数,默认为0
|
|
41
105
|
colors = {}
|
|
42
106
|
} = props;
|
|
107
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
43
108
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
44
109
|
const scrollViewRef = React.useRef(null);
|
|
45
110
|
const itemRefs = React.useRef([]);
|
|
@@ -47,26 +112,31 @@ function PickerGroupBasic(props) {
|
|
|
47
112
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
48
113
|
// 触摸状态用于优化用户体验
|
|
49
114
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
115
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
116
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
50
117
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
118
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
51
119
|
React.useEffect(() => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
120
|
+
Taro.getSystemInfo({
|
|
121
|
+
success: res => {
|
|
122
|
+
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
123
|
+
useMeasuredScaleRef.current = resolveUseMeasuredScale(res);
|
|
124
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
125
|
+
},
|
|
126
|
+
fail: () => {
|
|
127
|
+
lengthScaleRatioRef.current = 1;
|
|
128
|
+
useMeasuredScaleRef.current = false;
|
|
58
129
|
}
|
|
59
|
-
}
|
|
130
|
+
});
|
|
131
|
+
}, []);
|
|
132
|
+
React.useEffect(() => {
|
|
133
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
60
134
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
61
|
-
// 获取选中的索引
|
|
62
|
-
const getSelectedIndex = scrollTop => {
|
|
63
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
64
|
-
};
|
|
65
135
|
// 当selectedIndex变化时,调整滚动位置
|
|
66
136
|
React.useEffect(() => {
|
|
67
137
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
68
138
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
69
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
139
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
70
140
|
setCurrentIndex(selectedIndex);
|
|
71
141
|
}
|
|
72
142
|
}, [selectedIndex, range]);
|
|
@@ -83,16 +153,17 @@ function PickerGroupBasic(props) {
|
|
|
83
153
|
isCenterTimerId.current = setTimeout(() => {
|
|
84
154
|
if (!scrollViewRef.current) return;
|
|
85
155
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
86
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
156
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
87
157
|
setIsTouching(false);
|
|
88
158
|
const baseValue = newIndex * itemHeightRef.current;
|
|
89
159
|
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
90
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
160
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
91
161
|
updateIndex(newIndex, columnId);
|
|
92
162
|
onColumnChange === null || onColumnChange === void 0 ? void 0 : onColumnChange({
|
|
93
163
|
columnId,
|
|
94
164
|
index: newIndex
|
|
95
165
|
});
|
|
166
|
+
isCenterTimerId.current = null;
|
|
96
167
|
}, 100);
|
|
97
168
|
};
|
|
98
169
|
// 滚动处理 - 在滚动时计算索引然后更新选中项样式
|
|
@@ -103,7 +174,7 @@ function PickerGroupBasic(props) {
|
|
|
103
174
|
isCenterTimerId.current = null;
|
|
104
175
|
}
|
|
105
176
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
106
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
177
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
107
178
|
if (newIndex !== currentIndex) {
|
|
108
179
|
setCurrentIndex(newIndex);
|
|
109
180
|
}
|
|
@@ -143,9 +214,11 @@ function PickerGroupBasic(props) {
|
|
|
143
214
|
get children() {
|
|
144
215
|
return [createComponent(View, {
|
|
145
216
|
className: "taro-picker__mask"
|
|
146
|
-
}), createComponent(View, {
|
|
217
|
+
}), createComponent(View, mergeProps({
|
|
147
218
|
className: "taro-picker__indicator"
|
|
148
|
-
}
|
|
219
|
+
}, indicatorStyle ? {
|
|
220
|
+
style: indicatorStyle
|
|
221
|
+
} : {})), createComponent(ScrollView, {
|
|
149
222
|
ref: scrollViewRef,
|
|
150
223
|
scrollY: true,
|
|
151
224
|
showScrollbar: false,
|
|
@@ -173,30 +246,37 @@ function PickerGroupTime(props) {
|
|
|
173
246
|
selectedIndex = 0,
|
|
174
247
|
colors = {}
|
|
175
248
|
} = props;
|
|
249
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
176
250
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
177
251
|
const scrollViewRef = React.useRef(null);
|
|
178
252
|
const itemRefs = React.useRef([]);
|
|
179
253
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
180
254
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
255
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
256
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
181
257
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
258
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
182
259
|
React.useEffect(() => {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
260
|
+
Taro.getSystemInfo({
|
|
261
|
+
success: res => {
|
|
262
|
+
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
263
|
+
useMeasuredScaleRef.current = resolveUseMeasuredScale(res);
|
|
264
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
265
|
+
},
|
|
266
|
+
fail: () => {
|
|
267
|
+
lengthScaleRatioRef.current = 1;
|
|
268
|
+
useMeasuredScaleRef.current = false;
|
|
189
269
|
}
|
|
190
|
-
}
|
|
270
|
+
});
|
|
271
|
+
}, []);
|
|
272
|
+
React.useEffect(() => {
|
|
273
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
191
274
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
192
|
-
const getSelectedIndex = scrollTop => {
|
|
193
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
194
|
-
};
|
|
195
275
|
// 当selectedIndex变化时,调整滚动位置
|
|
196
276
|
React.useEffect(() => {
|
|
197
277
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
198
278
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
199
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
279
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
200
280
|
setCurrentIndex(selectedIndex);
|
|
201
281
|
}
|
|
202
282
|
}, [selectedIndex, range]);
|
|
@@ -213,7 +293,7 @@ function PickerGroupTime(props) {
|
|
|
213
293
|
isCenterTimerId.current = setTimeout(() => {
|
|
214
294
|
if (!scrollViewRef.current) return;
|
|
215
295
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
216
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
296
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
217
297
|
setIsTouching(false);
|
|
218
298
|
// 调用updateIndex执行限位逻辑,获取是否触发了限位
|
|
219
299
|
const isLimited = Boolean(updateIndex(newIndex, columnId, true));
|
|
@@ -221,8 +301,9 @@ function PickerGroupTime(props) {
|
|
|
221
301
|
if (!isLimited) {
|
|
222
302
|
const baseValue = newIndex * itemHeightRef.current;
|
|
223
303
|
const randomOffset = Math.random() * 0.001;
|
|
224
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
304
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
225
305
|
}
|
|
306
|
+
isCenterTimerId.current = null;
|
|
226
307
|
}, 100);
|
|
227
308
|
};
|
|
228
309
|
// 滚动处理
|
|
@@ -233,7 +314,7 @@ function PickerGroupTime(props) {
|
|
|
233
314
|
isCenterTimerId.current = null;
|
|
234
315
|
}
|
|
235
316
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
236
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
317
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
237
318
|
if (newIndex !== currentIndex) {
|
|
238
319
|
setCurrentIndex(newIndex);
|
|
239
320
|
}
|
|
@@ -273,9 +354,11 @@ function PickerGroupTime(props) {
|
|
|
273
354
|
get children() {
|
|
274
355
|
return [createComponent(View, {
|
|
275
356
|
className: "taro-picker__mask"
|
|
276
|
-
}), createComponent(View, {
|
|
357
|
+
}), createComponent(View, mergeProps({
|
|
277
358
|
className: "taro-picker__indicator"
|
|
278
|
-
}
|
|
359
|
+
}, indicatorStyle ? {
|
|
360
|
+
style: indicatorStyle
|
|
361
|
+
} : {})), createComponent(ScrollView, {
|
|
279
362
|
ref: scrollViewRef,
|
|
280
363
|
scrollY: true,
|
|
281
364
|
showScrollbar: false,
|
|
@@ -302,29 +385,36 @@ function PickerGroupDate(props) {
|
|
|
302
385
|
selectedIndex = 0,
|
|
303
386
|
colors = {}
|
|
304
387
|
} = props;
|
|
388
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
305
389
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
306
390
|
const scrollViewRef = React.useRef(null);
|
|
307
391
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
308
392
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
393
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
394
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
309
395
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
396
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
310
397
|
React.useEffect(() => {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
398
|
+
Taro.getSystemInfo({
|
|
399
|
+
success: res => {
|
|
400
|
+
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
401
|
+
useMeasuredScaleRef.current = resolveUseMeasuredScale(res);
|
|
402
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
403
|
+
},
|
|
404
|
+
fail: () => {
|
|
405
|
+
lengthScaleRatioRef.current = 1;
|
|
406
|
+
useMeasuredScaleRef.current = false;
|
|
317
407
|
}
|
|
318
|
-
}
|
|
408
|
+
});
|
|
409
|
+
}, []);
|
|
410
|
+
React.useEffect(() => {
|
|
411
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
319
412
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
320
|
-
const getSelectedIndex = scrollTop => {
|
|
321
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
322
|
-
};
|
|
323
413
|
// 当selectedIndex变化时,调整滚动位置
|
|
324
414
|
React.useEffect(() => {
|
|
325
415
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
326
416
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
327
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
417
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
328
418
|
setCurrentIndex(selectedIndex);
|
|
329
419
|
}
|
|
330
420
|
}, [selectedIndex, range]);
|
|
@@ -341,11 +431,11 @@ function PickerGroupDate(props) {
|
|
|
341
431
|
isCenterTimerId.current = setTimeout(() => {
|
|
342
432
|
if (!scrollViewRef.current) return;
|
|
343
433
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
344
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
434
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
345
435
|
setIsTouching(false);
|
|
346
436
|
const baseValue = newIndex * itemHeightRef.current;
|
|
347
437
|
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
348
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
438
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
349
439
|
// 更新日期值
|
|
350
440
|
if (updateDay) {
|
|
351
441
|
// 解析文本中的数字(移除年、月、日等后缀)
|
|
@@ -353,6 +443,7 @@ function PickerGroupDate(props) {
|
|
|
353
443
|
const numericValue = parseInt(valueText.replace(/[^0-9]/g, ''));
|
|
354
444
|
updateDay(isNaN(numericValue) ? 0 : numericValue, parseInt(columnId));
|
|
355
445
|
}
|
|
446
|
+
isCenterTimerId.current = null;
|
|
356
447
|
}, 100);
|
|
357
448
|
};
|
|
358
449
|
// 滚动处理
|
|
@@ -363,7 +454,7 @@ function PickerGroupDate(props) {
|
|
|
363
454
|
isCenterTimerId.current = null;
|
|
364
455
|
}
|
|
365
456
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
366
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
457
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
367
458
|
if (newIndex !== currentIndex) {
|
|
368
459
|
setCurrentIndex(newIndex);
|
|
369
460
|
}
|
|
@@ -401,9 +492,11 @@ function PickerGroupDate(props) {
|
|
|
401
492
|
get children() {
|
|
402
493
|
return [createComponent(View, {
|
|
403
494
|
className: "taro-picker__mask"
|
|
404
|
-
}), createComponent(View, {
|
|
495
|
+
}), createComponent(View, mergeProps({
|
|
405
496
|
className: "taro-picker__indicator"
|
|
406
|
-
}
|
|
497
|
+
}, indicatorStyle ? {
|
|
498
|
+
style: indicatorStyle
|
|
499
|
+
} : {})), createComponent(ScrollView, {
|
|
407
500
|
ref: scrollViewRef,
|
|
408
501
|
scrollY: true,
|
|
409
502
|
showScrollbar: false,
|
|
@@ -432,30 +525,37 @@ function PickerGroupRegion(props) {
|
|
|
432
525
|
// 使用selectedIndex参数,默认为0
|
|
433
526
|
colors = {}
|
|
434
527
|
} = props;
|
|
528
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
435
529
|
const scrollViewRef = React.useRef(null);
|
|
436
530
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
437
531
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
438
532
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
533
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
534
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
439
535
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
440
536
|
const isUserBeginScrollRef = React.useRef(false);
|
|
537
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
441
538
|
React.useEffect(() => {
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
539
|
+
Taro.getSystemInfo({
|
|
540
|
+
success: res => {
|
|
541
|
+
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
542
|
+
useMeasuredScaleRef.current = resolveUseMeasuredScale(res);
|
|
543
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
544
|
+
},
|
|
545
|
+
fail: () => {
|
|
546
|
+
lengthScaleRatioRef.current = 1;
|
|
547
|
+
useMeasuredScaleRef.current = false;
|
|
448
548
|
}
|
|
449
|
-
}
|
|
549
|
+
});
|
|
550
|
+
}, []);
|
|
551
|
+
React.useEffect(() => {
|
|
552
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
450
553
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
451
|
-
const getSelectedIndex = scrollTop => {
|
|
452
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
453
|
-
};
|
|
454
554
|
// 当selectedIndex变化时,调整滚动位置
|
|
455
555
|
React.useEffect(() => {
|
|
456
556
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
457
557
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
458
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
558
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
459
559
|
setCurrentIndex(selectedIndex);
|
|
460
560
|
}
|
|
461
561
|
}, [selectedIndex, range]);
|
|
@@ -471,11 +571,11 @@ function PickerGroupRegion(props) {
|
|
|
471
571
|
isCenterTimerId.current = setTimeout(() => {
|
|
472
572
|
if (!scrollViewRef.current) return;
|
|
473
573
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
474
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
574
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
475
575
|
setIsTouching(false);
|
|
476
576
|
const baseValue = newIndex * itemHeightRef.current;
|
|
477
577
|
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
478
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
578
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
479
579
|
updateIndex(newIndex, columnId, false, isUserBeginScrollRef.current);
|
|
480
580
|
}, 100);
|
|
481
581
|
};
|
|
@@ -487,7 +587,7 @@ function PickerGroupRegion(props) {
|
|
|
487
587
|
isCenterTimerId.current = null;
|
|
488
588
|
}
|
|
489
589
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
490
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
590
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
491
591
|
if (newIndex !== currentIndex) {
|
|
492
592
|
setCurrentIndex(newIndex);
|
|
493
593
|
}
|
|
@@ -526,9 +626,11 @@ function PickerGroupRegion(props) {
|
|
|
526
626
|
get children() {
|
|
527
627
|
return [createComponent(View, {
|
|
528
628
|
className: "taro-picker__mask"
|
|
529
|
-
}), createComponent(View, {
|
|
629
|
+
}), createComponent(View, mergeProps({
|
|
530
630
|
className: "taro-picker__indicator"
|
|
531
|
-
}
|
|
631
|
+
}, indicatorStyle ? {
|
|
632
|
+
style: indicatorStyle
|
|
633
|
+
} : {})), createComponent(ScrollView, {
|
|
532
634
|
ref: scrollViewRef,
|
|
533
635
|
scrollY: true,
|
|
534
636
|
showScrollbar: false,
|