@tarojs/components-react 4.1.12-beta.6 → 4.1.12-beta.61
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/image/index.js +5 -3
- package/dist/components/image/index.js.map +1 -1
- package/dist/components/map/MapContext.js +628 -0
- package/dist/components/map/MapContext.js.map +1 -0
- package/dist/components/map/MapCustomCallout.js +91 -0
- package/dist/components/map/MapCustomCallout.js.map +1 -0
- package/dist/components/map/common.js +4 -0
- package/dist/components/map/common.js.map +1 -0
- package/dist/components/map/createMapContext.js +34 -0
- package/dist/components/map/createMapContext.js.map +1 -0
- package/dist/components/map/handler.js +50 -0
- package/dist/components/map/handler.js.map +1 -0
- package/dist/components/map/index.js +329 -0
- package/dist/components/map/index.js.map +1 -0
- package/dist/components/picker/index.js +129 -38
- package/dist/components/picker/index.js.map +1 -1
- package/dist/components/picker/picker-group-legacy.js +936 -0
- package/dist/components/picker/picker-group-legacy.js.map +1 -0
- package/dist/components/picker/picker-group-slider.js +1046 -0
- package/dist/components/picker/picker-group-slider.js.map +1 -0
- package/dist/components/picker/picker-group.js +38 -638
- package/dist/components/picker/picker-group.js.map +1 -1
- package/dist/components/scroll-view/index.js +80 -36
- package/dist/components/scroll-view/index.js.map +1 -1
- package/dist/components/switch/index.js +125 -0
- package/dist/components/switch/index.js.map +1 -0
- package/dist/components/switch/style/index.scss.js +4 -0
- package/dist/components/switch/style/index.scss.js.map +1 -0
- 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 +5 -1
- package/dist/index.js.map +1 -1
- package/dist/original/components/image/index.js +5 -3
- package/dist/original/components/image/index.js.map +1 -1
- package/dist/original/components/image/style/index.scss +5 -1
- package/dist/original/components/map/MapContext.js +628 -0
- package/dist/original/components/map/MapContext.js.map +1 -0
- package/dist/original/components/map/MapCustomCallout.js +91 -0
- package/dist/original/components/map/MapCustomCallout.js.map +1 -0
- package/dist/original/components/map/common.js +4 -0
- package/dist/original/components/map/common.js.map +1 -0
- package/dist/original/components/map/createMapContext.js +34 -0
- package/dist/original/components/map/createMapContext.js.map +1 -0
- package/dist/original/components/map/handler.js +50 -0
- package/dist/original/components/map/handler.js.map +1 -0
- package/dist/original/components/map/index.js +329 -0
- package/dist/original/components/map/index.js.map +1 -0
- package/dist/original/components/picker/index.js +129 -38
- package/dist/original/components/picker/index.js.map +1 -1
- package/dist/original/components/picker/picker-group-legacy.js +936 -0
- package/dist/original/components/picker/picker-group-legacy.js.map +1 -0
- package/dist/original/components/picker/picker-group-slider.js +1046 -0
- package/dist/original/components/picker/picker-group-slider.js.map +1 -0
- package/dist/original/components/picker/picker-group.js +38 -638
- package/dist/original/components/picker/picker-group.js.map +1 -1
- package/dist/original/components/picker/style/index.scss +9 -8
- package/dist/original/components/scroll-view/index.js +80 -36
- package/dist/original/components/scroll-view/index.js.map +1 -1
- package/dist/original/components/switch/index.js +125 -0
- package/dist/original/components/switch/index.js.map +1 -0
- package/dist/original/components/switch/style/index.scss +35 -0
- package/dist/original/contexts/ScrollElementContext.js +6 -0
- package/dist/original/contexts/ScrollElementContext.js.map +1 -0
- package/dist/original/index.js +5 -1
- package/dist/original/index.js.map +1 -1
- package/dist/solid/components/image/index.js +5 -3
- package/dist/solid/components/image/index.js.map +1 -1
- package/dist/solid/components/picker/index.js +142 -45
- package/dist/solid/components/picker/index.js.map +1 -1
- package/dist/solid/components/picker/picker-group-legacy.js +952 -0
- package/dist/solid/components/picker/picker-group-legacy.js.map +1 -0
- package/dist/solid/components/picker/picker-group-slider.js +1071 -0
- package/dist/solid/components/picker/picker-group-slider.js.map +1 -0
- package/dist/solid/components/picker/picker-group.js +34 -655
- package/dist/solid/components/picker/picker-group.js.map +1 -1
- package/dist/solid/components/scroll-view/index.js +84 -40
- 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 +8 -6
|
@@ -1,664 +1,43 @@
|
|
|
1
|
-
import { createComponent
|
|
2
|
-
import { View, ScrollView } from '@tarojs/components';
|
|
1
|
+
import { createComponent } from 'solid-js/web';
|
|
3
2
|
import Taro from '@tarojs/taro';
|
|
4
|
-
import
|
|
3
|
+
import 'react';
|
|
4
|
+
import { PickerGroupLegacy } from './picker-group-legacy.js';
|
|
5
|
+
import { PickerGroupSlider } from './picker-group-slider.js';
|
|
6
|
+
export { PickerGroupBasic, PickerGroupDate, PickerGroupRegion, PickerGroupTime } from './picker-group-slider.js';
|
|
5
7
|
|
|
6
|
-
//
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
let lengthScaleRatio = res === null || res === void 0 ? void 0 : res.lengthScaleRatio;
|
|
19
|
-
if (lengthScaleRatio == null || lengthScaleRatio === 0) {
|
|
20
|
-
console.warn('Taro.getSystemInfo: lengthScaleRatio 不存在,使用计算值');
|
|
21
|
-
lengthScaleRatio = 1;
|
|
22
|
-
if (res.windowWidth < 320) {
|
|
23
|
-
lengthScaleRatio = res.windowWidth / 320;
|
|
24
|
-
} else if (res.windowWidth >= 400 && res.windowWidth < 600) {
|
|
25
|
-
lengthScaleRatio = res.windowWidth / 400;
|
|
26
|
-
}
|
|
27
|
-
const shortSide = res.windowWidth < res.windowHeight ? res.windowWidth : res.windowHeight;
|
|
28
|
-
const isBigScreen = shortSide >= 600;
|
|
29
|
-
if (isBigScreen) {
|
|
30
|
-
lengthScaleRatio = shortSide / 720;
|
|
31
|
-
}
|
|
8
|
+
// 启用新版无障碍(slider 遮挡方案)所需的最低 app 版本;低于此版本回退旧版逐项聚焦方案
|
|
9
|
+
const MIN_A11Y_APP_VERSION = '15.9.50';
|
|
10
|
+
// 逐段比较版本号:v1 > v2 返回 1,v1 < v2 返回 -1,相等返回 0(缺失段按 0 处理)
|
|
11
|
+
function compareVersion(v1, v2) {
|
|
12
|
+
const a = String(v1).split('.');
|
|
13
|
+
const b = String(v2).split('.');
|
|
14
|
+
const len = Math.max(a.length, b.length);
|
|
15
|
+
for (let i = 0; i < len; i++) {
|
|
16
|
+
const n1 = parseInt(a[i], 10) || 0;
|
|
17
|
+
const n2 = parseInt(b[i], 10) || 0;
|
|
18
|
+
if (n1 > n2) return 1;
|
|
19
|
+
if (n1 < n2) return -1;
|
|
32
20
|
}
|
|
33
|
-
return
|
|
34
|
-
};
|
|
35
|
-
// 辅助函数:获取系统信息的 lengthScaleRatio 并设置 targetScrollTop
|
|
36
|
-
const setTargetScrollTopWithScale = function (setTargetScrollTop, baseValue, randomOffset) {
|
|
37
|
-
let lengthScaleRatio = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
|
|
38
|
-
// H5 和 weapp 不参与放大计算,直接使用 baseValue
|
|
39
|
-
if (process.env.TARO_ENV === 'h5' || process.env.TARO_ENV === 'weapp') {
|
|
40
|
-
const finalValue = randomOffset !== undefined ? baseValue + randomOffset : baseValue;
|
|
41
|
-
setTargetScrollTop(finalValue);
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
if (process.env.TARO_PLATFORM === 'harmony') {
|
|
45
|
-
const scaledValue = baseValue;
|
|
46
|
-
const finalValue = randomOffset !== undefined ? scaledValue + randomOffset : scaledValue;
|
|
47
|
-
setTargetScrollTop(finalValue);
|
|
48
|
-
} else {
|
|
49
|
-
const scaledValue = baseValue * lengthScaleRatio;
|
|
50
|
-
const finalValue = randomOffset !== undefined ? scaledValue + randomOffset : scaledValue;
|
|
51
|
-
setTargetScrollTop(finalValue);
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
function PickerGroupBasic(props) {
|
|
55
|
-
const {
|
|
56
|
-
range = [],
|
|
57
|
-
rangeKey,
|
|
58
|
-
columnId,
|
|
59
|
-
updateIndex,
|
|
60
|
-
onColumnChange,
|
|
61
|
-
selectedIndex = 0,
|
|
62
|
-
// 使用selectedIndex参数,默认为0
|
|
63
|
-
colors = {}
|
|
64
|
-
} = props;
|
|
65
|
-
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
66
|
-
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
67
|
-
const scrollViewRef = React.useRef(null);
|
|
68
|
-
const itemRefs = React.useRef([]);
|
|
69
|
-
// 使用selectedIndex初始化当前索引
|
|
70
|
-
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
71
|
-
// 触摸状态用于优化用户体验
|
|
72
|
-
const [isTouching, setIsTouching] = React.useState(false);
|
|
73
|
-
const lengthScaleRatioRef = React.useRef(1);
|
|
74
|
-
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
75
|
-
// 初始化时计算 lengthScaleRatio
|
|
76
|
-
React.useEffect(() => {
|
|
77
|
-
Taro.getSystemInfo({
|
|
78
|
-
success: res => {
|
|
79
|
-
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
80
|
-
},
|
|
81
|
-
fail: () => {
|
|
82
|
-
// 失败时使用默认值 1
|
|
83
|
-
lengthScaleRatioRef.current = 1;
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
}, []);
|
|
87
|
-
React.useEffect(() => {
|
|
88
|
-
var _a;
|
|
89
|
-
if (process.env.TARO_PLATFORM === 'harmony') {
|
|
90
|
-
itemHeightRef.current = PICKER_LINE_HEIGHT * lengthScaleRatioRef.current;
|
|
91
|
-
} else {
|
|
92
|
-
if (scrollViewRef.current && ((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.scrollHeight)) {
|
|
93
|
-
itemHeightRef.current = scrollViewRef.current.scrollHeight / scrollViewRef.current.childNodes.length;
|
|
94
|
-
} else {
|
|
95
|
-
console.warn('Height measurement anomaly');
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}, [range.length]); // 只在range长度变化时重新计算
|
|
99
|
-
// 获取选中的索引
|
|
100
|
-
const getSelectedIndex = scrollTop => {
|
|
101
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
102
|
-
};
|
|
103
|
-
// 当selectedIndex变化时,调整滚动位置
|
|
104
|
-
React.useEffect(() => {
|
|
105
|
-
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
106
|
-
const baseValue = selectedIndex * itemHeightRef.current;
|
|
107
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
108
|
-
setCurrentIndex(selectedIndex);
|
|
109
|
-
}
|
|
110
|
-
}, [selectedIndex, range]);
|
|
111
|
-
// 是否处于归中状态
|
|
112
|
-
const isCenterTimerId = React.useRef(null);
|
|
113
|
-
// 简化为直接在滚动结束时通知父组件
|
|
114
|
-
const handleScrollEnd = () => {
|
|
115
|
-
if (!scrollViewRef.current) return;
|
|
116
|
-
if (isCenterTimerId.current) {
|
|
117
|
-
clearTimeout(isCenterTimerId.current);
|
|
118
|
-
isCenterTimerId.current = null;
|
|
119
|
-
}
|
|
120
|
-
// 做一个0.1s延时 0.1s之内没有新的滑动 则把选项归到中间 然后更新选中项
|
|
121
|
-
isCenterTimerId.current = setTimeout(() => {
|
|
122
|
-
if (!scrollViewRef.current) return;
|
|
123
|
-
const scrollTop = scrollViewRef.current.scrollTop;
|
|
124
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
125
|
-
setIsTouching(false);
|
|
126
|
-
const baseValue = newIndex * itemHeightRef.current;
|
|
127
|
-
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
128
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
129
|
-
updateIndex(newIndex, columnId);
|
|
130
|
-
onColumnChange === null || onColumnChange === void 0 ? void 0 : onColumnChange({
|
|
131
|
-
columnId,
|
|
132
|
-
index: newIndex
|
|
133
|
-
});
|
|
134
|
-
isCenterTimerId.current = null;
|
|
135
|
-
}, 100);
|
|
136
|
-
};
|
|
137
|
-
// 滚动处理 - 在滚动时计算索引然后更新选中项样式
|
|
138
|
-
const handleScroll = () => {
|
|
139
|
-
if (!scrollViewRef.current) return;
|
|
140
|
-
if (isCenterTimerId.current) {
|
|
141
|
-
clearTimeout(isCenterTimerId.current);
|
|
142
|
-
isCenterTimerId.current = null;
|
|
143
|
-
}
|
|
144
|
-
const scrollTop = scrollViewRef.current.scrollTop;
|
|
145
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
146
|
-
if (newIndex !== currentIndex) {
|
|
147
|
-
setCurrentIndex(newIndex);
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
// 渲染选项
|
|
151
|
-
const pickerItem = range.map((item, index) => {
|
|
152
|
-
const content = rangeKey && item && typeof item === 'object' ? item[rangeKey] : item;
|
|
153
|
-
return createComponent(View, {
|
|
154
|
-
id: `picker-item-${columnId}-${index}`,
|
|
155
|
-
key: index,
|
|
156
|
-
ref: el => itemRefs.current[index] = el,
|
|
157
|
-
className: `taro-picker__item${index === currentIndex ? ' taro-picker__item--selected' : ''}`,
|
|
158
|
-
get style() {
|
|
159
|
-
return {
|
|
160
|
-
height: PICKER_LINE_HEIGHT,
|
|
161
|
-
color: index === currentIndex ? colors.itemSelectedColor || undefined : colors.itemDefaultColor || undefined
|
|
162
|
-
};
|
|
163
|
-
},
|
|
164
|
-
children: content
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
const realPickerItems = [...new Array(PICKER_BLANK_ITEMS).fill(null).map((_, idx) => createComponent(View, {
|
|
168
|
-
key: `blank-top-${idx}`,
|
|
169
|
-
className: "taro-picker__item taro-picker__item--blank",
|
|
170
|
-
style: {
|
|
171
|
-
height: PICKER_LINE_HEIGHT
|
|
172
|
-
}
|
|
173
|
-
})), ...pickerItem, ...new Array(PICKER_BLANK_ITEMS).fill(null).map((_, idx) => createComponent(View, {
|
|
174
|
-
key: `blank-bottom-${idx}`,
|
|
175
|
-
className: "taro-picker__item taro-picker__item--blank",
|
|
176
|
-
style: {
|
|
177
|
-
height: PICKER_LINE_HEIGHT
|
|
178
|
-
}
|
|
179
|
-
}))];
|
|
180
|
-
return createComponent(View, {
|
|
181
|
-
className: "taro-picker__group",
|
|
182
|
-
get children() {
|
|
183
|
-
return [createComponent(View, {
|
|
184
|
-
className: "taro-picker__mask"
|
|
185
|
-
}), createComponent(View, mergeProps({
|
|
186
|
-
className: "taro-picker__indicator"
|
|
187
|
-
}, indicatorStyle ? {
|
|
188
|
-
style: indicatorStyle
|
|
189
|
-
} : {})), createComponent(ScrollView, {
|
|
190
|
-
ref: scrollViewRef,
|
|
191
|
-
scrollY: true,
|
|
192
|
-
showScrollbar: false,
|
|
193
|
-
className: "taro-picker__content",
|
|
194
|
-
style: {
|
|
195
|
-
height: PICKER_LINE_HEIGHT * PICKER_VISIBLE_ITEMS
|
|
196
|
-
},
|
|
197
|
-
scrollTop: targetScrollTop,
|
|
198
|
-
onScroll: handleScroll,
|
|
199
|
-
onTouchStart: () => setIsTouching(true),
|
|
200
|
-
onScrollEnd: handleScrollEnd,
|
|
201
|
-
scrollWithAnimation: true,
|
|
202
|
-
children: realPickerItems
|
|
203
|
-
})];
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
// 时间选择器实现
|
|
208
|
-
function PickerGroupTime(props) {
|
|
209
|
-
const {
|
|
210
|
-
range = [],
|
|
211
|
-
rangeKey,
|
|
212
|
-
columnId,
|
|
213
|
-
updateIndex,
|
|
214
|
-
selectedIndex = 0,
|
|
215
|
-
colors = {}
|
|
216
|
-
} = props;
|
|
217
|
-
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
218
|
-
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
219
|
-
const scrollViewRef = React.useRef(null);
|
|
220
|
-
const itemRefs = React.useRef([]);
|
|
221
|
-
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
222
|
-
const [isTouching, setIsTouching] = React.useState(false);
|
|
223
|
-
const lengthScaleRatioRef = React.useRef(1);
|
|
224
|
-
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
225
|
-
// 初始化时计算 lengthScaleRatio
|
|
226
|
-
React.useEffect(() => {
|
|
227
|
-
Taro.getSystemInfo({
|
|
228
|
-
success: res => {
|
|
229
|
-
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
230
|
-
},
|
|
231
|
-
fail: () => {
|
|
232
|
-
// 失败时使用默认值 1
|
|
233
|
-
lengthScaleRatioRef.current = 1;
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
}, []);
|
|
237
|
-
React.useEffect(() => {
|
|
238
|
-
var _a;
|
|
239
|
-
if (process.env.TARO_PLATFORM === 'harmony') {
|
|
240
|
-
itemHeightRef.current = PICKER_LINE_HEIGHT * lengthScaleRatioRef.current;
|
|
241
|
-
} else {
|
|
242
|
-
if (scrollViewRef.current && ((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.scrollHeight)) {
|
|
243
|
-
itemHeightRef.current = scrollViewRef.current.scrollHeight / scrollViewRef.current.childNodes.length;
|
|
244
|
-
} else {
|
|
245
|
-
console.warn('Height measurement anomaly');
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}, [range.length]); // 只在range长度变化时重新计算
|
|
249
|
-
const getSelectedIndex = scrollTop => {
|
|
250
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
251
|
-
};
|
|
252
|
-
// 当selectedIndex变化时,调整滚动位置
|
|
253
|
-
React.useEffect(() => {
|
|
254
|
-
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
255
|
-
const baseValue = selectedIndex * itemHeightRef.current;
|
|
256
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
257
|
-
setCurrentIndex(selectedIndex);
|
|
258
|
-
}
|
|
259
|
-
}, [selectedIndex, range]);
|
|
260
|
-
// 是否处于归中状态
|
|
261
|
-
const isCenterTimerId = React.useRef(null);
|
|
262
|
-
// 简化为直接在滚动结束时通知父组件
|
|
263
|
-
const handleScrollEnd = () => {
|
|
264
|
-
if (!scrollViewRef.current) return;
|
|
265
|
-
if (isCenterTimerId.current) {
|
|
266
|
-
clearTimeout(isCenterTimerId.current);
|
|
267
|
-
isCenterTimerId.current = null;
|
|
268
|
-
}
|
|
269
|
-
// 做一个0.1s延时 0.1s之内没有新的滑动 则把选项归到中间 然后更新选中项
|
|
270
|
-
isCenterTimerId.current = setTimeout(() => {
|
|
271
|
-
if (!scrollViewRef.current) return;
|
|
272
|
-
const scrollTop = scrollViewRef.current.scrollTop;
|
|
273
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
274
|
-
setIsTouching(false);
|
|
275
|
-
// 调用updateIndex执行限位逻辑,获取是否触发了限位
|
|
276
|
-
const isLimited = Boolean(updateIndex(newIndex, columnId, true));
|
|
277
|
-
// 如果没有触发限位,才执行归中逻辑
|
|
278
|
-
if (!isLimited) {
|
|
279
|
-
const baseValue = newIndex * itemHeightRef.current;
|
|
280
|
-
const randomOffset = Math.random() * 0.001;
|
|
281
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
282
|
-
}
|
|
283
|
-
isCenterTimerId.current = null;
|
|
284
|
-
}, 100);
|
|
285
|
-
};
|
|
286
|
-
// 滚动处理
|
|
287
|
-
const handleScroll = () => {
|
|
288
|
-
if (!scrollViewRef.current) return;
|
|
289
|
-
if (isCenterTimerId.current) {
|
|
290
|
-
clearTimeout(isCenterTimerId.current);
|
|
291
|
-
isCenterTimerId.current = null;
|
|
292
|
-
}
|
|
293
|
-
const scrollTop = scrollViewRef.current.scrollTop;
|
|
294
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
295
|
-
if (newIndex !== currentIndex) {
|
|
296
|
-
setCurrentIndex(newIndex);
|
|
297
|
-
}
|
|
298
|
-
};
|
|
299
|
-
// 渲染选项
|
|
300
|
-
const pickerItem = range.map((item, index) => {
|
|
301
|
-
const content = rangeKey && item && typeof item === 'object' ? item[rangeKey] : item;
|
|
302
|
-
return createComponent(View, {
|
|
303
|
-
id: `picker-item-${columnId}-${index}`,
|
|
304
|
-
key: index,
|
|
305
|
-
ref: el => itemRefs.current[index] = el,
|
|
306
|
-
className: `taro-picker__item${index === currentIndex ? ' taro-picker__item--selected' : ''}`,
|
|
307
|
-
get style() {
|
|
308
|
-
return {
|
|
309
|
-
height: PICKER_LINE_HEIGHT,
|
|
310
|
-
color: index === currentIndex ? colors.itemSelectedColor || undefined : colors.itemDefaultColor || undefined
|
|
311
|
-
};
|
|
312
|
-
},
|
|
313
|
-
children: content
|
|
314
|
-
});
|
|
315
|
-
});
|
|
316
|
-
const realPickerItems = [...new Array(PICKER_BLANK_ITEMS).fill(null).map((_, idx) => createComponent(View, {
|
|
317
|
-
key: `blank-top-${idx}`,
|
|
318
|
-
className: "taro-picker__item taro-picker__item--blank",
|
|
319
|
-
style: {
|
|
320
|
-
height: PICKER_LINE_HEIGHT
|
|
321
|
-
}
|
|
322
|
-
})), ...pickerItem, ...new Array(PICKER_BLANK_ITEMS).fill(null).map((_, idx) => createComponent(View, {
|
|
323
|
-
key: `blank-bottom-${idx}`,
|
|
324
|
-
className: "taro-picker__item taro-picker__item--blank",
|
|
325
|
-
style: {
|
|
326
|
-
height: PICKER_LINE_HEIGHT
|
|
327
|
-
}
|
|
328
|
-
}))];
|
|
329
|
-
return createComponent(View, {
|
|
330
|
-
className: "taro-picker__group",
|
|
331
|
-
get children() {
|
|
332
|
-
return [createComponent(View, {
|
|
333
|
-
className: "taro-picker__mask"
|
|
334
|
-
}), createComponent(View, mergeProps({
|
|
335
|
-
className: "taro-picker__indicator"
|
|
336
|
-
}, indicatorStyle ? {
|
|
337
|
-
style: indicatorStyle
|
|
338
|
-
} : {})), createComponent(ScrollView, {
|
|
339
|
-
ref: scrollViewRef,
|
|
340
|
-
scrollY: true,
|
|
341
|
-
showScrollbar: false,
|
|
342
|
-
className: "taro-picker__content",
|
|
343
|
-
style: {
|
|
344
|
-
height: PICKER_LINE_HEIGHT * PICKER_VISIBLE_ITEMS
|
|
345
|
-
},
|
|
346
|
-
scrollTop: targetScrollTop,
|
|
347
|
-
onScroll: handleScroll,
|
|
348
|
-
onTouchStart: () => setIsTouching(true),
|
|
349
|
-
onScrollEnd: handleScrollEnd,
|
|
350
|
-
scrollWithAnimation: true,
|
|
351
|
-
children: realPickerItems
|
|
352
|
-
})];
|
|
353
|
-
}
|
|
354
|
-
});
|
|
21
|
+
return 0;
|
|
355
22
|
}
|
|
356
|
-
//
|
|
357
|
-
function
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
const scrollViewRef = React.useRef(null);
|
|
368
|
-
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
369
|
-
const [isTouching, setIsTouching] = React.useState(false);
|
|
370
|
-
const lengthScaleRatioRef = React.useRef(1);
|
|
371
|
-
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
372
|
-
// 初始化时计算 lengthScaleRatio
|
|
373
|
-
React.useEffect(() => {
|
|
374
|
-
Taro.getSystemInfo({
|
|
375
|
-
success: res => {
|
|
376
|
-
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
377
|
-
},
|
|
378
|
-
fail: () => {
|
|
379
|
-
// 失败时使用默认值 1
|
|
380
|
-
lengthScaleRatioRef.current = 1;
|
|
381
|
-
}
|
|
382
|
-
});
|
|
383
|
-
}, []);
|
|
384
|
-
React.useEffect(() => {
|
|
385
|
-
var _a;
|
|
386
|
-
if (process.env.TARO_PLATFORM === 'harmony') {
|
|
387
|
-
itemHeightRef.current = PICKER_LINE_HEIGHT * lengthScaleRatioRef.current;
|
|
388
|
-
} else {
|
|
389
|
-
if (scrollViewRef.current && ((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.scrollHeight)) {
|
|
390
|
-
itemHeightRef.current = scrollViewRef.current.scrollHeight / scrollViewRef.current.childNodes.length;
|
|
391
|
-
} else {
|
|
392
|
-
console.warn('Height measurement anomaly');
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
}, [range.length]); // 只在range长度变化时重新计算
|
|
396
|
-
const getSelectedIndex = scrollTop => {
|
|
397
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
398
|
-
};
|
|
399
|
-
// 当selectedIndex变化时,调整滚动位置
|
|
400
|
-
React.useEffect(() => {
|
|
401
|
-
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
402
|
-
const baseValue = selectedIndex * itemHeightRef.current;
|
|
403
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, undefined, lengthScaleRatioRef.current);
|
|
404
|
-
setCurrentIndex(selectedIndex);
|
|
405
|
-
}
|
|
406
|
-
}, [selectedIndex, range]);
|
|
407
|
-
// 是否处于归中状态
|
|
408
|
-
const isCenterTimerId = React.useRef(null);
|
|
409
|
-
// 简化为直接在滚动结束时通知父组件
|
|
410
|
-
const handleScrollEnd = () => {
|
|
411
|
-
if (!scrollViewRef.current) return;
|
|
412
|
-
if (isCenterTimerId.current) {
|
|
413
|
-
clearTimeout(isCenterTimerId.current);
|
|
414
|
-
isCenterTimerId.current = null;
|
|
415
|
-
}
|
|
416
|
-
// 做一个0.1s延时 0.1s之内没有新的滑动 则把选项归到中间 然后更新选中项
|
|
417
|
-
isCenterTimerId.current = setTimeout(() => {
|
|
418
|
-
if (!scrollViewRef.current) return;
|
|
419
|
-
const scrollTop = scrollViewRef.current.scrollTop;
|
|
420
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
421
|
-
setIsTouching(false);
|
|
422
|
-
const baseValue = newIndex * itemHeightRef.current;
|
|
423
|
-
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
424
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
425
|
-
// 更新日期值
|
|
426
|
-
if (updateDay) {
|
|
427
|
-
// 解析文本中的数字(移除年、月、日等后缀)
|
|
428
|
-
const valueText = range[newIndex] || '';
|
|
429
|
-
const numericValue = parseInt(valueText.replace(/[^0-9]/g, ''));
|
|
430
|
-
updateDay(isNaN(numericValue) ? 0 : numericValue, parseInt(columnId));
|
|
431
|
-
}
|
|
432
|
-
isCenterTimerId.current = null;
|
|
433
|
-
}, 100);
|
|
434
|
-
};
|
|
435
|
-
// 滚动处理
|
|
436
|
-
const handleScroll = () => {
|
|
437
|
-
if (!scrollViewRef.current) return;
|
|
438
|
-
if (isCenterTimerId.current) {
|
|
439
|
-
clearTimeout(isCenterTimerId.current);
|
|
440
|
-
isCenterTimerId.current = null;
|
|
441
|
-
}
|
|
442
|
-
const scrollTop = scrollViewRef.current.scrollTop;
|
|
443
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
444
|
-
if (newIndex !== currentIndex) {
|
|
445
|
-
setCurrentIndex(newIndex);
|
|
446
|
-
}
|
|
447
|
-
};
|
|
448
|
-
// 渲染选项
|
|
449
|
-
const pickerItem = range.map((item, index) => {
|
|
450
|
-
return createComponent(View, {
|
|
451
|
-
id: `picker-item-${columnId}-${index}`,
|
|
452
|
-
key: index,
|
|
453
|
-
className: `taro-picker__item${index === currentIndex ? ' taro-picker__item--selected' : ''}`,
|
|
454
|
-
get style() {
|
|
455
|
-
return {
|
|
456
|
-
height: PICKER_LINE_HEIGHT,
|
|
457
|
-
color: index === currentIndex ? colors.itemSelectedColor || undefined : colors.itemDefaultColor || undefined
|
|
458
|
-
};
|
|
459
|
-
},
|
|
460
|
-
children: item
|
|
461
|
-
});
|
|
462
|
-
});
|
|
463
|
-
const realPickerItems = [...new Array(PICKER_BLANK_ITEMS).fill(null).map((_, idx) => createComponent(View, {
|
|
464
|
-
key: `blank-top-${idx}`,
|
|
465
|
-
className: "taro-picker__item taro-picker__item--blank",
|
|
466
|
-
style: {
|
|
467
|
-
height: PICKER_LINE_HEIGHT
|
|
468
|
-
}
|
|
469
|
-
})), ...pickerItem, ...new Array(PICKER_BLANK_ITEMS).fill(null).map((_, idx) => createComponent(View, {
|
|
470
|
-
key: `blank-bottom-${idx}`,
|
|
471
|
-
className: "taro-picker__item taro-picker__item--blank",
|
|
472
|
-
style: {
|
|
473
|
-
height: PICKER_LINE_HEIGHT
|
|
474
|
-
}
|
|
475
|
-
}))];
|
|
476
|
-
return createComponent(View, {
|
|
477
|
-
className: "taro-picker__group",
|
|
478
|
-
get children() {
|
|
479
|
-
return [createComponent(View, {
|
|
480
|
-
className: "taro-picker__mask"
|
|
481
|
-
}), createComponent(View, mergeProps({
|
|
482
|
-
className: "taro-picker__indicator"
|
|
483
|
-
}, indicatorStyle ? {
|
|
484
|
-
style: indicatorStyle
|
|
485
|
-
} : {})), createComponent(ScrollView, {
|
|
486
|
-
ref: scrollViewRef,
|
|
487
|
-
scrollY: true,
|
|
488
|
-
showScrollbar: false,
|
|
489
|
-
className: "taro-picker__content",
|
|
490
|
-
style: {
|
|
491
|
-
height: PICKER_LINE_HEIGHT * PICKER_VISIBLE_ITEMS
|
|
492
|
-
},
|
|
493
|
-
scrollTop: targetScrollTop,
|
|
494
|
-
onScroll: handleScroll,
|
|
495
|
-
onTouchStart: () => setIsTouching(true),
|
|
496
|
-
onScrollEnd: handleScrollEnd,
|
|
497
|
-
scrollWithAnimation: true,
|
|
498
|
-
children: realPickerItems
|
|
499
|
-
})];
|
|
500
|
-
}
|
|
501
|
-
});
|
|
502
|
-
}
|
|
503
|
-
// 地区选择器实现
|
|
504
|
-
function PickerGroupRegion(props) {
|
|
505
|
-
const {
|
|
506
|
-
range = [],
|
|
507
|
-
rangeKey,
|
|
508
|
-
columnId,
|
|
509
|
-
updateIndex,
|
|
510
|
-
selectedIndex = 0,
|
|
511
|
-
// 使用selectedIndex参数,默认为0
|
|
512
|
-
colors = {}
|
|
513
|
-
} = props;
|
|
514
|
-
const indicatorStyle = colors.lineColor ? getIndicatorStyle(colors.lineColor) : null;
|
|
515
|
-
const scrollViewRef = React.useRef(null);
|
|
516
|
-
const [targetScrollTop, setTargetScrollTop] = React.useState(0);
|
|
517
|
-
const [currentIndex, setCurrentIndex] = React.useState(selectedIndex);
|
|
518
|
-
const [isTouching, setIsTouching] = React.useState(false);
|
|
519
|
-
const lengthScaleRatioRef = React.useRef(1);
|
|
520
|
-
const itemHeightRef = React.useRef(PICKER_LINE_HEIGHT);
|
|
521
|
-
const isUserBeginScrollRef = React.useRef(false);
|
|
522
|
-
// 初始化时计算 lengthScaleRatio
|
|
523
|
-
React.useEffect(() => {
|
|
524
|
-
Taro.getSystemInfo({
|
|
525
|
-
success: res => {
|
|
526
|
-
lengthScaleRatioRef.current = calculateLengthScaleRatio(res);
|
|
527
|
-
},
|
|
528
|
-
fail: () => {
|
|
529
|
-
// 失败时使用默认值 1
|
|
530
|
-
lengthScaleRatioRef.current = 1;
|
|
531
|
-
}
|
|
532
|
-
});
|
|
533
|
-
}, []);
|
|
534
|
-
React.useEffect(() => {
|
|
535
|
-
var _a;
|
|
536
|
-
if (process.env.TARO_PLATFORM === 'harmony') {
|
|
537
|
-
itemHeightRef.current = PICKER_LINE_HEIGHT * lengthScaleRatioRef.current;
|
|
538
|
-
} else {
|
|
539
|
-
if (scrollViewRef.current && ((_a = scrollViewRef.current) === null || _a === void 0 ? void 0 : _a.scrollHeight)) {
|
|
540
|
-
itemHeightRef.current = scrollViewRef.current.scrollHeight / scrollViewRef.current.childNodes.length;
|
|
541
|
-
} else {
|
|
542
|
-
console.warn('Height measurement anomaly');
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
}, [range.length]); // 只在range长度变化时重新计算
|
|
546
|
-
const getSelectedIndex = scrollTop => {
|
|
547
|
-
return Math.round(scrollTop / itemHeightRef.current);
|
|
548
|
-
};
|
|
549
|
-
// 当selectedIndex变化时,调整滚动位置
|
|
550
|
-
React.useEffect(() => {
|
|
551
|
-
if (scrollViewRef.current && range.length > 0 && !isTouching) {
|
|
552
|
-
const baseValue = selectedIndex * itemHeightRef.current;
|
|
553
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue);
|
|
554
|
-
setCurrentIndex(selectedIndex);
|
|
555
|
-
}
|
|
556
|
-
}, [selectedIndex, range]);
|
|
557
|
-
// 滚动结束处理
|
|
558
|
-
const isCenterTimerId = React.useRef(null);
|
|
559
|
-
const handleScrollEnd = () => {
|
|
560
|
-
if (!scrollViewRef.current) return;
|
|
561
|
-
if (isCenterTimerId.current) {
|
|
562
|
-
clearTimeout(isCenterTimerId.current);
|
|
563
|
-
isCenterTimerId.current = null;
|
|
564
|
-
}
|
|
565
|
-
// 做一个0.1s延时 0.1s之内没有新的滑动 则把选项归到中间 然后更新选中项
|
|
566
|
-
isCenterTimerId.current = setTimeout(() => {
|
|
567
|
-
if (!scrollViewRef.current) return;
|
|
568
|
-
const scrollTop = scrollViewRef.current.scrollTop;
|
|
569
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
570
|
-
setIsTouching(false);
|
|
571
|
-
const baseValue = newIndex * itemHeightRef.current;
|
|
572
|
-
const randomOffset = Math.random() * 0.001; // 随机数为了在一个项内滚动时强制刷新
|
|
573
|
-
setTargetScrollTopWithScale(setTargetScrollTop, baseValue, randomOffset, lengthScaleRatioRef.current);
|
|
574
|
-
updateIndex(newIndex, columnId, false, isUserBeginScrollRef.current);
|
|
575
|
-
}, 100);
|
|
576
|
-
};
|
|
577
|
-
// 滚动处理 - 在滚动时计算索引
|
|
578
|
-
const handleScroll = () => {
|
|
579
|
-
if (!scrollViewRef.current) return;
|
|
580
|
-
if (isCenterTimerId.current) {
|
|
581
|
-
clearTimeout(isCenterTimerId.current);
|
|
582
|
-
isCenterTimerId.current = null;
|
|
583
|
-
}
|
|
584
|
-
const scrollTop = scrollViewRef.current.scrollTop;
|
|
585
|
-
const newIndex = getSelectedIndex(scrollTop);
|
|
586
|
-
if (newIndex !== currentIndex) {
|
|
587
|
-
setCurrentIndex(newIndex);
|
|
588
|
-
}
|
|
589
|
-
};
|
|
590
|
-
// 渲染选项
|
|
591
|
-
const pickerItem = range.map((item, index) => {
|
|
592
|
-
const content = rangeKey && item && typeof item === 'object' ? item[rangeKey] : item;
|
|
593
|
-
return createComponent(View, {
|
|
594
|
-
id: `picker-item-${columnId}-${index}`,
|
|
595
|
-
key: index,
|
|
596
|
-
className: `taro-picker__item${index === currentIndex ? ' taro-picker__item--selected' : ''}`,
|
|
597
|
-
get style() {
|
|
598
|
-
return {
|
|
599
|
-
height: PICKER_LINE_HEIGHT,
|
|
600
|
-
color: index === currentIndex ? colors.itemSelectedColor || undefined : colors.itemDefaultColor || undefined
|
|
601
|
-
};
|
|
602
|
-
},
|
|
603
|
-
children: content
|
|
604
|
-
});
|
|
605
|
-
});
|
|
606
|
-
const realPickerItems = [...new Array(PICKER_BLANK_ITEMS).fill(null).map((_, idx) => createComponent(View, {
|
|
607
|
-
key: `blank-top-${idx}`,
|
|
608
|
-
className: "taro-picker__item taro-picker__item--blank",
|
|
609
|
-
style: {
|
|
610
|
-
height: PICKER_LINE_HEIGHT
|
|
611
|
-
}
|
|
612
|
-
})), ...pickerItem, ...new Array(PICKER_BLANK_ITEMS).fill(null).map((_, idx) => createComponent(View, {
|
|
613
|
-
key: `blank-bottom-${idx}`,
|
|
614
|
-
className: "taro-picker__item taro-picker__item--blank",
|
|
615
|
-
style: {
|
|
616
|
-
height: PICKER_LINE_HEIGHT
|
|
617
|
-
}
|
|
618
|
-
}))];
|
|
619
|
-
return createComponent(View, {
|
|
620
|
-
className: "taro-picker__group",
|
|
621
|
-
get children() {
|
|
622
|
-
return [createComponent(View, {
|
|
623
|
-
className: "taro-picker__mask"
|
|
624
|
-
}), createComponent(View, mergeProps({
|
|
625
|
-
className: "taro-picker__indicator"
|
|
626
|
-
}, indicatorStyle ? {
|
|
627
|
-
style: indicatorStyle
|
|
628
|
-
} : {})), createComponent(ScrollView, {
|
|
629
|
-
ref: scrollViewRef,
|
|
630
|
-
scrollY: true,
|
|
631
|
-
showScrollbar: false,
|
|
632
|
-
className: "taro-picker__content",
|
|
633
|
-
style: {
|
|
634
|
-
height: PICKER_LINE_HEIGHT * PICKER_VISIBLE_ITEMS
|
|
635
|
-
},
|
|
636
|
-
scrollTop: targetScrollTop,
|
|
637
|
-
onScroll: handleScroll,
|
|
638
|
-
onTouchStart: () => {
|
|
639
|
-
setIsTouching(true);
|
|
640
|
-
isUserBeginScrollRef.current = true;
|
|
641
|
-
},
|
|
642
|
-
onScrollEnd: handleScrollEnd,
|
|
643
|
-
scrollWithAnimation: true,
|
|
644
|
-
children: realPickerItems
|
|
645
|
-
})];
|
|
646
|
-
}
|
|
647
|
-
});
|
|
23
|
+
// 读取运行环境判定是否启用新版无障碍:须同时满足 dynamic 模式 且 app 版本 >= 15.9.50;任一不满足或取不到版本时保守回退旧版(线上稳定实现)
|
|
24
|
+
function resolveUseSliderA11y() {
|
|
25
|
+
// 仅 dynamic 模式启用新版无障碍
|
|
26
|
+
if (process.env.TARO_ENV !== 'dynamic') return false;
|
|
27
|
+
try {
|
|
28
|
+
const version = Taro.getSystemInfoSync().version || '';
|
|
29
|
+
if (!version) return false;
|
|
30
|
+
return compareVersion(version, MIN_A11Y_APP_VERSION) >= 0;
|
|
31
|
+
} catch (_a) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
648
34
|
}
|
|
649
|
-
//
|
|
35
|
+
// 默认导出:按 app 版本整体分发到新版(slider)或旧版(legacy)无障碍实现
|
|
650
36
|
function PickerGroup(props) {
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
case 'date':
|
|
655
|
-
return createComponent(PickerGroupDate, props);
|
|
656
|
-
case 'region':
|
|
657
|
-
return createComponent(PickerGroupRegion, props);
|
|
658
|
-
default:
|
|
659
|
-
return createComponent(PickerGroupBasic, props);
|
|
660
|
-
}
|
|
37
|
+
// 在组件渲染时判定(此时 Taro runtime 已就绪,避免模块加载期 API 未初始化)
|
|
38
|
+
const useSliderA11y = resolveUseSliderA11y();
|
|
39
|
+
return useSliderA11y ? createComponent(PickerGroupSlider, props) : createComponent(PickerGroupLegacy, props);
|
|
661
40
|
}
|
|
662
41
|
|
|
663
|
-
export { PickerGroup
|
|
42
|
+
export { PickerGroup };
|
|
664
43
|
//# sourceMappingURL=picker-group.js.map
|