@tuya-miniapp/smart-ui 2.6.4-beta-6 → 2.6.4-beta-8

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.
@@ -3,6 +3,53 @@ var style = require('../wxs/style.wxs');
3
3
  var addUnit = require('../wxs/add-unit.wxs');
4
4
  var wxUtils = require('../wxs/utils.wxs');
5
5
 
6
+ let startPo = { y: 0 }; // 记录当前拖动元素的开始的位置
7
+
8
+ const setStyle = (ownerInstance, style, selector) => {
9
+ const dom = queryComponent(ownerInstance, selector);
10
+ if (!dom) {
11
+ console.log(selector, '--selector 无法获取');
12
+ return
13
+ }
14
+ dom.setStyle(style);
15
+ };
16
+
17
+ function range(num, min, max) {
18
+ return Math.min(Math.max(num, min), max);
19
+ }
20
+
21
+ function adjustIndex(index, options) {
22
+ const count = options.length;
23
+ index = range(index, 0, count);
24
+ for (let i = index; i < count; i++) {
25
+ if (!isDisabled(options[i])) return i;
26
+ }
27
+ for (let i = index - 1; i >= 0; i--) {
28
+ if (!isDisabled(options[i])) return i;
29
+ }
30
+ }
31
+
32
+ function isDisabled(option) {
33
+ return typeof option === 'object' && option.disabled;
34
+ }
35
+
36
+ function generateRangeArray(start, end) {
37
+ const resultArray = [];
38
+ for (let i = start; i < end; i++) {
39
+ resultArray.push(i);
40
+ }
41
+ return resultArray;
42
+ }
43
+
44
+ const queryComponent = function (ownerInstance, selector) {
45
+ const instance = ownerInstance?.selectComponent(selector);
46
+ return instance;
47
+ };
48
+
49
+ function sliceArray(list, start, end) {
50
+ return list.slice(start, end);
51
+ }
52
+
6
53
  function isObj(x) {
7
54
  var type = typeof x;
8
55
  return x !== null && (type === 'object' || type === 'function');
@@ -27,53 +74,433 @@ function wrapperStyle(data) {
27
74
  'text-indent': data.unit ? '-8rpx' : '0',
28
75
  transition: 'transform ' + data.duration + 'ms ease-out',
29
76
  'line-height': addUnit(data.itemHeight),
30
- transform: 'translate3d(0, ' + offset + ', 0)',
31
77
  });
32
78
  }
33
79
  return style({
34
80
  'text-indent': data.unit ? '-8rpx' : '0',
35
81
  'line-height': addUnit(data.itemHeight),
36
- transform: 'translate3d(0, ' + offset + ', 0)',
37
- });
38
- }
39
-
40
- function wrapperInterStyle(data) {
41
- var offset = data.renderStart * data.itemHeight;
42
- offset = addUnit(offset);
43
- return style({
44
- 'padding-top': offset,
45
82
  });
46
83
  }
47
84
 
48
85
  function wrapperItemStyle(data) {
49
86
  var heightStyleStr = "height: " + data.itemHeight + 'px;'
50
- var fontStyleStr = style(data.fontStyle);
51
- var activeStyleStr = style(data.activeStyle);
87
+ var maxSideShow = data.visibleItemCount + 2;
88
+ var offsetIndex = data.animationIndex - data.index;
89
+ if (Math.abs(offsetIndex) > maxSideShow) heightStyleStr
90
+ const finOffsetIndex = offsetIndex > 0 ? Math.min(offsetIndex, maxSideShow) : Math.max(offsetIndex, -maxSideShow);
91
+ var scale = 1 - Math.abs(finOffsetIndex * 0.15);
92
+ var rotateX = rotateX = Math.abs(finOffsetIndex * 10);
93
+ var direction = offsetIndex > 0 ? 1 : -1;
94
+ var translateYIndex = Math.abs(finOffsetIndex);
95
+ var translateYOffset = translateYIndex * translateYIndex * direction * state.itemHeight * 0.1
96
+ const transStyle = style({
97
+ transform: `rotateX(${rotateX}deg) scale(${scale}) translateY(${translateYOffset}px) translateZ(0)`,
98
+ });
99
+ return transStyle + ';' + heightStyleStr
100
+ }
52
101
 
53
- // var maxSideShow = Math.floor(data.visibleItemCount / 2) + 1;
54
- // var offsetIndex = data.animationIndex - data.index;
55
- // var scale = Math.min(Math.abs(offsetIndex * 0.2), 0.2 * maxSideShow)
56
- // var rotateX = offsetIndex * 25 > 0 ? Math.min(offsetIndex * 25, 25 * maxSideShow) : Math.max(offsetIndex * 25, -25 * maxSideShow)
57
- // var translateYIndex = offsetIndex > 0 ? Math.min(offsetIndex, maxSideShow) : Math.max(offsetIndex, -maxSideShow)
58
- // const transStyle = style({
59
- // transform: `rotateX(${rotateX}deg) scale(${1 - scale}) translateY(${translateYIndex * Math.abs(translateYIndex) * Math.abs(translateYIndex) * data.itemHeight * 0.1}px) translateZ(0)`,
60
- // });
61
- // return transStyle + ';' + heightStyleStr + (fontStyleStr ? fontStyleStr + ';' : fontStyleStr) + activeStyleStr
62
- return heightStyleStr + (fontStyleStr ? fontStyleStr + ';' : fontStyleStr) + activeStyleStr
102
+ function wrapperItemTextStyle(data) {
103
+ var fontStyle = data.fontStyle;
104
+ var activeStyle = data.activeStyle;
105
+ var isActive = Math.abs(data.index - data.animationIndex) < 0.5;
106
+ return fontStyle ? fontStyle + ';' : '' + (isActive ? activeStyle + ';' : '')
63
107
  }
64
108
 
65
109
  function wrapperItemClass(data) {
66
110
  var staticClass = 'smart-ellipsis';
67
111
  var activeClass = 'active-class';
68
- var isActive = Math.abs(data.renderStart + data.index - data.animationIndex) < 0.9;
69
- return staticClass + ' ' + wxUtils.bem('picker-column__item', { disabled: data.option && data.option.disabled, selected: isActive }) + ' ' + (isActive ? activeClass : '');
112
+ var isActive = Math.abs(data.index - data.animationIndex) < 0.5;
113
+ const currOption = data.options[data.index];
114
+ return staticClass + ' ' + wxUtils.bem('picker-column__item', { disabled: currOption && currOption.disabled, selected: isActive }) + ' ' + (isActive ? activeClass : '');
70
115
  }
71
116
 
117
+ var state = {}
118
+
119
+ var preStateObj = {}
120
+
121
+ function updateState(instanceId, key, value) {
122
+ if (!key) return;
123
+ state[instanceId] = state[instanceId] || {}
124
+ state[instanceId][key] = value
125
+ }
126
+
127
+ function getCurrState(instanceId) {
128
+ return state[instanceId]
129
+ }
130
+
131
+ function updatePreState(instanceId, state) {
132
+ const preStateStr = JSON.stringify(state)
133
+ preStateObj[instanceId] = preStateStr;
134
+ }
135
+
136
+ function getPreState(instanceId) {
137
+ return preStateObj[instanceId]
138
+ }
139
+
140
+ function getDomState(ownerInstance) {
141
+ const dom = queryComponent(ownerInstance, '.smart-picker-column');
142
+ const state = dom.getDataset();
143
+ return state
144
+ }
145
+
146
+ function initDomState(instanceId, ownerInstance) {
147
+ const state = getDomState(ownerInstance);
148
+ updateState(instanceId, 'options', state.options)
149
+ updateState(instanceId, 'valueKey', state.valuekey)
150
+ updateState(instanceId, 'itemHeight', state.itemheight)
151
+ updateState(instanceId, 'visibleItemCount', state.visibleitemcount)
152
+ updateState(instanceId, 'activeIndex', state.activeindex)
153
+ updateState(instanceId, 'loop', state.loop)
154
+ updateState(instanceId, 'animationTime', state.animationtime)
155
+ }
156
+
157
+ const updateValue = (instanceId, key) => (newOptions, oldOptions, ownerInstance) => {
158
+ if (!instanceId) return;
159
+ initDomState(instanceId, ownerInstance)
160
+ updateState(instanceId, key, newOptions)
161
+ updateOffset(instanceId, ownerInstance)
162
+ }
163
+
164
+ function updateOffset(instanceId, ownerInstance) {
165
+ const state = getCurrState(instanceId);
166
+ const domState = getDomState(ownerInstance);
167
+ if(getPreState(instanceId) === JSON.stringify(domState) || !state.itemHeight || !state.visibleItemCount || !Array.isArray(state.options) || state.animationTime === undefined) {
168
+ return
169
+ }
170
+ updatePreState(instanceId, domState)
171
+ const sideCount = Math.floor(state.visibleItemCount / 2)
172
+ const optionLength = state.options.length;
173
+ updateState(instanceId, 'sideCount', sideCount);
174
+ const currActiveIndex = state.activeIndex < 0 ? 0 : state.activeIndex >= optionLength ? optionLength - 1 : state.activeIndex;
175
+ const currList = getCurrList(instanceId, state.options, currActiveIndex, ownerInstance)
176
+ updateRenderPartOffset(instanceId, ownerInstance)
177
+ const textVarStyle = {}
178
+ currList.forEach((item, index) => {
179
+ textVarStyle['--picker-item-content_' + index] = "'" + optionText(item, state.valueKey) + "'"
180
+ })
181
+ const offset = state.itemHeight * (sideCount - currActiveIndex);
182
+ updateState(instanceId, 'offset', offset)
183
+ updateState(instanceId,'offsetActiveIndex', currActiveIndex);
184
+ setStyle(ownerInstance, {
185
+ transform: 'translateY(' + addUnit(offset) + ')',
186
+ ...textVarStyle,
187
+ }, '.smart-picker-column__offset');
188
+
189
+ setTimeout(() => {
190
+ updateItemStyle(instanceId, ownerInstance);
191
+ }, 10)
192
+ }
193
+ /** 更新聚焦点位样式 */
194
+ const updateItemStyle = (instanceId, ownerInstance, time) => {
195
+ const state = getCurrState(instanceId);
196
+ const currActiveIndex = state.offsetActiveIndex;
197
+ state.viewIndexList.slice(0, 20).map((item, index) => {
198
+ const viewOptionsActiveIndex = item;
199
+ const maxSideShow = state.sideCount + 2;
200
+ const offsetIndex = currActiveIndex - viewOptionsActiveIndex;
201
+ if(Math.abs(offsetIndex) > maxSideShow) return;
202
+ const finOffsetIndex = offsetIndex > 0 ? Math.min(offsetIndex, maxSideShow) : Math.max(offsetIndex, -maxSideShow);
203
+ const scale = 1 - Math.abs(finOffsetIndex * 0.15);
204
+ const rotateX = Math.abs(finOffsetIndex * 10);
205
+ const direction = offsetIndex > 0 ? 1 : -1;
206
+ const translateYIndex = Math.abs(finOffsetIndex);
207
+ const translateYOffset = translateYIndex * translateYIndex * direction * state.itemHeight * 0.1
208
+ const className = `.smart-picker-column__item_${index}`;
209
+ setStyle(ownerInstance, {
210
+ transform: `rotateX(${rotateX}deg) scale(${scale}) translateY(${translateYOffset}px) translateZ(0)`,
211
+ transition: !time ? 'none' : 'transform ' + time + 'ms',
212
+ }, className);
213
+ })
214
+ }
215
+
216
+ const getTwoPartOffset = (activeIndex) => {
217
+ const currActiveIndex = activeIndex < 0 ? 0 : activeIndex
218
+ let partNum = Math.floor((currActiveIndex) / 10);
219
+ const lastNum = activeIndex - partNum * 10;
220
+ if (lastNum < 5 && partNum > 0) {
221
+ partNum -= 1;
222
+ }
223
+ const part2Times = Math.floor(partNum / 2);
224
+ const part2Percent = partNum % 2;
225
+ const onePartOffset = part2Percent + part2Times;
226
+ const twoPartOffset = part2Times;
227
+ return { onePartOffset , twoPartOffset }
228
+ }
229
+
230
+ const getCurrList = (instanceId, options, activeIndex, ownerInstance) => {
231
+ const { onePartOffset, twoPartOffset } = getTwoPartOffset(activeIndex);
232
+ const isReverse = onePartOffset > twoPartOffset;
233
+ updateState(instanceId, 'onePartOffset', onePartOffset)
234
+ updateState(instanceId, 'twoPartOffset', twoPartOffset)
235
+ const startPart = twoPartOffset + onePartOffset;
236
+ const viewIndexList = !isReverse ? generateRangeArray(startPart * 10, startPart * 10 + 20) : [...generateRangeArray(startPart * 10 + 10, startPart * 10 + 20), ...generateRangeArray(startPart * 10, startPart * 10 + 10)]
237
+ updateState(instanceId,'viewIndexList', viewIndexList)
238
+ // ownerInstance.callMethod('viewOptionsChange', viewIndexList);
239
+ if (!isReverse) return options.slice(startPart * 10, startPart * 10 + 20);
240
+ let firstList = options.slice(startPart * 10 + 10, startPart * 10 + 20);
241
+ const scendList = options.slice(startPart * 10, startPart * 10 + 10);
242
+ if (firstList.length < 10) {
243
+ // firstList = [...firstList, ...options.slice(0, 10 - firstList.length)];
244
+ firstList = [...firstList, ...new Array(10 - firstList.length).fill('')];
245
+ }
246
+ return [...firstList, ...scendList];
247
+ }
248
+
249
+ const updateRenderPartOffset = (instanceId, ownerInstance, direction) => {
250
+ const state = getCurrState(instanceId);
251
+ const offsetDistance = 20 * state.itemHeight;
252
+ setStyle(ownerInstance, {
253
+ transform: 'translateY(' + addUnit(offsetDistance * state.onePartOffset) + ')',
254
+ }, '.smart-picker-column__visual__item_1');
255
+ setStyle(ownerInstance, {
256
+ transform: 'translateY(' + addUnit(offsetDistance * state.twoPartOffset) + ')',
257
+ }, '.smart-picker-column__visual__item_2');
258
+ }
259
+
260
+ const checkNeedUpdateItemStyle = (instanceId, currActiveIndex) => {
261
+ const state = getCurrState(instanceId);
262
+ const { onePartOffset, twoPartOffset } = getTwoPartOffset(currActiveIndex);
263
+ return onePartOffset !== state.onePartOffset || twoPartOffset !== state.twoPartOffset;
264
+ }
265
+
266
+ const updateOptionsStyle = (instanceId, ownerInstance, style, time) => {
267
+ const state = getCurrState(instanceId);
268
+ const needUpdateListOption = checkNeedUpdateItemStyle(instanceId, state.offsetActiveIndex);
269
+ if (!needUpdateListOption) {
270
+ setStyle(ownerInstance, {
271
+ ...style,
272
+ }, '.smart-picker-column__offset');
273
+ updateItemStyle(instanceId, ownerInstance, time);
274
+ return
275
+ }
276
+ const currList = getCurrList(instanceId, state.options, state.offsetActiveIndex, ownerInstance)
277
+ updateRenderPartOffset(instanceId, ownerInstance);
278
+ const textVarStyle = getCSSVarText(instanceId, currList)
279
+ setStyle(ownerInstance, {
280
+ ...style,
281
+ ...textVarStyle,
282
+ }, '.smart-picker-column__offset');
283
+ updateItemStyle(instanceId, ownerInstance, time);
284
+ }
285
+
286
+ const getCSSVarText = (instanceId, currList) => {
287
+ const state = getCurrState(instanceId);
288
+ const textVarStyle = {}
289
+ currList.forEach((item, index) => {
290
+ textVarStyle['--picker-item-content_' + index] = "'" + optionText(item, state.valueKey) + "'"
291
+ })
292
+ return textVarStyle;
293
+ }
294
+
295
+ const touchStart = (instanceId) => (e, ownerInstance) => {
296
+ const state = getCurrState(instanceId);
297
+ if(state.endTimer) {
298
+ clearInterval(state.endTimer);
299
+ updateState(instanceId, 'endTimer', null);
300
+ updateState(instanceId, 'offset', state.offsetting);
301
+ }
302
+ const { pageY } = e.touches[0];
303
+ startPo.y = pageY;
304
+ updateState(instanceId, 'offsetList', []);
305
+ updateState(instanceId, 'moving', false);
306
+ updateState(instanceId, 'offsetting', state.offset);
307
+ }
308
+
309
+
310
+ // 滚动期间:1.更新滚动位置 2.更新聚焦点位样式 3.更新列表渲染起始位置 4.更新列表文字CSS 变量
311
+ const touchMove = (instanceId) => (e, ownerInstance) => {
312
+ const state = getCurrState(instanceId);
313
+ updateState(instanceId, 'moving', true);
314
+ const { pageY } = e.touches[0];
315
+ const offsetY = pageY - startPo.y;
316
+ const offset = state.offset + offsetY;
317
+ const newOffsetList = [...state.offsetList, offset];
318
+ const currActiveIndex = -offset / state.itemHeight + state.sideCount;
319
+ const preIndexLast = Math.abs(state.offsetActiveIndex % 1);
320
+ const curIndexLast = Math.abs(currActiveIndex % 1);
321
+ const offsetCompare = offset - state.offsetting;
322
+ const direction = offsetCompare < 0 ? 'down' : offsetCompare > 0 ? 'up' : state.movingDirection || 'down';
323
+ updateState(instanceId, 'offsetActiveIndex', currActiveIndex);
324
+ updateState(instanceId, 'offsetting', offset);
325
+ updateState(instanceId, 'offsetList', newOffsetList);
326
+ updateState(instanceId, 'movingDirection', direction);
327
+ updateOptionsStyle(instanceId, ownerInstance, {
328
+ transform: 'translateY(' + addUnit(offset) + ')',
329
+ transition: 'none',
330
+ });
331
+ if((direction === 'down' && preIndexLast <= 0.5 && curIndexLast > 0.5) || (direction === 'up' && preIndexLast >= 0.5 && curIndexLast < 0.5)) {
332
+ ownerInstance.callMethod('animationIndexChange', currActiveIndex);
333
+ ownerInstance.callMethod('vibrateShort');
334
+ }
335
+ }
336
+
337
+
338
+ const touchEnd = (instanceId) => function (e, ownerInstance) {
339
+ const state = getCurrState(instanceId);
340
+ if(!state.moving) return;
341
+ const preOffsetList = state.offsetList;
342
+
343
+ const maxUpOptionsDistance = state.loop ? state.itemHeight * 500 : state.sideCount * state.itemHeight;
344
+ const maxDownOptionsDistance = state.loop ? -state.itemHeight * 500 : -Math.max((state.options.length - state.sideCount - 1) * state.itemHeight, 0);
345
+ // 计算最后几帧的平均速度,用于惯性滚动
346
+ let recentVelocity = 0;
347
+ /** -1: 向下, 1: 向上, 0: 无滚动 */
348
+ let scrollDirection = 0;
349
+
350
+ if (preOffsetList.length >= 2) {
351
+ // 计算速度,优先使用最后几帧的数据
352
+ let recentOffset = 0;
353
+ let recentTime = 0;
354
+
355
+ if (preOffsetList.length >= 3) {
356
+ // 有3个或以上数据点,使用最后3个点计算速度
357
+ recentOffset = preOffsetList[preOffsetList.length - 1] - preOffsetList[preOffsetList.length - 3];
358
+ recentTime = 2; // 2帧间隔
359
+ } else if (preOffsetList.length === 2) {
360
+ // 只有2个数据点,使用这2个点计算速度
361
+ recentOffset = preOffsetList[1] - preOffsetList[0];
362
+ recentTime = 1; // 1帧间隔
363
+ }
364
+
365
+ // 计算速度 (px/ms)
366
+ recentVelocity = Math.abs(recentOffset) / (recentTime * 16);
367
+
368
+ // 确定滚动方向
369
+ if (recentOffset > 0) {
370
+ scrollDirection = 1; // 向上滚动
371
+ } else if (recentOffset < 0) {
372
+ scrollDirection = -1; // 向下滚动
373
+ }
374
+ }
375
+
376
+ // 惯性滚动参数配置
377
+ const minVelocity = 0.1; // 最小速度阈值,低于此值停止滚动
378
+ const maxInertiaDistance = state.itemHeight * 8; // 最大惯性滚动距离
379
+
380
+ // 计算惯性滚动距离
381
+ let inertiaDistance = 0;
382
+ if (recentVelocity > minVelocity) {
383
+ // 使用物理公式计算惯性距离:distance = velocity^2 / (2 * friction)
384
+ // 这里简化处理,直接使用速度乘以一个系数
385
+ inertiaDistance = recentVelocity * 200; // 200ms的惯性时间
386
+
387
+ // 限制最大滚动距离
388
+ if (inertiaDistance > maxInertiaDistance) {
389
+ inertiaDistance = maxInertiaDistance;
390
+ }
391
+
392
+ // 根据滚动方向确定正负值
393
+ inertiaDistance = inertiaDistance * scrollDirection;
394
+ }
395
+
396
+ // 计算最终目标位置 和 index
397
+ let targetOffset = Math.round((state.offsetting + inertiaDistance) / state.itemHeight) * state.itemHeight;
398
+ let currTargetActiveIndex = -targetOffset / state.itemHeight + state.sideCount;
399
+ currTargetActiveIndex = adjustIndex(currTargetActiveIndex, state.options);
400
+ targetOffset = -(currTargetActiveIndex - state.sideCount) * state.itemHeight;
401
+
402
+ const isNeedTransition = Math.abs(targetOffset - state.offsetting) > 1;
403
+ const time = isNeedTransition ? state.animationTime : 0;
404
+ const animationOffset = Math.abs(targetOffset - state.offsetting);
405
+ const offsetCount = Math.floor(Math.abs(currTargetActiveIndex - state.offsetActiveIndex));
406
+ if (time > 150 && animationOffset > state.itemHeight) {
407
+ const midTime = 16;
408
+ const count = Math.floor((time - 150) / midTime);
409
+ const midOffset = (targetOffset - state.offsetting)/ count;
410
+ let startCount = 0
411
+ const endTimer = setInterval(() => {
412
+ startCount++;
413
+ const currOffset = state.offsetting + midOffset;
414
+ const currIndex = -currOffset / state.itemHeight + state.sideCount;
415
+ if (startCount >= count) {
416
+ // 动画结束,设置最终状态
417
+ updateState(instanceId, 'offsetActiveIndex', currTargetActiveIndex);
418
+ clearInterval(endTimer);
419
+ updateState(instanceId, 'offsetting', targetOffset);
420
+ updateState(instanceId, 'offset', targetOffset);
421
+ updateState(instanceId, 'moving', false);
422
+ updateOptionsStyle(instanceId, ownerInstance, {
423
+ transform: 'translateY(' + addUnit(Math.round(targetOffset)) + ')',
424
+ transition: 'transform ' + (time ? time + 100 : time) + 'ms',
425
+ });
426
+ if(currTargetActiveIndex !== state.activeIndex) {
427
+ ownerInstance.callMethod('activeIndexChange', currTargetActiveIndex);
428
+ } else {
429
+ ownerInstance.callMethod('animationIndexChange', currTargetActiveIndex);
430
+ }
431
+ return
432
+ };
433
+ updateState(instanceId, 'offsetActiveIndex', currIndex);
434
+ updateState(instanceId, 'offsetting', currOffset);
435
+ updateOptionsStyle(instanceId, ownerInstance, {
436
+ transform: 'translateY(' + addUnit(Math.round(targetOffset)) + ')',
437
+ transition: 'transform ' + (time ? time + 100 : time) + 'ms',
438
+ });
439
+ }, midTime);
440
+ updateState(instanceId, 'endTimer', endTimer);
441
+ ownerInstance.callMethod('vibrateShort', offsetCount);
442
+ } else {
443
+ Math.abs(currTargetActiveIndex - state.offsetActiveIndex) >= 1 && ownerInstance.callMethod('vibrateShort');
444
+ updateState(instanceId, 'offsetActiveIndex', currTargetActiveIndex);
445
+ updateState(instanceId, 'offsetting', targetOffset);
446
+ updateState(instanceId, 'offset', targetOffset);
447
+ updateState(instanceId, 'moving', false);
448
+ updateOptionsStyle(instanceId, ownerInstance, {
449
+ transform: 'translateY(' + addUnit(Math.round(targetOffset)) + ')',
450
+ transition: 'transform ' + (time ? time + 100 : time) + 'ms',
451
+ });
452
+ if(currTargetActiveIndex !== state.activeIndex) {
453
+ ownerInstance.callMethod('activeIndexChange', currTargetActiveIndex);
454
+ } else {
455
+ ownerInstance.callMethod('animationIndexChange', currTargetActiveIndex);
456
+ }
457
+ return
458
+ }
459
+ }
460
+
461
+ const tapItem = (instanceId) => (e, ownerInstance) => {
462
+ const state = getCurrState(instanceId);
463
+ const currTargetActiveIndex = e.currentTarget.dataset.index;
464
+ const option = state.options[currTargetActiveIndex];
465
+ if (option === undefined || option && typeof option === 'object' && option.disabled) return;
466
+ const targetOffset = -(currTargetActiveIndex - state.sideCount) * state.itemHeight;
467
+ if (state.startTimer) {
468
+ clearTimeout(state.startTimer);
469
+ updateState(instanceId, 'startTimer', null);
470
+ }
471
+ if (currTargetActiveIndex === state.offsetActiveIndex) return;
472
+ const offsetCount = Math.abs(currTargetActiveIndex - state.offsetActiveIndex);
473
+ if (state.tapTimer) {
474
+ clearTimeout(state.tapTimer);
475
+ updateState(instanceId, 'tapTimer', null);
476
+ }
477
+ updateState(instanceId, 'offsetActiveIndex', currTargetActiveIndex);
478
+ updateState(instanceId, 'offsetting', targetOffset);
479
+ updateState(instanceId, 'offset', targetOffset);
480
+ updateOptionsStyle(instanceId, ownerInstance, {
481
+ transform: 'translateY(' + addUnit(Math.round(targetOffset)) + ')',
482
+ transition: 'transform 200ms',
483
+ }, 200);
484
+ ownerInstance.callMethod('vibrateShort', offsetCount, 150);
485
+ const tapTimer = setTimeout(() => {
486
+ ownerInstance.callMethod('activeIndexChange', currTargetActiveIndex);
487
+ updateState(instanceId, 'tapTimer', null);
488
+ }, 150);
489
+ updateState(instanceId, 'tapTimer', tapTimer);
490
+ }
491
+
492
+
72
493
  module.exports = {
73
494
  optionText: optionText,
74
495
  rootStyle: rootStyle,
75
496
  wrapperStyle: wrapperStyle,
76
- wrapperInterStyle: wrapperInterStyle,
77
497
  wrapperItemStyle: wrapperItemStyle,
78
- wrapperItemClass: wrapperItemClass
498
+ wrapperItemClass: wrapperItemClass,
499
+ updateValue: updateValue,
500
+ touchStart: touchStart,
501
+ touchMove: touchMove,
502
+ touchEnd: touchEnd,
503
+ sliceArray: sliceArray,
504
+ wrapperItemTextStyle: wrapperItemTextStyle,
505
+ tapItem: tapItem,
79
506
  };
@@ -1 +1 @@
1
- @import '../common/index.wxss';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-dialog-background:#fff;--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent)}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-dialog-background:#333;--smart-ui-border-image:linear-gradient(90deg,hsla(0,0%,100%,0),hsla(0,0%,100%,.3),hsla(0,0%,100%,0))}.smart-picker-column{color:var(--picker-option-selected-text-color,var(--app-B6-N1,#000));font-size:var(--picker-option-font-size,16px);font-weight:var(--font-weight-bold,500);text-align:center}.smart-picker-column,.smart-picker-column__offset{position:relative;width:100%}.smart-picker-column__visual{position:absolute;top:0;width:100%}.smart-picker-column__item{pointer-events:none}.smart-picker-column__item--selected{color:var(--picker-option-selected-text-color,var(--app-B6-N1,#000));font-weight:var(--picker-option-selected-font-weight-bold,var(--font-weight-bold,700))}.smart-picker-column__item--disabled{opacity:var(--picker-option-disabled-opacity,.3)}.smart-picker-column__mask{background:transparent;display:flex;flex-direction:column;height:100%;position:absolute;top:0;width:100%;z-index:10}.smart-picker-column__mask__item{flex:1}.smart-picker-column__unit{align-items:center;display:flex;justify-content:center;position:absolute;top:50%;transform:translateY(-50%);width:100%}.smart-picker-column__unit_text{color:var(--picker-option-unit-text-color,var(--app-B6-N4,rgba(0,0,0,.4)));font-size:var(--picker-option-unit-font-size,12px);left:100%;margin-left:var(--picker-option-unit-mid-size,4px);position:absolute;text-align:left;top:50%;transform:translateY(-50%);white-space:nowrap}.smart-picker-column__max-text{color:transparent;font-size:var(--picker-option-font-size,16px);font-weight:var(--font-weight-bold,500);position:relative}.smart-picker-column--disabled{opacity:var(--picker-option-disabled-opacity,.3)}
1
+ @import '../common/index.wxss';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-dialog-background:#fff;--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent)}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-dialog-background:#333;--smart-ui-border-image:linear-gradient(90deg,hsla(0,0%,100%,0),hsla(0,0%,100%,.3),hsla(0,0%,100%,0))}.smart-picker-column{color:var(--picker-option-selected-text-color,var(--app-B6-N1,#000));font-size:var(--picker-option-font-size,16px);font-weight:var(--font-weight-bold,500);text-align:center}.smart-picker-column,.smart-picker-column__offset{position:relative;width:100%}.smart-picker-column__visual{position:absolute;top:0;width:100%}.smart-picker-column__item--selected{color:var(--picker-option-selected-text-color,var(--app-B6-N1,#000));font-weight:var(--picker-option-selected-font-weight-bold,var(--font-weight-bold,700))}.smart-picker-column__item--disabled{opacity:var(--picker-option-disabled-opacity,.3);pointer-events:none}.smart-picker-column__mask{background:transparent;display:flex;flex-direction:column;height:100%;position:absolute;top:0;width:100%;z-index:10}.smart-picker-column__mask__item{flex:1}.smart-picker-column__unit{align-items:center;display:flex;justify-content:center;position:absolute;top:50%;transform:translateY(-50%);width:100%}.smart-picker-column__unit_text{color:var(--picker-option-unit-text-color,var(--app-B6-N4,rgba(0,0,0,.4)));font-size:var(--picker-option-unit-font-size,12px);left:100%;margin-left:var(--picker-option-unit-mid-size,4px);position:absolute;text-align:left;top:50%;transform:translateY(-50%);white-space:nowrap}.smart-picker-column__max-text{color:transparent;font-size:var(--picker-option-font-size,16px);font-weight:var(--font-weight-bold,500);position:relative}.smart-picker-column--disabled{opacity:var(--picker-option-disabled-opacity,.3)}.smart-picker-column__item_0 .smart-picker-column__item__text:after{content:var(--picker-item-content_0,"")}.smart-picker-column__item_1 .smart-picker-column__item__text:after{content:var(--picker-item-content_1,"")}.smart-picker-column__item_2 .smart-picker-column__item__text:after{content:var(--picker-item-content_2,"")}.smart-picker-column__item_3 .smart-picker-column__item__text:after{content:var(--picker-item-content_3,"")}.smart-picker-column__item_4 .smart-picker-column__item__text:after{content:var(--picker-item-content_4,"")}.smart-picker-column__item_5 .smart-picker-column__item__text:after{content:var(--picker-item-content_5,"")}.smart-picker-column__item_6 .smart-picker-column__item__text:after{content:var(--picker-item-content_6,"")}.smart-picker-column__item_7 .smart-picker-column__item__text:after{content:var(--picker-item-content_7,"")}.smart-picker-column__item_8 .smart-picker-column__item__text:after{content:var(--picker-item-content_8,"")}.smart-picker-column__item_9 .smart-picker-column__item__text:after{content:var(--picker-item-content_9,"")}.smart-picker-column__item_10 .smart-picker-column__item__text:after{content:var(--picker-item-content_10,"")}.smart-picker-column__item_11 .smart-picker-column__item__text:after{content:var(--picker-item-content_11,"")}.smart-picker-column__item_12 .smart-picker-column__item__text:after{content:var(--picker-item-content_12,"")}.smart-picker-column__item_13 .smart-picker-column__item__text:after{content:var(--picker-item-content_13,"")}.smart-picker-column__item_14 .smart-picker-column__item__text:after{content:var(--picker-item-content_14,"")}.smart-picker-column__item_15 .smart-picker-column__item__text:after{content:var(--picker-item-content_15,"")}.smart-picker-column__item_16 .smart-picker-column__item__text:after{content:var(--picker-item-content_16,"")}.smart-picker-column__item_17 .smart-picker-column__item__text:after{content:var(--picker-item-content_17,"")}.smart-picker-column__item_18 .smart-picker-column__item__text:after{content:var(--picker-item-content_18,"")}.smart-picker-column__item_19 .smart-picker-column__item__text:after{content:var(--picker-item-content_19,"")}.smart-picker-column__item_20 .smart-picker-column__item__text:after{content:var(--picker-item-content_20,"")}
@@ -0,0 +1,10 @@
1
+ function strToStyleObject(str = '') {
2
+ const styleObject = {};
3
+ str.split(';').forEach(function (item) {
4
+ const [key, value] = item.split(':');
5
+ styleObject[key] = value;
6
+ });
7
+ return styleObject;
8
+ }
9
+
10
+ module.exports = strToStyleObject;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuya-miniapp/smart-ui",
3
- "version": "2.6.4-beta-6",
3
+ "version": "2.6.4-beta-8",
4
4
  "author": "MiniApp Team",
5
5
  "license": "MIT",
6
6
  "miniprogram": "lib",