@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
@@ -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
- // 辅助函数:获取系统信息的 lengthScaleRatio 并设置 targetScrollTop
10
- const setTargetScrollTopWithScale = (setTargetScrollTop, baseValue, randomOffset) => {
11
- Taro.getSystemInfo({
12
- success: res => {
13
- var _a;
14
- // 使用类型断言访问可能不存在的 lengthScaleRatio 属性
15
- const lengthScaleRatio = (_a = res.lengthScaleRatio) !== null && _a !== void 0 ? _a : 1;
16
- if (!res.lengthScaleRatio) {
17
- console.warn('Taro.getSystemInfo: lengthScaleRatio 不存在,使用默认值 1');
18
- }
19
- const scaledValue = baseValue * lengthScaleRatio;
20
- const finalValue = randomOffset !== undefined ? scaledValue + randomOffset : scaledValue;
21
- setTargetScrollTop(finalValue);
22
- },
23
- fail: err => {
24
- console.error('获取系统信息失败:', err);
25
- // 失败时使用默认值 1
26
- const finalValue = randomOffset !== undefined ? baseValue + randomOffset : baseValue;
27
- setTargetScrollTop(finalValue);
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
- var _a;
52
- if (process.env.TARO_PLATFORM !== 'harmony') {
53
- if (scrollViewRef.current && ((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.scrollHeigh)) {
54
- itemHeightRef.current = scrollViewRef.current.scrollHeight / scrollViewRef.current.childNodes.length;
55
- } else {
56
- console.warn('Height measurement anomaly');
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
- var _a;
176
- if (process.env.TARO_PLATFORM !== 'harmony') {
177
- if (scrollViewRef.current && ((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.scrollHeigh)) {
178
- itemHeightRef.current = scrollViewRef.current.scrollHeight / scrollViewRef.current.childNodes.length;
179
- } else {
180
- console.warn('Height measurement anomaly');
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
- var _a;
297
- if (process.env.TARO_PLATFORM !== 'harmony') {
298
- if (scrollViewRef.current && ((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.scrollHeigh)) {
299
- itemHeightRef.current = scrollViewRef.current.scrollHeight / scrollViewRef.current.childNodes.length;
300
- } else {
301
- console.warn('Height measurement anomaly');
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
- var _a;
421
- if (process.env.TARO_PLATFORM !== 'harmony') {
422
- if (scrollViewRef.current && ((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.scrollHeigh)) {
423
- itemHeightRef.current = scrollViewRef.current.scrollHeight / scrollViewRef.current.childNodes.length;
424
- } else {
425
- console.warn('Height measurement anomaly');
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,