@tuya-miniapp/smart-ui 2.11.2-beta-4 → 2.12.0-beta-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.
@@ -1,4 +1,5 @@
1
1
  import { basic } from '../mixins/basic';
2
+ import { guardComponentMethods } from '@ray-core/event-guard';
2
3
  function mapKeys(source, target, map) {
3
4
  Object.keys(map).forEach(key => {
4
5
  if (source[key]) {
@@ -41,6 +42,9 @@ function SmartComponent(smartOptions) {
41
42
  multipleSlots: true,
42
43
  addGlobalClass: true,
43
44
  };
45
+ if (options.methods) {
46
+ options.methods = guardComponentMethods(options.methods);
47
+ }
44
48
  Component(options);
45
49
  }
46
50
  export { SmartComponent };
@@ -24,6 +24,11 @@ SmartComponent({
24
24
  resolve('success');
25
25
  }, 50);
26
26
  },
27
+ fail: err => {
28
+ setTimeout(() => {
29
+ reject(err);
30
+ }, 50);
31
+ },
27
32
  });
28
33
  });
29
34
  });
@@ -0,0 +1,2 @@
1
+ declare const _default: "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20fill%3D%22none%22%20version%3D%221.1%22%20width%3D%2252%22%20height%3D%2244%22%20viewBox%3D%220%200%2052%2044%22%3E%3Cg%3E%3Cpath%20d%3D%22M50.967297%2C23.260168Q33.797146%2C44%2C22%2C44C9.8497353%2C44%2C0%2C34.150265%2C0%2C22C0%2C9.8497353%2C9.8497353%2C0%2C22%2C0Q33.797146%2C0%2C50.967297%2C20.739832C51.570396%2C21.468315%2C51.570396%2C22.531685%2C50.967297%2C23.260168%22%20fill%3D%22currentColor%22%20fill-opacity%3D%220.30000001192092896%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E";
2
+ export default _default;
@@ -0,0 +1 @@
1
+ export default 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20fill%3D%22none%22%20version%3D%221.1%22%20width%3D%2252%22%20height%3D%2244%22%20viewBox%3D%220%200%2052%2044%22%3E%3Cg%3E%3Cpath%20d%3D%22M50.967297%2C23.260168Q33.797146%2C44%2C22%2C44C9.8497353%2C44%2C0%2C34.150265%2C0%2C22C0%2C9.8497353%2C9.8497353%2C0%2C22%2C0Q33.797146%2C0%2C50.967297%2C20.739832C51.570396%2C21.468315%2C51.570396%2C22.531685%2C50.967297%2C23.260168%22%20fill%3D%22currentColor%22%20fill-opacity%3D%220.30000001192092896%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E';
@@ -1 +1 @@
1
- @import '../common/index.css';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:#fff;--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--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-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000}.smart-manrope{font-family:Manrope,sans-serif}.smart-index-bar{position:relative}.smart-index-bar__sidebar{display:flex;flex-direction:column;position:fixed;right:0;text-align:center;top:50%;transform:translateY(-50%);-webkit-user-select:none;user-select:none}.smart-index-bar__index{font-size:var(--index-bar-index-font-size,10px);font-weight:500;line-height:var(--index-bar-index-line-height,14px);padding:0 var(--padding-base,4px) 0 var(--padding-md,16px)}
1
+ @import '../common/index.css';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:#fff;--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--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-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000}.smart-manrope{font-family:Manrope,sans-serif}.smart-index-bar{position:relative}.smart-index-bar__sidebar{display:flex;flex-direction:column;position:fixed;right:0;text-align:center;top:50%;transform:translateY(-50%);-webkit-user-select:none;user-select:none}.smart-index-bar__move-tip{line-height:0;opacity:0;pointer-events:none;position:absolute;right:100%;transform:translateY(-50%);transition:opacity .2s ease;white-space:nowrap}.smart-index-bar__move-tip--visible{opacity:1}.smart-index-bar__move-tip-inner{position:relative}.smart-index-bar__move-tip-text{color:var(--index-bar-move-tip-text-color,#fff);font-size:var(--index-bar-move-tip-text-font-size,24px);font-weight:700;left:50%;line-height:var(--index-bar-move-tip-text-line-height,32px);padding:var(--index-bar-move-tip-text-padding,0 10px 0 0);position:absolute;text-align:center;top:50%;transform:translate(-50%,-50%)}.smart-index-bar__index{font-size:var(--index-bar-index-font-size,10px);font-weight:500;line-height:var(--index-bar-index-line-height,16px);padding:var(--index-anchor-index-padding,0 4px 0 20px)}
@@ -3,6 +3,7 @@ import { SmartComponent } from '../common/component';
3
3
  import { useChildren } from '../common/relation';
4
4
  import { getRect, isDef } from '../common/utils';
5
5
  import { pageScrollMixin } from '../mixins/page-scroll';
6
+ import iconSvg from './icon';
6
7
  import ty from '../common/ty';
7
8
  const indexList = () => {
8
9
  const indexList = [];
@@ -47,6 +48,10 @@ SmartComponent({
47
48
  type: Array,
48
49
  value: indexList(),
49
50
  },
51
+ showMoveTip: {
52
+ type: Boolean,
53
+ value: false,
54
+ },
50
55
  },
51
56
  mixins: [
52
57
  pageScrollMixin(function (event) {
@@ -55,15 +60,27 @@ SmartComponent({
55
60
  }),
56
61
  ],
57
62
  data: {
63
+ iconSvg,
58
64
  activeAnchorIndex: null,
59
65
  showSidebar: false,
66
+ showMoveIcon: false,
67
+ lowestActiveIndex: -1,
68
+ currentMoveIconText: '',
69
+ moveTipTop: 0,
60
70
  },
61
71
  // @ts-ignore
62
72
  pendingAnchor: null,
73
+ // 用于过滤 clientY 偶现跳变:保留最近 3 次有效值,与其中至少 2 个都超阈值才判定本帧为异常
74
+ lastValidOffsetYHistory: null,
75
+ preMoveTipTop: null,
63
76
  watch: {
64
- activeAnchorIndex(newVal) {
65
- if (newVal !== null && newVal !== -1) {
77
+ moveTipTop(newVal) {
78
+ if (this.preMoveTipTop === null) {
79
+ this.preMoveTipTop = newVal;
80
+ }
81
+ if (newVal !== null && newVal !== 0 && newVal !== this.preMoveTipTop) {
66
82
  ty.vibrateShort({ type: 'light' });
83
+ this.preMoveTipTop = newVal;
67
84
  }
68
85
  },
69
86
  },
@@ -72,6 +89,10 @@ SmartComponent({
72
89
  },
73
90
  methods: {
74
91
  updateData() {
92
+ // 列表更新时重置记录的最低滚动节点
93
+ this.setData({
94
+ lowestActiveIndex: -1,
95
+ });
75
96
  wx.nextTick(() => {
76
97
  if (this.timer != null) {
77
98
  clearTimeout(this.timer);
@@ -81,13 +102,19 @@ SmartComponent({
81
102
  showSidebar: !!this.children.length,
82
103
  });
83
104
  this.setRect().then(() => {
105
+ this.computeLowestActiveIndex();
84
106
  this.onScroll();
85
107
  });
86
108
  }, 0);
87
109
  });
88
110
  },
89
111
  setRect() {
90
- return Promise.all([this.setAnchorsRect(), this.setListRect(), this.setSidebarRect()]);
112
+ return Promise.all([
113
+ this.setAnchorsRect(),
114
+ this.setListRect(),
115
+ this.setSidebarRect(),
116
+ this.getPageHeight(),
117
+ ]);
91
118
  },
92
119
  setAnchorsRect() {
93
120
  return Promise.all(this.children.map(anchor => getRect(anchor, '.smart-index-anchor-wrapper').then(rect => {
@@ -97,6 +124,18 @@ SmartComponent({
97
124
  });
98
125
  })));
99
126
  },
127
+ getPageHeight() {
128
+ return new Promise(resolve => {
129
+ const query = wx.createSelectorQuery();
130
+ query.selectViewport().scrollOffset(); // 也可以使用 .boundingClientRect()
131
+ query.exec(res => {
132
+ resolve(res[0].scrollHeight);
133
+ Object.assign(this, {
134
+ pageHeight: res[0].scrollHeight,
135
+ });
136
+ });
137
+ });
138
+ },
100
139
  setListRect() {
101
140
  return getRect(this, '.smart-index-bar').then(rect => {
102
141
  if (!isDef(rect)) {
@@ -119,6 +158,34 @@ SmartComponent({
119
158
  };
120
159
  });
121
160
  },
161
+ /**
162
+ * 用视口高度与内容高度几何计算「能滚动到吸顶位置」的最底部锚点索引,
163
+ * 用于 scrollToAnchor 时限制目标索引,避免点击无法滚到顶的锚点。
164
+ */
165
+ computeLowestActiveIndex() {
166
+ const { children } = this;
167
+ if (!children || children.length === 0) {
168
+ this.setData({ lowestActiveIndex: -1 });
169
+ return;
170
+ }
171
+ const { stickyOffsetTop } = this.data;
172
+ // 页面滚动内容总高度 = 最后一个锚点的 top + height(与 setAnchorsRect 中存的一致:文档坐标)
173
+ const contentHeight = this.pageHeight;
174
+ const sysInfo = wx.getSystemInfoSync && wx.getSystemInfoSync();
175
+ // @ts-ignore
176
+ const viewportHeight = (sysInfo && sysInfo.useableWindowHeight) || sysInfo.windowHeight;
177
+ const maxScrollTop = Math.max(0, contentHeight - viewportHeight);
178
+ // 锚点 i 能滚到吸顶 ⟺ 所需 scrollTop = anchor[i].top - stickyOffsetTop ≤ maxScrollTop
179
+ // 即 anchor[i].top ≤ maxScrollTop + stickyOffsetTop;从后往前取第一个满足的 i
180
+ let lowest = -1;
181
+ for (let i = children.length - 1; i >= 0; i--) {
182
+ if (children[i].top <= maxScrollTop + stickyOffsetTop) {
183
+ lowest = i;
184
+ break;
185
+ }
186
+ }
187
+ this.setData({ lowestActiveIndex: lowest });
188
+ },
122
189
  setDiffData({ target, data }) {
123
190
  const diffData = {};
124
191
  Object.keys(data).forEach(key => {
@@ -148,13 +215,22 @@ SmartComponent({
148
215
  }
149
216
  return -1;
150
217
  },
151
- onScroll() {
218
+ onScroll(controlActiveIndex) {
152
219
  const { children = [], scrollTop } = this;
153
220
  if (!children.length) {
154
221
  return;
155
222
  }
223
+ const hasIndex = controlActiveIndex !== undefined;
224
+ const currScrollGetIndex = this.getActiveAnchorIndex();
225
+ // 程序化滚动(如 sidebar 点击)未完成时,不根据当前 scrollTop 更新 UI,
226
+ // 避免 scrollTop 已变而 anchor 几何未重测导致 getActiveAnchorIndex 算错引发闪动。
227
+ // 滚动结束后在 scrollToAnchor 的 then 里会 setRect + onScroll 做一次正确更新。
228
+ if (this.pendingAnchor && this.pendingAnchor.length > 0 && !hasIndex) {
229
+ return;
230
+ }
231
+ // lowestActiveIndex 已改为在 setRect 后由 computeLowestActiveIndex() 几何计算,此处不再根据滚动推断
156
232
  const { sticky, stickyOffsetTop, zIndex, highlightColor } = this.data;
157
- const active = this.getActiveAnchorIndex();
233
+ const active = hasIndex ? controlActiveIndex : currScrollGetIndex;
158
234
  this.setDiffData({
159
235
  target: this,
160
236
  data: {
@@ -167,6 +243,7 @@ SmartComponent({
167
243
  isActiveAnchorSticky = children[active].top <= stickyOffsetTop + scrollTop;
168
244
  }
169
245
  children.forEach((item, index) => {
246
+ // 为当前的 anchor 设置 fixed 吸顶和文字颜色
170
247
  if (index === active) {
171
248
  let wrapperStyle = '';
172
249
  let anchorStyle = `
@@ -191,8 +268,9 @@ SmartComponent({
191
268
  wrapperStyle,
192
269
  },
193
270
  });
271
+ // 滚动模式时 上一个tab 要有种慢慢被滚动切换的效果
194
272
  }
195
- else if (index === active - 1) {
273
+ else if (index === active - 1 && !hasIndex) {
196
274
  const currentAnchor = children[index];
197
275
  const currentOffsetTop = currentAnchor.top;
198
276
  const targetOffsetTop = index === children.length - 1 ? this.top : children[index + 1].top;
@@ -213,6 +291,7 @@ SmartComponent({
213
291
  });
214
292
  }
215
293
  else {
294
+ // 其他恢复原样
216
295
  this.setDiffData({
217
296
  target: item,
218
297
  data: {
@@ -226,6 +305,7 @@ SmartComponent({
226
305
  }
227
306
  },
228
307
  onClick(event) {
308
+ ty.vibrateShort({ type: 'light' });
229
309
  this.scrollToAnchor(event.target.dataset.index);
230
310
  },
231
311
  onTouchMove(event) {
@@ -233,32 +313,47 @@ SmartComponent({
233
313
  return;
234
314
  const sidebarLength = this.children.length;
235
315
  const touch = event.touches[0];
236
- const itemHeight = this.sidebar.height / sidebarLength;
237
- let index = Math.floor((touch.clientY - this.sidebar.top) / itemHeight);
238
- // 有时候会莫名间断出现 -90多的情况
239
- if (index < -20) {
240
- return;
241
- }
242
- if (index < 0) {
243
- index = 0;
316
+ let offsetY = touch.clientY - this.sidebar.top;
317
+ const threshold = this.sidebar.height * 0.25;
318
+ if (!this.lastValidOffsetYHistory) {
319
+ this.lastValidOffsetYHistory = [];
244
320
  }
245
- else if (index > sidebarLength - 1) {
246
- index = sidebarLength - 1;
321
+ const nearCount = this.lastValidOffsetYHistory.filter(h => Math.abs(offsetY - h) < threshold).length;
322
+ // 与最近 3 次中至少 2 个都超阈值则判定本帧为异常,沿用上次有效值
323
+ if (this.lastValidOffsetYHistory.length === 3 && nearCount < 2) {
324
+ return;
247
325
  }
326
+ this.lastValidOffsetYHistory.push(offsetY);
327
+ if (this.lastValidOffsetYHistory.length > 3)
328
+ this.lastValidOffsetYHistory.shift();
329
+ offsetY = Math.max(0, Math.min(offsetY, this.sidebar.height));
330
+ const itemHeight = this.sidebar.height / sidebarLength;
331
+ const index = Math.floor(offsetY / itemHeight);
332
+ this.setData({
333
+ showMoveIcon: true,
334
+ moveTipTop: index * itemHeight + itemHeight / 2,
335
+ });
248
336
  this.scrollToAnchor(index);
249
337
  },
250
338
  onTouchStop() {
251
339
  if (!this.data.scrollable)
252
340
  return;
341
+ this.setData({
342
+ showMoveIcon: false,
343
+ });
253
344
  this.scrollToAnchorIndex = null;
345
+ this.lastValidOffsetYHistory = [];
254
346
  },
255
347
  scrollToAnchor(index) {
256
348
  if (typeof index !== 'number' || this.scrollToAnchorIndex === index) {
257
349
  return;
258
350
  }
259
- this.scrollToAnchorIndex = index;
351
+ const safeIndex = this.data.lowestActiveIndex !== -1 && index > this.data.lowestActiveIndex
352
+ ? this.data.lowestActiveIndex
353
+ : index;
354
+ const safeAnchor = this.children.find(item => item.data.index === this.data.indexList[safeIndex]);
260
355
  const anchor = this.children.find(item => item.data.index === this.data.indexList[index]);
261
- if (!anchor)
356
+ if (!anchor || !safeAnchor)
262
357
  return;
263
358
  // 如果当前有正在进行的滚动,将新的滚动任务加入队列
264
359
  if (!this.pendingAnchor) {
@@ -269,13 +364,18 @@ SmartComponent({
269
364
  return;
270
365
  }
271
366
  this.pendingAnchor = [anchor];
272
- anchor
367
+ this.scrollToAnchorIndex = index;
368
+ this.setData({
369
+ currentMoveIconText: anchor.data.index,
370
+ });
371
+ safeAnchor
273
372
  .scrollIntoView(this.scrollTop)
274
373
  .then(() => {
374
+ this.onScroll(safeIndex);
275
375
  if (this.pendingAnchor.length > 0 && this.pendingAnchor[0] !== anchor) {
276
376
  const index = this.data.indexList.indexOf(this.pendingAnchor[0].data.index);
277
- this.scrollToAnchor(index);
278
377
  this.pendingAnchor = [];
378
+ this.scrollToAnchor(index);
279
379
  return;
280
380
  }
281
381
  this.pendingAnchor = [];
@@ -284,8 +384,8 @@ SmartComponent({
284
384
  console.error(err);
285
385
  if (this.pendingAnchor.length > 0 && this.pendingAnchor[0] !== anchor) {
286
386
  const index = this.data.indexList.indexOf(this.pendingAnchor[0].data.index);
287
- this.scrollToAnchor(index);
288
387
  this.pendingAnchor = [];
388
+ this.scrollToAnchor(index);
289
389
  return;
290
390
  }
291
391
  this.pendingAnchor = [];
@@ -1,3 +1,6 @@
1
1
  {
2
- "component": true
2
+ "component": true,
3
+ "usingComponents": {
4
+ "smart-icon": "../icon/index"
5
+ }
3
6
  }
@@ -9,6 +9,17 @@
9
9
  catch:touchend="onTouchStop"
10
10
  catch:touchcancel="onTouchStop"
11
11
  >
12
+ <view
13
+ wx:if="{{ showMoveTip }}"
14
+ class="smart-index-bar__move-tip {{ showMoveIcon ? 'smart-index-bar__move-tip--visible' : '' }}"
15
+ style="top: {{ moveTipTop }}px;"
16
+ >
17
+ <view class="smart-index-bar__move-tip-inner">
18
+ <slot name="move-tip" />
19
+ <smart-icon name="{{iconSvg}}" size="44px" customStyle="width: 1.18em;" />
20
+ <text class="smart-index-bar__move-tip-text">{{ currentMoveIconText }}</text>
21
+ </view>
22
+ </view>
12
23
  <view
13
24
  wx:for="{{ indexList }}"
14
25
  wx:key="index"
@@ -1 +1 @@
1
- @import '../common/index.wxss';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:#fff;--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--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-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000}.smart-manrope{font-family:Manrope,sans-serif}.smart-index-bar{position:relative}.smart-index-bar__sidebar{display:flex;flex-direction:column;position:fixed;right:0;text-align:center;top:50%;transform:translateY(-50%);-webkit-user-select:none;user-select:none}.smart-index-bar__index{font-size:var(--index-bar-index-font-size,10px);font-weight:500;line-height:var(--index-bar-index-line-height,14px);padding:0 var(--padding-base,4px) 0 var(--padding-md,16px)}
1
+ @import '../common/index.wxss';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:#fff;--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--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-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000}.smart-manrope{font-family:Manrope,sans-serif}.smart-index-bar{position:relative}.smart-index-bar__sidebar{display:flex;flex-direction:column;position:fixed;right:0;text-align:center;top:50%;transform:translateY(-50%);-webkit-user-select:none;user-select:none}.smart-index-bar__move-tip{line-height:0;opacity:0;pointer-events:none;position:absolute;right:100%;transform:translateY(-50%);transition:opacity .2s ease;white-space:nowrap}.smart-index-bar__move-tip--visible{opacity:1}.smart-index-bar__move-tip-inner{position:relative}.smart-index-bar__move-tip-text{color:var(--index-bar-move-tip-text-color,#fff);font-size:var(--index-bar-move-tip-text-font-size,24px);font-weight:700;left:50%;line-height:var(--index-bar-move-tip-text-line-height,32px);padding:var(--index-bar-move-tip-text-padding,0 10px 0 0);position:absolute;text-align:center;top:50%;transform:translate(-50%,-50%)}.smart-index-bar__index{font-size:var(--index-bar-index-font-size,10px);font-weight:500;line-height:var(--index-bar-index-line-height,16px);padding:var(--index-anchor-index-padding,0 4px 0 20px)}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SmartComponent = void 0;
4
4
  var basic_1 = require("../mixins/basic");
5
+ var event_guard_1 = require("@ray-core/event-guard");
5
6
  function mapKeys(source, target, map) {
6
7
  Object.keys(map).forEach(function (key) {
7
8
  if (source[key]) {
@@ -44,6 +45,9 @@ function SmartComponent(smartOptions) {
44
45
  multipleSlots: true,
45
46
  addGlobalClass: true,
46
47
  };
48
+ if (options.methods) {
49
+ options.methods = (0, event_guard_1.guardComponentMethods)(options.methods);
50
+ }
47
51
  Component(options);
48
52
  }
49
53
  exports.SmartComponent = SmartComponent;
@@ -27,6 +27,11 @@ var relation_1 = require("../common/relation");
27
27
  resolve('success');
28
28
  }, 50);
29
29
  },
30
+ fail: function (err) {
31
+ setTimeout(function () {
32
+ reject(err);
33
+ }, 50);
34
+ },
30
35
  });
31
36
  });
32
37
  });
@@ -0,0 +1,2 @@
1
+ declare const _default: "data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20fill%3D%22none%22%20version%3D%221.1%22%20width%3D%2252%22%20height%3D%2244%22%20viewBox%3D%220%200%2052%2044%22%3E%3Cg%3E%3Cpath%20d%3D%22M50.967297%2C23.260168Q33.797146%2C44%2C22%2C44C9.8497353%2C44%2C0%2C34.150265%2C0%2C22C0%2C9.8497353%2C9.8497353%2C0%2C22%2C0Q33.797146%2C0%2C50.967297%2C20.739832C51.570396%2C21.468315%2C51.570396%2C22.531685%2C50.967297%2C23.260168%22%20fill%3D%22currentColor%22%20fill-opacity%3D%220.30000001192092896%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E";
2
+ export default _default;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20fill%3D%22none%22%20version%3D%221.1%22%20width%3D%2252%22%20height%3D%2244%22%20viewBox%3D%220%200%2052%2044%22%3E%3Cg%3E%3Cpath%20d%3D%22M50.967297%2C23.260168Q33.797146%2C44%2C22%2C44C9.8497353%2C44%2C0%2C34.150265%2C0%2C22C0%2C9.8497353%2C9.8497353%2C0%2C22%2C0Q33.797146%2C0%2C50.967297%2C20.739832C51.570396%2C21.468315%2C51.570396%2C22.531685%2C50.967297%2C23.260168%22%20fill%3D%22currentColor%22%20fill-opacity%3D%220.30000001192092896%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E';
@@ -1 +1 @@
1
- @import '../common/index.css';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:#fff;--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--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-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000}.smart-manrope{font-family:Manrope,sans-serif}.smart-index-bar{position:relative}.smart-index-bar__sidebar{display:flex;flex-direction:column;position:fixed;right:0;text-align:center;top:50%;transform:translateY(-50%);-webkit-user-select:none;user-select:none}.smart-index-bar__index{font-size:var(--index-bar-index-font-size,10px);font-weight:500;line-height:var(--index-bar-index-line-height,14px);padding:0 var(--padding-base,4px) 0 var(--padding-md,16px)}
1
+ @import '../common/index.css';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:#fff;--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--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-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000}.smart-manrope{font-family:Manrope,sans-serif}.smart-index-bar{position:relative}.smart-index-bar__sidebar{display:flex;flex-direction:column;position:fixed;right:0;text-align:center;top:50%;transform:translateY(-50%);-webkit-user-select:none;user-select:none}.smart-index-bar__move-tip{line-height:0;opacity:0;pointer-events:none;position:absolute;right:100%;transform:translateY(-50%);transition:opacity .2s ease;white-space:nowrap}.smart-index-bar__move-tip--visible{opacity:1}.smart-index-bar__move-tip-inner{position:relative}.smart-index-bar__move-tip-text{color:var(--index-bar-move-tip-text-color,#fff);font-size:var(--index-bar-move-tip-text-font-size,24px);font-weight:700;left:50%;line-height:var(--index-bar-move-tip-text-line-height,32px);padding:var(--index-bar-move-tip-text-padding,0 10px 0 0);position:absolute;text-align:center;top:50%;transform:translate(-50%,-50%)}.smart-index-bar__index{font-size:var(--index-bar-index-font-size,10px);font-weight:500;line-height:var(--index-bar-index-line-height,16px);padding:var(--index-anchor-index-padding,0 4px 0 20px)}
@@ -8,6 +8,7 @@ var component_1 = require("../common/component");
8
8
  var relation_1 = require("../common/relation");
9
9
  var utils_1 = require("../common/utils");
10
10
  var page_scroll_1 = require("../mixins/page-scroll");
11
+ var icon_1 = __importDefault(require("./icon"));
11
12
  var ty_1 = __importDefault(require("../common/ty"));
12
13
  var indexList = function () {
13
14
  var indexList = [];
@@ -52,6 +53,10 @@ var indexList = function () {
52
53
  type: Array,
53
54
  value: indexList(),
54
55
  },
56
+ showMoveTip: {
57
+ type: Boolean,
58
+ value: false,
59
+ },
55
60
  },
56
61
  mixins: [
57
62
  (0, page_scroll_1.pageScrollMixin)(function (event) {
@@ -60,15 +65,27 @@ var indexList = function () {
60
65
  }),
61
66
  ],
62
67
  data: {
68
+ iconSvg: icon_1.default,
63
69
  activeAnchorIndex: null,
64
70
  showSidebar: false,
71
+ showMoveIcon: false,
72
+ lowestActiveIndex: -1,
73
+ currentMoveIconText: '',
74
+ moveTipTop: 0,
65
75
  },
66
76
  // @ts-ignore
67
77
  pendingAnchor: null,
78
+ // 用于过滤 clientY 偶现跳变:保留最近 3 次有效值,与其中至少 2 个都超阈值才判定本帧为异常
79
+ lastValidOffsetYHistory: null,
80
+ preMoveTipTop: null,
68
81
  watch: {
69
- activeAnchorIndex: function (newVal) {
70
- if (newVal !== null && newVal !== -1) {
82
+ moveTipTop: function (newVal) {
83
+ if (this.preMoveTipTop === null) {
84
+ this.preMoveTipTop = newVal;
85
+ }
86
+ if (newVal !== null && newVal !== 0 && newVal !== this.preMoveTipTop) {
71
87
  ty_1.default.vibrateShort({ type: 'light' });
88
+ this.preMoveTipTop = newVal;
72
89
  }
73
90
  },
74
91
  },
@@ -78,6 +95,10 @@ var indexList = function () {
78
95
  methods: {
79
96
  updateData: function () {
80
97
  var _this = this;
98
+ // 列表更新时重置记录的最低滚动节点
99
+ this.setData({
100
+ lowestActiveIndex: -1,
101
+ });
81
102
  wx.nextTick(function () {
82
103
  if (_this.timer != null) {
83
104
  clearTimeout(_this.timer);
@@ -87,13 +108,19 @@ var indexList = function () {
87
108
  showSidebar: !!_this.children.length,
88
109
  });
89
110
  _this.setRect().then(function () {
111
+ _this.computeLowestActiveIndex();
90
112
  _this.onScroll();
91
113
  });
92
114
  }, 0);
93
115
  });
94
116
  },
95
117
  setRect: function () {
96
- return Promise.all([this.setAnchorsRect(), this.setListRect(), this.setSidebarRect()]);
118
+ return Promise.all([
119
+ this.setAnchorsRect(),
120
+ this.setListRect(),
121
+ this.setSidebarRect(),
122
+ this.getPageHeight(),
123
+ ]);
97
124
  },
98
125
  setAnchorsRect: function () {
99
126
  var _this = this;
@@ -106,6 +133,19 @@ var indexList = function () {
106
133
  });
107
134
  }));
108
135
  },
136
+ getPageHeight: function () {
137
+ var _this = this;
138
+ return new Promise(function (resolve) {
139
+ var query = wx.createSelectorQuery();
140
+ query.selectViewport().scrollOffset(); // 也可以使用 .boundingClientRect()
141
+ query.exec(function (res) {
142
+ resolve(res[0].scrollHeight);
143
+ Object.assign(_this, {
144
+ pageHeight: res[0].scrollHeight,
145
+ });
146
+ });
147
+ });
148
+ },
109
149
  setListRect: function () {
110
150
  var _this = this;
111
151
  return (0, utils_1.getRect)(this, '.smart-index-bar').then(function (rect) {
@@ -130,6 +170,34 @@ var indexList = function () {
130
170
  };
131
171
  });
132
172
  },
173
+ /**
174
+ * 用视口高度与内容高度几何计算「能滚动到吸顶位置」的最底部锚点索引,
175
+ * 用于 scrollToAnchor 时限制目标索引,避免点击无法滚到顶的锚点。
176
+ */
177
+ computeLowestActiveIndex: function () {
178
+ var children = this.children;
179
+ if (!children || children.length === 0) {
180
+ this.setData({ lowestActiveIndex: -1 });
181
+ return;
182
+ }
183
+ var stickyOffsetTop = this.data.stickyOffsetTop;
184
+ // 页面滚动内容总高度 = 最后一个锚点的 top + height(与 setAnchorsRect 中存的一致:文档坐标)
185
+ var contentHeight = this.pageHeight;
186
+ var sysInfo = wx.getSystemInfoSync && wx.getSystemInfoSync();
187
+ // @ts-ignore
188
+ var viewportHeight = (sysInfo && sysInfo.useableWindowHeight) || sysInfo.windowHeight;
189
+ var maxScrollTop = Math.max(0, contentHeight - viewportHeight);
190
+ // 锚点 i 能滚到吸顶 ⟺ 所需 scrollTop = anchor[i].top - stickyOffsetTop ≤ maxScrollTop
191
+ // 即 anchor[i].top ≤ maxScrollTop + stickyOffsetTop;从后往前取第一个满足的 i
192
+ var lowest = -1;
193
+ for (var i = children.length - 1; i >= 0; i--) {
194
+ if (children[i].top <= maxScrollTop + stickyOffsetTop) {
195
+ lowest = i;
196
+ break;
197
+ }
198
+ }
199
+ this.setData({ lowestActiveIndex: lowest });
200
+ },
133
201
  setDiffData: function (_a) {
134
202
  var target = _a.target, data = _a.data;
135
203
  var diffData = {};
@@ -160,14 +228,23 @@ var indexList = function () {
160
228
  }
161
229
  return -1;
162
230
  },
163
- onScroll: function () {
231
+ onScroll: function (controlActiveIndex) {
164
232
  var _this = this;
165
233
  var _a = this, _b = _a.children, children = _b === void 0 ? [] : _b, scrollTop = _a.scrollTop;
166
234
  if (!children.length) {
167
235
  return;
168
236
  }
237
+ var hasIndex = controlActiveIndex !== undefined;
238
+ var currScrollGetIndex = this.getActiveAnchorIndex();
239
+ // 程序化滚动(如 sidebar 点击)未完成时,不根据当前 scrollTop 更新 UI,
240
+ // 避免 scrollTop 已变而 anchor 几何未重测导致 getActiveAnchorIndex 算错引发闪动。
241
+ // 滚动结束后在 scrollToAnchor 的 then 里会 setRect + onScroll 做一次正确更新。
242
+ if (this.pendingAnchor && this.pendingAnchor.length > 0 && !hasIndex) {
243
+ return;
244
+ }
245
+ // lowestActiveIndex 已改为在 setRect 后由 computeLowestActiveIndex() 几何计算,此处不再根据滚动推断
169
246
  var _c = this.data, sticky = _c.sticky, stickyOffsetTop = _c.stickyOffsetTop, zIndex = _c.zIndex, highlightColor = _c.highlightColor;
170
- var active = this.getActiveAnchorIndex();
247
+ var active = hasIndex ? controlActiveIndex : currScrollGetIndex;
171
248
  this.setDiffData({
172
249
  target: this,
173
250
  data: {
@@ -180,6 +257,7 @@ var indexList = function () {
180
257
  isActiveAnchorSticky_1 = children[active].top <= stickyOffsetTop + scrollTop;
181
258
  }
182
259
  children.forEach(function (item, index) {
260
+ // 为当前的 anchor 设置 fixed 吸顶和文字颜色
183
261
  if (index === active) {
184
262
  var wrapperStyle = '';
185
263
  var anchorStyle = "\n color: ".concat(highlightColor, ";\n ");
@@ -195,8 +273,9 @@ var indexList = function () {
195
273
  wrapperStyle: wrapperStyle,
196
274
  },
197
275
  });
276
+ // 滚动模式时 上一个tab 要有种慢慢被滚动切换的效果
198
277
  }
199
- else if (index === active - 1) {
278
+ else if (index === active - 1 && !hasIndex) {
200
279
  var currentAnchor = children[index];
201
280
  var currentOffsetTop = currentAnchor.top;
202
281
  var targetOffsetTop = index === children.length - 1 ? _this.top : children[index + 1].top;
@@ -212,6 +291,7 @@ var indexList = function () {
212
291
  });
213
292
  }
214
293
  else {
294
+ // 其他恢复原样
215
295
  _this.setDiffData({
216
296
  target: item,
217
297
  data: {
@@ -225,6 +305,7 @@ var indexList = function () {
225
305
  }
226
306
  },
227
307
  onClick: function (event) {
308
+ ty_1.default.vibrateShort({ type: 'light' });
228
309
  this.scrollToAnchor(event.target.dataset.index);
229
310
  },
230
311
  onTouchMove: function (event) {
@@ -232,33 +313,48 @@ var indexList = function () {
232
313
  return;
233
314
  var sidebarLength = this.children.length;
234
315
  var touch = event.touches[0];
235
- var itemHeight = this.sidebar.height / sidebarLength;
236
- var index = Math.floor((touch.clientY - this.sidebar.top) / itemHeight);
237
- // 有时候会莫名间断出现 -90多的情况
238
- if (index < -20) {
239
- return;
240
- }
241
- if (index < 0) {
242
- index = 0;
316
+ var offsetY = touch.clientY - this.sidebar.top;
317
+ var threshold = this.sidebar.height * 0.25;
318
+ if (!this.lastValidOffsetYHistory) {
319
+ this.lastValidOffsetYHistory = [];
243
320
  }
244
- else if (index > sidebarLength - 1) {
245
- index = sidebarLength - 1;
321
+ var nearCount = this.lastValidOffsetYHistory.filter(function (h) { return Math.abs(offsetY - h) < threshold; }).length;
322
+ // 与最近 3 次中至少 2 个都超阈值则判定本帧为异常,沿用上次有效值
323
+ if (this.lastValidOffsetYHistory.length === 3 && nearCount < 2) {
324
+ return;
246
325
  }
326
+ this.lastValidOffsetYHistory.push(offsetY);
327
+ if (this.lastValidOffsetYHistory.length > 3)
328
+ this.lastValidOffsetYHistory.shift();
329
+ offsetY = Math.max(0, Math.min(offsetY, this.sidebar.height));
330
+ var itemHeight = this.sidebar.height / sidebarLength;
331
+ var index = Math.floor(offsetY / itemHeight);
332
+ this.setData({
333
+ showMoveIcon: true,
334
+ moveTipTop: index * itemHeight + itemHeight / 2,
335
+ });
247
336
  this.scrollToAnchor(index);
248
337
  },
249
338
  onTouchStop: function () {
250
339
  if (!this.data.scrollable)
251
340
  return;
341
+ this.setData({
342
+ showMoveIcon: false,
343
+ });
252
344
  this.scrollToAnchorIndex = null;
345
+ this.lastValidOffsetYHistory = [];
253
346
  },
254
347
  scrollToAnchor: function (index) {
255
348
  var _this = this;
256
349
  if (typeof index !== 'number' || this.scrollToAnchorIndex === index) {
257
350
  return;
258
351
  }
259
- this.scrollToAnchorIndex = index;
352
+ var safeIndex = this.data.lowestActiveIndex !== -1 && index > this.data.lowestActiveIndex
353
+ ? this.data.lowestActiveIndex
354
+ : index;
355
+ var safeAnchor = this.children.find(function (item) { return item.data.index === _this.data.indexList[safeIndex]; });
260
356
  var anchor = this.children.find(function (item) { return item.data.index === _this.data.indexList[index]; });
261
- if (!anchor)
357
+ if (!anchor || !safeAnchor)
262
358
  return;
263
359
  // 如果当前有正在进行的滚动,将新的滚动任务加入队列
264
360
  if (!this.pendingAnchor) {
@@ -269,13 +365,18 @@ var indexList = function () {
269
365
  return;
270
366
  }
271
367
  this.pendingAnchor = [anchor];
272
- anchor
368
+ this.scrollToAnchorIndex = index;
369
+ this.setData({
370
+ currentMoveIconText: anchor.data.index,
371
+ });
372
+ safeAnchor
273
373
  .scrollIntoView(this.scrollTop)
274
374
  .then(function () {
375
+ _this.onScroll(safeIndex);
275
376
  if (_this.pendingAnchor.length > 0 && _this.pendingAnchor[0] !== anchor) {
276
377
  var index_1 = _this.data.indexList.indexOf(_this.pendingAnchor[0].data.index);
277
- _this.scrollToAnchor(index_1);
278
378
  _this.pendingAnchor = [];
379
+ _this.scrollToAnchor(index_1);
279
380
  return;
280
381
  }
281
382
  _this.pendingAnchor = [];
@@ -284,8 +385,8 @@ var indexList = function () {
284
385
  console.error(err);
285
386
  if (_this.pendingAnchor.length > 0 && _this.pendingAnchor[0] !== anchor) {
286
387
  var index_2 = _this.data.indexList.indexOf(_this.pendingAnchor[0].data.index);
287
- _this.scrollToAnchor(index_2);
288
388
  _this.pendingAnchor = [];
389
+ _this.scrollToAnchor(index_2);
289
390
  return;
290
391
  }
291
392
  _this.pendingAnchor = [];
@@ -1,3 +1,6 @@
1
1
  {
2
- "component": true
2
+ "component": true,
3
+ "usingComponents": {
4
+ "smart-icon": "../icon/index"
5
+ }
3
6
  }
@@ -9,6 +9,17 @@
9
9
  catch:touchend="onTouchStop"
10
10
  catch:touchcancel="onTouchStop"
11
11
  >
12
+ <view
13
+ wx:if="{{ showMoveTip }}"
14
+ class="smart-index-bar__move-tip {{ showMoveIcon ? 'smart-index-bar__move-tip--visible' : '' }}"
15
+ style="top: {{ moveTipTop }}px;"
16
+ >
17
+ <view class="smart-index-bar__move-tip-inner">
18
+ <slot name="move-tip" />
19
+ <smart-icon name="{{iconSvg}}" size="44px" customStyle="width: 1.18em;" />
20
+ <text class="smart-index-bar__move-tip-text">{{ currentMoveIconText }}</text>
21
+ </view>
22
+ </view>
12
23
  <view
13
24
  wx:for="{{ indexList }}"
14
25
  wx:key="index"
@@ -1 +1 @@
1
- @import '../common/index.wxss';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:#fff;--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--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-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000}.smart-manrope{font-family:Manrope,sans-serif}.smart-index-bar{position:relative}.smart-index-bar__sidebar{display:flex;flex-direction:column;position:fixed;right:0;text-align:center;top:50%;transform:translateY(-50%);-webkit-user-select:none;user-select:none}.smart-index-bar__index{font-size:var(--index-bar-index-font-size,10px);font-weight:500;line-height:var(--index-bar-index-line-height,14px);padding:0 var(--padding-base,4px) 0 var(--padding-md,16px)}
1
+ @import '../common/index.wxss';:root{--smart-ui-overlay:rgba(0,0,0,.4);--smart-ui-bottom-sheet-dragger-node-background:rgba(0,0,0,.3);--smart-ui-dialog-background:#fff;--smart-ui-border-image:linear-gradient(90deg,transparent,rgba(0,0,0,.3),transparent);--smart-ui-battery-body-base-background:rgba(0,0,0,.25);--smart-ui-battery-text-color:rgba(0,0,0,.6);--smart-ui-battery-slash-border-color:#fff}:root[theme=dark]{--smart-ui-overlay:rgba(0,0,0,.7);--smart-ui-bottom-sheet-dragger-node-background:hsla(0,0%,100%,.3);--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-ui-battery-body-base-background:hsla(0,0%,100%,.4);--smart-ui-battery-text-color:#fff;--smart-ui-battery-slash-border-color:#000}.smart-manrope{font-family:Manrope,sans-serif}.smart-index-bar{position:relative}.smart-index-bar__sidebar{display:flex;flex-direction:column;position:fixed;right:0;text-align:center;top:50%;transform:translateY(-50%);-webkit-user-select:none;user-select:none}.smart-index-bar__move-tip{line-height:0;opacity:0;pointer-events:none;position:absolute;right:100%;transform:translateY(-50%);transition:opacity .2s ease;white-space:nowrap}.smart-index-bar__move-tip--visible{opacity:1}.smart-index-bar__move-tip-inner{position:relative}.smart-index-bar__move-tip-text{color:var(--index-bar-move-tip-text-color,#fff);font-size:var(--index-bar-move-tip-text-font-size,24px);font-weight:700;left:50%;line-height:var(--index-bar-move-tip-text-line-height,32px);padding:var(--index-bar-move-tip-text-padding,0 10px 0 0);position:absolute;text-align:center;top:50%;transform:translate(-50%,-50%)}.smart-index-bar__index{font-size:var(--index-bar-index-font-size,10px);font-weight:500;line-height:var(--index-bar-index-line-height,16px);padding:var(--index-anchor-index-padding,0 4px 0 20px)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuya-miniapp/smart-ui",
3
- "version": "2.11.2-beta-4",
3
+ "version": "2.12.0-beta-1",
4
4
  "author": "MiniApp Team",
5
5
  "license": "MIT",
6
6
  "miniprogram": "lib",
@@ -88,7 +88,8 @@
88
88
  ],
89
89
  "dependencies": {
90
90
  "@ray-js/components-ty-slider": "^0.3.8",
91
- "@tuya-miniapp/icons": "^2.3.0"
91
+ "@tuya-miniapp/icons": "^2.3.0",
92
+ "@ray-core/event-guard": "0.4.13-beta.0"
92
93
  },
93
94
  "maintainers": [
94
95
  {