@tarojs/components-react 4.1.9-beta.1 → 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 +242 -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 +242 -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 +243 -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,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,26 +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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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;
|
|
57
183
|
}
|
|
58
|
-
}
|
|
184
|
+
});
|
|
185
|
+
}, []);
|
|
186
|
+
React.useEffect(() => {
|
|
187
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
59
188
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
60
|
-
// 获取选中的索引
|
|
61
|
-
const getSelectedIndex = scrollTop => {
|
|
62
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
63
|
-
};
|
|
64
189
|
// 当selectedIndex变化时,调整滚动位置
|
|
65
190
|
React.useEffect(() => {
|
|
66
191
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
67
192
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
68
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
193
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
69
194
|
setCurrentIndex(selectedIndex);
|
|
70
195
|
}
|
|
71
196
|
}, [selectedIndex, range]);
|
|
@@ -82,16 +207,17 @@ function PickerGroupBasic(props) {
|
|
|
82
207
|
isCenterTimerId.current = setTimeout(() => {
|
|
83
208
|
if (!scrollViewRef.current) return;
|
|
84
209
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
85
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
210
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
86
211
|
setIsTouching(false);
|
|
87
212
|
const baseValue = newIndex * itemHeightRef.current;
|
|
88
213
|
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
89
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
214
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
90
215
|
updateIndex(newIndex, columnId);
|
|
91
216
|
onColumnChange === null || onColumnChange === void 0 ? void 0 : onColumnChange({
|
|
92
217
|
columnId,
|
|
93
218
|
index: newIndex
|
|
94
219
|
});
|
|
220
|
+
isCenterTimerId.current = null;
|
|
95
221
|
}, 100);
|
|
96
222
|
};
|
|
97
223
|
// 滚动处理 - 在滚动时计算索引然后更新选中项样式
|
|
@@ -102,7 +228,7 @@ function PickerGroupBasic(props) {
|
|
|
102
228
|
isCenterTimerId.current = null;
|
|
103
229
|
}
|
|
104
230
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
105
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
231
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
106
232
|
if (newIndex !== currentIndex) {
|
|
107
233
|
setCurrentIndex(newIndex);
|
|
108
234
|
}
|
|
@@ -137,7 +263,10 @@ function PickerGroupBasic(props) {
|
|
|
137
263
|
children: [/*#__PURE__*/jsx(View, {
|
|
138
264
|
className: "taro-picker__mask"
|
|
139
265
|
}), /*#__PURE__*/jsx(View, {
|
|
140
|
-
className: "taro-picker__indicator"
|
|
266
|
+
className: "taro-picker__indicator",
|
|
267
|
+
...(indicatorStyle ? {
|
|
268
|
+
style: indicatorStyle
|
|
269
|
+
} : {})
|
|
141
270
|
}), /*#__PURE__*/jsx(ScrollView, {
|
|
142
271
|
ref: scrollViewRef,
|
|
143
272
|
scrollY: true,
|
|
@@ -165,30 +294,37 @@ function PickerGroupTime(props) {
|
|
|
165
294
|
selectedIndex = 0,
|
|
166
295
|
colors = {}
|
|
167
296
|
} = props;
|
|
297
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
168
298
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
169
299
|
const scrollViewRef = React.useRef(null);
|
|
170
300
|
const itemRefs = React.useRef([]);
|
|
171
301
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
172
302
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
303
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
304
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
173
305
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
306
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
174
307
|
React.useEffect(() => {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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;
|
|
181
317
|
}
|
|
182
|
-
}
|
|
318
|
+
});
|
|
319
|
+
}, []);
|
|
320
|
+
React.useEffect(() => {
|
|
321
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
183
322
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
184
|
-
const getSelectedIndex = scrollTop => {
|
|
185
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
186
|
-
};
|
|
187
323
|
// 当selectedIndex变化时,调整滚动位置
|
|
188
324
|
React.useEffect(() => {
|
|
189
325
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
190
326
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
191
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
327
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
192
328
|
setCurrentIndex(selectedIndex);
|
|
193
329
|
}
|
|
194
330
|
}, [selectedIndex, range]);
|
|
@@ -205,7 +341,7 @@ function PickerGroupTime(props) {
|
|
|
205
341
|
isCenterTimerId.current = setTimeout(() => {
|
|
206
342
|
if (!scrollViewRef.current) return;
|
|
207
343
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
208
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
344
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
209
345
|
setIsTouching(false);
|
|
210
346
|
// 调用updateIndex执行限位逻辑,获取是否触发了限位
|
|
211
347
|
const isLimited = Boolean(updateIndex(newIndex, columnId, true));
|
|
@@ -213,8 +349,9 @@ function PickerGroupTime(props) {
|
|
|
213
349
|
if (!isLimited) {
|
|
214
350
|
const baseValue = newIndex * itemHeightRef.current;
|
|
215
351
|
const randomOffset = Math.random() * 0.001;
|
|
216
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
352
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
217
353
|
}
|
|
354
|
+
isCenterTimerId.current = null;
|
|
218
355
|
}, 100);
|
|
219
356
|
};
|
|
220
357
|
// 滚动处理
|
|
@@ -225,7 +362,7 @@ function PickerGroupTime(props) {
|
|
|
225
362
|
isCenterTimerId.current = null;
|
|
226
363
|
}
|
|
227
364
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
228
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
365
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
229
366
|
if (newIndex !== currentIndex) {
|
|
230
367
|
setCurrentIndex(newIndex);
|
|
231
368
|
}
|
|
@@ -260,7 +397,10 @@ function PickerGroupTime(props) {
|
|
|
260
397
|
children: [/*#__PURE__*/jsx(View, {
|
|
261
398
|
className: "taro-picker__mask"
|
|
262
399
|
}), /*#__PURE__*/jsx(View, {
|
|
263
|
-
className: "taro-picker__indicator"
|
|
400
|
+
className: "taro-picker__indicator",
|
|
401
|
+
...(indicatorStyle ? {
|
|
402
|
+
style: indicatorStyle
|
|
403
|
+
} : {})
|
|
264
404
|
}), /*#__PURE__*/jsx(ScrollView, {
|
|
265
405
|
ref: scrollViewRef,
|
|
266
406
|
scrollY: true,
|
|
@@ -287,29 +427,36 @@ function PickerGroupDate(props) {
|
|
|
287
427
|
selectedIndex = 0,
|
|
288
428
|
colors = {}
|
|
289
429
|
} = props;
|
|
430
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
290
431
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
291
432
|
const scrollViewRef = React.useRef(null);
|
|
292
433
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
293
434
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
435
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
436
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
294
437
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
438
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
295
439
|
React.useEffect(() => {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
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;
|
|
302
449
|
}
|
|
303
|
-
}
|
|
450
|
+
});
|
|
451
|
+
}, []);
|
|
452
|
+
React.useEffect(() => {
|
|
453
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
304
454
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
305
|
-
const getSelectedIndex = scrollTop => {
|
|
306
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
307
|
-
};
|
|
308
455
|
// 当selectedIndex变化时,调整滚动位置
|
|
309
456
|
React.useEffect(() => {
|
|
310
457
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
311
458
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
312
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
459
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
313
460
|
setCurrentIndex(selectedIndex);
|
|
314
461
|
}
|
|
315
462
|
}, [selectedIndex, range]);
|
|
@@ -326,11 +473,11 @@ function PickerGroupDate(props) {
|
|
|
326
473
|
isCenterTimerId.current = setTimeout(() => {
|
|
327
474
|
if (!scrollViewRef.current) return;
|
|
328
475
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
329
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
476
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
330
477
|
setIsTouching(false);
|
|
331
478
|
const baseValue = newIndex * itemHeightRef.current;
|
|
332
479
|
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
333
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
480
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
334
481
|
// 更新日期值
|
|
335
482
|
if (updateDay) {
|
|
336
483
|
// 解析文本中的数字(移除年、月、日等后缀)
|
|
@@ -338,6 +485,7 @@ function PickerGroupDate(props) {
|
|
|
338
485
|
const numericValue = parseInt(valueText.replace(/[^0-9]/g, ''));
|
|
339
486
|
updateDay(isNaN(numericValue) ? 0 : numericValue, parseInt(columnId));
|
|
340
487
|
}
|
|
488
|
+
isCenterTimerId.current = null;
|
|
341
489
|
}, 100);
|
|
342
490
|
};
|
|
343
491
|
// 滚动处理
|
|
@@ -348,7 +496,7 @@ function PickerGroupDate(props) {
|
|
|
348
496
|
isCenterTimerId.current = null;
|
|
349
497
|
}
|
|
350
498
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
351
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
499
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
352
500
|
if (newIndex !== currentIndex) {
|
|
353
501
|
setCurrentIndex(newIndex);
|
|
354
502
|
}
|
|
@@ -381,7 +529,10 @@ function PickerGroupDate(props) {
|
|
|
381
529
|
children: [/*#__PURE__*/jsx(View, {
|
|
382
530
|
className: "taro-picker__mask"
|
|
383
531
|
}), /*#__PURE__*/jsx(View, {
|
|
384
|
-
className: "taro-picker__indicator"
|
|
532
|
+
className: "taro-picker__indicator",
|
|
533
|
+
...(indicatorStyle ? {
|
|
534
|
+
style: indicatorStyle
|
|
535
|
+
} : {})
|
|
385
536
|
}), /*#__PURE__*/jsx(ScrollView, {
|
|
386
537
|
ref: scrollViewRef,
|
|
387
538
|
scrollY: true,
|
|
@@ -410,30 +561,37 @@ function PickerGroupRegion(props) {
|
|
|
410
561
|
// 使用selectedIndex参数,默认为0
|
|
411
562
|
colors = {}
|
|
412
563
|
} = props;
|
|
564
|
+
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
413
565
|
const scrollViewRef = React.useRef(null);
|
|
414
566
|
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
415
567
|
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
416
568
|
const [isTouching, setIsTouching] = React.useState(false);
|
|
569
|
+
const lengthScaleRatioRef = React.useRef(1);
|
|
570
|
+
const useMeasuredScaleRef = React.useRef(false);
|
|
417
571
|
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
418
572
|
const isUserBeginScrollRef = React.useRef(false);
|
|
573
|
+
// 初始化时计算 lengthScaleRatio 并判定缩放模式
|
|
419
574
|
React.useEffect(() => {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
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;
|
|
426
584
|
}
|
|
427
|
-
}
|
|
585
|
+
});
|
|
586
|
+
}, []);
|
|
587
|
+
React.useEffect(() => {
|
|
588
|
+
itemHeightRef.current = calculateItemHeight(scrollViewRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
428
589
|
}, [range.length]); // 只在range长度变化时重新计算
|
|
429
|
-
const getSelectedIndex = scrollTop => {
|
|
430
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
431
|
-
};
|
|
432
590
|
// 当selectedIndex变化时,调整滚动位置
|
|
433
591
|
React.useEffect(() => {
|
|
434
592
|
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
435
593
|
const baseValue = selectedIndex * itemHeightRef.current;
|
|
436
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
594
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
437
595
|
setCurrentIndex(selectedIndex);
|
|
438
596
|
}
|
|
439
597
|
}, [selectedIndex, range]);
|
|
@@ -449,11 +607,11 @@ function PickerGroupRegion(props) {
|
|
|
449
607
|
isCenterTimerId.current = setTimeout(() => {
|
|
450
608
|
if (!scrollViewRef.current) return;
|
|
451
609
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
452
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
610
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
453
611
|
setIsTouching(false);
|
|
454
612
|
const baseValue = newIndex * itemHeightRef.current;
|
|
455
613
|
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
456
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset);
|
|
614
|
+
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
457
615
|
updateIndex(newIndex, columnId, false, isUserBeginScrollRef.current);
|
|
458
616
|
}, 100);
|
|
459
617
|
};
|
|
@@ -465,7 +623,7 @@ function PickerGroupRegion(props) {
|
|
|
465
623
|
isCenterTimerId.current = null;
|
|
466
624
|
}
|
|
467
625
|
const scrollTop = scrollViewRef.current.scrollTop;
|
|
468
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
626
|
+
const newIndex = getSelectedIndex(scrollTop, itemHeightRef.current, lengthScaleRatioRef.current, useMeasuredScaleRef.current);
|
|
469
627
|
if (newIndex !== currentIndex) {
|
|
470
628
|
setCurrentIndex(newIndex);
|
|
471
629
|
}
|
|
@@ -499,7 +657,10 @@ function PickerGroupRegion(props) {
|
|
|
499
657
|
children: [/*#__PURE__*/jsx(View, {
|
|
500
658
|
className: "taro-picker__mask"
|
|
501
659
|
}), /*#__PURE__*/jsx(View, {
|
|
502
|
-
className: "taro-picker__indicator"
|
|
660
|
+
className: "taro-picker__indicator",
|
|
661
|
+
...(indicatorStyle ? {
|
|
662
|
+
style: indicatorStyle
|
|
663
|
+
} : {})
|
|
503
664
|
}), /*#__PURE__*/jsx(ScrollView, {
|
|
504
665
|
ref: scrollViewRef,
|
|
505
666
|
scrollY: true,
|