@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
|
@@ -6,27 +6,91 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
6
6
|
const PICKER_LINE_HEIGHT = 34; // px
|
|
7
7
|
const PICKER_VISIBLE_ITEMS = 7; // 可见行数
|
|
8
8
|
const PICKER_BLANK_ITEMS = 3; // 空白行数
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
9
|
+
const getIndicatorStyle = lineColor => {
|
|
10
|
+
return {
|
|
11
|
+
borderTopColor: lineColor,
|
|
12
|
+
borderBottomColor: lineColor
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
// 大屏方案版本要求
|
|
16
|
+
const MIN_DESIGN_APP_VERSION = 16;
|
|
17
|
+
// 判断是否启用测量值缩放适配(true=启用, false=使用系统侧缩放)
|
|
18
|
+
const resolveUseMeasuredScale = res => {
|
|
19
|
+
// H5/weapp 不参与大屏系数
|
|
20
|
+
if (process.env.TARO_ENV === 'h5' || process.env.TARO_ENV === 'weapp') {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
const designAppVersionRaw = res.designAppVersion;
|
|
24
|
+
const designAppVersionMajor = designAppVersionRaw != null ? parseInt(String(designAppVersionRaw).trim(), 10) : Number.NaN;
|
|
25
|
+
if (!Number.isFinite(designAppVersionMajor) || designAppVersionMajor < MIN_DESIGN_APP_VERSION) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const platform = String(res.platform || '').toLowerCase();
|
|
29
|
+
if (platform === 'harmony' || platform === 'android' || platform === 'ios') {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
};
|
|
34
|
+
// 辅助函数:计算 lengthScaleRatio
|
|
35
|
+
const calculateLengthScaleRatio = res => {
|
|
36
|
+
let lengthScaleRatio = res === null || res === void 0 ? void 0 : res.lengthScaleRatio;
|
|
37
|
+
if (lengthScaleRatio == null || lengthScaleRatio === 0) {
|
|
38
|
+
console.warn('Taro.getSystemInfo: lengthScaleRatio 不存在,使用计算值');
|
|
39
|
+
lengthScaleRatio = 1;
|
|
40
|
+
if (res.windowWidth < 320) {
|
|
41
|
+
lengthScaleRatio = res.windowWidth / 320;
|
|
42
|
+
} else if (res.windowWidth >= 400 && res.windowWidth < 600) {
|
|
43
|
+
lengthScaleRatio = res.windowWidth / 400;
|
|
28
44
|
}
|
|
29
|
-
|
|
45
|
+
const shortSide = res.windowWidth < res.windowHeight ? res.windowWidth : res.windowHeight;
|
|
46
|
+
const isBigScreen = shortSide >= 600;
|
|
47
|
+
if (isBigScreen) {
|
|
48
|
+
lengthScaleRatio = shortSide / 720;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return lengthScaleRatio;
|
|
52
|
+
};
|
|
53
|
+
// 辅助函数:获取系统信息的 lengthScaleRatio 并设置 targetScrollTop
|
|
54
|
+
const setTargetScrollTopWithScale = function (setTargetScrollTop, baseValue, randomOffset) {
|
|
55
|
+
let lengthScaleRatio = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
|
|
56
|
+
// H5 和 weapp 不参与放大计算,直接使用 baseValue
|
|
57
|
+
if (process.env.TARO_ENV === 'h5' || process.env.TARO_ENV === 'weapp') {
|
|
58
|
+
const finalValue = randomOffset !== undefined ? baseValue + randomOffset : baseValue;
|
|
59
|
+
setTargetScrollTop(finalValue);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (process.env.TARO_PLATFORM === 'harmony') {
|
|
63
|
+
const scaledValue = baseValue;
|
|
64
|
+
const finalValue = randomOffset !== undefined ? scaledValue + randomOffset : scaledValue;
|
|
65
|
+
setTargetScrollTop(finalValue);
|
|
66
|
+
} else {
|
|
67
|
+
const scaledValue = baseValue * lengthScaleRatio;
|
|
68
|
+
const finalValue = randomOffset !== undefined ? scaledValue + randomOffset : scaledValue;
|
|
69
|
+
setTargetScrollTop(finalValue);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
// 根据 scrollTop 计算选中索引
|
|
73
|
+
// 系统侧缩放模式:scrollHeight 已被系统缩放,直接相除即可
|
|
74
|
+
// 自行缩放模式:需要除以 ratio 换算(harmony 特殊处理,ratio 已内嵌在 itemHeight 中)
|
|
75
|
+
const getSelectedIndex = function (scrollTop, itemHeight) {
|
|
76
|
+
let lengthScaleRatio = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
|
|
77
|
+
let useMeasuredScale = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
78
|
+
if (!useMeasuredScale || process.env.TARO_PLATFORM === 'harmony') {
|
|
79
|
+
return Math.round(scrollTop / itemHeight);
|
|
80
|
+
}
|
|
81
|
+
return Math.round(scrollTop / lengthScaleRatio / itemHeight);
|
|
82
|
+
};
|
|
83
|
+
// 计算单项高度(返回设计稿值)
|
|
84
|
+
const calculateItemHeight = function (scrollView, lengthScaleRatio) {
|
|
85
|
+
let useMeasuredScale = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
86
|
+
if (process.env.TARO_PLATFORM === 'harmony') {
|
|
87
|
+
return useMeasuredScale ? PICKER_LINE_HEIGHT * lengthScaleRatio : PICKER_LINE_HEIGHT;
|
|
88
|
+
}
|
|
89
|
+
if (scrollView && (scrollView === null || scrollView === void 0 ? void 0 : scrollView.scrollHeight)) {
|
|
90
|
+
return useMeasuredScale ? scrollView.scrollHeight / lengthScaleRatio / scrollView.childNodes.length : scrollView.scrollHeight / scrollView.childNodes.length;
|
|
91
|
+
}
|
|
92
|
+
console.warn('Height measurement anomaly');
|
|
93
|
+
return PICKER_LINE_HEIGHT;
|
|
30
94
|
};
|
|
31
95
|
function PickerGroupBasic(props) {
|
|
32
96
|
const {
|
|
@@ -39,6 +103,7 @@ function PickerGroupBasic(props) {
|
|
|
39
103
|
// 使用selectedIndex参数,默认为0
|
|
40
104
|
colors = {}
|
|
41
105
|
} = props;
|
|
106
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
42
107
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
43
108
|
const scrollViewRef = React.useRef(null);
|
|
44
109
|
const itemRefs = React.useRef([]);
|
|
@@ -46,26 +111,31 @@ function PickerGroupBasic(props) {
|
|
|
46
111
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
47
112
|
// 触摸状态用于优化用户体验
|
|
48
113
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
114
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
115
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
49
116
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
117
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
50
118
|
React.useEffect(() => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
119
|
+
Taro.getSystemInfo({
|
|
120
|
+
success: res => {
|
|
121
|
+
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
122
|
+
useMeasuredScaleRef.current = resolveUseMeasuredScale(res);
|
|
123
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
124
|
+
},
|
|
125
|
+
fail: () => {
|
|
126
|
+
lengthScaleRatioRef.current = 1;
|
|
127
|
+
useMeasuredScaleRef.current = false;
|
|
57
128
|
}
|
|
58
|
-
}
|
|
129
|
+
});
|
|
130
|
+
}, []);
|
|
131
|
+
React.useEffect(() => {
|
|
132
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
59
133
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
60
|
-
// 获取选中的索引
|
|
61
|
-
const getSelectedIndex = scrollTop => {
|
|
62
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
63
|
-
};
|
|
64
134
|
// 当selectedIndex变化时,调整滚动位置
|
|
65
135
|
React.useEffect(() => {
|
|
66
136
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
67
137
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
68
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
138
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
69
139
|
setCurrentIndex(selectedIndex);
|
|
70
140
|
}
|
|
71
141
|
}, [selectedIndex, range]);
|
|
@@ -82,16 +152,17 @@ function PickerGroupBasic(props) {
|
|
|
82
152
|
isCenterTimerId.current = setTimeout(() => {
|
|
83
153
|
if (!scrollViewRef.current) return;
|
|
84
154
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
85
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
155
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
86
156
|
setIsTouching(false);
|
|
87
157
|
const baseValue = newIndex * itemHeightRef.current;
|
|
88
158
|
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
89
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
159
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
90
160
|
updateIndex(newIndex, columnId);
|
|
91
161
|
onColumnChange === null || onColumnChange === void 0 ? void 0 : onColumnChange({
|
|
92
162
|
columnId,
|
|
93
163
|
index: newIndex
|
|
94
164
|
});
|
|
165
|
+
isCenterTimerId.current = null;
|
|
95
166
|
}, 100);
|
|
96
167
|
};
|
|
97
168
|
// 滚动处理 - 在滚动时计算索引然后更新选中项样式
|
|
@@ -102,7 +173,7 @@ function PickerGroupBasic(props) {
|
|
|
102
173
|
isCenterTimerId.current = null;
|
|
103
174
|
}
|
|
104
175
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
105
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
176
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
106
177
|
if (newIndex !== currentIndex) {
|
|
107
178
|
setCurrentIndex(newIndex);
|
|
108
179
|
}
|
|
@@ -137,7 +208,10 @@ function PickerGroupBasic(props) {
|
|
|
137
208
|
children: [/*#__PURE__*/jsx(View, {
|
|
138
209
|
className: "taro-picker__mask"
|
|
139
210
|
}), /*#__PURE__*/jsx(View, {
|
|
140
|
-
className: "taro-picker__indicator"
|
|
211
|
+
className: "taro-picker__indicator",
|
|
212
|
+
...(indicatorStyle ? {
|
|
213
|
+
style: indicatorStyle
|
|
214
|
+
} : {})
|
|
141
215
|
}), /*#__PURE__*/jsx(ScrollView, {
|
|
142
216
|
ref: scrollViewRef,
|
|
143
217
|
scrollY: true,
|
|
@@ -165,30 +239,37 @@ function PickerGroupTime(props) {
|
|
|
165
239
|
selectedIndex = 0,
|
|
166
240
|
colors = {}
|
|
167
241
|
} = props;
|
|
242
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
168
243
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
169
244
|
const scrollViewRef = React.useRef(null);
|
|
170
245
|
const itemRefs = React.useRef([]);
|
|
171
246
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
172
247
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
248
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
249
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
173
250
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
251
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
174
252
|
React.useEffect(() => {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
253
|
+
Taro.getSystemInfo({
|
|
254
|
+
success: res => {
|
|
255
|
+
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
256
|
+
useMeasuredScaleRef.current = resolveUseMeasuredScale(res);
|
|
257
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
258
|
+
},
|
|
259
|
+
fail: () => {
|
|
260
|
+
lengthScaleRatioRef.current = 1;
|
|
261
|
+
useMeasuredScaleRef.current = false;
|
|
181
262
|
}
|
|
182
|
-
}
|
|
263
|
+
});
|
|
264
|
+
}, []);
|
|
265
|
+
React.useEffect(() => {
|
|
266
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
183
267
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
184
|
-
const getSelectedIndex = scrollTop => {
|
|
185
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
186
|
-
};
|
|
187
268
|
// 当selectedIndex变化时,调整滚动位置
|
|
188
269
|
React.useEffect(() => {
|
|
189
270
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
190
271
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
191
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
272
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
192
273
|
setCurrentIndex(selectedIndex);
|
|
193
274
|
}
|
|
194
275
|
}, [selectedIndex, range]);
|
|
@@ -205,7 +286,7 @@ function PickerGroupTime(props) {
|
|
|
205
286
|
isCenterTimerId.current = setTimeout(() => {
|
|
206
287
|
if (!scrollViewRef.current) return;
|
|
207
288
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
208
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
289
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
209
290
|
setIsTouching(false);
|
|
210
291
|
// 调用updateIndex执行限位逻辑,获取是否触发了限位
|
|
211
292
|
const isLimited = Boolean(updateIndex(newIndex, columnId, true));
|
|
@@ -213,8 +294,9 @@ function PickerGroupTime(props) {
|
|
|
213
294
|
if (!isLimited) {
|
|
214
295
|
const baseValue = newIndex * itemHeightRef.current;
|
|
215
296
|
const randomOffset = Math.random() * 0.001;
|
|
216
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
297
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
217
298
|
}
|
|
299
|
+
isCenterTimerId.current = null;
|
|
218
300
|
}, 100);
|
|
219
301
|
};
|
|
220
302
|
// 滚动处理
|
|
@@ -225,7 +307,7 @@ function PickerGroupTime(props) {
|
|
|
225
307
|
isCenterTimerId.current = null;
|
|
226
308
|
}
|
|
227
309
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
228
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
310
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
229
311
|
if (newIndex !== currentIndex) {
|
|
230
312
|
setCurrentIndex(newIndex);
|
|
231
313
|
}
|
|
@@ -260,7 +342,10 @@ function PickerGroupTime(props) {
|
|
|
260
342
|
children: [/*#__PURE__*/jsx(View, {
|
|
261
343
|
className: "taro-picker__mask"
|
|
262
344
|
}), /*#__PURE__*/jsx(View, {
|
|
263
|
-
className: "taro-picker__indicator"
|
|
345
|
+
className: "taro-picker__indicator",
|
|
346
|
+
...(indicatorStyle ? {
|
|
347
|
+
style: indicatorStyle
|
|
348
|
+
} : {})
|
|
264
349
|
}), /*#__PURE__*/jsx(ScrollView, {
|
|
265
350
|
ref: scrollViewRef,
|
|
266
351
|
scrollY: true,
|
|
@@ -287,29 +372,36 @@ function PickerGroupDate(props) {
|
|
|
287
372
|
selectedIndex = 0,
|
|
288
373
|
colors = {}
|
|
289
374
|
} = props;
|
|
375
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
290
376
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
291
377
|
const scrollViewRef = React.useRef(null);
|
|
292
378
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
293
379
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
380
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
381
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
294
382
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
383
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
295
384
|
React.useEffect(() => {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
385
|
+
Taro.getSystemInfo({
|
|
386
|
+
success: res => {
|
|
387
|
+
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
388
|
+
useMeasuredScaleRef.current = resolveUseMeasuredScale(res);
|
|
389
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
390
|
+
},
|
|
391
|
+
fail: () => {
|
|
392
|
+
lengthScaleRatioRef.current = 1;
|
|
393
|
+
useMeasuredScaleRef.current = false;
|
|
302
394
|
}
|
|
303
|
-
}
|
|
395
|
+
});
|
|
396
|
+
}, []);
|
|
397
|
+
React.useEffect(() => {
|
|
398
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
304
399
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
305
|
-
const getSelectedIndex = scrollTop => {
|
|
306
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
307
|
-
};
|
|
308
400
|
// 当selectedIndex变化时,调整滚动位置
|
|
309
401
|
React.useEffect(() => {
|
|
310
402
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
311
403
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
312
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
404
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
313
405
|
setCurrentIndex(selectedIndex);
|
|
314
406
|
}
|
|
315
407
|
}, [selectedIndex, range]);
|
|
@@ -326,11 +418,11 @@ function PickerGroupDate(props) {
|
|
|
326
418
|
isCenterTimerId.current = setTimeout(() => {
|
|
327
419
|
if (!scrollViewRef.current) return;
|
|
328
420
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
329
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
421
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
330
422
|
setIsTouching(false);
|
|
331
423
|
const baseValue = newIndex * itemHeightRef.current;
|
|
332
424
|
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
333
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
425
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
334
426
|
// 更新日期值
|
|
335
427
|
if (updateDay) {
|
|
336
428
|
// 解析文本中的数字(移除年、月、日等后缀)
|
|
@@ -338,6 +430,7 @@ function PickerGroupDate(props) {
|
|
|
338
430
|
const numericValue = parseInt(valueText.replace(/[^0-9]/g, ''));
|
|
339
431
|
updateDay(isNaN(numericValue) ? 0 : numericValue, parseInt(columnId));
|
|
340
432
|
}
|
|
433
|
+
isCenterTimerId.current = null;
|
|
341
434
|
}, 100);
|
|
342
435
|
};
|
|
343
436
|
// 滚动处理
|
|
@@ -348,7 +441,7 @@ function PickerGroupDate(props) {
|
|
|
348
441
|
isCenterTimerId.current = null;
|
|
349
442
|
}
|
|
350
443
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
351
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
444
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
352
445
|
if (newIndex !== currentIndex) {
|
|
353
446
|
setCurrentIndex(newIndex);
|
|
354
447
|
}
|
|
@@ -381,7 +474,10 @@ function PickerGroupDate(props) {
|
|
|
381
474
|
children: [/*#__PURE__*/jsx(View, {
|
|
382
475
|
className: "taro-picker__mask"
|
|
383
476
|
}), /*#__PURE__*/jsx(View, {
|
|
384
|
-
className: "taro-picker__indicator"
|
|
477
|
+
className: "taro-picker__indicator",
|
|
478
|
+
...(indicatorStyle ? {
|
|
479
|
+
style: indicatorStyle
|
|
480
|
+
} : {})
|
|
385
481
|
}), /*#__PURE__*/jsx(ScrollView, {
|
|
386
482
|
ref: scrollViewRef,
|
|
387
483
|
scrollY: true,
|
|
@@ -410,30 +506,37 @@ function PickerGroupRegion(props) {
|
|
|
410
506
|
// 使用selectedIndex参数,默认为0
|
|
411
507
|
colors = {}
|
|
412
508
|
} = props;
|
|
509
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
413
510
|
const scrollViewRef = React.useRef(null);
|
|
414
511
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
415
512
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
416
513
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
514
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
515
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
417
516
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
418
517
|
const isUserBeginScrollRef = React.useRef(false);
|
|
518
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
419
519
|
React.useEffect(() => {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
520
|
+
Taro.getSystemInfo({
|
|
521
|
+
success: res => {
|
|
522
|
+
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
523
|
+
useMeasuredScaleRef.current = resolveUseMeasuredScale(res);
|
|
524
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
525
|
+
},
|
|
526
|
+
fail: () => {
|
|
527
|
+
lengthScaleRatioRef.current = 1;
|
|
528
|
+
useMeasuredScaleRef.current = false;
|
|
426
529
|
}
|
|
427
|
-
}
|
|
530
|
+
});
|
|
531
|
+
}, []);
|
|
532
|
+
React.useEffect(() => {
|
|
533
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
428
534
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
429
|
-
const getSelectedIndex = scrollTop => {
|
|
430
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
431
|
-
};
|
|
432
535
|
// 当selectedIndex变化时,调整滚动位置
|
|
433
536
|
React.useEffect(() => {
|
|
434
537
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
435
538
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
436
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
539
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
437
540
|
setCurrentIndex(selectedIndex);
|
|
438
541
|
}
|
|
439
542
|
}, [selectedIndex, range]);
|
|
@@ -449,11 +552,11 @@ function PickerGroupRegion(props) {
|
|
|
449
552
|
isCenterTimerId.current = setTimeout(() => {
|
|
450
553
|
if (!scrollViewRef.current) return;
|
|
451
554
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
452
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
555
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
453
556
|
setIsTouching(false);
|
|
454
557
|
const baseValue = newIndex * itemHeightRef.current;
|
|
455
558
|
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
456
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
559
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
457
560
|
updateIndex(newIndex, columnId, false, isUserBeginScrollRef.current);
|
|
458
561
|
}, 100);
|
|
459
562
|
};
|
|
@@ -465,7 +568,7 @@ function PickerGroupRegion(props) {
|
|
|
465
568
|
isCenterTimerId.current = null;
|
|
466
569
|
}
|
|
467
570
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
468
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
571
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
469
572
|
if (newIndex !== currentIndex) {
|
|
470
573
|
setCurrentIndex(newIndex);
|
|
471
574
|
}
|
|
@@ -499,7 +602,10 @@ function PickerGroupRegion(props) {
|
|
|
499
602
|
children: [/*#__PURE__*/jsx(View, {
|
|
500
603
|
className: "taro-picker__mask"
|
|
501
604
|
}), /*#__PURE__*/jsx(View, {
|
|
502
|
-
className: "taro-picker__indicator"
|
|
605
|
+
className: "taro-picker__indicator",
|
|
606
|
+
...(indicatorStyle ? {
|
|
607
|
+
style: indicatorStyle
|
|
608
|
+
} : {})
|
|
503
609
|
}), /*#__PURE__*/jsx(ScrollView, {
|
|
504
610
|
ref: scrollViewRef,
|
|
505
611
|
scrollY: true,
|