@arco-design/mobile-react 2.27.1 → 2.27.2

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.
Files changed (47) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.en-US.md +2 -2
  3. package/README.md +2 -2
  4. package/cjs/_helpers/index.d.ts +1 -0
  5. package/cjs/_helpers/index.js +10 -0
  6. package/cjs/index-bar/type.d.ts +3 -3
  7. package/cjs/load-more/index.js +4 -1
  8. package/cjs/nav-bar/index.js +2 -2
  9. package/cjs/show-monitor/index.js +112 -38
  10. package/cjs/swipe-load/demo/style/css/mobile.css +3 -0
  11. package/cjs/swipe-load/demo/style/mobile.less +11 -0
  12. package/cjs/swipe-load/index.js +86 -32
  13. package/cjs/swipe-load/style/css/index.css +3 -0
  14. package/cjs/swipe-load/style/index.less +7 -0
  15. package/cjs/swipe-load/type.d.ts +29 -0
  16. package/cjs/tabs/index.js +1 -0
  17. package/dist/index.js +218 -81
  18. package/dist/index.min.js +4 -4
  19. package/dist/style.css +3 -0
  20. package/dist/style.min.css +1 -1
  21. package/esm/_helpers/index.d.ts +1 -0
  22. package/esm/_helpers/index.js +7 -0
  23. package/esm/index-bar/type.d.ts +3 -3
  24. package/esm/load-more/index.js +4 -1
  25. package/esm/nav-bar/index.js +2 -2
  26. package/esm/show-monitor/index.js +112 -38
  27. package/esm/swipe-load/demo/style/css/mobile.css +3 -0
  28. package/esm/swipe-load/demo/style/mobile.less +11 -0
  29. package/esm/swipe-load/index.js +85 -32
  30. package/esm/swipe-load/style/css/index.css +3 -0
  31. package/esm/swipe-load/style/index.less +7 -0
  32. package/esm/swipe-load/type.d.ts +29 -0
  33. package/esm/tabs/index.js +1 -0
  34. package/package.json +3 -3
  35. package/umd/_helpers/index.d.ts +1 -0
  36. package/umd/_helpers/index.js +10 -0
  37. package/umd/index-bar/type.d.ts +3 -3
  38. package/umd/load-more/index.js +4 -1
  39. package/umd/nav-bar/index.js +2 -2
  40. package/umd/show-monitor/index.js +112 -38
  41. package/umd/swipe-load/demo/style/css/mobile.css +3 -0
  42. package/umd/swipe-load/demo/style/mobile.less +11 -0
  43. package/umd/swipe-load/index.js +88 -36
  44. package/umd/swipe-load/style/css/index.css +3 -0
  45. package/umd/swipe-load/style/index.less +7 -0
  46. package/umd/swipe-load/type.d.ts +29 -0
  47. package/umd/tabs/index.js +1 -0
@@ -9,7 +9,7 @@ export interface IndexBarBaseData {
9
9
  */
10
10
  content: ReactNode;
11
11
  }
12
- interface IndexBarGroupItem<Data extends IndexBarBaseData> {
12
+ interface IndexBarGroupItem<Data extends IndexBarBaseData = IndexBarBaseData> {
13
13
  /**
14
14
  * IndexBarGroup对应的索引
15
15
  * @en Index corresponding to IndexBarGroup
@@ -39,7 +39,7 @@ export interface IndexBarSideBarProps {
39
39
  renderSideBar?: (Content: ReactNode) => ReactElement;
40
40
  renderTip?: (index: IndexBarIndexType) => ReactNode;
41
41
  }
42
- export interface IndexBarGroupProps<Data extends IndexBarBaseData> extends IndexBarGroupItem<Data> {
42
+ export interface IndexBarGroupProps<Data extends IndexBarBaseData = IndexBarBaseData> extends IndexBarGroupItem<Data> {
43
43
  /**
44
44
  * 自定义类名
45
45
  * @en Custom classname
@@ -78,7 +78,7 @@ export interface IndexBarGroupProps<Data extends IndexBarBaseData> extends Index
78
78
  }
79
79
  export interface IndexBarGroupRef extends BaseRef {
80
80
  }
81
- export interface IndexBarProps<Data extends IndexBarBaseData> {
81
+ export interface IndexBarProps<Data extends IndexBarBaseData = IndexBarBaseData> {
82
82
  /**
83
83
  * 自定义类名
84
84
  * @en Custom classname
@@ -80,11 +80,14 @@
80
80
 
81
81
  changeStatus('loading', scene);
82
82
  getData == null ? void 0 : getData(function (st) {
83
- lastScrollEndRef.current = false;
84
83
  changeStatus(st, 'manual');
85
84
  });
86
85
  }, [blockWhenLoading, changeStatus, getData]);
87
86
  (0, _react.useEffect)(function () {
87
+ if (!blockWhenLoading || nowStatus !== 'loading') {
88
+ lastScrollEndRef.current = false;
89
+ }
90
+
88
91
  statusRef.current = nowStatus;
89
92
  }, [nowStatus]);
90
93
  (0, _helpers.useUpdateEffect)(function () {
@@ -150,7 +150,7 @@
150
150
  ref: navBarRef,
151
151
  className: (0, _mobileUtils.cls)(wrapClass, prefixCls + "-nav-bar", (_cls = {}, _cls[prefixCls + "-nav-bar-fixed"] = fixed, _cls[prefixCls + "-nav-bar-float"] = !placeholder, _cls[prefixCls + "-nav-bar-hide"] = scrollToggleHide, _cls)),
152
152
  style: (0, _extends2.default)({
153
- paddingTop: fixed && statusBarHeight ? statusBarHeight + "px" : ''
153
+ paddingTop: fixed && statusBarHeight ? statusBarHeight + "px" : '0px'
154
154
  }, style || {}, relBackground ? {
155
155
  background: relBackground
156
156
  } : {}),
@@ -159,7 +159,7 @@
159
159
  }, /*#__PURE__*/_react.default.createElement("div", {
160
160
  className: (0, _mobileUtils.cls)(className, system, prefixCls + "-nav-bar-wrapper", (_cls2 = {}, _cls2[prefixCls + "-nav-bar-wrapper-fixed"] = fixed, _cls2[prefixCls + "-nav-bar-wrapper-border"] = hasBottomLine, _cls2)),
161
161
  style: (0, _extends2.default)({
162
- paddingTop: statusBarHeight ? statusBarHeight + "px" : ''
162
+ paddingTop: statusBarHeight ? statusBarHeight + "px" : '0px'
163
163
  }, customStyle)
164
164
  }, /*#__PURE__*/_react.default.createElement("div", {
165
165
  className: prefixCls + "-nav-bar-inner all-border-box"
@@ -38,6 +38,18 @@
38
38
 
39
39
  var listeners = {};
40
40
  var onOnceEmittedListeners = {};
41
+ /**
42
+ * Intersection Observer 同一 root 节点下的监听队列
43
+ * @en Intersection Observer Listening queue under the same root node
44
+ */
45
+
46
+ var ioListeners = [];
47
+ /**
48
+ * Intersection Observer 监听 visible 状态队列
49
+ * @en Intersection Observer listens to the visible status queue
50
+ */
51
+
52
+ var ioVisibleList = [];
41
53
  var throttlingVisibleChange;
42
54
  /**
43
55
  * 通过滚动事件监测 children 是否进入视口或离开视口。
@@ -85,12 +97,6 @@
85
97
  */
86
98
 
87
99
  var domRefParent = (0, _react.useRef)(null);
88
- /**
89
- * 当前元素是否在可视区域内
90
- * @en Whether the current element is in the visible area
91
- */
92
-
93
- var isVisible = (0, _react.useRef)(false);
94
100
  /**
95
101
  * 保存当前节点信息,类似于 class component 中 this
96
102
  * @en Save current node information, similar to this in class component
@@ -137,10 +143,8 @@
137
143
  * @en Reset the initial visible state of the element to false, and re-detect the visibility of the element, the priority is lower than 'disabled'(Usually used to re-listen when elements inside ShowMonitor change)
138
144
  */
139
145
  flushVisibleStatus: function flushVisibleStatus() {
140
- isVisible.current = false;
141
-
142
- if (isSupportNativeApi && io.current && domRef.current) {
143
- disabled ? io.current.unobserve(domRef.current) : io.current.observe(domRef.current);
146
+ if (isSupportNativeApi) {
147
+ disabled ? ioUnobserve() : ioObserve();
144
148
  } else if (listener.current) {
145
149
  var _key = wrapperKey.current;
146
150
 
@@ -204,7 +208,7 @@
204
208
  */
205
209
 
206
210
 
207
- curVisible !== preVisible.current && handleCheckChildrenExist() && onCompVisibleChange(curVisible, node);
211
+ curVisible !== preVisible && handleCheckChildrenExist() && onCompVisibleChange(curVisible, node);
208
212
  var key = wrapperKey.current;
209
213
  /**
210
214
  * 监听一次后加入 pendingList 队列,随后被 listeners 过滤掉
@@ -220,8 +224,7 @@
220
224
  */
221
225
 
222
226
 
223
- curVisible && !preVisible.current && compOnce && onOnceEmittedListeners[key].push(component);
224
- preVisible.current = curVisible;
227
+ curVisible && !preVisible && compOnce && onOnceEmittedListeners[key].push(component);
225
228
  }
226
229
 
227
230
  var checkVisibleHandler = (0, _react.useCallback)(function () {
@@ -241,22 +244,98 @@
241
244
  }
242
245
 
243
246
  function handleObserverStatusChange(entries) {
244
- var _io$current;
247
+ entries.forEach(function (entry) {
248
+ var isIntersecting = entry.isIntersecting,
249
+ target = entry.target;
250
+ var visibleItem = ioVisibleList.find(function (item) {
251
+ return item.node === target;
252
+ });
245
253
 
246
- var isIntersecting = entries[0].isIntersecting;
247
- /**
248
- * 当前元素 visible 对比之前发生改变,触发回调函数
249
- * @en Callback when the visible status of current element changes before the comparison
250
- */
254
+ if (visibleItem) {
255
+ var curVisible = visibleItem.isVisible,
256
+ onCompVisibleChange = visibleItem.onVisibleChange,
257
+ onceEmit = visibleItem.once;
258
+ /**
259
+ * 当前元素 visible 对比之前发生改变,触发回调函数
260
+ * @en Callback when the visible status of current element changes before the comparison
261
+ */
262
+
263
+ isIntersecting !== curVisible && handleCheckChildrenExist() && onCompVisibleChange(isIntersecting, target);
264
+ /**
265
+ * 当前元素状态由不可见变为可见,且只触发一次
266
+ * @en The current element is invisible -> visible, and once, triggers the callback
267
+ */
268
+
269
+ isIntersecting && !curVisible && onceEmit && target && ioUnobserve(target);
270
+ visibleItem.isVisible = isIntersecting;
271
+ }
272
+ });
273
+ }
274
+ /**
275
+ * 获取 io 单例
276
+ * @en Get the io singleton
277
+ */
251
278
 
252
- isIntersecting !== isVisible.current && handleCheckChildrenExist() && onVisibleChange(isIntersecting, domRef.current);
253
- /**
254
- * 当前元素不可见 -> 可见,且 once, 触发回调函数
255
- * @en The current element is invisible -> visible, and once, triggers the callback
256
- */
257
279
 
258
- isIntersecting && !isVisible.current && once && domRef.current && ((_io$current = io.current) == null ? void 0 : _io$current.unobserve(domRef.current));
259
- isVisible.current = isIntersecting;
280
+ function getIOSingleton(ioOptions) {
281
+ var root = ioOptions.root,
282
+ rootMargin = ioOptions.rootMargin,
283
+ ioThreshold = ioOptions.threshold;
284
+ var ioKey = JSON.stringify({
285
+ rootMargin: rootMargin,
286
+ threshold: ioThreshold
287
+ });
288
+
289
+ var _ioListener = ioListeners.find(function (ioListener) {
290
+ return ioListener.root === root && ioListener.key === ioKey;
291
+ });
292
+
293
+ if (!_ioListener) {
294
+ ioListeners.push({
295
+ root: root,
296
+ key: ioKey,
297
+ listener: io.current = new IntersectionObserver(handleObserverStatusChange, ioOptions)
298
+ });
299
+ } else {
300
+ io.current = _ioListener.listener;
301
+ }
302
+ }
303
+
304
+ function ioObserve() {
305
+ if (domRef.current && io.current) {
306
+ var curIdx = ioVisibleList.findIndex(function (ioVisibleItem) {
307
+ return ioVisibleItem.node === domRef.current;
308
+ });
309
+
310
+ if (curIdx !== -1) {
311
+ ioVisibleList[curIdx].isVisible = false;
312
+ } else {
313
+ ioVisibleList.push({
314
+ node: domRef.current,
315
+ isVisible: false,
316
+ once: once,
317
+ onVisibleChange: onVisibleChange
318
+ });
319
+ }
320
+
321
+ io.current.observe(domRef.current);
322
+ }
323
+ }
324
+
325
+ function ioUnobserve(target) {
326
+ var targetNode = target || domRef.current;
327
+
328
+ if (io.current && targetNode) {
329
+ var curIdx = ioVisibleList.findIndex(function (ioVisibleItem) {
330
+ return ioVisibleItem.node === targetNode;
331
+ });
332
+
333
+ if (curIdx !== -1) {
334
+ ioVisibleList.splice(curIdx, 1);
335
+ }
336
+
337
+ io.current.unobserve(targetNode);
338
+ }
260
339
  }
261
340
  /**
262
341
  * 非首次下disabled变化时,重新监听元素
@@ -266,14 +345,11 @@
266
345
 
267
346
  (0, _react.useEffect)(function () {
268
347
  if (isSupportNativeApi) {
269
- // 非首次下
348
+ // 非首次 render 下
270
349
  // @en Not for the first time
271
- if (io.current && domRef.current) {
272
- // 禁用监听 || 监听
273
- disabled ? io.current.unobserve(domRef.current) : io.current.observe(domRef.current);
274
- }
350
+ disabled ? ioUnobserve() : ioObserve();
275
351
  } else {
276
- // 非首次下
352
+ // 非首次 render 下
277
353
  // @en Not for the first time
278
354
  if (wrapperKey.current !== -1 && listener.current && listeners[wrapperKey.current]) {
279
355
  // 禁用监听,找到对应listener并删除
@@ -337,12 +413,12 @@
337
413
  rootMargin = offset + "px";
338
414
  }
339
415
 
340
- io.current = new IntersectionObserver(handleObserverStatusChange, {
416
+ getIOSingleton({
341
417
  root: root,
342
418
  rootMargin: rootMargin,
343
419
  threshold: threshold
344
420
  });
345
- !disabled && io.current.observe(domRef.current);
421
+ !disabled && ioObserve();
346
422
  }
347
423
  } else {
348
424
  // 节流后回调函数
@@ -386,7 +462,7 @@
386
462
 
387
463
  listener.current = {
388
464
  node: domRef.current,
389
- isVisible: isVisible,
465
+ isVisible: false,
390
466
  overflow: overflow,
391
467
  once: once,
392
468
  offset: offset,
@@ -403,9 +479,7 @@
403
479
  (0, _react.useEffect)(function () {
404
480
  return function () {
405
481
  if (isSupportNativeApi) {
406
- var _io$current2;
407
-
408
- domRef.current && ((_io$current2 = io.current) == null ? void 0 : _io$current2.unobserve(domRef.current));
482
+ ioUnobserve();
409
483
  } else {
410
484
  if (overflow) {
411
485
  var parent = domRefParent.current;
@@ -2,6 +2,9 @@
2
2
  width: 100%;
3
3
  background: #e5e6eb ;
4
4
  }
5
+ #demo-swipe-load .list-container::-webkit-scrollbar {
6
+ display: none;
7
+ }
5
8
  #demo-swipe-load .course-list {
6
9
  display: -webkit-inline-box;
7
10
  display: -webkit-inline-flex;
@@ -4,36 +4,47 @@
4
4
  .list-container {
5
5
  width: 100%;
6
6
  .use-var(background, line-color);
7
+
8
+ &::-webkit-scrollbar {
9
+ display: none;
10
+ }
7
11
  }
12
+
8
13
  .course-list {
9
14
  display: inline-flex;
10
15
  align-items: flex-start;
11
16
  padding: 12px 0;
12
17
  }
18
+
13
19
  .list-item,
14
20
  .list-item-color {
15
21
  height: 72px;
16
22
  margin-right: 10px;
17
23
  .use-var(background, background-color);
18
24
  }
25
+
19
26
  .list-item-color {
20
27
  .use-var(background, primary-disabled-color);
21
28
  }
29
+
22
30
  .mylabel-start,
23
31
  .mylabel-end {
24
32
  width: 100px;
25
33
  height: 96px;
26
34
  transition: background 0.2s;
27
35
  .use-var(background, background-color);
36
+
28
37
  &.end {
29
38
  .use-var(background, line-color);
30
39
  }
31
40
  }
41
+
32
42
  .mylabel-single {
33
43
  width: 100px;
34
44
  height: 88px;
35
45
  .use-var(background, primary-disabled-color);
36
46
  }
47
+
37
48
  .single-element {
38
49
  height: 88px;
39
50
  .use-var(background, primary-disabled-color);
@@ -1,16 +1,16 @@
1
1
  (function (global, factory) {
2
2
  if (typeof define === "function" && define.amd) {
3
- define(["exports", "react", "@arco-design/mobile-utils", "../context-provider", "../_helpers/hooks", "./type"], factory);
3
+ define(["exports", "react", "@arco-design/mobile-utils", "../context-provider", "../_helpers", "../_helpers/hooks", "./type"], factory);
4
4
  } else if (typeof exports !== "undefined") {
5
- factory(exports, require("react"), require("@arco-design/mobile-utils"), require("../context-provider"), require("../_helpers/hooks"), require("./type"));
5
+ factory(exports, require("react"), require("@arco-design/mobile-utils"), require("../context-provider"), require("../_helpers"), require("../_helpers/hooks"), require("./type"));
6
6
  } else {
7
7
  var mod = {
8
8
  exports: {}
9
9
  };
10
- factory(mod.exports, global.react, global.mobileUtils, global.contextProvider, global.hooks, global.type);
10
+ factory(mod.exports, global.react, global.mobileUtils, global.contextProvider, global._helpers, global.hooks, global.type);
11
11
  global.index = mod.exports;
12
12
  }
13
- })(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _react, _mobileUtils, _contextProvider, _hooks, _type) {
13
+ })(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _react, _mobileUtils, _contextProvider, _helpers, _hooks, _type) {
14
14
  "use strict";
15
15
 
16
16
  _exports.__esModule = true;
@@ -60,7 +60,22 @@
60
60
  _props$activeText = props.activeText,
61
61
  activeText = _props$activeText === void 0 ? '' : _props$activeText,
62
62
  _props$initPos = props.initPos,
63
- initPos = _props$initPos === void 0 ? 0 : _props$initPos;
63
+ initPos = _props$initPos === void 0 ? 0 : _props$initPos,
64
+ _props$bounceWhenBump = props.bounceWhenBumpBoundary,
65
+ bounceWhenBumpBoundary = _props$bounceWhenBump === void 0 ? false : _props$bounceWhenBump,
66
+ _props$bounceDampRate = props.bounceDampRate,
67
+ bounceDampRate = _props$bounceDampRate === void 0 ? 3 : _props$bounceDampRate,
68
+ _props$bounceAnimateD = props.bounceAnimateDuration,
69
+ bounceAnimateDuration = _props$bounceAnimateD === void 0 ? 300 : _props$bounceAnimateD,
70
+ damping = props.damping,
71
+ bounceDistanceProcessor = props.bounceDistanceProcessor,
72
+ getScrollContainer = props.getScrollContainer,
73
+ getBounceContainer = props.getBounceContainer,
74
+ onTouchStart = props.onTouchStart,
75
+ onTouchEnd = props.onTouchEnd,
76
+ onTouchCancel = props.onTouchCancel,
77
+ onTouchMove = props.onTouchMove,
78
+ renderLabel = props.renderLabel;
64
79
 
65
80
  var _useContext = (0, _react.useContext)(_contextProvider.GlobalContext),
66
81
  _useContext$locale = _useContext.locale,
@@ -79,13 +94,14 @@
79
94
  var loadingLabelRef = (0, _react.useRef)(null);
80
95
  var showLoadMoreRef = (0, _react.useRef)(false);
81
96
  var ifToRightRef = (0, _react.useRef)(false);
97
+ var bouncingRef = (0, _react.useRef)(false);
82
98
  var offsetRef = (0, _react.useRef)(0);
83
99
  var domRef = (0, _react.useRef)(null);
84
100
  var wrapperEl = domRef.current;
85
- (0, _hooks.useAddListener)(wrapperEl, 'touchstart', props.onTouchStart);
86
- (0, _hooks.useAddListener)(wrapperEl, 'touchend', props.onTouchEnd);
87
- (0, _hooks.useAddListener)(wrapperEl, 'touchcancel', props.onTouchCancel);
88
- (0, _hooks.useAddListener)(wrapperEl, 'touchmove', props.onTouchMove);
101
+ (0, _hooks.useAddListener)(wrapperEl, 'touchstart', onTouchStart);
102
+ (0, _hooks.useAddListener)(wrapperEl, 'touchend', onTouchEnd);
103
+ (0, _hooks.useAddListener)(wrapperEl, 'touchcancel', onTouchCancel);
104
+ (0, _hooks.useAddListener)(wrapperEl, 'touchmove', onTouchMove);
89
105
  (0, _react.useEffect)(function () {
90
106
  if (disabled || !containerRef.current || disableState) {
91
107
  return;
@@ -99,13 +115,11 @@
99
115
  // @en If no child element is passed in, component will be disabled
100
116
  setDisableState(true);
101
117
  } else if (containerRef.current.childNodes.length === 1) {
118
+ var _getScrollContainer;
119
+
102
120
  // 传入一个子元素 滑动单个元素
103
121
  // @en Pass in a child element swipe the single element
104
- if (props.getScrollContainer) {
105
- scrollContainer = props.getScrollContainer();
106
- } else {
107
- scrollContainer = containerRef.current.firstChild;
108
- }
122
+ scrollContainer = (_getScrollContainer = getScrollContainer == null ? void 0 : getScrollContainer()) != null ? _getScrollContainer : containerRef.current.firstChild;
109
123
  } else {
110
124
  // 传入多个子元素(列表元素为例) 组件控制自行滑动 不推荐
111
125
  // @en Pass in multiple sub-elements (list elements as an example) Component control slides by itself which is not recommended
@@ -125,17 +139,20 @@
125
139
 
126
140
  if (!loadingCurrent) {
127
141
  return;
128
- } // 初始不显示标签
129
- // @en Initially no labels are displayed
142
+ }
130
143
 
144
+ var bounceScrollContainer = (getBounceContainer == null ? void 0 : getBounceContainer()) || scrollContainer; // 初始不显示标签
145
+ // @en Initially no labels are displayed
131
146
 
132
147
  loadingCurrent.style.display = 'none';
133
148
  var startX = 0;
134
- var endX = 0; // 触摸页面确定X起始坐标
149
+ var endX = 0;
150
+ var bounceDistance = 0; // 触摸页面确定X起始坐标
135
151
  // @en Determine the X starting coordinate on touchstart
136
152
 
137
153
  var touchstart = function touchstart(e) {
138
- startX = e.touches[0].pageX;
154
+ var evt = e.touches[0];
155
+ startX = evt.clientX || 0;
139
156
  }; // 页面滑动确定X终止坐标,更新手指的X坐标,改变loading中的文字和大小
140
157
  // @en Determine the X end coordinate, update the X coordinate of the finger, change the text and size in the loading on touchmove
141
158
 
@@ -147,12 +164,30 @@
147
164
  scrollContainer.scrollLeft = 1;
148
165
  }
149
166
 
150
- endX = e.touches[0].pageX;
167
+ endX = e.touches[0].clientX || 0;
151
168
  var diff = endX - startX;
152
169
  offsetRef.current = diff;
153
- var labelDiff = (0, _mobileUtils.fingerDisToLabelDis)(Math.abs(diff), props.damping); // 向左滑动到尽头 '更多'标签加载 根据scrollLeft判断 滚动容器到达边缘触发 非滚动容器不判断
170
+ var labelDiff = (0, _mobileUtils.fingerDisToLabelDis)(Math.abs(diff), damping); // 滑动到最左侧,处理回弹效果
171
+ // @en Swipe to the far left to handle the rebound effect
172
+
173
+ if (diff > 0 && scrollContainer.scrollLeft <= 1 && bounceWhenBumpBoundary) {
174
+ e.stopPropagation();
175
+ e.cancelBubble && e.preventDefault();
176
+ bouncingRef.current = true;
177
+
178
+ var processor = bounceDistanceProcessor || function (dis) {
179
+ return Math.min(dis, bounceScrollContainer.offsetWidth) / bounceDampRate;
180
+ };
181
+
182
+ bounceDistance = processor(diff);
183
+ (0, _helpers.setStyleWithVendor)(bounceScrollContainer, {
184
+ transition: 'none',
185
+ transform: "translateX(" + bounceDistance + "px) translateZ(0)"
186
+ });
187
+ } // 向左滑动到尽头 '更多'标签加载 根据scrollLeft判断 滚动容器到达边缘触发 非滚动容器不判断
154
188
  // @en Swipe left to the end and the 'more' label is loaded. Judging by scrollLeft, the scroll container reaches the edge and the non-scroll container does not judge
155
189
 
190
+
156
191
  if (diff < 0 && (scrollContainer.scrollLeft + scrollContainer.clientWidth >= scrollContainer.scrollWidth - 1 || !scrollContainer.scrollLeft) && !ifToRightRef.current) {
157
192
  showLoadMoreRef.current = true;
158
193
  loadingCurrent.style.display = 'flex';
@@ -178,12 +213,14 @@
178
213
  loadingLabelCurrent.innerHTML = labelDiff >= minConfirmOffset ? activeText || locale.SwipeLoad.activeText : normalText || locale.SwipeLoad.normalText;
179
214
  }
180
215
 
181
- loadingCurrent.style.transition = 'all 0.02s';
182
- loadingCurrent.style.webkitTransform = "translateX(-" + labelRightMargin + "px)";
183
- loadingCurrent.style.transform = "translateX(-" + labelRightMargin + "px)";
184
- scrollContainer.style.transition = 'all 0.03s';
185
- scrollContainer.style.webkitTransform = "translateX(-" + listRightMargin + "px)";
186
- scrollContainer.style.transform = "translateX(-" + listRightMargin + "px)";
216
+ (0, _helpers.setStyleWithVendor)(loadingCurrent, {
217
+ transition: 'none',
218
+ transform: "translateX(-" + labelRightMargin + "px) translateZ(0)"
219
+ });
220
+ (0, _helpers.setStyleWithVendor)(scrollContainer, {
221
+ transition: 'none',
222
+ transform: "translateX(-" + listRightMargin + "px) translateZ(0)"
223
+ });
187
224
  }
188
225
 
189
226
  if (diff > 0 && scrollContainer.scrollLeft + scrollContainer.clientWidth <= scrollContainer.scrollWidth - 1) {
@@ -208,13 +245,28 @@
208
245
  var labelDiff = (0, _mobileUtils.fingerDisToLabelDis)(Math.abs(diff));
209
246
 
210
247
  var resumeAnimation = function resumeAnimation() {
211
- scrollContainer.style.transition = "all " + labelAnimationDuration + "ms " + labelAnimationFunction;
212
- scrollContainer.style.webkitTransform = 'translateX(0px)';
213
- scrollContainer.style.transform = 'translateX(0px)';
214
- loadingCurrent.style.transition = "all " + labelAnimationDuration + "ms " + labelAnimationFunction;
215
- loadingCurrent.style.webkitTransform = 'translateX(0px)';
216
- loadingCurrent.style.transform = 'translateX(0px)';
217
- showLoadMoreRef.current = false;
248
+ if (showLoadMoreRef.current) {
249
+ showLoadMoreRef.current = false;
250
+ var scrollTransitionCssStyle = "all " + labelAnimationDuration + "ms " + labelAnimationFunction;
251
+ var scrollTransformCssStyle = 'translateX(0px) translateZ(0)';
252
+ (0, _helpers.setStyleWithVendor)(scrollContainer, {
253
+ transition: scrollTransitionCssStyle,
254
+ transform: scrollTransformCssStyle
255
+ });
256
+ (0, _helpers.setStyleWithVendor)(loadingCurrent, {
257
+ transition: scrollTransitionCssStyle,
258
+ transform: scrollTransformCssStyle
259
+ });
260
+ }
261
+
262
+ if (bouncingRef.current) {
263
+ bouncingRef.current = false;
264
+ (0, _helpers.setStyleWithVendor)(bounceScrollContainer, {
265
+ transition: "all " + bounceAnimateDuration + "ms",
266
+ transform: 'translateX(0px) translateZ(0)'
267
+ });
268
+ }
269
+
218
270
  ifToRightRef.current = false;
219
271
  setTimeout(function () {
220
272
  loadingCurrent.style.display = 'none';
@@ -244,7 +296,7 @@
244
296
  scrollContainer.removeEventListener('touchmove', touchmove);
245
297
  scrollContainer.removeEventListener('touchend', touchend);
246
298
  };
247
- }, [disabled]);
299
+ }, [disabled, getScrollContainer, getBounceContainer, bounceWhenBumpBoundary, bounceDampRate, bounceAnimateDuration]);
248
300
  (0, _react.useImperativeHandle)(ref, function () {
249
301
  return {
250
302
  dom: domRef.current
@@ -258,14 +310,14 @@
258
310
  }, /*#__PURE__*/_react.default.createElement("div", {
259
311
  className: (0, _mobileUtils.cls)(prefixCls + "-list-area"),
260
312
  ref: containerRef
261
- }, children), props.renderLabel ? /*#__PURE__*/_react.default.createElement("div", {
313
+ }, children), renderLabel ? /*#__PURE__*/_react.default.createElement("div", {
262
314
  className: (0, _mobileUtils.cls)(prefixCls + "-custom-loading-area"),
263
315
  ref: loadingRef,
264
316
  style: {
265
317
  position: 'absolute',
266
318
  right: initPos + "px"
267
319
  }
268
- }, props.renderLabel.length ? props.renderLabel(labelOffsetState) : props.renderLabel()) : /*#__PURE__*/_react.default.createElement("div", {
320
+ }, renderLabel.length ? renderLabel(labelOffsetState) : renderLabel()) : /*#__PURE__*/_react.default.createElement("div", {
269
321
  className: (0, _mobileUtils.cls)(prefixCls + "-loading-area"),
270
322
  ref: loadingRef,
271
323
  style: {
@@ -9,6 +9,9 @@
9
9
  position: relative;
10
10
  width: 100%;
11
11
  }
12
+ .arco-swipe-load .arco-list-area::-webkit-scrollbar {
13
+ display: none;
14
+ }
12
15
  .arco-swipe-load .arco-loading-area {
13
16
  background-color: #f8f8f8 ;
14
17
  margin-top: 0;
@@ -4,14 +4,21 @@
4
4
  position: relative;
5
5
  display: inline-flex;
6
6
  width: 100%;
7
+
7
8
  .@{prefix}-list-area {
8
9
  position: relative;
9
10
  width: 100%;
11
+
12
+ &::-webkit-scrollbar {
13
+ display: none;
14
+ }
10
15
  }
16
+
11
17
  .@{prefix}-loading-area {
12
18
  .use-var(background-color, swipe-load-label-background);
13
19
  margin-top: 0;
14
20
  .use-var(border-radius, swipe-load-label-border-radius);
21
+
15
22
  .@{prefix}-loading-label {
16
23
  .use-var(margin-left, swipe-load-label-text-margin-left);
17
24
  .use-var(width, swipe-load-label-text-width);
@@ -77,6 +77,35 @@ export interface SwipeLoadProps {
77
77
  * @default_en "Release to view"
78
78
  */
79
79
  activeText?: string;
80
+ /**
81
+ * 触碰左侧边界时是否需要回弹效果
82
+ * @en Whether a bounce effect is required when touching the left boundary
83
+ * @default false
84
+ */
85
+ bounceWhenBumpBoundary?: boolean;
86
+ /**
87
+ * 当开启回弹效果时的阻尼系数
88
+ * @en Damping coefficient when the rebound effect is turned on
89
+ * @default 3
90
+ */
91
+ bounceDampRate?: number;
92
+ /**
93
+ * 当开启回弹效果时的动画毫秒时间
94
+ * @en Animation in milliseconds when the bounce effect is turned on
95
+ * @default 300
96
+ */
97
+ bounceAnimateDuration?: number;
98
+ /**
99
+ * 回弹效果开启时需要回弹的容器,默认为 getScrollContainer 返回的容器或容器的一个子元素
100
+ * @en The container that needs to be rebounded when the rebound effect is enabled, the default is the container returned by getScrollContainer or a child element of the container
101
+ */
102
+ getBounceContainer?: () => HTMLElement | null;
103
+ /**
104
+ * 当开启回弹效果时自定义手指滑动跟手的距离计算方式,dis表示touchmove的距离
105
+ * @en When the rebound effect is turned on, customize the calculation method of the distance between the finger sliding and the hand, and dis indicates the distance of touchmove
106
+ * @default (dis) => Math.min(dis, bounceScrollContainer.offsetWidth) / bounceDampRate
107
+ */
108
+ bounceDistanceProcessor?: (dis: number) => number;
80
109
  /**
81
110
  * 抛出外层touch事件,便于自定义,常用于阻止划动退出,切换tab等手势冲突
82
111
  * @en Throw the outer touchstart event, which is easy to customize. It is often used to prevent gesture conflicts such as swiping to exit, switching tabs, etc.
package/umd/tabs/index.js CHANGED
@@ -246,6 +246,7 @@
246
246
  // 利用受控手动更改index时,给cell line加上动画
247
247
  // @en Animate the cell line when changeing the index
248
248
  setCellTrans(true);
249
+ changeFromRef.current = 'manual';
249
250
  }, [activeTab]);
250
251
  (0, _helpers.useUpdateEffect)(function () {
251
252
  onDistanceChange && onDistanceChange(distance, wrapWidth, activeIndex);