@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.
Files changed (32) hide show
  1. package/dist/components/picker/index.js +22 -3
  2. package/dist/components/picker/index.js.map +1 -1
  3. package/dist/components/picker/picker-group.js +187 -81
  4. package/dist/components/picker/picker-group.js.map +1 -1
  5. package/dist/components/scroll-view/index.js +104 -30
  6. package/dist/components/scroll-view/index.js.map +1 -1
  7. package/dist/contexts/ScrollElementContext.js +6 -0
  8. package/dist/contexts/ScrollElementContext.js.map +1 -0
  9. package/dist/index.css +1 -1
  10. package/dist/index.js +1 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/original/components/picker/index.js +22 -3
  13. package/dist/original/components/picker/index.js.map +1 -1
  14. package/dist/original/components/picker/picker-group.js +187 -81
  15. package/dist/original/components/picker/picker-group.js.map +1 -1
  16. package/dist/original/components/picker/style/index.scss +146 -46
  17. package/dist/original/components/scroll-view/index.js +104 -30
  18. package/dist/original/components/scroll-view/index.js.map +1 -1
  19. package/dist/original/contexts/ScrollElementContext.js +6 -0
  20. package/dist/original/contexts/ScrollElementContext.js.map +1 -0
  21. package/dist/original/index.js +1 -0
  22. package/dist/original/index.js.map +1 -1
  23. package/dist/solid/components/picker/index.js +33 -14
  24. package/dist/solid/components/picker/index.js.map +1 -1
  25. package/dist/solid/components/picker/picker-group.js +188 -86
  26. package/dist/solid/components/picker/picker-group.js.map +1 -1
  27. package/dist/solid/components/scroll-view/index.js +109 -35
  28. package/dist/solid/components/scroll-view/index.js.map +1 -1
  29. package/dist/solid/contexts/ScrollElementContext.js +6 -0
  30. package/dist/solid/contexts/ScrollElementContext.js.map +1 -0
  31. package/dist/solid/index.css +1 -1
  32. 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
- // 辅助函数:获取系统信息的 lengthScaleRatio 并设置 targetScrollTop
11
- const setTargetScrollTopWithScale = (setTargetScrollTop, baseValue, randomOffset) => {
12
- Taro.getSystemInfo({
13
- success: res => {
14
- var _a;
15
- // 使用类型断言访问可能不存在的 lengthScaleRatio 属性
16
- const lengthScaleRatio = (_a = res.lengthScaleRatio) !== null && _a !== void 0 ? _a : 1;
17
- if (!res.lengthScaleRatio) {
18
- console.warn('Taro.getSystemInfo: lengthScaleRatio 不存在,使用默认值 1');
19
- }
20
- const scaledValue = baseValue * lengthScaleRatio;
21
- const finalValue = randomOffset !== undefined ? scaledValue + randomOffset : scaledValue;
22
- setTargetScrollTop(finalValue);
23
- },
24
- fail: err => {
25
- console.error('获取系统信息失败:', err);
26
- // 失败时使用默认值 1
27
- const finalValue = randomOffset !== undefined ? baseValue + randomOffset : baseValue;
28
- setTargetScrollTop(finalValue);
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
- var _a;
53
- if (process.env.TARO_PLATFORM !== 'harmony') {
54
- if (scrollViewRef.current && ((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.scrollHeigh)) {
55
- itemHeightRef.current = scrollViewRef.current.scrollHeight / scrollViewRef.current.childNodes.length;
56
- } else {
57
- console.warn('Height measurement anomaly');
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
- }), createComponent(ScrollView, {
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
- var _a;
184
- if (process.env.TARO_PLATFORM !== 'harmony') {
185
- if (scrollViewRef.current && ((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.scrollHeigh)) {
186
- itemHeightRef.current = scrollViewRef.current.scrollHeight / scrollViewRef.current.childNodes.length;
187
- } else {
188
- console.warn('Height measurement anomaly');
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
- }), createComponent(ScrollView, {
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
- var _a;
312
- if (process.env.TARO_PLATFORM !== 'harmony') {
313
- if (scrollViewRef.current && ((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.scrollHeigh)) {
314
- itemHeightRef.current = scrollViewRef.current.scrollHeight / scrollViewRef.current.childNodes.length;
315
- } else {
316
- console.warn('Height measurement anomaly');
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
- }), createComponent(ScrollView, {
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
- var _a;
443
- if (process.env.TARO_PLATFORM !== 'harmony') {
444
- if (scrollViewRef.current && ((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.scrollHeigh)) {
445
- itemHeightRef.current = scrollViewRef.current.scrollHeight / scrollViewRef.current.childNodes.length;
446
- } else {
447
- console.warn('Height measurement anomaly');
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
- }), createComponent(ScrollView, {
631
+ }, indicatorStyle ? {
632
+ style: indicatorStyle
633
+ } : {})), createComponent(ScrollView, {
532
634
  ref: scrollViewRef,
533
635
  scrollY: true,
534
636
  showScrollbar: false,