@tarojs/components-advanced 4.1.12-beta.8 → 4.2.0-beta.0

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 (41) hide show
  1. package/dist/components/index.js +1 -2
  2. package/dist/components/index.js.map +1 -1
  3. package/dist/components/list/index.d.ts +3 -65
  4. package/dist/components/list/index.js +111 -1050
  5. package/dist/components/list/index.js.map +1 -1
  6. package/dist/components/virtual-list/vue/list.d.ts +2 -2
  7. package/dist/components/virtual-waterfall/vue/waterfall.d.ts +1 -1
  8. package/dist/components/water-flow/interface.d.ts +2 -14
  9. package/dist/components/water-flow/root.d.ts +1 -3
  10. package/dist/components/water-flow/root.js +9 -10
  11. package/dist/components/water-flow/root.js.map +1 -1
  12. package/dist/components/water-flow/utils.d.ts +0 -2
  13. package/dist/components/water-flow/utils.js +1 -3
  14. package/dist/components/water-flow/utils.js.map +1 -1
  15. package/dist/components/water-flow/water-flow.d.ts +1 -1
  16. package/dist/components/water-flow/water-flow.js +24 -151
  17. package/dist/components/water-flow/water-flow.js.map +1 -1
  18. package/dist/index.js +1 -2
  19. package/dist/index.js.map +1 -1
  20. package/package.json +8 -9
  21. package/dist/components/list/NoMore.d.ts +0 -30
  22. package/dist/components/list/NoMore.js +0 -10
  23. package/dist/components/list/NoMore.js.map +0 -1
  24. package/dist/components/list/hooks/useItemSizeCache.d.ts +0 -13
  25. package/dist/components/list/hooks/useItemSizeCache.js +0 -40
  26. package/dist/components/list/hooks/useItemSizeCache.js.map +0 -1
  27. package/dist/components/list/hooks/useMeasureStartOffset.d.ts +0 -10
  28. package/dist/components/list/hooks/useMeasureStartOffset.js +0 -43
  29. package/dist/components/list/hooks/useMeasureStartOffset.js.map +0 -1
  30. package/dist/components/list/hooks/useRefresher.d.ts +0 -74
  31. package/dist/components/list/hooks/useRefresher.js +0 -503
  32. package/dist/components/list/hooks/useRefresher.js.map +0 -1
  33. package/dist/components/list/hooks/useResizeObserver.d.ts +0 -26
  34. package/dist/components/list/hooks/useResizeObserver.js +0 -152
  35. package/dist/components/list/hooks/useResizeObserver.js.map +0 -1
  36. package/dist/components/list/hooks/useScrollCorrection.d.ts +0 -19
  37. package/dist/components/list/hooks/useScrollCorrection.js +0 -73
  38. package/dist/components/list/hooks/useScrollCorrection.js.map +0 -1
  39. package/dist/components/list/utils.d.ts +0 -16
  40. package/dist/components/list/utils.js +0 -19
  41. package/dist/components/list/utils.js.map +0 -1
@@ -40,8 +40,6 @@ const createImperativePromise = () => {
40
40
  return Object.assign(Object.assign({}, handle), { promise });
41
41
  };
42
42
  const isWeb = () => getEnv().toLowerCase() === 'web';
43
- /** 判断是否为 H5(用于 scrollElement 模式等) */
44
- const isH5 = process.env.TARO_ENV === 'h5';
45
43
 
46
- export { createImperativePromise, getMatrixPosition, getSysInfo, isH5, isSameRenderRange, isWeb };
44
+ export { createImperativePromise, getMatrixPosition, getSysInfo, isSameRenderRange, isWeb };
47
45
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/components/water-flow/utils.ts"],"sourcesContent":["import { getEnv, getSystemInfoSync } from '@tarojs/taro'\n\nlet sysInfo: ReturnType<typeof getSystemInfoSync>\n\nexport const getSysInfo = () => {\n if (sysInfo) return sysInfo\n sysInfo = getSystemInfoSync()\n return sysInfo\n}\n\ntype ArrIndex = number;\n/**\n * 一维数组索引换算到二维数组\n * @param i 一维数组索引\n * @param columns 列数\n */\nexport function getMatrixPosition(i: ArrIndex, columns: number) {\n const col = i % columns // 列号\n const row = Math.floor(i / columns) // 行号\n return { row, col }\n}\n\n/**\n * 简单比较渲染区间范围\n */\nexport function isSameRenderRange(a: any[], b: any[]) {\n return JSON.stringify(a) === JSON.stringify(b)\n}\n\n/**\n * 创建一个命令式的 promise 对象\n *\n * 返回的对象包含以下属性:\n * - promise: 一个新的 Promise 对象,初始状态为 pending。\n * - resolve: 一个函数,用于将 promise 状态置为 resolved。\n * - reject: 一个函数,用于将 promise 状态置为 rejected,并可以传递一个原因参数。\n */\nexport const createImperativePromise = () => {\n type ImperativePromiseHandle = {\n resolve: () => void\n reject: (reason?: any) => void\n };\n const handle = {} as ImperativePromiseHandle\n const promise = new Promise<void>((resolve, reject) => {\n handle.resolve = resolve\n handle.reject = reject\n })\n return {\n ...handle,\n promise,\n }\n}\n\nexport const isWeb = () => getEnv().toLowerCase() === 'web'\n\n/** 判断是否为 H5(用于 scrollElement 模式等) */\nexport const isH5 = process.env.TARO_ENV === 'h5'\n"],"names":[],"mappings":";;AAEA,IAAI,OAA6C;AAE1C,MAAM,UAAU,GAAG,MAAK;AAC7B,IAAA,IAAI,OAAO;AAAE,QAAA,OAAO,OAAO;IAC3B,OAAO,GAAG,iBAAiB,EAAE;AAC7B,IAAA,OAAO,OAAO;AAChB;AAGA;;;;AAIG;AACa,SAAA,iBAAiB,CAAC,CAAW,EAAE,OAAe,EAAA;AAC5D,IAAA,MAAM,GAAG,GAAG,CAAC,GAAG,OAAO,CAAA;AACvB,IAAA,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,OAAO,CAAC,CAAA;AACnC,IAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE;AACrB;AAEA;;AAEG;AACa,SAAA,iBAAiB,CAAC,CAAQ,EAAE,CAAQ,EAAA;AAClD,IAAA,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;AAChD;AAEA;;;;;;;AAOG;AACI,MAAM,uBAAuB,GAAG,MAAK;IAK1C,MAAM,MAAM,GAAG,EAA6B;IAC5C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,KAAI;AACpD,QAAA,MAAM,CAAC,OAAO,GAAG,OAAO;AACxB,QAAA,MAAM,CAAC,MAAM,GAAG,MAAM;AACxB,KAAC,CAAC;IACF,OACK,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAA,MAAM,CACT,EAAA,EAAA,OAAO,EACR,CAAA;AACH;AAEO,MAAM,KAAK,GAAG,MAAM,MAAM,EAAE,CAAC,WAAW,EAAE,KAAK;AAEtD;AACa,MAAA,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK;;;;"}
1
+ {"version":3,"file":"utils.js","sources":["../../../src/components/water-flow/utils.ts"],"sourcesContent":["import { getEnv, getSystemInfoSync } from '@tarojs/taro'\n\nlet sysInfo: ReturnType<typeof getSystemInfoSync>\n\nexport const getSysInfo = () => {\n if (sysInfo) return sysInfo\n sysInfo = getSystemInfoSync()\n return sysInfo\n}\n\ntype ArrIndex = number;\n/**\n * 一维数组索引换算到二维数组\n * @param i 一维数组索引\n * @param columns 列数\n */\nexport function getMatrixPosition(i: ArrIndex, columns: number) {\n const col = i % columns // 列号\n const row = Math.floor(i / columns) // 行号\n return { row, col }\n}\n\n/**\n * 简单比较渲染区间范围\n */\nexport function isSameRenderRange(a: any[], b: any[]) {\n return JSON.stringify(a) === JSON.stringify(b)\n}\n\n/**\n * 创建一个命令式的 promise 对象\n *\n * 返回的对象包含以下属性:\n * - promise: 一个新的 Promise 对象,初始状态为 pending。\n * - resolve: 一个函数,用于将 promise 状态置为 resolved。\n * - reject: 一个函数,用于将 promise 状态置为 rejected,并可以传递一个原因参数。\n */\nexport const createImperativePromise = () => {\n type ImperativePromiseHandle = {\n resolve: () => void\n reject: (reason?: any) => void\n };\n const handle = {} as ImperativePromiseHandle\n const promise = new Promise<void>((resolve, reject) => {\n handle.resolve = resolve\n handle.reject = reject\n })\n return {\n ...handle,\n promise,\n }\n}\n\nexport const isWeb = () => getEnv().toLowerCase() === 'web'\n"],"names":[],"mappings":";;AAEA,IAAI,OAA6C;AAE1C,MAAM,UAAU,GAAG,MAAK;AAC7B,IAAA,IAAI,OAAO;AAAE,QAAA,OAAO,OAAO;IAC3B,OAAO,GAAG,iBAAiB,EAAE;AAC7B,IAAA,OAAO,OAAO;AAChB;AAGA;;;;AAIG;AACa,SAAA,iBAAiB,CAAC,CAAW,EAAE,OAAe,EAAA;AAC5D,IAAA,MAAM,GAAG,GAAG,CAAC,GAAG,OAAO,CAAA;AACvB,IAAA,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,OAAO,CAAC,CAAA;AACnC,IAAA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE;AACrB;AAEA;;AAEG;AACa,SAAA,iBAAiB,CAAC,CAAQ,EAAE,CAAQ,EAAA;AAClD,IAAA,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;AAChD;AAEA;;;;;;;AAOG;AACI,MAAM,uBAAuB,GAAG,MAAK;IAK1C,MAAM,MAAM,GAAG,EAA6B;IAC5C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,KAAI;AACpD,QAAA,MAAM,CAAC,OAAO,GAAG,OAAO;AACxB,QAAA,MAAM,CAAC,MAAM,GAAG,MAAM;AACxB,KAAC,CAAC;IACF,OACK,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAA,MAAM,CACT,EAAA,EAAA,OAAO,EACR,CAAA;AACH;AAEO,MAAM,KAAK,GAAG,MAAM,MAAM,EAAE,CAAC,WAAW,EAAE,KAAK;;;;"}
@@ -1,4 +1,4 @@
1
1
  import { ScrollViewProps } from '@tarojs/components';
2
2
  import { PropsWithChildren, ReactElement } from 'react';
3
3
  import type { WaterFlowProps } from './interface';
4
- export declare function WaterFlow({ children, ...props }: PropsWithChildren<WaterFlowProps>): ReactElement<import("@tarojs/components").ViewProps, string | import("react").JSXElementConstructor<any>> | ReactElement<ScrollViewProps, string | import("react").JSXElementConstructor<any>>;
4
+ export declare function WaterFlow({ children, ...props }: PropsWithChildren<WaterFlowProps>): ReactElement<ScrollViewProps, string | import("react").JSXElementConstructor<any>>;
@@ -1,48 +1,20 @@
1
1
  import { __rest } from 'tslib';
2
- import { View, ScrollView } from '@tarojs/components';
2
+ import { ScrollView, View } from '@tarojs/components';
3
3
  import { nextTick } from '@tarojs/taro';
4
- import { useContext, useRef, useId, useMemo, Children, cloneElement, useEffect, createElement } from 'react';
4
+ import { useId, useMemo, useRef, Children, cloneElement, useEffect, createElement } from 'react';
5
5
  import '../../utils/index.js';
6
- import { ListScrollElementContext } from '../list/index.js';
7
- import { useMeasureStartOffset } from '../list/hooks/useMeasureStartOffset.js';
8
6
  import { Root, RootEvents } from './root.js';
9
7
  import { Section } from './section.js';
10
8
  import { useMemoizedFn } from './use-memoized-fn.js';
11
9
  import { useObservedAttr } from './use-observed-attr.js';
12
- import { getSysInfo, isH5 } from './utils.js';
10
+ import { getSysInfo } from './utils.js';
13
11
  import { getScrollViewContextNode } from '../../utils/dom.js';
14
12
  import { debounce } from '../../utils/lodash.js';
15
13
 
16
14
  getSysInfo();
17
15
  function WaterFlow(_a) {
18
- var _b, _c;
19
16
  var { children } = _a, props = __rest(_a, ["children"]);
20
- const { id, style = {}, className, cacheCount = 1, onScrollToUpper, onScrollToLower, upperThresholdCount, lowerThresholdCount, scrollIntoView, type: flowType = 'default', scrollElement, startOffset, containerHeight, onScrollHeightChange, onScrollIntoViewComplete } = props, rest = __rest(props
21
- // 任务 4.1:支持从 ListScrollElementContext 获取(List 内嵌 WaterFlow 时)
22
- , ["id", "style", "className", "cacheCount", "onScrollToUpper", "onScrollToLower", "upperThresholdCount", "lowerThresholdCount", "scrollIntoView", "type", "scrollElement", "startOffset", "containerHeight", "onScrollHeightChange", "onScrollIntoViewComplete"]);
23
- // 任务 4.1:支持从 ListScrollElementContext 获取(List 内嵌 WaterFlow 时)
24
- const listScrollCtx = useContext(ListScrollElementContext);
25
- const effectiveScrollElement = scrollElement !== null && scrollElement !== void 0 ? scrollElement : listScrollCtx === null || listScrollCtx === void 0 ? void 0 : listScrollCtx.scrollRef;
26
- const contentWrapperRef = useRef(null);
27
- const measuredStartOffset = useMeasureStartOffset(effectiveScrollElement !== null && effectiveScrollElement !== void 0 ? effectiveScrollElement : { current: null }, contentWrapperRef, {
28
- enabled: !!((flowType === 'nested' && effectiveScrollElement && isH5) &&
29
- startOffset == null &&
30
- !listScrollCtx),
31
- isHorizontal: false,
32
- });
33
- const effectiveStartOffset = (_c = (_b = startOffset !== null && startOffset !== void 0 ? startOffset : listScrollCtx === null || listScrollCtx === void 0 ? void 0 : listScrollCtx.startOffset) !== null && _b !== void 0 ? _b : measuredStartOffset) !== null && _c !== void 0 ? _c : 0;
34
- const effectiveContainerHeight = containerHeight !== null && containerHeight !== void 0 ? containerHeight : listScrollCtx === null || listScrollCtx === void 0 ? void 0 : listScrollCtx.containerHeight;
35
- const startOffsetRef = useRef(effectiveStartOffset);
36
- const containerHeightRef = useRef(effectiveContainerHeight);
37
- const lastReportedHeightRef = useRef(0);
38
- startOffsetRef.current = effectiveStartOffset;
39
- containerHeightRef.current = effectiveContainerHeight;
40
- // type=nested 时显式开启 scrollElement 模式;否则始终用 default(自有 ScrollView)
41
- const useScrollElementMode = flowType === 'nested' && !!(effectiveScrollElement && isH5);
42
- if (flowType === 'nested' && !effectiveScrollElement && isH5) {
43
- // eslint-disable-next-line no-console
44
- console.warn('[WaterFlow] type=nested 但无 scrollElement(props 或 Context),回退为 default');
45
- }
17
+ const { id, style = {}, className, cacheCount = 1, onScrollToUpper, onScrollToLower, upperThresholdCount, lowerThresholdCount, scrollIntoView } = props, rest = __rest(props, ["id", "style", "className", "cacheCount", "onScrollToUpper", "onScrollToLower", "upperThresholdCount", "lowerThresholdCount", "scrollIntoView"]);
46
18
  const defaultId = useId().replace(/:/g, '');
47
19
  /**
48
20
  * 初始化数据模型
@@ -53,9 +25,8 @@ function WaterFlow(_a) {
53
25
  cacheCount,
54
26
  upperThresholdCount,
55
27
  lowerThresholdCount,
56
- skipContainerMeasure: useScrollElementMode,
57
28
  });
58
- }, [id, cacheCount, upperThresholdCount, lowerThresholdCount, useScrollElementMode]);
29
+ }, [id, cacheCount, upperThresholdCount, lowerThresholdCount]);
59
30
  const isScrolling$ = useObservedAttr(root, 'isScrolling');
60
31
  const scrollHeight$ = useObservedAttr(root, 'scrollHeight');
61
32
  const renderRange$ = useObservedAttr(root, 'renderRange');
@@ -108,19 +79,9 @@ function WaterFlow(_a) {
108
79
  })) === null || _a === void 0 ? void 0 : _a.slice(start, end + 1);
109
80
  }, [renderRange$[0], renderRange$[1], children, root, props.id]);
110
81
  const scrollTo = useMemoizedFn((scrollOffset = 0) => {
111
- var _a;
112
82
  scrollOffset = Math.max(0, scrollOffset);
113
83
  if (root.getState().scrollOffset === scrollOffset)
114
84
  return;
115
- // scrollElement 模式下需操作外部容器,且需加上 startOffset
116
- if (useScrollElementMode && (effectiveScrollElement === null || effectiveScrollElement === void 0 ? void 0 : effectiveScrollElement.current) && isH5) {
117
- const el = effectiveScrollElement.current;
118
- const scrollTarget = scrollOffset + ((_a = startOffsetRef.current) !== null && _a !== void 0 ? _a : 0);
119
- el.scrollTo({ top: scrollTarget });
120
- root.setStateBatch({ scrollOffset, isScrolling: true });
121
- root.sections.forEach((s) => s.getNodeRenderRange());
122
- return;
123
- }
124
85
  getScrollViewContextNode(`#${root.id}`).then((node) => {
125
86
  node.scrollTo({
126
87
  animated: true,
@@ -156,121 +117,33 @@ function WaterFlow(_a) {
156
117
  }, [onScrollToUpper, onScrollToLower]);
157
118
  /**
158
119
  * 处理 scrollIntoView
159
- * 竞态:快速切换目标时,取消前一次滚动,避免后发先至
160
120
  */
161
121
  useEffect(() => {
162
- let cancelled = false;
163
122
  handleScrollIntoView();
164
123
  async function handleScrollIntoView() {
165
- if (!scrollIntoView)
166
- return;
167
- const targetNode = root.findNode(scrollIntoView);
168
- if (!targetNode) {
169
- nextTick(() => { if (!cancelled)
170
- onScrollIntoViewComplete === null || onScrollIntoViewComplete === void 0 ? void 0 : onScrollIntoViewComplete(); });
171
- return;
172
- }
173
- const targetSection = targetNode.section;
174
- const doScroll = () => {
175
- if (cancelled)
176
- return;
177
- scrollTo(targetNode.getState().scrollTop);
178
- if (cancelled)
124
+ if (scrollIntoView) {
125
+ if (root.getState().scrollOffset > 0) {
126
+ // 说明在自动滚动前手动滚动过了,不应该自动滚动了,避免造成困扰
179
127
  return;
180
- nextTick(() => { if (!cancelled)
181
- onScrollIntoViewComplete === null || onScrollIntoViewComplete === void 0 ? void 0 : onScrollIntoViewComplete(); });
182
- };
183
- if (!targetSection.getState().layouted) {
184
- const order = targetSection.order;
185
- root.setStateIn('renderRange', [
186
- Math.min(renderRange$[0], order),
187
- Math.max(renderRange$[1], order),
188
- ]);
189
- nextTick(async () => {
190
- await targetNode.section.layoutedSignal.promise;
191
- if (cancelled)
128
+ }
129
+ const targetNode = root.findNode(scrollIntoView);
130
+ if (targetNode) {
131
+ const targetSection = targetNode.section;
132
+ if (!targetSection.getState().layouted) {
133
+ const order = targetSection.order;
134
+ root.setStateIn('renderRange', [renderRange$[0], order]);
135
+ nextTick(async () => {
136
+ await targetNode.section.layoutedSignal.promise;
137
+ scrollTo(targetNode.getState().scrollTop);
138
+ });
192
139
  return;
193
- doScroll();
194
- });
195
- return;
140
+ }
141
+ await targetNode.section.layoutedSignal.promise;
142
+ scrollTo(targetNode.getState().scrollTop);
143
+ }
196
144
  }
197
- await targetSection.layoutedSignal.promise;
198
- if (cancelled)
199
- return;
200
- doScroll();
201
145
  }
202
- return () => { cancelled = true; };
203
- }, [scrollIntoView, renderRange$[0], renderRange$[1], onScrollIntoViewComplete]);
204
- // 任务 3.3:scrollElement 模式下监听外部滚动,更新 root.scrollOffset
205
- useEffect(() => {
206
- if (!useScrollElementMode || !effectiveScrollElement)
207
- return;
208
- const el = effectiveScrollElement.current;
209
- if (!el)
210
- return;
211
- const handler = () => {
212
- var _a;
213
- const scrollTop = el.scrollTop;
214
- const offset = scrollTop - ((_a = startOffsetRef.current) !== null && _a !== void 0 ? _a : 0);
215
- const effectiveOffset = Math.max(0, offset);
216
- const scrollDirection = root.getState().scrollOffset < effectiveOffset ? 'forward' : 'backward';
217
- root.sections.forEach((section) => section.getNodeRenderRange());
218
- root.setStateBatch({
219
- scrollDirection,
220
- scrollOffset: effectiveOffset,
221
- isScrolling: true,
222
- });
223
- };
224
- // 同步初始位置
225
- handler();
226
- el.addEventListener('scroll', handler, { passive: true });
227
- return () => el.removeEventListener('scroll', handler);
228
- }, [useScrollElementMode, effectiveScrollElement, root]);
229
- // 任务 4.2:scrollHeight 变化时回调,便于 List 动高联动(props 优先,其次从 Context 获取)
230
- // 防抖上报:Root 多源触发 updateScrollHeight 可能产生多轮不同值;等 150ms 无新值时上报当前值(视为布局收敛结果)
231
- const reportHeight = onScrollHeightChange !== null && onScrollHeightChange !== void 0 ? onScrollHeightChange : listScrollCtx === null || listScrollCtx === void 0 ? void 0 : listScrollCtx.reportNestedHeightChange;
232
- useEffect(() => {
233
- if (!reportHeight || scrollHeight$ <= 0)
234
- return;
235
- const timer = setTimeout(() => {
236
- if (Math.abs(lastReportedHeightRef.current - scrollHeight$) < 1)
237
- return;
238
- lastReportedHeightRef.current = scrollHeight$;
239
- reportHeight(scrollHeight$);
240
- }, 150);
241
- return () => clearTimeout(timer);
242
- }, [scrollHeight$, reportHeight]);
243
- // 任务 3.4:scrollElement 模式下 containerSize 从 containerHeight / scrollElement 获取
244
- // ResizeObserver 监听 scrollElement 尺寸变化;containerHeight prop 变化时也需同步(如 List 内嵌时父传子)
245
- useEffect(() => {
246
- if (!useScrollElementMode || !effectiveScrollElement)
247
- return;
248
- const el = effectiveScrollElement.current;
249
- if (!el || typeof ResizeObserver === 'undefined')
250
- return;
251
- const update = () => {
252
- var _a;
253
- const height = (_a = containerHeightRef.current) !== null && _a !== void 0 ? _a : el.clientHeight;
254
- const width = el.clientWidth;
255
- if (height > 0 && width > 0) {
256
- root.setStateIn('containerSize', { width, height });
257
- }
258
- };
259
- update();
260
- const ro = new ResizeObserver(update);
261
- ro.observe(el);
262
- return () => ro.disconnect();
263
- }, [useScrollElementMode, effectiveScrollElement, root, effectiveContainerHeight]);
264
- // 任务 3.2:scrollElement 模式下不渲染 ScrollView,只渲染内容 View
265
- // 内容高度必须为 scrollHeight,否则父 scrollElement 无法正确滚动;显式写 height 覆盖 style 中的 height
266
- if (useScrollElementMode) {
267
- return createElement(View, {
268
- ref: contentWrapperRef,
269
- id: root.id,
270
- style: Object.assign(Object.assign({}, style), { width: '100%', position: 'relative', height: scrollHeight$, pointerEvents: isScrolling$ ? 'none' : 'auto' }),
271
- className,
272
- }, sections);
273
- }
146
+ }, [scrollIntoView, renderRange$[0]]);
274
147
  return createElement(ScrollView, Object.assign({ id: root.id, style: Object.assign({ WebkitOverflowScrolling: 'touch', overflow: 'auto' }, style), className, scrollY: true, onScroll: handleScroll }, rest), createElement(View, {
275
148
  id: 'waterflow-root',
276
149
  style: {
@@ -1 +1 @@
1
- {"version":3,"file":"water-flow.js","sources":["../../../src/components/water-flow/water-flow.ts"],"sourcesContent":["import { BaseEventOrig, ScrollView, ScrollViewProps, View } from '@tarojs/components'\nimport { nextTick } from '@tarojs/taro'\nimport {\n Children,\n cloneElement,\n createElement,\n PropsWithChildren,\n ReactElement,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n} from 'react'\n\nimport { debounce, getScrollViewContextNode } from '../../utils'\nimport { ListScrollElementContext } from '../list'\nimport { useMeasureStartOffset } from '../list/hooks/useMeasureStartOffset'\nimport { _FlowSectionProps } from './flow-section'\nimport { Root, RootEvents } from './root'\nimport { Section } from './section'\nimport { useMemoizedFn } from './use-memoized-fn'\nimport { useObservedAttr } from './use-observed-attr'\nimport { getSysInfo, isH5 } from './utils'\n\nimport type { ScrollDirection, WaterFlowProps } from './interface'\n\ngetSysInfo()\n\nexport function WaterFlow({ children, ...props }: PropsWithChildren<WaterFlowProps>) {\n const {\n id,\n style = {},\n className,\n cacheCount = 1,\n onScrollToUpper,\n onScrollToLower,\n upperThresholdCount,\n lowerThresholdCount,\n scrollIntoView,\n type: flowType = 'default',\n scrollElement,\n startOffset,\n containerHeight,\n onScrollHeightChange,\n onScrollIntoViewComplete,\n ...rest\n } = props\n // 任务 4.1:支持从 ListScrollElementContext 获取(List 内嵌 WaterFlow 时)\n const listScrollCtx = useContext(ListScrollElementContext)\n const effectiveScrollElement = scrollElement ?? listScrollCtx?.scrollRef\n const contentWrapperRef = useRef<HTMLDivElement>(null)\n const measuredStartOffset = useMeasureStartOffset(\n effectiveScrollElement ?? { current: null },\n contentWrapperRef,\n {\n enabled: !!(\n (flowType === 'nested' && effectiveScrollElement && isH5) &&\n startOffset == null &&\n !listScrollCtx\n ),\n isHorizontal: false,\n }\n )\n const effectiveStartOffset = startOffset ?? listScrollCtx?.startOffset ?? measuredStartOffset ?? 0\n const effectiveContainerHeight = containerHeight ?? listScrollCtx?.containerHeight\n\n const startOffsetRef = useRef(effectiveStartOffset)\n const containerHeightRef = useRef(effectiveContainerHeight)\n const lastReportedHeightRef = useRef<number>(0)\n startOffsetRef.current = effectiveStartOffset\n containerHeightRef.current = effectiveContainerHeight\n\n // type=nested 时显式开启 scrollElement 模式;否则始终用 default(自有 ScrollView)\n const useScrollElementMode =\n flowType === 'nested' && !!(effectiveScrollElement && isH5)\n if (flowType === 'nested' && !effectiveScrollElement && isH5) {\n // eslint-disable-next-line no-console\n console.warn('[WaterFlow] type=nested 但无 scrollElement(props 或 Context),回退为 default')\n }\n const defaultId = useId().replace(/:/g, '')\n /**\n * 初始化数据模型\n */\n const root = useMemo(() => {\n return new Root({\n id: id ?? defaultId,\n cacheCount,\n upperThresholdCount,\n lowerThresholdCount,\n skipContainerMeasure: useScrollElementMode,\n })\n }, [id, cacheCount, upperThresholdCount, lowerThresholdCount, useScrollElementMode])\n const isScrolling$ = useObservedAttr(root, 'isScrolling')\n const scrollHeight$ = useObservedAttr(root, 'scrollHeight')\n const renderRange$ = useObservedAttr(root, 'renderRange')\n const refEventOrig = useRef<BaseEventOrig>()\n\n /**\n * 滚动事件\n */\n const handleScroll = useMemoizedFn((ev: BaseEventOrig<ScrollViewProps.onScrollDetail>) => {\n refEventOrig.current = ev\n root.sections.forEach((section) => section.getNodeRenderRange())\n const { scrollTop } = ev.detail\n // 确定滚动方向\n const scrollDirection: ScrollDirection = root.getState().scrollOffset < scrollTop ? 'forward' : 'backward'\n // 设置滚动信息,包括方向和偏移量\n root.setStateBatch({\n scrollDirection: scrollDirection,\n scrollOffset: scrollTop,\n isScrolling: true,\n })\n })\n\n const sections = useMemo(() => {\n const [start, end] = renderRange$\n return Children.map(children, (child: ReactElement<PropsWithChildren<_FlowSectionProps>>, order) => {\n if (Object.is(child, null)) {\n return null\n }\n const sectionProps = child.props\n const sectionId = sectionProps.id || `section-${order}`\n const childCount = Children.count(sectionProps.children)\n let section = root.findSection(sectionId)\n if (section) {\n const originalCount = section.count\n if (childCount > originalCount) {\n section.pushNodes(childCount - originalCount)\n }\n } else {\n section = new Section(root, {\n id: sectionId,\n order,\n col: sectionProps.column ?? 1,\n rowGap: sectionProps.rowGap || 0,\n columnGap: sectionProps.columnGap || 0,\n count: Children.count(sectionProps.children),\n })\n }\n\n return cloneElement(child, { section, key: `${props.id}-${order}` })\n })?.slice(start, end + 1)\n }, [renderRange$[0], renderRange$[1], children, root, props.id])\n\n const scrollTo = useMemoizedFn((scrollOffset = 0) => {\n scrollOffset = Math.max(0, scrollOffset)\n if (root.getState().scrollOffset === scrollOffset) return\n // scrollElement 模式下需操作外部容器,且需加上 startOffset\n if (useScrollElementMode && effectiveScrollElement?.current && isH5) {\n const el = effectiveScrollElement.current\n const scrollTarget = scrollOffset + (startOffsetRef.current ?? 0)\n el.scrollTo({ top: scrollTarget })\n root.setStateBatch({ scrollOffset, isScrolling: true })\n root.sections.forEach((s) => s.getNodeRenderRange())\n return\n }\n getScrollViewContextNode(`#${root.id}`).then((node: any) => {\n node.scrollTo({\n animated: true,\n duration: 300,\n top: scrollOffset,\n })\n })\n })\n\n const resetScrolling = useMemoizedFn(() => {\n root.setStateIn('isScrolling', false)\n })\n\n const debouncedResetScrolling = debounce(resetScrolling)\n\n useEffect(() => {\n debouncedResetScrolling()\n }, [isScrolling$])\n\n /**\n * 处理滚动阈值\n */\n useEffect(() => {\n const disposers = [\n root.sub(\n RootEvents.ReachUpperThreshold,\n debounce(() => {\n onScrollToUpper?.(refEventOrig.current!)\n })\n ),\n root.sub(\n RootEvents.ReachLowerThreshold,\n debounce(() => {\n onScrollToLower?.(refEventOrig.current!)\n })\n ),\n ]\n return () => {\n disposers.forEach((disposer) => {\n disposer()\n })\n }\n }, [onScrollToUpper, onScrollToLower])\n\n /**\n * 处理 scrollIntoView\n * 竞态:快速切换目标时,取消前一次滚动,避免后发先至\n */\n useEffect(() => {\n let cancelled = false\n handleScrollIntoView()\n async function handleScrollIntoView() {\n if (!scrollIntoView) return\n const targetNode = root.findNode(scrollIntoView)\n if (!targetNode) {\n nextTick(() => { if (!cancelled) onScrollIntoViewComplete?.() })\n return\n }\n const targetSection = targetNode.section\n const doScroll = () => {\n if (cancelled) return\n scrollTo(targetNode.getState().scrollTop)\n if (cancelled) return\n nextTick(() => { if (!cancelled) onScrollIntoViewComplete?.() })\n }\n if (!targetSection.getState().layouted) {\n const order = targetSection.order\n root.setStateIn('renderRange', [\n Math.min(renderRange$[0], order),\n Math.max(renderRange$[1], order),\n ])\n nextTick(async () => {\n await targetNode.section.layoutedSignal.promise\n if (cancelled) return\n doScroll()\n })\n return\n }\n await targetSection.layoutedSignal.promise\n if (cancelled) return\n doScroll()\n }\n return () => { cancelled = true }\n }, [scrollIntoView, renderRange$[0], renderRange$[1], onScrollIntoViewComplete])\n\n // 任务 3.3:scrollElement 模式下监听外部滚动,更新 root.scrollOffset\n useEffect(() => {\n if (!useScrollElementMode || !effectiveScrollElement) return\n const el = effectiveScrollElement.current\n if (!el) return\n\n const handler = () => {\n const scrollTop = el.scrollTop\n const offset = scrollTop - (startOffsetRef.current ?? 0)\n const effectiveOffset = Math.max(0, offset)\n const scrollDirection: ScrollDirection = root.getState().scrollOffset < effectiveOffset ? 'forward' : 'backward'\n\n root.sections.forEach((section) => section.getNodeRenderRange())\n root.setStateBatch({\n scrollDirection,\n scrollOffset: effectiveOffset,\n isScrolling: true,\n })\n }\n\n // 同步初始位置\n handler()\n el.addEventListener('scroll', handler, { passive: true })\n return () => el.removeEventListener('scroll', handler)\n }, [useScrollElementMode, effectiveScrollElement, root])\n\n // 任务 4.2:scrollHeight 变化时回调,便于 List 动高联动(props 优先,其次从 Context 获取)\n // 防抖上报:Root 多源触发 updateScrollHeight 可能产生多轮不同值;等 150ms 无新值时上报当前值(视为布局收敛结果)\n const reportHeight = onScrollHeightChange ?? listScrollCtx?.reportNestedHeightChange\n useEffect(() => {\n if (!reportHeight || scrollHeight$ <= 0) return\n const timer = setTimeout(() => {\n if (Math.abs(lastReportedHeightRef.current - scrollHeight$) < 1) return\n lastReportedHeightRef.current = scrollHeight$\n reportHeight(scrollHeight$)\n }, 150)\n return () => clearTimeout(timer)\n }, [scrollHeight$, reportHeight])\n\n // 任务 3.4:scrollElement 模式下 containerSize 从 containerHeight / scrollElement 获取\n // ResizeObserver 监听 scrollElement 尺寸变化;containerHeight prop 变化时也需同步(如 List 内嵌时父传子)\n useEffect(() => {\n if (!useScrollElementMode || !effectiveScrollElement) return\n const el = effectiveScrollElement.current\n if (!el || typeof ResizeObserver === 'undefined') return\n\n const update = () => {\n const height = containerHeightRef.current ?? el.clientHeight\n const width = el.clientWidth\n if (height > 0 && width > 0) {\n root.setStateIn('containerSize', { width, height })\n }\n }\n update()\n const ro = new ResizeObserver(update)\n ro.observe(el)\n return () => ro.disconnect()\n }, [useScrollElementMode, effectiveScrollElement, root, effectiveContainerHeight])\n\n // 任务 3.2:scrollElement 模式下不渲染 ScrollView,只渲染内容 View\n // 内容高度必须为 scrollHeight,否则父 scrollElement 无法正确滚动;显式写 height 覆盖 style 中的 height\n if (useScrollElementMode) {\n return createElement(\n View,\n {\n ref: contentWrapperRef as any,\n id: root.id,\n style: {\n ...style,\n width: '100%',\n position: 'relative',\n height: scrollHeight$,\n pointerEvents: isScrolling$ ? 'none' : 'auto',\n },\n className,\n },\n sections\n )\n }\n\n return createElement(\n ScrollView,\n {\n id: root.id,\n style: {\n WebkitOverflowScrolling: 'touch',\n overflow: 'auto',\n ...style,\n },\n className,\n scrollY: true,\n onScroll: handleScroll,\n ...rest,\n },\n createElement(\n View,\n {\n id: 'waterflow-root',\n style: {\n width: '100%',\n position: 'relative',\n height: scrollHeight$,\n pointerEvents: isScrolling$ ? 'none' : 'auto',\n },\n },\n sections\n )\n )\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"water-flow.js","sources":["../../../src/components/water-flow/water-flow.ts"],"sourcesContent":["import { BaseEventOrig, ScrollView, ScrollViewProps, View } from '@tarojs/components'\nimport { nextTick } from '@tarojs/taro'\nimport {\n Children,\n cloneElement,\n createElement,\n PropsWithChildren,\n ReactElement,\n useEffect,\n useId,\n useMemo,\n useRef,\n} from 'react'\n\nimport { debounce, getScrollViewContextNode } from '../../utils'\nimport { _FlowSectionProps } from './flow-section'\nimport { Root, RootEvents } from './root'\nimport { Section } from './section'\nimport { useMemoizedFn } from './use-memoized-fn'\nimport { useObservedAttr } from './use-observed-attr'\nimport { getSysInfo } from './utils'\n\nimport type { ScrollDirection, WaterFlowProps } from './interface'\n\ngetSysInfo()\n\nexport function WaterFlow({ children, ...props }: PropsWithChildren<WaterFlowProps>) {\n const {\n id,\n style = {},\n className,\n cacheCount = 1,\n onScrollToUpper,\n onScrollToLower,\n upperThresholdCount,\n lowerThresholdCount,\n scrollIntoView,\n ...rest\n } = props\n const defaultId = useId().replace(/:/g, '')\n /**\n * 初始化数据模型\n */\n const root = useMemo(() => {\n return new Root({\n id: id ?? defaultId,\n cacheCount,\n upperThresholdCount,\n lowerThresholdCount,\n })\n }, [id, cacheCount, upperThresholdCount, lowerThresholdCount])\n const isScrolling$ = useObservedAttr(root, 'isScrolling')\n const scrollHeight$ = useObservedAttr(root, 'scrollHeight')\n const renderRange$ = useObservedAttr(root, 'renderRange')\n const refEventOrig = useRef<BaseEventOrig>()\n\n /**\n * 滚动事件\n */\n const handleScroll = useMemoizedFn((ev: BaseEventOrig<ScrollViewProps.onScrollDetail>) => {\n refEventOrig.current = ev\n root.sections.forEach((section) => section.getNodeRenderRange())\n const { scrollTop } = ev.detail\n // 确定滚动方向\n const scrollDirection: ScrollDirection = root.getState().scrollOffset < scrollTop ? 'forward' : 'backward'\n // 设置滚动信息,包括方向和偏移量\n root.setStateBatch({\n scrollDirection: scrollDirection,\n scrollOffset: scrollTop,\n isScrolling: true,\n })\n })\n\n const sections = useMemo(() => {\n const [start, end] = renderRange$\n return Children.map(children, (child: ReactElement<PropsWithChildren<_FlowSectionProps>>, order) => {\n if (Object.is(child, null)) {\n return null\n }\n const sectionProps = child.props\n const sectionId = sectionProps.id || `section-${order}`\n const childCount = Children.count(sectionProps.children)\n let section = root.findSection(sectionId)\n if (section) {\n const originalCount = section.count\n if (childCount > originalCount) {\n section.pushNodes(childCount - originalCount)\n }\n } else {\n section = new Section(root, {\n id: sectionId,\n order,\n col: sectionProps.column ?? 1,\n rowGap: sectionProps.rowGap || 0,\n columnGap: sectionProps.columnGap || 0,\n count: Children.count(sectionProps.children),\n })\n }\n\n return cloneElement(child, { section, key: `${props.id}-${order}` })\n })?.slice(start, end + 1)\n }, [renderRange$[0], renderRange$[1], children, root, props.id])\n\n const scrollTo = useMemoizedFn((scrollOffset = 0) => {\n scrollOffset = Math.max(0, scrollOffset)\n if (root.getState().scrollOffset === scrollOffset) return\n getScrollViewContextNode(`#${root.id}`).then((node: any) => {\n node.scrollTo({\n animated: true,\n duration: 300,\n top: scrollOffset,\n })\n })\n })\n\n const resetScrolling = useMemoizedFn(() => {\n root.setStateIn('isScrolling', false)\n })\n\n const debouncedResetScrolling = debounce(resetScrolling)\n\n useEffect(() => {\n debouncedResetScrolling()\n }, [isScrolling$])\n\n /**\n * 处理滚动阈值\n */\n useEffect(() => {\n const disposers = [\n root.sub(\n RootEvents.ReachUpperThreshold,\n debounce(() => {\n onScrollToUpper?.(refEventOrig.current!)\n })\n ),\n root.sub(\n RootEvents.ReachLowerThreshold,\n debounce(() => {\n onScrollToLower?.(refEventOrig.current!)\n })\n ),\n ]\n return () => {\n disposers.forEach((disposer) => {\n disposer()\n })\n }\n }, [onScrollToUpper, onScrollToLower])\n\n /**\n * 处理 scrollIntoView\n */\n useEffect(() => {\n handleScrollIntoView()\n async function handleScrollIntoView() {\n if (scrollIntoView) {\n if (root.getState().scrollOffset > 0) {\n // 说明在自动滚动前手动滚动过了,不应该自动滚动了,避免造成困扰\n return\n }\n const targetNode = root.findNode(scrollIntoView)\n if (targetNode) {\n const targetSection = targetNode.section\n if (!targetSection.getState().layouted) {\n const order = targetSection.order\n root.setStateIn('renderRange', [renderRange$[0], order])\n nextTick(async () => {\n await targetNode.section.layoutedSignal.promise\n scrollTo(targetNode.getState().scrollTop)\n })\n return\n }\n await targetNode.section.layoutedSignal.promise\n scrollTo(targetNode.getState().scrollTop)\n }\n }\n }\n }, [scrollIntoView, renderRange$[0]])\n\n return createElement(\n ScrollView,\n {\n id: root.id,\n style: {\n WebkitOverflowScrolling: 'touch',\n overflow: 'auto',\n ...style,\n },\n className,\n scrollY: true,\n onScroll: handleScroll,\n ...rest,\n },\n createElement(\n View,\n {\n id: 'waterflow-root',\n style: {\n width: '100%',\n position: 'relative',\n height: scrollHeight$,\n pointerEvents: isScrolling$ ? 'none' : 'auto',\n },\n },\n sections\n )\n )\n}\n"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,8 +1,7 @@
1
1
  import './components/index.js';
2
2
  import './utils/index.js';
3
- export { List, ListScrollElementContext, accumulate, isShaking } from './components/list/index.js';
3
+ export { List, accumulate, isShaking } from './components/list/index.js';
4
4
  export { ListItem } from './components/list/ListItem.js';
5
- export { NoMore } from './components/list/NoMore.js';
6
5
  export { StickyHeader } from './components/list/StickyHeader.js';
7
6
  export { StickySection } from './components/list/StickySection.js';
8
7
  export { VirtualList } from './components/virtual-list/index.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tarojs/components-advanced",
3
- "version": "4.1.12-beta.8",
3
+ "version": "4.2.0-beta.0",
4
4
  "description": "",
5
5
  "author": "O2Team",
6
6
  "license": "MIT",
@@ -20,20 +20,19 @@
20
20
  "csstype": "^3.1.1",
21
21
  "memoize-one": "^6.0.0",
22
22
  "tslib": "^2.6.2",
23
- "@tarojs/components": "4.1.12-beta.8",
24
- "@tarojs/components-react": "4.1.12-beta.8"
23
+ "@tarojs/components": "4.2.0-beta.0"
25
24
  },
26
25
  "devDependencies": {
27
26
  "vue": "3.2.47",
28
- "@tarojs/runtime": "4.1.12-beta.8",
29
- "@tarojs/shared": "4.1.12-beta.8",
30
- "@tarojs/taro": "4.1.12-beta.8"
27
+ "@tarojs/runtime": "4.2.0-beta.0",
28
+ "@tarojs/shared": "4.2.0-beta.0",
29
+ "@tarojs/taro": "4.2.0-beta.0"
31
30
  },
32
31
  "peerDependencies": {
33
32
  "react": ">=18",
34
- "@tarojs/shared": "~4.1.12-beta.8",
35
- "@tarojs/taro": "~4.1.12-beta.8",
36
- "@tarojs/runtime": "~4.1.12-beta.8"
33
+ "@tarojs/runtime": "~4.2.0-beta.0",
34
+ "@tarojs/taro": "~4.2.0-beta.0",
35
+ "@tarojs/shared": "~4.2.0-beta.0"
37
36
  },
38
37
  "peerDependenciesMeta": {
39
38
  "react": {
@@ -1,30 +0,0 @@
1
- import React from 'react';
2
- /**
3
- * NoMore 组件 - 底部"没有更多"提示
4
- *
5
- * 这是一个标记组件,不直接渲染内容,仅用于向 List 组件传递配置。
6
- * 实际渲染由 List 组件内部处理。
7
- *
8
- * @example
9
- * ```tsx
10
- * <List>
11
- * <ListItem>Item 1</ListItem>
12
- * <NoMore visible={!hasMore} text="没有更多了" />
13
- * </List>
14
- * ```
15
- */
16
- export interface NoMoreProps {
17
- /** 是否显示(默认 true) */
18
- visible?: boolean;
19
- /** 提示文字(默认 "没有更多了") */
20
- text?: string;
21
- /** 自定义样式 */
22
- style?: React.CSSProperties;
23
- /** 自定义内容(优先级高于 text) */
24
- children?: React.ReactNode;
25
- /** NoMore 区域高度(用于动态高度计算,默认 60) */
26
- height?: number;
27
- }
28
- declare const NoMore: React.FC<NoMoreProps>;
29
- export { NoMore };
30
- export default NoMore;
@@ -1,10 +0,0 @@
1
- const NoMore = () => {
2
- // 标记组件,不实际渲染
3
- // 实际渲染由 List 组件内部的 renderNoMoreContent() 处理
4
- return null;
5
- };
6
- // 设置 displayName 便于调试
7
- NoMore.displayName = 'NoMore';
8
-
9
- export { NoMore, NoMore as default };
10
- //# sourceMappingURL=NoMore.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"NoMore.js","sources":["../../../src/components/list/NoMore.tsx"],"sourcesContent":["import React from 'react'\n\n/**\n * NoMore 组件 - 底部\"没有更多\"提示\n *\n * 这是一个标记组件,不直接渲染内容,仅用于向 List 组件传递配置。\n * 实际渲染由 List 组件内部处理。\n *\n * @example\n * ```tsx\n * <List>\n * <ListItem>Item 1</ListItem>\n * <NoMore visible={!hasMore} text=\"没有更多了\" />\n * </List>\n * ```\n */\n\nexport interface NoMoreProps {\n /** 是否显示(默认 true) */\n visible?: boolean\n\n /** 提示文字(默认 \"没有更多了\") */\n text?: string\n\n /** 自定义样式 */\n style?: React.CSSProperties\n\n /** 自定义内容(优先级高于 text) */\n children?: React.ReactNode\n\n /** NoMore 区域高度(用于动态高度计算,默认 60) */\n height?: number\n}\n\nconst NoMore: React.FC<NoMoreProps> = () => {\n // 标记组件,不实际渲染\n // 实际渲染由 List 组件内部的 renderNoMoreContent() 处理\n return null\n}\n\n// 设置 displayName 便于调试\nNoMore.displayName = 'NoMore'\n\nexport { NoMore }\nexport default NoMore\n"],"names":[],"mappings":"AAkCM,MAAA,MAAM,GAA0B,MAAK;;;AAGzC,IAAA,OAAO,IAAI;AACb;AAEA;AACA,MAAM,CAAC,WAAW,GAAG,QAAQ;;;;"}
@@ -1,13 +0,0 @@
1
- interface UseItemSizeCacheOptions {
2
- isHorizontal: boolean;
3
- estimatedItemSize: number;
4
- itemCount: number;
5
- }
6
- interface UseItemSizeCacheReturn {
7
- /** 获取项的尺寸(高度或宽度) */
8
- getItemSize: (index: number) => number;
9
- /** 设置项的尺寸 */
10
- setItemSize: (index: number, size: number) => void;
11
- }
12
- export declare function useItemSizeCache(options: UseItemSizeCacheOptions): UseItemSizeCacheReturn;
13
- export {};
@@ -1,40 +0,0 @@
1
- import { useRef, useCallback } from 'react';
2
-
3
- function useItemSizeCache(options) {
4
- const { estimatedItemSize } = options;
5
- // 缓存 Map:key = 索引,value = 尺寸信息
6
- const cacheRef = useRef(new Map());
7
- /**
8
- * 获取项的尺寸
9
- * 优先返回实际测量值,否则返回估算值
10
- */
11
- const getItemSize = useCallback((index) => {
12
- const cached = cacheRef.current.get(index);
13
- if ((cached === null || cached === void 0 ? void 0 : cached.isMeasured) && cached.measuredSize !== null) {
14
- return cached.measuredSize;
15
- }
16
- return estimatedItemSize;
17
- }, [estimatedItemSize]);
18
- /**
19
- * 设置项的尺寸(实际测量后调用)
20
- */
21
- const setItemSize = useCallback((index, size) => {
22
- const cached = cacheRef.current.get(index);
23
- // 尺寸变化小于 1px,忽略(避免微小抖动)
24
- if ((cached === null || cached === void 0 ? void 0 : cached.measuredSize) && Math.abs(cached.measuredSize - size) < 1) {
25
- return;
26
- }
27
- cacheRef.current.set(index, {
28
- measuredSize: size,
29
- estimatedSize: estimatedItemSize,
30
- isMeasured: true
31
- });
32
- }, [estimatedItemSize]);
33
- return {
34
- getItemSize,
35
- setItemSize
36
- };
37
- }
38
-
39
- export { useItemSizeCache };
40
- //# sourceMappingURL=useItemSizeCache.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useItemSizeCache.js","sources":["../../../../src/components/list/hooks/useItemSizeCache.ts"],"sourcesContent":["import { useCallback, useRef } from 'react'\n\n/**\n * useItemSizeCache Hook - 动态尺寸缓存管理\n *\n * 支持垂直滚动(高度)和水平滚动(宽度)两种模式\n */\n\n/** 单个项的尺寸缓存 */\ninterface ItemMeasureCache {\n measuredSize: number | null // 实际测量尺寸\n estimatedSize: number // 估算尺寸\n isMeasured: boolean // 是否已测量\n}\n\ninterface UseItemSizeCacheOptions {\n isHorizontal: boolean // 是否水平滚动\n estimatedItemSize: number // 估算尺寸\n itemCount: number // 项总数\n}\n\ninterface UseItemSizeCacheReturn {\n /** 获取项的尺寸(高度或宽度) */\n getItemSize: (index: number) => number\n\n /** 设置项的尺寸 */\n setItemSize: (index: number, size: number) => void\n}\n\nexport function useItemSizeCache(\n options: UseItemSizeCacheOptions\n): UseItemSizeCacheReturn {\n const { estimatedItemSize } = options\n\n // 缓存 Map:key = 索引,value = 尺寸信息\n const cacheRef = useRef<Map<number, ItemMeasureCache>>(new Map())\n\n /**\n * 获取项的尺寸\n * 优先返回实际测量值,否则返回估算值\n */\n const getItemSize = useCallback((index: number): number => {\n const cached = cacheRef.current.get(index)\n\n if (cached?.isMeasured && cached.measuredSize !== null) {\n return cached.measuredSize\n }\n\n return estimatedItemSize\n }, [estimatedItemSize])\n\n /**\n * 设置项的尺寸(实际测量后调用)\n */\n const setItemSize = useCallback((index: number, size: number) => {\n const cached = cacheRef.current.get(index)\n\n // 尺寸变化小于 1px,忽略(避免微小抖动)\n if (cached?.measuredSize && Math.abs(cached.measuredSize - size) < 1) {\n return\n }\n\n cacheRef.current.set(index, {\n measuredSize: size,\n estimatedSize: estimatedItemSize,\n isMeasured: true\n })\n }, [estimatedItemSize])\n\n return {\n getItemSize,\n setItemSize\n }\n}\n"],"names":[],"mappings":";;AA6BM,SAAU,gBAAgB,CAC9B,OAAgC,EAAA;AAEhC,IAAA,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO;;IAGrC,MAAM,QAAQ,GAAG,MAAM,CAAgC,IAAI,GAAG,EAAE,CAAC;AAEjE;;;AAGG;AACH,IAAA,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,KAAa,KAAY;QACxD,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;AAE1C,QAAA,IAAI,CAAA,MAAM,KAAN,IAAA,IAAA,MAAM,uBAAN,MAAM,CAAE,UAAU,KAAI,MAAM,CAAC,YAAY,KAAK,IAAI,EAAE;YACtD,OAAO,MAAM,CAAC,YAAY;;AAG5B,QAAA,OAAO,iBAAiB;AAC1B,KAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC;AAEvB;;AAEG;IACH,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,KAAa,EAAE,IAAY,KAAI;QAC9D,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;;QAG1C,IAAI,CAAA,MAAM,KAAN,IAAA,IAAA,MAAM,uBAAN,MAAM,CAAE,YAAY,KAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE;YACpE;;AAGF,QAAA,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE;AAC1B,YAAA,YAAY,EAAE,IAAI;AAClB,YAAA,aAAa,EAAE,iBAAiB;AAChC,YAAA,UAAU,EAAE;AACb,SAAA,CAAC;AACJ,KAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC;IAEvB,OAAO;QACL,WAAW;QACX;KACD;AACH;;;;"}
@@ -1,10 +0,0 @@
1
- import type { RefObject } from 'react';
2
- /**
3
- * 测量 scrollElement 内 content 节点之前所有兄弟的高度/宽度之和,作为 startOffset。
4
- * 用于 scrollElement 模式下无 Context 时自动计算上方内容高度(与下方 DOM stacking 对称)。
5
- * 用「累加前兄弟尺寸」替代 offsetTop/offsetLeft,避免 offsetParent 包含外部区域导致偏大。
6
- */
7
- export declare function useMeasureStartOffset(scrollElRef: RefObject<HTMLElement | null>, contentRef: RefObject<HTMLElement | null>, options: {
8
- enabled: boolean;
9
- isHorizontal?: boolean;
10
- }): number;
@@ -1,43 +0,0 @@
1
- import { useState, useEffect } from 'react';
2
-
3
- /**
4
- * 测量 scrollElement 内 content 节点之前所有兄弟的高度/宽度之和,作为 startOffset。
5
- * 用于 scrollElement 模式下无 Context 时自动计算上方内容高度(与下方 DOM stacking 对称)。
6
- * 用「累加前兄弟尺寸」替代 offsetTop/offsetLeft,避免 offsetParent 包含外部区域导致偏大。
7
- */
8
- function useMeasureStartOffset(scrollElRef, contentRef, options) {
9
- const { enabled, isHorizontal = false } = options;
10
- const [measuredStartOffset, setMeasuredStartOffset] = useState(0);
11
- useEffect(() => {
12
- if (!enabled)
13
- return;
14
- const scrollEl = scrollElRef.current;
15
- const contentEl = contentRef.current;
16
- if (!scrollEl || !contentEl)
17
- return;
18
- const measure = () => {
19
- const el = contentRef.current;
20
- if (!el || el.parentElement !== scrollEl)
21
- return;
22
- let offset = 0;
23
- let prev = el.previousElementSibling;
24
- while (prev) {
25
- offset += isHorizontal ? prev.offsetWidth : prev.offsetHeight;
26
- prev = prev.previousElementSibling;
27
- }
28
- setMeasuredStartOffset((prevVal) => (Math.abs(prevVal - offset) < 1 ? prevVal : offset));
29
- };
30
- measure();
31
- const ro = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(measure) : null;
32
- if (ro) {
33
- ro.observe(scrollEl);
34
- // 同时观察 scrollEl 的直系子节点:图片加载、展开/收起等会改变兄弟高度,但 scrollEl 自身 clientHeight 不变,需观察子节点
35
- Array.from(scrollEl.children).forEach((child) => ro.observe(child));
36
- return () => ro.disconnect();
37
- }
38
- }, [enabled, scrollElRef, contentRef, isHorizontal]);
39
- return measuredStartOffset;
40
- }
41
-
42
- export { useMeasureStartOffset };
43
- //# sourceMappingURL=useMeasureStartOffset.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useMeasureStartOffset.js","sources":["../../../../src/components/list/hooks/useMeasureStartOffset.ts"],"sourcesContent":["import { useEffect, useState } from 'react'\n\nimport type { RefObject } from 'react'\n\n/**\n * 测量 scrollElement 内 content 节点之前所有兄弟的高度/宽度之和,作为 startOffset。\n * 用于 scrollElement 模式下无 Context 时自动计算上方内容高度(与下方 DOM stacking 对称)。\n * 用「累加前兄弟尺寸」替代 offsetTop/offsetLeft,避免 offsetParent 包含外部区域导致偏大。\n */\nexport function useMeasureStartOffset(\n scrollElRef: RefObject<HTMLElement | null>,\n contentRef: RefObject<HTMLElement | null>,\n options: { enabled: boolean, isHorizontal?: boolean }\n): number {\n const { enabled, isHorizontal = false } = options\n const [measuredStartOffset, setMeasuredStartOffset] = useState(0)\n\n useEffect(() => {\n if (!enabled) return\n const scrollEl = scrollElRef.current\n const contentEl = contentRef.current\n if (!scrollEl || !contentEl) return\n\n const measure = () => {\n const el = contentRef.current\n if (!el || el.parentElement !== scrollEl) return\n let offset = 0\n let prev: Element | null = el.previousElementSibling\n while (prev) {\n offset += isHorizontal ? (prev as HTMLElement).offsetWidth : (prev as HTMLElement).offsetHeight\n prev = prev.previousElementSibling\n }\n setMeasuredStartOffset((prevVal) => (Math.abs(prevVal - offset) < 1 ? prevVal : offset))\n }\n measure()\n const ro = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(measure) : null\n if (ro) {\n ro.observe(scrollEl)\n // 同时观察 scrollEl 的直系子节点:图片加载、展开/收起等会改变兄弟高度,但 scrollEl 自身 clientHeight 不变,需观察子节点\n Array.from(scrollEl.children).forEach((child) => ro.observe(child))\n return () => ro.disconnect()\n }\n }, [enabled, scrollElRef, contentRef, isHorizontal])\n\n return measuredStartOffset\n}\n"],"names":[],"mappings":";;AAIA;;;;AAIG;SACa,qBAAqB,CACnC,WAA0C,EAC1C,UAAyC,EACzC,OAAqD,EAAA;IAErD,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,OAAO;IACjD,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC;IAEjE,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,OAAO;YAAE;AACd,QAAA,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO;AACpC,QAAA,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO;AACpC,QAAA,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS;YAAE;QAE7B,MAAM,OAAO,GAAG,MAAK;AACnB,YAAA,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO;AAC7B,YAAA,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,aAAa,KAAK,QAAQ;gBAAE;YAC1C,IAAI,MAAM,GAAG,CAAC;AACd,YAAA,IAAI,IAAI,GAAmB,EAAE,CAAC,sBAAsB;YACpD,OAAO,IAAI,EAAE;AACX,gBAAA,MAAM,IAAI,YAAY,GAAI,IAAoB,CAAC,WAAW,GAAI,IAAoB,CAAC,YAAY;AAC/F,gBAAA,IAAI,GAAG,IAAI,CAAC,sBAAsB;;YAEpC,sBAAsB,CAAC,CAAC,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;AAC1F,SAAC;AACD,QAAA,OAAO,EAAE;AACT,QAAA,MAAM,EAAE,GAAG,OAAO,cAAc,KAAK,WAAW,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,GAAG,IAAI;QACrF,IAAI,EAAE,EAAE;AACN,YAAA,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;;YAEpB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACnE,YAAA,OAAO,MAAM,EAAE,CAAC,UAAU,EAAE;;KAE/B,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;AAEpD,IAAA,OAAO,mBAAmB;AAC5B;;;;"}