@tarojs/components-react 4.1.9-beta.0 → 4.1.9-beta.1-patch.1
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 +246 -65
- 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 +246 -65
- 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 +247 -70
- 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,146 @@ 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
|
+
const MIN_APP_VERSION = '15.7.0';
|
|
18
|
+
// semver 版本比较
|
|
19
|
+
const isAppVersionAtLeast = (version, min) => {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
if (!version || typeof version !== 'string') return false;
|
|
22
|
+
const parts = v => {
|
|
23
|
+
const m = String(v).trim().match(/^(\d+)(?:\.(\d+))?(?:\.(\d+))?/);
|
|
24
|
+
if (!m) return [];
|
|
25
|
+
return [parseInt(m[1], 10) || 0, parseInt(m[2] || '0', 10) || 0, parseInt(m[3] || '0', 10) || 0];
|
|
26
|
+
};
|
|
27
|
+
const a = parts(version);
|
|
28
|
+
const b = parts(min);
|
|
29
|
+
if (a.length === 0) return false;
|
|
30
|
+
if (b.length === 0) return true;
|
|
31
|
+
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
|
32
|
+
const da = (_a = a[i]) !== null && _a !== void 0 ? _a : 0;
|
|
33
|
+
const db = (_b = b[i]) !== null && _b !== void 0 ? _b : 0;
|
|
34
|
+
if (da > db) return true;
|
|
35
|
+
if (da < db) return false;
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
};
|
|
39
|
+
// 读取 JDMobileConfig,异常时返回 undefined
|
|
40
|
+
const tryGetMobileConfigSync = opt => {
|
|
41
|
+
var _a;
|
|
42
|
+
try {
|
|
43
|
+
const fn = (_a = Taro.JDMobileConfig) === null || _a === void 0 ? void 0 : _a.getMobileConfigSync;
|
|
44
|
+
if (typeof fn !== 'function') return undefined;
|
|
45
|
+
return fn(opt);
|
|
46
|
+
} catch (_b) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
// 判断是否启用测量值缩放适配(true=启用, false=使用系统侧缩放)
|
|
51
|
+
const resolveUseMeasuredScale = res => {
|
|
52
|
+
// H5/weapp 不参与大屏系数
|
|
53
|
+
if (process.env.TARO_ENV === 'h5' || process.env.TARO_ENV === 'weapp') {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
// 条件1: designAppVersion < 16,不满足则使用系统侧缩放
|
|
57
|
+
const designAppVersionRaw = res.designAppVersion;
|
|
58
|
+
const designAppVersionMajor = designAppVersionRaw != null ? parseInt(String(designAppVersionRaw).trim(), 10) : Number.NaN;
|
|
59
|
+
if (!Number.isFinite(designAppVersionMajor) || designAppVersionMajor < MIN_DESIGN_APP_VERSION) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
// 条件2: appVersion < 15.7.0,不满足则使用系统侧缩放
|
|
63
|
+
if (!isAppVersionAtLeast(res.version, MIN_APP_VERSION)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
// 条件3: 平台判断
|
|
67
|
+
const platform = String(res.platform || '').toLowerCase();
|
|
68
|
+
if (platform === 'harmony') {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
if (platform === 'android') {
|
|
72
|
+
const raw = tryGetMobileConfigSync({
|
|
73
|
+
space: 'taro',
|
|
74
|
+
configName: 'config',
|
|
75
|
+
key: 'disableFixBoundingScaleRatio'
|
|
76
|
+
});
|
|
77
|
+
return raw !== 1 && raw !== '1';
|
|
78
|
+
}
|
|
79
|
+
if (platform === 'ios') {
|
|
80
|
+
const raw = tryGetMobileConfigSync({
|
|
81
|
+
space: 'Taro',
|
|
82
|
+
configName: 'excutor',
|
|
83
|
+
key: 'disableBoundingScaleRatio'
|
|
84
|
+
});
|
|
85
|
+
return raw !== 1 && raw !== '1';
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
};
|
|
89
|
+
// 辅助函数:计算 lengthScaleRatio
|
|
90
|
+
const calculateLengthScaleRatio = res => {
|
|
91
|
+
let lengthScaleRatio = res === null || res === void 0 ? void 0 : res.lengthScaleRatio;
|
|
92
|
+
if (lengthScaleRatio == null || lengthScaleRatio === 0) {
|
|
93
|
+
console.warn('Taro.getSystemInfo: lengthScaleRatio 不存在,使用计算值');
|
|
94
|
+
lengthScaleRatio = 1;
|
|
95
|
+
if (res.windowWidth < 320) {
|
|
96
|
+
lengthScaleRatio = res.windowWidth / 320;
|
|
97
|
+
} else if (res.windowWidth >= 400 && res.windowWidth < 600) {
|
|
98
|
+
lengthScaleRatio = res.windowWidth / 400;
|
|
28
99
|
}
|
|
29
|
-
|
|
100
|
+
const shortSide = res.windowWidth < res.windowHeight ? res.windowWidth : res.windowHeight;
|
|
101
|
+
const isBigScreen = shortSide >= 600;
|
|
102
|
+
if (isBigScreen) {
|
|
103
|
+
lengthScaleRatio = shortSide / 720;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return lengthScaleRatio;
|
|
107
|
+
};
|
|
108
|
+
// 辅助函数:获取系统信息的 lengthScaleRatio 并设置 targetScrollTop
|
|
109
|
+
const setTargetScrollTopWithScale = function (setTargetScrollTop, baseValue, randomOffset) {
|
|
110
|
+
let lengthScaleRatio = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
|
|
111
|
+
// H5 和 weapp 不参与放大计算,直接使用 baseValue
|
|
112
|
+
if (process.env.TARO_ENV === 'h5' || process.env.TARO_ENV === 'weapp') {
|
|
113
|
+
const finalValue = randomOffset !== undefined ? baseValue + randomOffset : baseValue;
|
|
114
|
+
setTargetScrollTop(finalValue);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (process.env.TARO_PLATFORM === 'harmony') {
|
|
118
|
+
const scaledValue = baseValue;
|
|
119
|
+
const finalValue = randomOffset !== undefined ? scaledValue + randomOffset : scaledValue;
|
|
120
|
+
setTargetScrollTop(finalValue);
|
|
121
|
+
} else {
|
|
122
|
+
const scaledValue = baseValue * lengthScaleRatio;
|
|
123
|
+
const finalValue = randomOffset !== undefined ? scaledValue + randomOffset : scaledValue;
|
|
124
|
+
setTargetScrollTop(finalValue);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
// 根据 scrollTop 计算选中索引
|
|
128
|
+
// 系统侧缩放模式:scrollHeight 已被系统缩放,直接相除即可
|
|
129
|
+
// 自行缩放模式:需要除以 ratio 换算(harmony 特殊处理,ratio 已内嵌在 itemHeight 中)
|
|
130
|
+
const getSelectedIndex = function (scrollTop, itemHeight) {
|
|
131
|
+
let lengthScaleRatio = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
|
|
132
|
+
let useMeasuredScale = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
133
|
+
if (!useMeasuredScale || process.env.TARO_PLATFORM === 'harmony') {
|
|
134
|
+
return Math.round(scrollTop / itemHeight);
|
|
135
|
+
}
|
|
136
|
+
return Math.round(scrollTop / lengthScaleRatio / itemHeight);
|
|
137
|
+
};
|
|
138
|
+
// 计算单项高度(返回设计稿值)
|
|
139
|
+
const calculateItemHeight = function (scrollView, lengthScaleRatio) {
|
|
140
|
+
let useMeasuredScale = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
141
|
+
if (process.env.TARO_PLATFORM === 'harmony') {
|
|
142
|
+
return useMeasuredScale ? PICKER_LINE_HEIGHT * lengthScaleRatio : PICKER_LINE_HEIGHT;
|
|
143
|
+
}
|
|
144
|
+
if (scrollView && (scrollView === null || scrollView === void 0 ? void 0 : scrollView.scrollHeight)) {
|
|
145
|
+
return useMeasuredScale ? scrollView.scrollHeight / lengthScaleRatio / scrollView.childNodes.length : scrollView.scrollHeight / scrollView.childNodes.length;
|
|
146
|
+
}
|
|
147
|
+
console.warn('Height measurement anomaly');
|
|
148
|
+
return PICKER_LINE_HEIGHT;
|
|
30
149
|
};
|
|
31
150
|
function PickerGroupBasic(props) {
|
|
32
151
|
const {
|
|
@@ -39,6 +158,7 @@ function PickerGroupBasic(props) {
|
|
|
39
158
|
// 使用selectedIndex参数,默认为0
|
|
40
159
|
colors = {}
|
|
41
160
|
} = props;
|
|
161
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
42
162
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
43
163
|
const scrollViewRef = React.useRef(null);
|
|
44
164
|
const itemRefs = React.useRef([]);
|
|
@@ -46,21 +166,31 @@ function PickerGroupBasic(props) {
|
|
|
46
166
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
47
167
|
// 触摸状态用于优化用户体验
|
|
48
168
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
169
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
170
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
49
171
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
172
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
50
173
|
React.useEffect(() => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
174
|
+
Taro.getSystemInfo({
|
|
175
|
+
success: res => {
|
|
176
|
+
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
177
|
+
useMeasuredScaleRef.current = resolveUseMeasuredScale(res);
|
|
178
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
179
|
+
},
|
|
180
|
+
fail: () => {
|
|
181
|
+
lengthScaleRatioRef.current = 1;
|
|
182
|
+
useMeasuredScaleRef.current = false;
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}, []);
|
|
186
|
+
React.useEffect(() => {
|
|
187
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
54
188
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
55
|
-
// 获取选中的索引
|
|
56
|
-
const getSelectedIndex = scrollTop => {
|
|
57
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
58
|
-
};
|
|
59
189
|
// 当selectedIndex变化时,调整滚动位置
|
|
60
190
|
React.useEffect(() => {
|
|
61
191
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
62
192
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
63
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
193
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
64
194
|
setCurrentIndex(selectedIndex);
|
|
65
195
|
}
|
|
66
196
|
}, [selectedIndex, range]);
|
|
@@ -77,16 +207,17 @@ function PickerGroupBasic(props) {
|
|
|
77
207
|
isCenterTimerId.current = setTimeout(() => {
|
|
78
208
|
if (!scrollViewRef.current) return;
|
|
79
209
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
80
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
210
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
81
211
|
setIsTouching(false);
|
|
82
212
|
const baseValue = newIndex * itemHeightRef.current;
|
|
83
213
|
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
84
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
214
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
85
215
|
updateIndex(newIndex, columnId);
|
|
86
216
|
onColumnChange === null || onColumnChange === void 0 ? void 0 : onColumnChange({
|
|
87
217
|
columnId,
|
|
88
218
|
index: newIndex
|
|
89
219
|
});
|
|
220
|
+
isCenterTimerId.current = null;
|
|
90
221
|
}, 100);
|
|
91
222
|
};
|
|
92
223
|
// 滚动处理 - 在滚动时计算索引然后更新选中项样式
|
|
@@ -97,7 +228,7 @@ function PickerGroupBasic(props) {
|
|
|
97
228
|
isCenterTimerId.current = null;
|
|
98
229
|
}
|
|
99
230
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
100
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
231
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
101
232
|
if (newIndex !== currentIndex) {
|
|
102
233
|
setCurrentIndex(newIndex);
|
|
103
234
|
}
|
|
@@ -132,7 +263,10 @@ function PickerGroupBasic(props) {
|
|
|
132
263
|
children: [/*#__PURE__*/jsx(View, {
|
|
133
264
|
className: "taro-picker__mask"
|
|
134
265
|
}), /*#__PURE__*/jsx(View, {
|
|
135
|
-
className: "taro-picker__indicator"
|
|
266
|
+
className: "taro-picker__indicator",
|
|
267
|
+
...(indicatorStyle ? {
|
|
268
|
+
style: indicatorStyle
|
|
269
|
+
} : {})
|
|
136
270
|
}), /*#__PURE__*/jsx(ScrollView, {
|
|
137
271
|
ref: scrollViewRef,
|
|
138
272
|
scrollY: true,
|
|
@@ -160,25 +294,37 @@ function PickerGroupTime(props) {
|
|
|
160
294
|
selectedIndex = 0,
|
|
161
295
|
colors = {}
|
|
162
296
|
} = props;
|
|
297
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
163
298
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
164
299
|
const scrollViewRef = React.useRef(null);
|
|
165
300
|
const itemRefs = React.useRef([]);
|
|
166
301
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
167
302
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
303
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
304
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
168
305
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
306
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
169
307
|
React.useEffect(() => {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
308
|
+
Taro.getSystemInfo({
|
|
309
|
+
success: res => {
|
|
310
|
+
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
311
|
+
useMeasuredScaleRef.current = resolveUseMeasuredScale(res);
|
|
312
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
313
|
+
},
|
|
314
|
+
fail: () => {
|
|
315
|
+
lengthScaleRatioRef.current = 1;
|
|
316
|
+
useMeasuredScaleRef.current = false;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
}, []);
|
|
320
|
+
React.useEffect(() => {
|
|
321
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
173
322
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
174
|
-
const getSelectedIndex = scrollTop => {
|
|
175
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
176
|
-
};
|
|
177
323
|
// 当selectedIndex变化时,调整滚动位置
|
|
178
324
|
React.useEffect(() => {
|
|
179
325
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
180
326
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
181
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
327
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
182
328
|
setCurrentIndex(selectedIndex);
|
|
183
329
|
}
|
|
184
330
|
}, [selectedIndex, range]);
|
|
@@ -195,7 +341,7 @@ function PickerGroupTime(props) {
|
|
|
195
341
|
isCenterTimerId.current = setTimeout(() => {
|
|
196
342
|
if (!scrollViewRef.current) return;
|
|
197
343
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
198
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
344
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
199
345
|
setIsTouching(false);
|
|
200
346
|
// 调用updateIndex执行限位逻辑,获取是否触发了限位
|
|
201
347
|
const isLimited = Boolean(updateIndex(newIndex, columnId, true));
|
|
@@ -203,8 +349,9 @@ function PickerGroupTime(props) {
|
|
|
203
349
|
if (!isLimited) {
|
|
204
350
|
const baseValue = newIndex * itemHeightRef.current;
|
|
205
351
|
const randomOffset = Math.random() * 0.001;
|
|
206
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
352
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
207
353
|
}
|
|
354
|
+
isCenterTimerId.current = null;
|
|
208
355
|
}, 100);
|
|
209
356
|
};
|
|
210
357
|
// 滚动处理
|
|
@@ -215,7 +362,7 @@ function PickerGroupTime(props) {
|
|
|
215
362
|
isCenterTimerId.current = null;
|
|
216
363
|
}
|
|
217
364
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
218
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
365
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
219
366
|
if (newIndex !== currentIndex) {
|
|
220
367
|
setCurrentIndex(newIndex);
|
|
221
368
|
}
|
|
@@ -250,7 +397,10 @@ function PickerGroupTime(props) {
|
|
|
250
397
|
children: [/*#__PURE__*/jsx(View, {
|
|
251
398
|
className: "taro-picker__mask"
|
|
252
399
|
}), /*#__PURE__*/jsx(View, {
|
|
253
|
-
className: "taro-picker__indicator"
|
|
400
|
+
className: "taro-picker__indicator",
|
|
401
|
+
...(indicatorStyle ? {
|
|
402
|
+
style: indicatorStyle
|
|
403
|
+
} : {})
|
|
254
404
|
}), /*#__PURE__*/jsx(ScrollView, {
|
|
255
405
|
ref: scrollViewRef,
|
|
256
406
|
scrollY: true,
|
|
@@ -277,24 +427,36 @@ function PickerGroupDate(props) {
|
|
|
277
427
|
selectedIndex = 0,
|
|
278
428
|
colors = {}
|
|
279
429
|
} = props;
|
|
430
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
280
431
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
281
432
|
const scrollViewRef = React.useRef(null);
|
|
282
433
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
283
434
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
435
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
436
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
284
437
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
438
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
285
439
|
React.useEffect(() => {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
440
|
+
Taro.getSystemInfo({
|
|
441
|
+
success: res => {
|
|
442
|
+
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
443
|
+
useMeasuredScaleRef.current = resolveUseMeasuredScale(res);
|
|
444
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
445
|
+
},
|
|
446
|
+
fail: () => {
|
|
447
|
+
lengthScaleRatioRef.current = 1;
|
|
448
|
+
useMeasuredScaleRef.current = false;
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
}, []);
|
|
452
|
+
React.useEffect(() => {
|
|
453
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
289
454
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
290
|
-
const getSelectedIndex = scrollTop => {
|
|
291
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
292
|
-
};
|
|
293
455
|
// 当selectedIndex变化时,调整滚动位置
|
|
294
456
|
React.useEffect(() => {
|
|
295
457
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
296
458
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
297
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
459
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
298
460
|
setCurrentIndex(selectedIndex);
|
|
299
461
|
}
|
|
300
462
|
}, [selectedIndex, range]);
|
|
@@ -311,11 +473,11 @@ function PickerGroupDate(props) {
|
|
|
311
473
|
isCenterTimerId.current = setTimeout(() => {
|
|
312
474
|
if (!scrollViewRef.current) return;
|
|
313
475
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
314
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
476
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
315
477
|
setIsTouching(false);
|
|
316
478
|
const baseValue = newIndex * itemHeightRef.current;
|
|
317
479
|
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
318
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
480
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
319
481
|
// 更新日期值
|
|
320
482
|
if (updateDay) {
|
|
321
483
|
// 解析文本中的数字(移除年、月、日等后缀)
|
|
@@ -323,6 +485,7 @@ function PickerGroupDate(props) {
|
|
|
323
485
|
const numericValue = parseInt(valueText.replace(/[^0-9]/g, ''));
|
|
324
486
|
updateDay(isNaN(numericValue) ? 0 : numericValue, parseInt(columnId));
|
|
325
487
|
}
|
|
488
|
+
isCenterTimerId.current = null;
|
|
326
489
|
}, 100);
|
|
327
490
|
};
|
|
328
491
|
// 滚动处理
|
|
@@ -333,7 +496,7 @@ function PickerGroupDate(props) {
|
|
|
333
496
|
isCenterTimerId.current = null;
|
|
334
497
|
}
|
|
335
498
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
336
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
499
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
337
500
|
if (newIndex !== currentIndex) {
|
|
338
501
|
setCurrentIndex(newIndex);
|
|
339
502
|
}
|
|
@@ -366,7 +529,10 @@ function PickerGroupDate(props) {
|
|
|
366
529
|
children: [/*#__PURE__*/jsx(View, {
|
|
367
530
|
className: "taro-picker__mask"
|
|
368
531
|
}), /*#__PURE__*/jsx(View, {
|
|
369
|
-
className: "taro-picker__indicator"
|
|
532
|
+
className: "taro-picker__indicator",
|
|
533
|
+
...(indicatorStyle ? {
|
|
534
|
+
style: indicatorStyle
|
|
535
|
+
} : {})
|
|
370
536
|
}), /*#__PURE__*/jsx(ScrollView, {
|
|
371
537
|
ref: scrollViewRef,
|
|
372
538
|
scrollY: true,
|
|
@@ -395,25 +561,37 @@ function PickerGroupRegion(props) {
|
|
|
395
561
|
// 使用selectedIndex参数,默认为0
|
|
396
562
|
colors = {}
|
|
397
563
|
} = props;
|
|
564
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
398
565
|
const scrollViewRef = React.useRef(null);
|
|
399
566
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
400
567
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
401
568
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
569
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
570
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
402
571
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
403
572
|
const isUserBeginScrollRef = React.useRef(false);
|
|
573
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
404
574
|
React.useEffect(() => {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
575
|
+
Taro.getSystemInfo({
|
|
576
|
+
success: res => {
|
|
577
|
+
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
578
|
+
useMeasuredScaleRef.current = resolveUseMeasuredScale(res);
|
|
579
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
580
|
+
},
|
|
581
|
+
fail: () => {
|
|
582
|
+
lengthScaleRatioRef.current = 1;
|
|
583
|
+
useMeasuredScaleRef.current = false;
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
}, []);
|
|
587
|
+
React.useEffect(() => {
|
|
588
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
408
589
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
409
|
-
const getSelectedIndex = scrollTop => {
|
|
410
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
411
|
-
};
|
|
412
590
|
// 当selectedIndex变化时,调整滚动位置
|
|
413
591
|
React.useEffect(() => {
|
|
414
592
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
415
593
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
416
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
594
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
417
595
|
setCurrentIndex(selectedIndex);
|
|
418
596
|
}
|
|
419
597
|
}, [selectedIndex, range]);
|
|
@@ -429,11 +607,11 @@ function PickerGroupRegion(props) {
|
|
|
429
607
|
isCenterTimerId.current = setTimeout(() => {
|
|
430
608
|
if (!scrollViewRef.current) return;
|
|
431
609
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
432
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
610
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
433
611
|
setIsTouching(false);
|
|
434
612
|
const baseValue = newIndex * itemHeightRef.current;
|
|
435
613
|
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
436
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
614
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
437
615
|
updateIndex(newIndex, columnId, false, isUserBeginScrollRef.current);
|
|
438
616
|
}, 100);
|
|
439
617
|
};
|
|
@@ -445,7 +623,7 @@ function PickerGroupRegion(props) {
|
|
|
445
623
|
isCenterTimerId.current = null;
|
|
446
624
|
}
|
|
447
625
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
448
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
626
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
449
627
|
if (newIndex !== currentIndex) {
|
|
450
628
|
setCurrentIndex(newIndex);
|
|
451
629
|
}
|
|
@@ -479,7 +657,10 @@ function PickerGroupRegion(props) {
|
|
|
479
657
|
children: [/*#__PURE__*/jsx(View, {
|
|
480
658
|
className: "taro-picker__mask"
|
|
481
659
|
}), /*#__PURE__*/jsx(View, {
|
|
482
|
-
className: "taro-picker__indicator"
|
|
660
|
+
className: "taro-picker__indicator",
|
|
661
|
+
...(indicatorStyle ? {
|
|
662
|
+
style: indicatorStyle
|
|
663
|
+
} : {})
|
|
483
664
|
}), /*#__PURE__*/jsx(ScrollView, {
|
|
484
665
|
ref: scrollViewRef,
|
|
485
666
|
scrollY: true,
|