@tarojs/components-advanced 4.1.12-beta.3 → 4.1.12-beta.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/index.js +2 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/list/NoMore.d.ts +30 -0
- package/dist/components/list/NoMore.js +10 -0
- package/dist/components/list/NoMore.js.map +1 -0
- package/dist/components/list/hooks/useItemSizeCache.d.ts +13 -0
- package/dist/components/list/hooks/useItemSizeCache.js +40 -0
- package/dist/components/list/hooks/useItemSizeCache.js.map +1 -0
- package/dist/components/list/hooks/useListNestedScroll.d.ts +18 -0
- package/dist/components/list/hooks/useListNestedScroll.js +61 -0
- package/dist/components/list/hooks/useListNestedScroll.js.map +1 -0
- package/dist/components/list/hooks/useListScrollElementAttach.d.ts +25 -0
- package/dist/components/list/hooks/useListScrollElementAttach.js +88 -0
- package/dist/components/list/hooks/useListScrollElementAttach.js.map +1 -0
- package/dist/components/list/hooks/useListScrollElementAttachWeapp.d.ts +14 -0
- package/dist/components/list/hooks/useListScrollElementAttachWeapp.js +134 -0
- package/dist/components/list/hooks/useListScrollElementAttachWeapp.js.map +1 -0
- package/dist/components/list/hooks/useMeasureStartOffset.d.ts +12 -0
- package/dist/components/list/hooks/useMeasureStartOffset.js +84 -0
- package/dist/components/list/hooks/useMeasureStartOffset.js.map +1 -0
- package/dist/components/list/hooks/useMeasureStartOffsetWeapp.d.ts +14 -0
- package/dist/components/list/hooks/useMeasureStartOffsetWeapp.js +82 -0
- package/dist/components/list/hooks/useMeasureStartOffsetWeapp.js.map +1 -0
- package/dist/components/list/hooks/useRefresher.d.ts +73 -0
- package/dist/components/list/hooks/useRefresher.js +500 -0
- package/dist/components/list/hooks/useRefresher.js.map +1 -0
- package/dist/components/list/hooks/useResizeObserver.d.ts +27 -0
- package/dist/components/list/hooks/useResizeObserver.js +152 -0
- package/dist/components/list/hooks/useResizeObserver.js.map +1 -0
- package/dist/components/list/hooks/useScrollCorrection.d.ts +19 -0
- package/dist/components/list/hooks/useScrollCorrection.js +74 -0
- package/dist/components/list/hooks/useScrollCorrection.js.map +1 -0
- package/dist/components/list/hooks/useScrollParentAutoFind.d.ts +20 -0
- package/dist/components/list/hooks/useScrollParentAutoFind.js +81 -0
- package/dist/components/list/hooks/useScrollParentAutoFind.js.map +1 -0
- package/dist/components/list/index.d.ts +66 -7
- package/dist/components/list/index.js +1079 -162
- package/dist/components/list/index.js.map +1 -1
- package/dist/components/list/utils.d.ts +21 -0
- package/dist/components/list/utils.js +35 -0
- package/dist/components/list/utils.js.map +1 -0
- package/dist/components/virtual-list/vue/list.d.ts +12 -12
- package/dist/components/virtual-waterfall/vue/waterfall.d.ts +11 -11
- package/dist/components/water-flow/flow-item.js +6 -4
- package/dist/components/water-flow/flow-item.js.map +1 -1
- package/dist/components/water-flow/flow-section.js +1 -1
- package/dist/components/water-flow/flow-section.js.map +1 -1
- package/dist/components/water-flow/index.d.ts +1 -1
- package/dist/components/water-flow/interface.d.ts +18 -2
- package/dist/components/water-flow/root.d.ts +35 -4
- package/dist/components/water-flow/root.js +114 -42
- package/dist/components/water-flow/root.js.map +1 -1
- package/dist/components/water-flow/section.d.ts +7 -1
- package/dist/components/water-flow/section.js +54 -9
- package/dist/components/water-flow/section.js.map +1 -1
- package/dist/components/water-flow/utils.d.ts +4 -0
- package/dist/components/water-flow/utils.js +5 -1
- package/dist/components/water-flow/utils.js.map +1 -1
- package/dist/components/water-flow/water-flow-node-cache.d.ts +24 -0
- package/dist/components/water-flow/water-flow-node-cache.js +161 -0
- package/dist/components/water-flow/water-flow-node-cache.js.map +1 -0
- package/dist/components/water-flow/water-flow.d.ts +2 -3
- package/dist/components/water-flow/water-flow.js +286 -31
- package/dist/components/water-flow/water-flow.js.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/scrollElementContext.d.ts +15 -0
- package/dist/utils/scrollElementContext.js +14 -0
- package/dist/utils/scrollElementContext.js.map +1 -0
- package/dist/utils/scrollParent.d.ts +33 -0
- package/dist/utils/scrollParent.js +88 -0
- package/dist/utils/scrollParent.js.map +1 -0
- package/package.json +9 -8
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Slot, View } from '@tarojs/components';
|
|
3
|
+
import React, { useState, useRef, useCallback } from 'react';
|
|
4
|
+
import { supportsNativeRefresher } from '../utils.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 下拉刷新(List 内部)
|
|
8
|
+
*
|
|
9
|
+
* - 小程序:ScrollView 原生 refresher-*;业务 Promise reject 时补发 Failed(4)(原生不派发)
|
|
10
|
+
* - H5:触顶 + touch 拖拽;最大行程 / 阻尼停拉线为视口高的 0.9 / 0.8(innerHeight);收尾仅依赖 onRefresherRefresh 的 Promise
|
|
11
|
+
* - 动画时间戳用 nowMs():小程序部分环境无 performance,避免抛错中断回弹
|
|
12
|
+
* - rafRef 与受控 refresherTriggered→false 的 effect 共用:effect 内 cancel 可能打断 H5 成功回弹,须在 effect 动画结束处释放 refreshingLockRef
|
|
13
|
+
* - H5 reject:onRefresherStatusChange 顺序 Failed(4) → Completed(3) → Idle(0)
|
|
14
|
+
* - emitStatusChange:仅 status 变化时回调(同 status 不重复)
|
|
15
|
+
*/
|
|
16
|
+
const BOUNCE_MS = 300;
|
|
17
|
+
const AT_TOP_THRESHOLD = 3;
|
|
18
|
+
const H5_PULL_DISTANCE_MAX_VH = 0.9;
|
|
19
|
+
const H5_DAMPING_LIMIT_VH = 0.8;
|
|
20
|
+
const VIEWPORT_HEIGHT_FALLBACK = 800;
|
|
21
|
+
const DEG_LIMIT = 40;
|
|
22
|
+
const DEFAULT_REFRESHER_HEIGHT = 50;
|
|
23
|
+
function nowMs() {
|
|
24
|
+
if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
|
|
25
|
+
return performance.now();
|
|
26
|
+
}
|
|
27
|
+
return Date.now();
|
|
28
|
+
}
|
|
29
|
+
function getViewportHeightPx() {
|
|
30
|
+
if (typeof window === 'undefined' || !Number.isFinite(window.innerHeight) || window.innerHeight <= 0) {
|
|
31
|
+
return VIEWPORT_HEIGHT_FALLBACK;
|
|
32
|
+
}
|
|
33
|
+
return window.innerHeight;
|
|
34
|
+
}
|
|
35
|
+
/** 阻尼增量:ratio=总下拉位移/视口高;超过 dampingLimit 后不再累加 */
|
|
36
|
+
function dampIncrement(diff, totalMove, currentPull, viewportHeight, dampingLimit) {
|
|
37
|
+
if (diff <= 0)
|
|
38
|
+
return 0;
|
|
39
|
+
if (currentPull >= dampingLimit)
|
|
40
|
+
return 0;
|
|
41
|
+
const ratio = Math.min(totalMove / viewportHeight, 1);
|
|
42
|
+
return diff * (1 - ratio) * 0.6;
|
|
43
|
+
}
|
|
44
|
+
function useRefresher(config,
|
|
45
|
+
/** 列表逻辑顶部对应的 scrollTop,用于触顶判断;H5「顶栏悬浮+只滚列表」时传 0,imperative 内以 DOM scrollTop 为准 */
|
|
46
|
+
scrollTopAtLogicalTop,
|
|
47
|
+
/** scrollElement 模式下可选:下拉起始点须在 List 内才触发刷新;未传时默认 true(沿用原逻辑) */
|
|
48
|
+
getIsTouchInListArea) {
|
|
49
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
50
|
+
const [internalRefreshing, setInternalRefreshing] = useState(false);
|
|
51
|
+
const [pullDistance, setPullDistance] = useState(0);
|
|
52
|
+
const pullDistanceRef = useRef(0);
|
|
53
|
+
const rafRef = useRef(null);
|
|
54
|
+
const setPullDistanceRef = useRef(setPullDistance);
|
|
55
|
+
const setInternalRefreshingRef = useRef(setInternalRefreshing);
|
|
56
|
+
setPullDistanceRef.current = setPullDistance;
|
|
57
|
+
setInternalRefreshingRef.current = setInternalRefreshing;
|
|
58
|
+
pullDistanceRef.current = pullDistance;
|
|
59
|
+
const isControlled = typeof (config === null || config === void 0 ? void 0 : config.refresherTriggered) === 'boolean';
|
|
60
|
+
const isRefreshing = isControlled ? ((_a = config === null || config === void 0 ? void 0 : config.refresherTriggered) !== null && _a !== void 0 ? _a : false) : internalRefreshing;
|
|
61
|
+
const isRefreshingRef = useRef(isRefreshing);
|
|
62
|
+
isRefreshingRef.current = isRefreshing;
|
|
63
|
+
/** 刷新中锁:runRefresh 内同步置 true,避免 setState 未重渲染前再次触摸触发刷新 */
|
|
64
|
+
const refreshingLockRef = useRef(false);
|
|
65
|
+
/** H5 当前刷新状态,用于 onRefresherStatusChange 避免重复触发 */
|
|
66
|
+
const refreshStatusRef = useRef(0 /* RefreshStatus.Idle */);
|
|
67
|
+
/** H5 是否启用下拉刷新:refresherEnabled === false 时不挂 touch、不显示顶栏 */
|
|
68
|
+
const h5RefresherEnabled = !!config && config.refresherEnabled !== false;
|
|
69
|
+
/** touch 只挂一次,回调里读 ref 才能拿到最新配置,避免改预设后仍用旧值 */
|
|
70
|
+
const thresholdRef = useRef((_b = config === null || config === void 0 ? void 0 : config.refresherThreshold) !== null && _b !== void 0 ? _b : 45);
|
|
71
|
+
thresholdRef.current = (_c = config === null || config === void 0 ? void 0 : config.refresherThreshold) !== null && _c !== void 0 ? _c : 45;
|
|
72
|
+
const configRef = useRef(config);
|
|
73
|
+
configRef.current = config;
|
|
74
|
+
const emitStatusChangeRef = useRef((status, dy) => {
|
|
75
|
+
var _a, _b;
|
|
76
|
+
if (refreshStatusRef.current !== status) {
|
|
77
|
+
refreshStatusRef.current = status;
|
|
78
|
+
(_b = (_a = configRef.current) === null || _a === void 0 ? void 0 : _a.onRefresherStatusChange) === null || _b === void 0 ? void 0 : _b.call(_a, { detail: { status, dy } });
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
const isControlledRef = useRef(isControlled);
|
|
82
|
+
isControlledRef.current = isControlled;
|
|
83
|
+
/** H5 顶栏悬浮时 List 传 0,触顶即 scrollTop<=0+阈值;否则由 List 传列表顶对应的 scrollTop */
|
|
84
|
+
const scrollTopWhenAtTop = !supportsNativeRefresher && config ? scrollTopAtLogicalTop : 0;
|
|
85
|
+
const topThresholdPx = scrollTopWhenAtTop + AT_TOP_THRESHOLD;
|
|
86
|
+
const topThresholdPxRef = useRef(topThresholdPx);
|
|
87
|
+
topThresholdPxRef.current = topThresholdPx;
|
|
88
|
+
const getIsTouchInListAreaRef = useRef(getIsTouchInListArea);
|
|
89
|
+
getIsTouchInListAreaRef.current = getIsTouchInListArea;
|
|
90
|
+
const scrollViewRefresherProps = config && supportsNativeRefresher ? {
|
|
91
|
+
refresherEnabled: (_d = config.refresherEnabled) !== null && _d !== void 0 ? _d : true,
|
|
92
|
+
refresherThreshold: (_e = config.refresherThreshold) !== null && _e !== void 0 ? _e : 45,
|
|
93
|
+
refresherDefaultStyle: (_f = config.refresherDefaultStyle) !== null && _f !== void 0 ? _f : 'black',
|
|
94
|
+
refresherBackground: (_g = config.refresherBackground) !== null && _g !== void 0 ? _g : '#fff',
|
|
95
|
+
refresherTriggered: isRefreshing,
|
|
96
|
+
} : {};
|
|
97
|
+
const scrollViewRefresherHandlers = config && supportsNativeRefresher ? {
|
|
98
|
+
onRefresherPulling: (e) => {
|
|
99
|
+
var _a, _b, _c;
|
|
100
|
+
(_a = config.onRefresherPulling) === null || _a === void 0 ? void 0 : _a.call(config, { detail: { deltaY: (_c = (_b = e.detail) === null || _b === void 0 ? void 0 : _b.deltaY) !== null && _c !== void 0 ? _c : 0 } });
|
|
101
|
+
},
|
|
102
|
+
onRefresherRefresh: async () => {
|
|
103
|
+
var _a, _b;
|
|
104
|
+
if (!isControlled)
|
|
105
|
+
setInternalRefreshing(true);
|
|
106
|
+
try {
|
|
107
|
+
await ((_a = config.onRefresherRefresh) === null || _a === void 0 ? void 0 : _a.call(config));
|
|
108
|
+
}
|
|
109
|
+
catch (_c) {
|
|
110
|
+
// 原生不派发 Failed(4),补发便于与 H5 一致
|
|
111
|
+
(_b = config.onRefresherStatusChange) === null || _b === void 0 ? void 0 : _b.call(config, { detail: { status: 4 /* RefreshStatus.Failed */, dy: 0 } });
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
if (!isControlled)
|
|
115
|
+
setInternalRefreshing(false);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
onRefresherRestore: () => { var _a; return (_a = config.onRefresherRestore) === null || _a === void 0 ? void 0 : _a.call(config); },
|
|
119
|
+
onRefresherAbort: () => { var _a; return (_a = config.onRefresherAbort) === null || _a === void 0 ? void 0 : _a.call(config); },
|
|
120
|
+
// 小程序特有事件:即将触发刷新(拖动超过 threshold 时)
|
|
121
|
+
onRefresherWillRefresh: () => { var _a; return (_a = config.onRefresherWillRefresh) === null || _a === void 0 ? void 0 : _a.call(config); },
|
|
122
|
+
// 小程序特有事件:下拉刷新状态变化
|
|
123
|
+
onRefresherStatusChange: (e) => {
|
|
124
|
+
var _a, _b, _c;
|
|
125
|
+
(_a = config.onRefresherStatusChange) === null || _a === void 0 ? void 0 : _a.call(config, { detail: { status: (_b = e.detail) === null || _b === void 0 ? void 0 : _b.status, dy: (_c = e.detail) === null || _c === void 0 ? void 0 : _c.dy } });
|
|
126
|
+
},
|
|
127
|
+
} : {};
|
|
128
|
+
const addImperativeTouchListeners = React.useCallback((el) => {
|
|
129
|
+
if (supportsNativeRefresher || !configRef.current || !h5RefresherEnabled)
|
|
130
|
+
return () => { };
|
|
131
|
+
const scrollEl = el;
|
|
132
|
+
const startY = { current: 0 };
|
|
133
|
+
const startX = { current: 0 };
|
|
134
|
+
const lastY = { current: 0 };
|
|
135
|
+
let touchStartedAtTop = false;
|
|
136
|
+
/** 下拉起始点是否在 List 内(scrollElement 模式);未传 getIsTouchInListArea 时恒为 true */
|
|
137
|
+
let touchStartedInListArea = true;
|
|
138
|
+
let dragOnEdge = false;
|
|
139
|
+
let lastPull = 0;
|
|
140
|
+
/** 用于 onTouchEnd 判断是否触发刷新;刷新完成后必须置 0,否则下次点击(无 touchMove)会误用上次的 lastPull 再次触发 */
|
|
141
|
+
const lastPullRef = { current: 0 };
|
|
142
|
+
const pullAtReleaseRef = { current: 0 };
|
|
143
|
+
const setPull = (v) => {
|
|
144
|
+
lastPull = v;
|
|
145
|
+
lastPullRef.current = v;
|
|
146
|
+
setPullDistanceRef.current(v);
|
|
147
|
+
};
|
|
148
|
+
const runBounceBack = (fromValue, onComplete) => {
|
|
149
|
+
if (rafRef.current != null)
|
|
150
|
+
cancelAnimationFrame(rafRef.current);
|
|
151
|
+
const startTime = nowMs();
|
|
152
|
+
const animate = () => {
|
|
153
|
+
const t = Math.min((nowMs() - startTime) / BOUNCE_MS, 1);
|
|
154
|
+
const ease = 1 - Math.pow(1 - t, 3);
|
|
155
|
+
const v = fromValue * (1 - ease);
|
|
156
|
+
setPullDistanceRef.current(v);
|
|
157
|
+
lastPullRef.current = v;
|
|
158
|
+
lastPull = v;
|
|
159
|
+
if (t < 1) {
|
|
160
|
+
rafRef.current = requestAnimationFrame(animate);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
setPullDistanceRef.current(0);
|
|
164
|
+
if (!isControlledRef.current)
|
|
165
|
+
setInternalRefreshingRef.current(false);
|
|
166
|
+
rafRef.current = null;
|
|
167
|
+
onComplete === null || onComplete === void 0 ? void 0 : onComplete();
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
rafRef.current = requestAnimationFrame(animate);
|
|
171
|
+
};
|
|
172
|
+
/** 未达阈值松手回弹结束:通知中止 */
|
|
173
|
+
const runBounceBackAbort = (fromValue) => {
|
|
174
|
+
if (rafRef.current != null)
|
|
175
|
+
cancelAnimationFrame(rafRef.current);
|
|
176
|
+
const startTime = nowMs();
|
|
177
|
+
const animate = () => {
|
|
178
|
+
var _a, _b;
|
|
179
|
+
const t = Math.min((nowMs() - startTime) / BOUNCE_MS, 1);
|
|
180
|
+
const ease = 1 - Math.pow(1 - t, 3);
|
|
181
|
+
const v = fromValue * (1 - ease);
|
|
182
|
+
setPullDistanceRef.current(v);
|
|
183
|
+
lastPullRef.current = v;
|
|
184
|
+
lastPull = v;
|
|
185
|
+
if (t < 1)
|
|
186
|
+
rafRef.current = requestAnimationFrame(animate);
|
|
187
|
+
else {
|
|
188
|
+
setPullDistanceRef.current(0);
|
|
189
|
+
rafRef.current = null;
|
|
190
|
+
lastPullRef.current = 0;
|
|
191
|
+
lastPull = 0;
|
|
192
|
+
(_b = (_a = configRef.current) === null || _a === void 0 ? void 0 : _a.onRefresherAbort) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
193
|
+
emitStatusChangeRef.current(0 /* RefreshStatus.Idle */, 0);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
rafRef.current = requestAnimationFrame(animate);
|
|
197
|
+
};
|
|
198
|
+
/** 收起到加载高度后再执行 onRefresherRefresh */
|
|
199
|
+
const runBounceToLoading = (fromValue, toValue, onReach) => {
|
|
200
|
+
if (rafRef.current != null)
|
|
201
|
+
cancelAnimationFrame(rafRef.current);
|
|
202
|
+
const startTime = nowMs();
|
|
203
|
+
const animate = () => {
|
|
204
|
+
const t = Math.min((nowMs() - startTime) / BOUNCE_MS, 1);
|
|
205
|
+
const ease = 1 - Math.pow(1 - t, 3);
|
|
206
|
+
setPullDistanceRef.current(fromValue + (toValue - fromValue) * ease);
|
|
207
|
+
if (t < 1) {
|
|
208
|
+
rafRef.current = requestAnimationFrame(animate);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
setPullDistanceRef.current(toValue);
|
|
212
|
+
rafRef.current = null;
|
|
213
|
+
onReach();
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
rafRef.current = requestAnimationFrame(animate);
|
|
217
|
+
};
|
|
218
|
+
const isEdge = () => { var _a; return ((_a = scrollEl.scrollTop) !== null && _a !== void 0 ? _a : 0) <= topThresholdPxRef.current; };
|
|
219
|
+
const onTouchStart = (e) => {
|
|
220
|
+
var _a, _b;
|
|
221
|
+
if (refreshingLockRef.current || isRefreshingRef.current)
|
|
222
|
+
return;
|
|
223
|
+
if (rafRef.current != null) {
|
|
224
|
+
cancelAnimationFrame(rafRef.current);
|
|
225
|
+
rafRef.current = null;
|
|
226
|
+
}
|
|
227
|
+
lastPull = lastPullRef.current;
|
|
228
|
+
touchStartedAtTop = isEdge();
|
|
229
|
+
touchStartedInListArea = (_b = (_a = getIsTouchInListAreaRef.current) === null || _a === void 0 ? void 0 : _a.call(getIsTouchInListAreaRef, e)) !== null && _b !== void 0 ? _b : true;
|
|
230
|
+
const t0 = e.touches[0];
|
|
231
|
+
if (t0) {
|
|
232
|
+
startY.current = t0.clientY;
|
|
233
|
+
startX.current = t0.clientX;
|
|
234
|
+
lastY.current = t0.clientY;
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
const onTouchMove = (ev) => {
|
|
238
|
+
var _a, _b, _c, _d;
|
|
239
|
+
if (refreshingLockRef.current || isRefreshingRef.current)
|
|
240
|
+
return;
|
|
241
|
+
if (!touchStartedInListArea)
|
|
242
|
+
return;
|
|
243
|
+
const touch = ev.touches[0];
|
|
244
|
+
if (!touch)
|
|
245
|
+
return;
|
|
246
|
+
const currentY = touch.clientY;
|
|
247
|
+
const currentX = touch.clientX;
|
|
248
|
+
if (!isEdge()) {
|
|
249
|
+
setPull(0);
|
|
250
|
+
dragOnEdge = false;
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
// 到顶后:若 touch 开始时不在顶部,在首次下拉(dy>0)时「采纳」该手势,使同一手势内滚到顶后继续下拉可触发刷新
|
|
254
|
+
if (!touchStartedAtTop && !dragOnEdge) {
|
|
255
|
+
const dyCheck = currentY - lastY.current;
|
|
256
|
+
if (dyCheck <= 0)
|
|
257
|
+
return;
|
|
258
|
+
touchStartedAtTop = true;
|
|
259
|
+
// 重置起点,避免采纳时 dy 过大导致刷新层瞬间拉满
|
|
260
|
+
startY.current = currentY;
|
|
261
|
+
startX.current = currentX;
|
|
262
|
+
lastY.current = currentY;
|
|
263
|
+
}
|
|
264
|
+
const dy = currentY - lastY.current;
|
|
265
|
+
// 还没进入下拉拖拽阶段(dragOnEdge=false)时,先看第一下是往上还是往下:
|
|
266
|
+
// - 第一笔就是往上滑(dy<=0):视为正常滚动,直接交给原生 Scroll,不拦截、不启动下拉逻辑
|
|
267
|
+
// - 第一笔是往下滑(dy>0):才认为是一次「下拉刷新」手势,进入拖拽模式
|
|
268
|
+
if (!dragOnEdge) {
|
|
269
|
+
if (dy <= 0) {
|
|
270
|
+
lastY.current = currentY;
|
|
271
|
+
startY.current = currentY;
|
|
272
|
+
startX.current = currentX;
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
// 真正开始下拉刷新
|
|
276
|
+
dragOnEdge = true;
|
|
277
|
+
startY.current = currentY;
|
|
278
|
+
startX.current = currentX;
|
|
279
|
+
}
|
|
280
|
+
if (ev.cancelable)
|
|
281
|
+
ev.preventDefault();
|
|
282
|
+
const totalMove = currentY - startY.current;
|
|
283
|
+
const dx = currentX - startX.current;
|
|
284
|
+
if (dy <= 0) {
|
|
285
|
+
lastY.current = currentY;
|
|
286
|
+
const next = Math.max(0, lastPull + dy);
|
|
287
|
+
setPull(next);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const deg = Math.atan(Math.abs(dx) / dy) * (180 / Math.PI);
|
|
291
|
+
if (deg > DEG_LIMIT) {
|
|
292
|
+
startY.current = currentY;
|
|
293
|
+
startX.current = currentX;
|
|
294
|
+
lastY.current = currentY;
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
lastY.current = currentY;
|
|
298
|
+
const vh = getViewportHeightPx();
|
|
299
|
+
const maxPull = vh * H5_PULL_DISTANCE_MAX_VH;
|
|
300
|
+
const dampingLimit = vh * H5_DAMPING_LIMIT_VH;
|
|
301
|
+
const damped = dampIncrement(dy, totalMove, lastPull, vh, dampingLimit);
|
|
302
|
+
const next = Math.min(lastPull + damped, maxPull);
|
|
303
|
+
setPull(next);
|
|
304
|
+
(_b = (_a = configRef.current) === null || _a === void 0 ? void 0 : _a.onRefresherPulling) === null || _b === void 0 ? void 0 : _b.call(_a, { detail: { deltaY: next } });
|
|
305
|
+
if (next >= thresholdRef.current) {
|
|
306
|
+
(_d = (_c = configRef.current) === null || _c === void 0 ? void 0 : _c.onRefresherWillRefresh) === null || _d === void 0 ? void 0 : _d.call(_c);
|
|
307
|
+
emitStatusChangeRef.current(1 /* RefreshStatus.CanRefresh */, next);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
emitStatusChangeRef.current(0 /* RefreshStatus.Idle */, next);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
const runRefresh = () => {
|
|
314
|
+
const cfg = configRef.current;
|
|
315
|
+
if (!cfg || refreshingLockRef.current || isRefreshingRef.current)
|
|
316
|
+
return;
|
|
317
|
+
refreshingLockRef.current = true;
|
|
318
|
+
const pullValue = lastPull;
|
|
319
|
+
const height = DEFAULT_REFRESHER_HEIGHT;
|
|
320
|
+
pullAtReleaseRef.current = pullValue;
|
|
321
|
+
if (!isControlledRef.current)
|
|
322
|
+
setInternalRefreshingRef.current(true);
|
|
323
|
+
emitStatusChangeRef.current(2 /* RefreshStatus.Refreshing */, pullValue);
|
|
324
|
+
runBounceToLoading(pullValue, height, () => {
|
|
325
|
+
var _a, _b;
|
|
326
|
+
const safeReset = () => {
|
|
327
|
+
var _a, _b;
|
|
328
|
+
setPullDistanceRef.current(0);
|
|
329
|
+
if (!isControlledRef.current)
|
|
330
|
+
setInternalRefreshingRef.current(false);
|
|
331
|
+
refreshingLockRef.current = false;
|
|
332
|
+
lastPullRef.current = 0;
|
|
333
|
+
lastPull = 0;
|
|
334
|
+
pullAtReleaseRef.current = 0;
|
|
335
|
+
(_b = (_a = configRef.current) === null || _a === void 0 ? void 0 : _a.onRefresherRestore) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
336
|
+
emitStatusChangeRef.current(0 /* RefreshStatus.Idle */, 0);
|
|
337
|
+
};
|
|
338
|
+
Promise.resolve((_b = (_a = configRef.current) === null || _a === void 0 ? void 0 : _a.onRefresherRefresh) === null || _b === void 0 ? void 0 : _b.call(_a))
|
|
339
|
+
.then(() => {
|
|
340
|
+
if (!refreshingLockRef.current)
|
|
341
|
+
return;
|
|
342
|
+
emitStatusChangeRef.current(3 /* RefreshStatus.Completed */, DEFAULT_REFRESHER_HEIGHT);
|
|
343
|
+
requestAnimationFrame(() => runBounceBack(DEFAULT_REFRESHER_HEIGHT, () => {
|
|
344
|
+
var _a, _b;
|
|
345
|
+
refreshingLockRef.current = false;
|
|
346
|
+
lastPullRef.current = 0;
|
|
347
|
+
lastPull = 0;
|
|
348
|
+
pullAtReleaseRef.current = 0;
|
|
349
|
+
(_b = (_a = configRef.current) === null || _a === void 0 ? void 0 : _a.onRefresherRestore) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
350
|
+
emitStatusChangeRef.current(0 /* RefreshStatus.Idle */, 0);
|
|
351
|
+
}));
|
|
352
|
+
}, () => {
|
|
353
|
+
emitStatusChangeRef.current(4 /* RefreshStatus.Failed */, pullValue);
|
|
354
|
+
emitStatusChangeRef.current(3 /* RefreshStatus.Completed */, DEFAULT_REFRESHER_HEIGHT);
|
|
355
|
+
safeReset();
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
};
|
|
359
|
+
const onTouchEnd = () => {
|
|
360
|
+
if (refreshingLockRef.current)
|
|
361
|
+
return;
|
|
362
|
+
if (!touchStartedInListArea)
|
|
363
|
+
return;
|
|
364
|
+
dragOnEdge = false;
|
|
365
|
+
const current = lastPullRef.current;
|
|
366
|
+
if (current >= thresholdRef.current) {
|
|
367
|
+
runRefresh();
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
if (current > 0) {
|
|
371
|
+
runBounceBackAbort(current);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
const optsMove = { passive: false, capture: true };
|
|
376
|
+
const optsEnd = { passive: true, capture: true };
|
|
377
|
+
el.addEventListener('touchstart', onTouchStart, { passive: true });
|
|
378
|
+
el.addEventListener('touchmove', onTouchMove, optsMove);
|
|
379
|
+
el.addEventListener('touchend', onTouchEnd, optsEnd);
|
|
380
|
+
el.addEventListener('touchcancel', onTouchEnd, optsEnd);
|
|
381
|
+
return () => {
|
|
382
|
+
if (rafRef.current != null)
|
|
383
|
+
cancelAnimationFrame(rafRef.current);
|
|
384
|
+
el.removeEventListener('touchstart', onTouchStart);
|
|
385
|
+
el.removeEventListener('touchmove', onTouchMove, optsMove);
|
|
386
|
+
el.removeEventListener('touchend', onTouchEnd, optsEnd);
|
|
387
|
+
el.removeEventListener('touchcancel', onTouchEnd, optsEnd);
|
|
388
|
+
};
|
|
389
|
+
}, [h5RefresherEnabled]);
|
|
390
|
+
const renderRefresherContent = useCallback(() => {
|
|
391
|
+
var _a, _b, _c;
|
|
392
|
+
if (!config)
|
|
393
|
+
return null;
|
|
394
|
+
const threshold = (_a = config.refresherThreshold) !== null && _a !== void 0 ? _a : 45;
|
|
395
|
+
const defaultStyle = (_b = config.refresherDefaultStyle) !== null && _b !== void 0 ? _b : 'black';
|
|
396
|
+
const background = (_c = config.refresherBackground) !== null && _c !== void 0 ? _c : '#fff';
|
|
397
|
+
const hasCustomChildren = config.children != null;
|
|
398
|
+
// 小程序:自定义内容时返回 Slot(name=refresher),避免 View 的 slot 属性在模板层被过滤
|
|
399
|
+
// 样式对齐 H5:由内层 View 统一承载容器样式
|
|
400
|
+
if (supportsNativeRefresher) {
|
|
401
|
+
// 小程序需要名为 refresher 的插槽来指定自定义刷新内容
|
|
402
|
+
return hasCustomChildren && defaultStyle === 'none'
|
|
403
|
+
? (jsx(Slot, { name: "refresher", style: {
|
|
404
|
+
position: 'absolute',
|
|
405
|
+
left: 0,
|
|
406
|
+
right: 0,
|
|
407
|
+
zIndex: 0,
|
|
408
|
+
}, children: jsx(View, { style: {
|
|
409
|
+
width: '100%',
|
|
410
|
+
flexShrink: 0,
|
|
411
|
+
display: 'flex',
|
|
412
|
+
justifyContent: 'center',
|
|
413
|
+
alignItems: 'center',
|
|
414
|
+
background,
|
|
415
|
+
}, children: config.children }) }))
|
|
416
|
+
: null;
|
|
417
|
+
}
|
|
418
|
+
// H5:refresherDefaultStyle 控制默认指示器样式(对齐小程序 black/white/none)
|
|
419
|
+
// black=深色文案 white=浅色文案 none=仅展示 children,不展示默认「下拉/释放/加载中」
|
|
420
|
+
const textColor = defaultStyle === 'white' ? '#fff' : defaultStyle === 'black' ? '#333' : undefined;
|
|
421
|
+
// 有自定义 children 且 style=none 时隐藏默认文字
|
|
422
|
+
const showDefaultText = !(defaultStyle === 'none' && hasCustomChildren);
|
|
423
|
+
const defaultText = showDefaultText
|
|
424
|
+
? (isRefreshing ? '加载中...' : pullDistance >= threshold ? '释放刷新' : '下拉刷新')
|
|
425
|
+
: null;
|
|
426
|
+
return (jsx(View, { style: {
|
|
427
|
+
width: '100%',
|
|
428
|
+
minHeight: hasCustomChildren ? undefined : DEFAULT_REFRESHER_HEIGHT,
|
|
429
|
+
height: hasCustomChildren ? 'auto' : DEFAULT_REFRESHER_HEIGHT,
|
|
430
|
+
flexShrink: 0,
|
|
431
|
+
display: 'flex',
|
|
432
|
+
justifyContent: 'center',
|
|
433
|
+
alignItems: 'center',
|
|
434
|
+
background,
|
|
435
|
+
}, children: hasCustomChildren ? config.children : (defaultText ? jsx(View, { style: textColor ? { color: textColor } : undefined, children: defaultText }) : null) }));
|
|
436
|
+
}, [config, pullDistance, isRefreshing]);
|
|
437
|
+
/** 受控 refresherTriggered=true:无下拉也显示加载条 */
|
|
438
|
+
React.useEffect(() => {
|
|
439
|
+
if (!isControlled || !config || config.refresherTriggered !== true)
|
|
440
|
+
return;
|
|
441
|
+
if (pullDistanceRef.current >= DEFAULT_REFRESHER_HEIGHT)
|
|
442
|
+
return;
|
|
443
|
+
setPullDistanceRef.current(DEFAULT_REFRESHER_HEIGHT);
|
|
444
|
+
pullDistanceRef.current = DEFAULT_REFRESHER_HEIGHT;
|
|
445
|
+
emitStatusChangeRef.current(2 /* RefreshStatus.Refreshing */, DEFAULT_REFRESHER_HEIGHT);
|
|
446
|
+
}, [isControlled, config === null || config === void 0 ? void 0 : config.refresherTriggered]);
|
|
447
|
+
/** 受控 refresherTriggered=false:回弹清零;与 touch 共用 rafRef,cancel 时须在此释放 refreshingLockRef */
|
|
448
|
+
const prevTriggeredRef = useRef(config === null || config === void 0 ? void 0 : config.refresherTriggered);
|
|
449
|
+
React.useEffect(() => {
|
|
450
|
+
if (!isControlled || !config || config.refresherTriggered !== false) {
|
|
451
|
+
prevTriggeredRef.current = config === null || config === void 0 ? void 0 : config.refresherTriggered;
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
const prev = prevTriggeredRef.current;
|
|
455
|
+
prevTriggeredRef.current = false;
|
|
456
|
+
if (prev === true && (pullDistanceRef.current > 0 || isRefreshingRef.current)) {
|
|
457
|
+
if (rafRef.current != null)
|
|
458
|
+
cancelAnimationFrame(rafRef.current);
|
|
459
|
+
const from = pullDistanceRef.current > 0 ? pullDistanceRef.current : DEFAULT_REFRESHER_HEIGHT;
|
|
460
|
+
emitStatusChangeRef.current(3 /* RefreshStatus.Completed */, from);
|
|
461
|
+
const startTime = nowMs();
|
|
462
|
+
const animate = () => {
|
|
463
|
+
var _a;
|
|
464
|
+
const t = Math.min((nowMs() - startTime) / BOUNCE_MS, 1);
|
|
465
|
+
const ease = 1 - Math.pow(1 - t, 3);
|
|
466
|
+
const v = from * (1 - ease);
|
|
467
|
+
setPullDistanceRef.current(v);
|
|
468
|
+
pullDistanceRef.current = v;
|
|
469
|
+
if (t < 1)
|
|
470
|
+
rafRef.current = requestAnimationFrame(animate);
|
|
471
|
+
else {
|
|
472
|
+
setPullDistanceRef.current(0);
|
|
473
|
+
pullDistanceRef.current = 0;
|
|
474
|
+
if (!isControlledRef.current)
|
|
475
|
+
setInternalRefreshingRef.current(false);
|
|
476
|
+
rafRef.current = null;
|
|
477
|
+
refreshingLockRef.current = false;
|
|
478
|
+
(_a = config.onRefresherRestore) === null || _a === void 0 ? void 0 : _a.call(config);
|
|
479
|
+
emitStatusChangeRef.current(0 /* RefreshStatus.Idle */, 0);
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
rafRef.current = requestAnimationFrame(animate);
|
|
483
|
+
}
|
|
484
|
+
}, [isControlled, config === null || config === void 0 ? void 0 : config.refresherTriggered]);
|
|
485
|
+
return {
|
|
486
|
+
scrollViewRefresherProps,
|
|
487
|
+
scrollViewRefresherHandlers,
|
|
488
|
+
h5RefresherProps: {
|
|
489
|
+
touchHandlers: {},
|
|
490
|
+
pullDistance,
|
|
491
|
+
isRefreshing,
|
|
492
|
+
showRefresherLayer: !supportsNativeRefresher && !!config && h5RefresherEnabled,
|
|
493
|
+
},
|
|
494
|
+
addImperativeTouchListeners: !supportsNativeRefresher && config && h5RefresherEnabled ? addImperativeTouchListeners : undefined,
|
|
495
|
+
renderRefresherContent,
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
export { DEFAULT_REFRESHER_HEIGHT, useRefresher };
|
|
500
|
+
//# sourceMappingURL=useRefresher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRefresher.js","sources":["../../../../src/components/list/hooks/useRefresher.tsx"],"sourcesContent":["import { Slot, View } from '@tarojs/components'\nimport React, { useCallback, useRef, useState } from 'react'\n\nimport { supportsNativeRefresher } from '../utils'\n\n/**\n * List 组件内部的 refresher 配置类型(独立于 Refresher 组件)\n * 与 ScrollView refresher 相关属性语义对齐\n */\nexport interface ListRefresherConfig {\n refresherEnabled?: boolean\n refresherThreshold?: number\n refresherDefaultStyle?: 'black' | 'white' | 'none'\n refresherBackground?: string\n refresherTriggered?: boolean\n /** 自定义刷新内容(来自 Refresher 子组件的 children) */\n children?: React.ReactNode\n onRefresherPulling?: (e?: { detail?: { deltaY?: number } }) => void\n onRefresherRefresh?: () => void | Promise<void>\n onRefresherRestore?: () => void\n onRefresherAbort?: () => void\n onRefresherWillRefresh?: () => void\n onRefresherStatusChange?: (e?: { detail?: { status?: number, dy?: number } }) => void\n}\n\n/**\n * 下拉刷新(List 内部)\n *\n * - 小程序:ScrollView 原生 refresher-*;业务 Promise reject 时补发 Failed(4)(原生不派发)\n * - H5:触顶 + touch 拖拽;最大行程 / 阻尼停拉线为视口高的 0.9 / 0.8(innerHeight);收尾仅依赖 onRefresherRefresh 的 Promise\n * - 动画时间戳用 nowMs():小程序部分环境无 performance,避免抛错中断回弹\n * - rafRef 与受控 refresherTriggered→false 的 effect 共用:effect 内 cancel 可能打断 H5 成功回弹,须在 effect 动画结束处释放 refreshingLockRef\n * - H5 reject:onRefresherStatusChange 顺序 Failed(4) → Completed(3) → Idle(0)\n * - emitStatusChange:仅 status 变化时回调(同 status 不重复)\n */\n\nconst BOUNCE_MS = 300\nconst AT_TOP_THRESHOLD = 3\nconst H5_PULL_DISTANCE_MAX_VH = 0.9\nconst H5_DAMPING_LIMIT_VH = 0.8\nconst VIEWPORT_HEIGHT_FALLBACK = 800\nconst DEG_LIMIT = 40\nexport const DEFAULT_REFRESHER_HEIGHT = 50\n\nfunction nowMs (): number {\n if (typeof performance !== 'undefined' && typeof performance.now === 'function') {\n return performance.now()\n }\n return Date.now()\n}\n\n/** 下拉刷新状态枚举(对齐微信小程序 RefreshStatus) */\nexport const enum RefreshStatus {\n /** 空闲 */\n Idle = 0,\n /** 超过下拉刷新阈值 */\n CanRefresh = 1,\n /** 刷新中 */\n Refreshing = 2,\n /** 刷新完成 */\n Completed = 3,\n /** 刷新失败 */\n Failed = 4,\n}\n\nfunction getViewportHeightPx (): number {\n if (typeof window === 'undefined' || !Number.isFinite(window.innerHeight) || window.innerHeight <= 0) {\n return VIEWPORT_HEIGHT_FALLBACK\n }\n return window.innerHeight\n}\n\n/** 阻尼增量:ratio=总下拉位移/视口高;超过 dampingLimit 后不再累加 */\nfunction dampIncrement (\n diff: number,\n totalMove: number,\n currentPull: number,\n viewportHeight: number,\n dampingLimit: number\n): number {\n if (diff <= 0) return 0\n if (currentPull >= dampingLimit) return 0\n const ratio = Math.min(totalMove / viewportHeight, 1)\n return diff * (1 - ratio) * 0.6\n}\n\ninterface UseRefresherReturn {\n scrollViewRefresherProps: {\n refresherEnabled?: boolean\n refresherThreshold?: number\n refresherDefaultStyle?: string\n refresherBackground?: string\n refresherTriggered?: boolean\n }\n scrollViewRefresherHandlers: {\n onRefresherPulling?: (e: any) => void\n onRefresherRefresh?: (e: any) => void\n onRefresherRestore?: () => void\n onRefresherAbort?: () => void\n }\n h5RefresherProps: {\n touchHandlers: Record<string, unknown>\n pullDistance: number\n isRefreshing: boolean\n /** H5 单结构下恒为 true,仅兼容旧类型 */\n showRefresherLayer: boolean\n }\n addImperativeTouchListeners?: (el: HTMLElement) => () => void\n renderRefresherContent: () => React.ReactNode | null\n}\n\nexport function useRefresher(\n config: ListRefresherConfig | null,\n /** 列表逻辑顶部对应的 scrollTop,用于触顶判断;H5「顶栏悬浮+只滚列表」时传 0,imperative 内以 DOM scrollTop 为准 */\n scrollTopAtLogicalTop: number,\n /** scrollElement 模式下可选:下拉起始点须在 List 内才触发刷新;未传时默认 true(沿用原逻辑) */\n getIsTouchInListArea?: (ev: TouchEvent) => boolean\n): UseRefresherReturn {\n const [internalRefreshing, setInternalRefreshing] = useState(false)\n const [pullDistance, setPullDistance] = useState(0)\n const pullDistanceRef = useRef(0)\n const rafRef = useRef<number | null>(null)\n const setPullDistanceRef = useRef(setPullDistance)\n const setInternalRefreshingRef = useRef(setInternalRefreshing)\n setPullDistanceRef.current = setPullDistance\n setInternalRefreshingRef.current = setInternalRefreshing\n pullDistanceRef.current = pullDistance\n\n const isControlled = typeof config?.refresherTriggered === 'boolean'\n const isRefreshing = isControlled ? (config?.refresherTriggered ?? false) : internalRefreshing\n const isRefreshingRef = useRef(isRefreshing)\n isRefreshingRef.current = isRefreshing\n /** 刷新中锁:runRefresh 内同步置 true,避免 setState 未重渲染前再次触摸触发刷新 */\n const refreshingLockRef = useRef(false)\n /** H5 当前刷新状态,用于 onRefresherStatusChange 避免重复触发 */\n const refreshStatusRef = useRef<RefreshStatus>(RefreshStatus.Idle)\n /** H5 是否启用下拉刷新:refresherEnabled === false 时不挂 touch、不显示顶栏 */\n const h5RefresherEnabled = !!config && config.refresherEnabled !== false\n\n /** touch 只挂一次,回调里读 ref 才能拿到最新配置,避免改预设后仍用旧值 */\n const thresholdRef = useRef(config?.refresherThreshold ?? 45)\n thresholdRef.current = config?.refresherThreshold ?? 45\n const configRef = useRef(config)\n configRef.current = config\n\n const emitStatusChangeRef = useRef((status: RefreshStatus, dy: number) => {\n if (refreshStatusRef.current !== status) {\n refreshStatusRef.current = status\n configRef.current?.onRefresherStatusChange?.({ detail: { status, dy } })\n }\n })\n const isControlledRef = useRef(isControlled)\n isControlledRef.current = isControlled\n /** H5 顶栏悬浮时 List 传 0,触顶即 scrollTop<=0+阈值;否则由 List 传列表顶对应的 scrollTop */\n const scrollTopWhenAtTop = !supportsNativeRefresher && config ? scrollTopAtLogicalTop : 0\n const topThresholdPx = scrollTopWhenAtTop + AT_TOP_THRESHOLD\n const topThresholdPxRef = useRef(topThresholdPx)\n topThresholdPxRef.current = topThresholdPx\n\n const getIsTouchInListAreaRef = useRef(getIsTouchInListArea)\n getIsTouchInListAreaRef.current = getIsTouchInListArea\n\n const scrollViewRefresherProps = config && supportsNativeRefresher ? {\n refresherEnabled: config.refresherEnabled ?? true,\n refresherThreshold: config.refresherThreshold ?? 45,\n refresherDefaultStyle: config.refresherDefaultStyle ?? 'black',\n refresherBackground: config.refresherBackground ?? '#fff',\n refresherTriggered: isRefreshing,\n } : {}\n\n const scrollViewRefresherHandlers = config && supportsNativeRefresher ? {\n onRefresherPulling: (e: any) => {\n config.onRefresherPulling?.({ detail: { deltaY: e.detail?.deltaY ?? 0 } })\n },\n onRefresherRefresh: async () => {\n if (!isControlled) setInternalRefreshing(true)\n try {\n await config.onRefresherRefresh?.()\n } catch {\n // 原生不派发 Failed(4),补发便于与 H5 一致\n config.onRefresherStatusChange?.({ detail: { status: RefreshStatus.Failed, dy: 0 } })\n } finally {\n if (!isControlled) setInternalRefreshing(false)\n }\n },\n onRefresherRestore: () => config.onRefresherRestore?.(),\n onRefresherAbort: () => config.onRefresherAbort?.(),\n // 小程序特有事件:即将触发刷新(拖动超过 threshold 时)\n onRefresherWillRefresh: () => config.onRefresherWillRefresh?.(),\n // 小程序特有事件:下拉刷新状态变化\n onRefresherStatusChange: (e: any) => {\n config.onRefresherStatusChange?.({ detail: { status: e.detail?.status, dy: e.detail?.dy } })\n },\n } : {}\n\n const addImperativeTouchListeners = React.useCallback((el: HTMLElement) => {\n if (supportsNativeRefresher || !configRef.current || !h5RefresherEnabled) return () => {}\n const scrollEl = el as HTMLDivElement\n const startY = { current: 0 }\n const startX = { current: 0 }\n const lastY = { current: 0 }\n let touchStartedAtTop = false\n /** 下拉起始点是否在 List 内(scrollElement 模式);未传 getIsTouchInListArea 时恒为 true */\n let touchStartedInListArea = true\n let dragOnEdge = false\n let lastPull = 0\n /** 用于 onTouchEnd 判断是否触发刷新;刷新完成后必须置 0,否则下次点击(无 touchMove)会误用上次的 lastPull 再次触发 */\n const lastPullRef = { current: 0 }\n const pullAtReleaseRef = { current: 0 }\n\n const setPull = (v: number) => {\n lastPull = v\n lastPullRef.current = v\n setPullDistanceRef.current(v)\n }\n\n const runBounceBack = (fromValue: number, onComplete?: () => void) => {\n if (rafRef.current != null) cancelAnimationFrame(rafRef.current)\n const startTime = nowMs()\n const animate = () => {\n const t = Math.min((nowMs() - startTime) / BOUNCE_MS, 1)\n const ease = 1 - Math.pow(1 - t, 3)\n const v = fromValue * (1 - ease)\n setPullDistanceRef.current(v)\n lastPullRef.current = v\n lastPull = v\n if (t < 1) {\n rafRef.current = requestAnimationFrame(animate)\n } else {\n setPullDistanceRef.current(0)\n if (!isControlledRef.current) setInternalRefreshingRef.current(false)\n rafRef.current = null\n onComplete?.()\n }\n }\n rafRef.current = requestAnimationFrame(animate)\n }\n\n /** 未达阈值松手回弹结束:通知中止 */\n const runBounceBackAbort = (fromValue: number) => {\n if (rafRef.current != null) cancelAnimationFrame(rafRef.current)\n const startTime = nowMs()\n const animate = () => {\n const t = Math.min((nowMs() - startTime) / BOUNCE_MS, 1)\n const ease = 1 - Math.pow(1 - t, 3)\n const v = fromValue * (1 - ease)\n setPullDistanceRef.current(v)\n lastPullRef.current = v\n lastPull = v\n if (t < 1) rafRef.current = requestAnimationFrame(animate)\n else {\n setPullDistanceRef.current(0)\n rafRef.current = null\n lastPullRef.current = 0\n lastPull = 0\n configRef.current?.onRefresherAbort?.()\n emitStatusChangeRef.current(RefreshStatus.Idle, 0)\n }\n }\n rafRef.current = requestAnimationFrame(animate)\n }\n\n /** 收起到加载高度后再执行 onRefresherRefresh */\n const runBounceToLoading = (fromValue: number, toValue: number, onReach: () => void) => {\n if (rafRef.current != null) cancelAnimationFrame(rafRef.current)\n const startTime = nowMs()\n const animate = () => {\n const t = Math.min((nowMs() - startTime) / BOUNCE_MS, 1)\n const ease = 1 - Math.pow(1 - t, 3)\n setPullDistanceRef.current(fromValue + (toValue - fromValue) * ease)\n if (t < 1) {\n rafRef.current = requestAnimationFrame(animate)\n } else {\n setPullDistanceRef.current(toValue)\n rafRef.current = null\n onReach()\n }\n }\n rafRef.current = requestAnimationFrame(animate)\n }\n\n const isEdge = () => (scrollEl.scrollTop ?? 0) <= topThresholdPxRef.current\n\n const onTouchStart = (e: TouchEvent) => {\n if (refreshingLockRef.current || isRefreshingRef.current) return\n if (rafRef.current != null) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n lastPull = lastPullRef.current\n touchStartedAtTop = isEdge()\n touchStartedInListArea = getIsTouchInListAreaRef.current?.(e) ?? true\n const t0 = e.touches[0]\n if (t0) {\n startY.current = t0.clientY\n startX.current = t0.clientX\n lastY.current = t0.clientY\n }\n }\n\n const onTouchMove = (ev: TouchEvent) => {\n if (refreshingLockRef.current || isRefreshingRef.current) return\n if (!touchStartedInListArea) return\n const touch = ev.touches[0]\n if (!touch) return\n const currentY = touch.clientY\n const currentX = touch.clientX\n if (!isEdge()) {\n setPull(0)\n dragOnEdge = false\n return\n }\n // 到顶后:若 touch 开始时不在顶部,在首次下拉(dy>0)时「采纳」该手势,使同一手势内滚到顶后继续下拉可触发刷新\n if (!touchStartedAtTop && !dragOnEdge) {\n const dyCheck = currentY - lastY.current\n if (dyCheck <= 0) return\n touchStartedAtTop = true\n // 重置起点,避免采纳时 dy 过大导致刷新层瞬间拉满\n startY.current = currentY\n startX.current = currentX\n lastY.current = currentY\n }\n\n const dy = currentY - lastY.current\n // 还没进入下拉拖拽阶段(dragOnEdge=false)时,先看第一下是往上还是往下:\n // - 第一笔就是往上滑(dy<=0):视为正常滚动,直接交给原生 Scroll,不拦截、不启动下拉逻辑\n // - 第一笔是往下滑(dy>0):才认为是一次「下拉刷新」手势,进入拖拽模式\n if (!dragOnEdge) {\n if (dy <= 0) {\n lastY.current = currentY\n startY.current = currentY\n startX.current = currentX\n return\n }\n // 真正开始下拉刷新\n dragOnEdge = true\n startY.current = currentY\n startX.current = currentX\n }\n\n if (ev.cancelable) ev.preventDefault()\n const totalMove = currentY - startY.current\n const dx = currentX - startX.current\n if (dy <= 0) {\n lastY.current = currentY\n const next = Math.max(0, lastPull + dy)\n setPull(next)\n return\n }\n const deg = Math.atan(Math.abs(dx) / dy) * (180 / Math.PI)\n if (deg > DEG_LIMIT) {\n startY.current = currentY\n startX.current = currentX\n lastY.current = currentY\n return\n }\n lastY.current = currentY\n const vh = getViewportHeightPx()\n const maxPull = vh * H5_PULL_DISTANCE_MAX_VH\n const dampingLimit = vh * H5_DAMPING_LIMIT_VH\n const damped = dampIncrement(dy, totalMove, lastPull, vh, dampingLimit)\n const next = Math.min(lastPull + damped, maxPull)\n setPull(next)\n configRef.current?.onRefresherPulling?.({ detail: { deltaY: next } })\n if (next >= thresholdRef.current) {\n configRef.current?.onRefresherWillRefresh?.()\n emitStatusChangeRef.current(RefreshStatus.CanRefresh, next)\n } else {\n emitStatusChangeRef.current(RefreshStatus.Idle, next)\n }\n }\n\n const runRefresh = () => {\n const cfg = configRef.current\n if (!cfg || refreshingLockRef.current || isRefreshingRef.current) return\n refreshingLockRef.current = true\n const pullValue = lastPull\n const height = DEFAULT_REFRESHER_HEIGHT\n pullAtReleaseRef.current = pullValue\n if (!isControlledRef.current) setInternalRefreshingRef.current(true)\n emitStatusChangeRef.current(RefreshStatus.Refreshing, pullValue)\n runBounceToLoading(pullValue, height, () => {\n const safeReset = () => {\n setPullDistanceRef.current(0)\n if (!isControlledRef.current) setInternalRefreshingRef.current(false)\n refreshingLockRef.current = false\n lastPullRef.current = 0\n lastPull = 0\n pullAtReleaseRef.current = 0\n configRef.current?.onRefresherRestore?.()\n emitStatusChangeRef.current(RefreshStatus.Idle, 0)\n }\n Promise.resolve(configRef.current?.onRefresherRefresh?.())\n .then(\n () => {\n if (!refreshingLockRef.current) return\n emitStatusChangeRef.current(RefreshStatus.Completed, DEFAULT_REFRESHER_HEIGHT)\n requestAnimationFrame(() =>\n runBounceBack(DEFAULT_REFRESHER_HEIGHT, () => {\n refreshingLockRef.current = false\n lastPullRef.current = 0\n lastPull = 0\n pullAtReleaseRef.current = 0\n configRef.current?.onRefresherRestore?.()\n emitStatusChangeRef.current(RefreshStatus.Idle, 0)\n })\n )\n },\n () => {\n emitStatusChangeRef.current(RefreshStatus.Failed, pullValue)\n emitStatusChangeRef.current(RefreshStatus.Completed, DEFAULT_REFRESHER_HEIGHT)\n safeReset()\n }\n )\n })\n }\n\n const onTouchEnd = () => {\n if (refreshingLockRef.current) return\n if (!touchStartedInListArea) return\n dragOnEdge = false\n const current = lastPullRef.current\n if (current >= thresholdRef.current) {\n runRefresh()\n } else {\n if (current > 0) {\n runBounceBackAbort(current)\n }\n }\n }\n\n const optsMove = { passive: false, capture: true }\n const optsEnd = { passive: true, capture: true }\n el.addEventListener('touchstart', onTouchStart, { passive: true })\n el.addEventListener('touchmove', onTouchMove, optsMove)\n el.addEventListener('touchend', onTouchEnd, optsEnd)\n el.addEventListener('touchcancel', onTouchEnd, optsEnd)\n return () => {\n if (rafRef.current != null) cancelAnimationFrame(rafRef.current)\n el.removeEventListener('touchstart', onTouchStart)\n el.removeEventListener('touchmove', onTouchMove, optsMove)\n el.removeEventListener('touchend', onTouchEnd, optsEnd)\n el.removeEventListener('touchcancel', onTouchEnd, optsEnd)\n }\n }, [h5RefresherEnabled])\n\n const renderRefresherContent = useCallback(() => {\n if (!config) return null\n const threshold = config.refresherThreshold ?? 45\n const defaultStyle = config.refresherDefaultStyle ?? 'black'\n const background = config.refresherBackground ?? '#fff'\n const hasCustomChildren = config.children != null\n\n // 小程序:自定义内容时返回 Slot(name=refresher),避免 View 的 slot 属性在模板层被过滤\n // 样式对齐 H5:由内层 View 统一承载容器样式\n if (supportsNativeRefresher) {\n // 小程序需要名为 refresher 的插槽来指定自定义刷新内容\n return hasCustomChildren && defaultStyle === 'none'\n ? (\n <Slot\n name=\"refresher\"\n style={{\n position: 'absolute',\n left: 0,\n right: 0,\n zIndex: 0,\n }}\n >\n <View\n style={{\n width: '100%',\n flexShrink: 0,\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background,\n }}\n >\n {config.children}\n </View>\n </Slot>\n )\n : null\n }\n\n // H5:refresherDefaultStyle 控制默认指示器样式(对齐小程序 black/white/none)\n // black=深色文案 white=浅色文案 none=仅展示 children,不展示默认「下拉/释放/加载中」\n const textColor = defaultStyle === 'white' ? '#fff' : defaultStyle === 'black' ? '#333' : undefined\n // 有自定义 children 且 style=none 时隐藏默认文字\n const showDefaultText = !(defaultStyle === 'none' && hasCustomChildren)\n const defaultText = showDefaultText\n ? (isRefreshing ? '加载中...' : pullDistance >= threshold ? '释放刷新' : '下拉刷新')\n : null\n\n return (\n <View\n style={{\n width: '100%',\n minHeight: hasCustomChildren ? undefined : DEFAULT_REFRESHER_HEIGHT,\n height: hasCustomChildren ? 'auto' : DEFAULT_REFRESHER_HEIGHT,\n flexShrink: 0,\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n background,\n }}\n >\n {hasCustomChildren ? config.children : (\n defaultText ? <View style={textColor ? { color: textColor } : undefined}>{defaultText}</View> : null\n )}\n </View>\n )\n }, [config, pullDistance, isRefreshing])\n\n /** 受控 refresherTriggered=true:无下拉也显示加载条 */\n React.useEffect(() => {\n if (!isControlled || !config || config.refresherTriggered !== true) return\n if (pullDistanceRef.current >= DEFAULT_REFRESHER_HEIGHT) return\n setPullDistanceRef.current(DEFAULT_REFRESHER_HEIGHT)\n pullDistanceRef.current = DEFAULT_REFRESHER_HEIGHT\n emitStatusChangeRef.current(RefreshStatus.Refreshing, DEFAULT_REFRESHER_HEIGHT)\n }, [isControlled, config?.refresherTriggered])\n\n /** 受控 refresherTriggered=false:回弹清零;与 touch 共用 rafRef,cancel 时须在此释放 refreshingLockRef */\n const prevTriggeredRef = useRef(config?.refresherTriggered)\n React.useEffect(() => {\n if (!isControlled || !config || config.refresherTriggered !== false) {\n prevTriggeredRef.current = config?.refresherTriggered\n return\n }\n const prev = prevTriggeredRef.current\n prevTriggeredRef.current = false\n if (prev === true && (pullDistanceRef.current > 0 || isRefreshingRef.current)) {\n if (rafRef.current != null) cancelAnimationFrame(rafRef.current)\n const from = pullDistanceRef.current > 0 ? pullDistanceRef.current : DEFAULT_REFRESHER_HEIGHT\n emitStatusChangeRef.current(RefreshStatus.Completed, from)\n const startTime = nowMs()\n const animate = () => {\n const t = Math.min((nowMs() - startTime) / BOUNCE_MS, 1)\n const ease = 1 - Math.pow(1 - t, 3)\n const v = from * (1 - ease)\n setPullDistanceRef.current(v)\n pullDistanceRef.current = v\n if (t < 1) rafRef.current = requestAnimationFrame(animate)\n else {\n setPullDistanceRef.current(0)\n pullDistanceRef.current = 0\n if (!isControlledRef.current) setInternalRefreshingRef.current(false)\n rafRef.current = null\n refreshingLockRef.current = false\n config.onRefresherRestore?.()\n emitStatusChangeRef.current(RefreshStatus.Idle, 0)\n }\n }\n rafRef.current = requestAnimationFrame(animate)\n }\n }, [isControlled, config?.refresherTriggered])\n\n return {\n scrollViewRefresherProps,\n scrollViewRefresherHandlers,\n h5RefresherProps: {\n touchHandlers: {},\n pullDistance,\n isRefreshing,\n showRefresherLayer: !supportsNativeRefresher && !!config && h5RefresherEnabled,\n },\n addImperativeTouchListeners: !supportsNativeRefresher && config && h5RefresherEnabled ? addImperativeTouchListeners : undefined,\n renderRefresherContent,\n }\n}\n"],"names":["_jsx"],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useResizeObserver Hook - 尺寸变化监听(平台适配)
|
|
3
|
+
*
|
|
4
|
+
* H5: 使用 ResizeObserver API
|
|
5
|
+
* 小程序: 使用 IntersectionObserver + SelectorQuery
|
|
6
|
+
*/
|
|
7
|
+
interface UseResizeObserverOptions {
|
|
8
|
+
/** 是否启用监听 */
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
/** 是否水平滚动(监听 width 还是 height) */
|
|
11
|
+
isHorizontal: boolean;
|
|
12
|
+
/** List 容器 ID(小程序用于 SelectorQuery) */
|
|
13
|
+
listId: string;
|
|
14
|
+
selectorQueryScope?: object;
|
|
15
|
+
/** 尺寸变化回调 */
|
|
16
|
+
onResize: (index: number, size: number) => void;
|
|
17
|
+
}
|
|
18
|
+
interface UseResizeObserverReturn {
|
|
19
|
+
/** 观察指定元素(传入 ref 和索引) */
|
|
20
|
+
observe: (element: HTMLElement | null, index: number) => void;
|
|
21
|
+
/** 取消观察指定元素 */
|
|
22
|
+
unobserve: (element: HTMLElement | null) => void;
|
|
23
|
+
/** 断开所有观察 */
|
|
24
|
+
disconnect: () => void;
|
|
25
|
+
}
|
|
26
|
+
export declare function useResizeObserver(options: UseResizeObserverOptions): UseResizeObserverReturn;
|
|
27
|
+
export {};
|