@tarojs/components-advanced 4.1.12-beta.43 → 4.1.12-beta.45

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 (43) hide show
  1. package/dist/components/list/hooks/useListNestedScroll.d.ts +1 -1
  2. package/dist/components/list/hooks/useListNestedScroll.js +2 -2
  3. package/dist/components/list/hooks/useListNestedScroll.js.map +1 -1
  4. package/dist/components/list/hooks/useListScrollElementAttachWeapp.d.ts +2 -1
  5. package/dist/components/list/hooks/useListScrollElementAttachWeapp.js +7 -6
  6. package/dist/components/list/hooks/useListScrollElementAttachWeapp.js.map +1 -1
  7. package/dist/components/list/hooks/useMeasureStartOffsetWeapp.d.ts +4 -4
  8. package/dist/components/list/hooks/useMeasureStartOffsetWeapp.js +30 -25
  9. package/dist/components/list/hooks/useMeasureStartOffsetWeapp.js.map +1 -1
  10. package/dist/components/list/hooks/useResizeObserver.d.ts +4 -2
  11. package/dist/components/list/hooks/useResizeObserver.js +7 -6
  12. package/dist/components/list/hooks/useResizeObserver.js.map +1 -1
  13. package/dist/components/list/index.d.ts +0 -2
  14. package/dist/components/list/index.js +7 -7
  15. package/dist/components/list/index.js.map +1 -1
  16. package/dist/components/list/utils.d.ts +11 -4
  17. package/dist/components/list/utils.js +18 -12
  18. package/dist/components/list/utils.js.map +1 -1
  19. package/dist/components/water-flow/flow-item.js +12 -7
  20. package/dist/components/water-flow/flow-item.js.map +1 -1
  21. package/dist/components/water-flow/node.d.ts +3 -0
  22. package/dist/components/water-flow/node.js +34 -1
  23. package/dist/components/water-flow/node.js.map +1 -1
  24. package/dist/components/water-flow/root.d.ts +4 -0
  25. package/dist/components/water-flow/root.js +37 -9
  26. package/dist/components/water-flow/root.js.map +1 -1
  27. package/dist/components/water-flow/section.d.ts +2 -0
  28. package/dist/components/water-flow/section.js +16 -9
  29. package/dist/components/water-flow/section.js.map +1 -1
  30. package/dist/components/water-flow/water-flow.js +26 -11
  31. package/dist/components/water-flow/water-flow.js.map +1 -1
  32. package/dist/index.js +1 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/utils/dom.d.ts +2 -2
  35. package/dist/utils/dom.js +7 -6
  36. package/dist/utils/dom.js.map +1 -1
  37. package/dist/utils/index.d.ts +1 -0
  38. package/dist/utils/index.js +1 -0
  39. package/dist/utils/index.js.map +1 -1
  40. package/dist/utils/weapp-scope.d.ts +7 -0
  41. package/dist/utils/weapp-scope.js +20 -0
  42. package/dist/utils/weapp-scope.js.map +1 -0
  43. package/package.json +9 -9
@@ -15,4 +15,4 @@ export interface UseListNestedScrollResult {
15
15
  /**
16
16
  * 合并嵌套滚动相关逻辑:Context、自动查找、startOffset 测量、scrollElement 解析
17
17
  */
18
- export declare function useListNestedScroll(listType: 'default' | 'nested', scrollElement?: RefObject<HTMLElement | null>, startOffsetProp?: number, isHorizontal?: boolean, selectorQueryScope?: object): UseListNestedScrollResult;
18
+ export declare function useListNestedScroll(listType: 'default' | 'nested', scrollElement?: RefObject<HTMLElement | null>, startOffsetProp?: number, isHorizontal?: boolean): UseListNestedScrollResult;
@@ -9,7 +9,7 @@ const EMPTY_SCROLL_REF = { current: null };
9
9
  /**
10
10
  * 合并嵌套滚动相关逻辑:Context、自动查找、startOffset 测量、scrollElement 解析
11
11
  */
12
- function useListNestedScroll(listType, scrollElement, startOffsetProp, isHorizontal = false, selectorQueryScope) {
12
+ function useListNestedScroll(listType, scrollElement, startOffsetProp, isHorizontal = false) {
13
13
  var _a, _b, _c, _d;
14
14
  const contentWrapperRef = useRef(null);
15
15
  const contentId = useMemo(() => `list-content-${Math.random().toString(36).slice(2, 11)}`, []);
@@ -34,7 +34,7 @@ function useListNestedScroll(listType, scrollElement, startOffsetProp, isHorizon
34
34
  !hasExplicitCtxStartOffset;
35
35
  const effectiveStartOffsetRef = useRef(0);
36
36
  const measuredStartOffset = useMeasureStartOffset(effectiveScrollElement !== null && effectiveScrollElement !== void 0 ? effectiveScrollElement : EMPTY_SCROLL_REF, contentWrapperRef, { enabled: !!needMeasure, isHorizontal });
37
- const measuredStartOffsetWeapp = useMeasureStartOffsetWeapp(effectiveScrollElement !== null && effectiveScrollElement !== void 0 ? effectiveScrollElement : EMPTY_SCROLL_REF, contentId, { enabled: !!needMeasureWeapp, isHorizontal, startOffsetRef: effectiveStartOffsetRef, selectorQueryScope });
37
+ const measuredStartOffsetWeapp = useMeasureStartOffsetWeapp(effectiveScrollElement !== null && effectiveScrollElement !== void 0 ? effectiveScrollElement : EMPTY_SCROLL_REF, contentId, { enabled: !!needMeasureWeapp, isHorizontal, startOffsetRef: effectiveStartOffsetRef, contentWrapperRef });
38
38
  const effectiveStartOffset = (_d = (_c = (_b = startOffsetProp !== null && startOffsetProp !== void 0 ? startOffsetProp : (ctxStart != null && ctxStart > 0 ? ctxStart : null)) !== null && _b !== void 0 ? _b : measuredStartOffset) !== null && _c !== void 0 ? _c : measuredStartOffsetWeapp) !== null && _d !== void 0 ? _d : 0;
39
39
  // needMeasureWeapp 时由 useMeasureStartOffsetWeapp 的 exec 回调更新 ref,不在此覆盖,避免 re-render 用 stale 0 覆盖已测量的值
40
40
  if (!needMeasureWeapp) {
@@ -1 +1 @@
1
- {"version":3,"file":"useListNestedScroll.js","sources":["../../../../src/components/list/hooks/useListNestedScroll.ts"],"sourcesContent":["import React, { useContext, useMemo, useRef } from 'react'\n\nimport {\n type ScrollElementContextValueShape,\n ScrollElementContextOrFallback,\n} from '../../../utils/scrollElementContext'\nimport { isH5, isWeapp } from '../utils'\nimport { useMeasureStartOffset } from './useMeasureStartOffset'\nimport { useMeasureStartOffsetWeapp } from './useMeasureStartOffsetWeapp'\nimport { useScrollParentAutoFind } from './useScrollParentAutoFind'\n\nimport type { RefObject } from 'react'\n\nconst EMPTY_SCROLL_REF = { current: null as HTMLElement | null }\n\nexport interface UseListNestedScrollResult {\n effectiveScrollElement: RefObject<HTMLElement | null> | null\n effectiveStartOffset: number\n /** 小程序用:实时读取 startOffset,避免 useState 异步更新导致 useListScrollElementAttachWeapp 读到 0 */\n effectiveStartOffsetRef: React.MutableRefObject<number>\n useScrollElementMode: boolean\n needAutoFind: boolean\n autoFindStatus: 'pending' | 'found' | 'not-found'\n contentWrapperRef: RefObject<HTMLDivElement | null>\n /** 小程序自动查找用:content 节点的 id,需挂到 contentWrapper 对应的 View 上 */\n contentId: string\n}\n\n/**\n * 合并嵌套滚动相关逻辑:Context、自动查找、startOffset 测量、scrollElement 解析\n */\nexport function useListNestedScroll(\n listType: 'default' | 'nested',\n scrollElement?: RefObject<HTMLElement | null>,\n startOffsetProp?: number,\n isHorizontal: boolean = false,\n selectorQueryScope?: object\n): UseListNestedScrollResult {\n const contentWrapperRef = useRef<HTMLDivElement>(null)\n const contentId = useMemo(() => `list-content-${Math.random().toString(36).slice(2, 11)}`, [])\n const scrollElementCtx = useContext(ScrollElementContextOrFallback) as ScrollElementContextValueShape | null\n const ctxStart = scrollElementCtx?.startOffset\n const hasExplicitCtxStartOffset = ctxStart != null && ctxStart > 0\n\n const needAutoFind =\n listType === 'nested' &&\n !scrollElement &&\n !scrollElementCtx?.scrollRef &&\n (isH5 || isWeapp)\n const { scrollParentRef: autoFoundRef, status: autoFindStatus } = useScrollParentAutoFind(\n contentWrapperRef,\n { enabled: !!needAutoFind, isHorizontal, contentId: isWeapp ? contentId : undefined }\n )\n\n const effectiveScrollElement =\n scrollElement ??\n scrollElementCtx?.scrollRef ??\n (needAutoFind && autoFindStatus === 'found' ? autoFoundRef : null)\n\n const needMeasure =\n listType === 'nested' &&\n effectiveScrollElement &&\n isH5 &&\n startOffsetProp == null &&\n !hasExplicitCtxStartOffset\n const needMeasureWeapp =\n listType === 'nested' &&\n effectiveScrollElement &&\n isWeapp &&\n startOffsetProp == null &&\n !hasExplicitCtxStartOffset\n const effectiveStartOffsetRef = useRef(0)\n const measuredStartOffset = useMeasureStartOffset(\n effectiveScrollElement ?? EMPTY_SCROLL_REF,\n contentWrapperRef,\n { enabled: !!needMeasure, isHorizontal }\n )\n const measuredStartOffsetWeapp = useMeasureStartOffsetWeapp(\n effectiveScrollElement ?? EMPTY_SCROLL_REF,\n contentId,\n { enabled: !!needMeasureWeapp, isHorizontal, startOffsetRef: effectiveStartOffsetRef, selectorQueryScope }\n )\n\n const effectiveStartOffset =\n startOffsetProp ??\n (ctxStart != null && ctxStart > 0 ? ctxStart : null) ??\n measuredStartOffset ??\n measuredStartOffsetWeapp ??\n 0\n\n // needMeasureWeapp 时由 useMeasureStartOffsetWeapp 的 exec 回调更新 ref,不在此覆盖,避免 re-render 用 stale 0 覆盖已测量的值\n if (!needMeasureWeapp) {\n effectiveStartOffsetRef.current = effectiveStartOffset\n }\n\n const useScrollElementMode = listType === 'nested' && !!(effectiveScrollElement && (isH5 || isWeapp))\n\n if (listType === 'nested' && !effectiveScrollElement && (isH5 || isWeapp) && autoFindStatus === 'not-found') {\n // eslint-disable-next-line no-console\n console.warn('[List] nestedScroll 模式但无 scrollElement(props/Context/自动查找),回退为 default')\n }\n\n return {\n effectiveScrollElement,\n effectiveStartOffset,\n effectiveStartOffsetRef,\n useScrollElementMode,\n needAutoFind,\n autoFindStatus,\n contentWrapperRef,\n contentId,\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useListNestedScroll.js","sources":["../../../../src/components/list/hooks/useListNestedScroll.ts"],"sourcesContent":["import React, { useContext, useMemo, useRef } from 'react'\n\nimport {\n type ScrollElementContextValueShape,\n ScrollElementContextOrFallback,\n} from '../../../utils/scrollElementContext'\nimport { isH5, isWeapp } from '../utils'\nimport { useMeasureStartOffset } from './useMeasureStartOffset'\nimport { useMeasureStartOffsetWeapp } from './useMeasureStartOffsetWeapp'\nimport { useScrollParentAutoFind } from './useScrollParentAutoFind'\n\nimport type { RefObject } from 'react'\n\nconst EMPTY_SCROLL_REF = { current: null as HTMLElement | null }\n\nexport interface UseListNestedScrollResult {\n effectiveScrollElement: RefObject<HTMLElement | null> | null\n effectiveStartOffset: number\n /** 小程序用:实时读取 startOffset,避免 useState 异步更新导致 useListScrollElementAttachWeapp 读到 0 */\n effectiveStartOffsetRef: React.MutableRefObject<number>\n useScrollElementMode: boolean\n needAutoFind: boolean\n autoFindStatus: 'pending' | 'found' | 'not-found'\n contentWrapperRef: RefObject<HTMLDivElement | null>\n /** 小程序自动查找用:content 节点的 id,需挂到 contentWrapper 对应的 View 上 */\n contentId: string\n}\n\n/**\n * 合并嵌套滚动相关逻辑:Context、自动查找、startOffset 测量、scrollElement 解析\n */\nexport function useListNestedScroll(\n listType: 'default' | 'nested',\n scrollElement?: RefObject<HTMLElement | null>,\n startOffsetProp?: number,\n isHorizontal: boolean = false\n): UseListNestedScrollResult {\n const contentWrapperRef = useRef<HTMLDivElement>(null)\n const contentId = useMemo(() => `list-content-${Math.random().toString(36).slice(2, 11)}`, [])\n const scrollElementCtx = useContext(ScrollElementContextOrFallback) as ScrollElementContextValueShape | null\n const ctxStart = scrollElementCtx?.startOffset\n const hasExplicitCtxStartOffset = ctxStart != null && ctxStart > 0\n\n const needAutoFind =\n listType === 'nested' &&\n !scrollElement &&\n !scrollElementCtx?.scrollRef &&\n (isH5 || isWeapp)\n const { scrollParentRef: autoFoundRef, status: autoFindStatus } = useScrollParentAutoFind(\n contentWrapperRef,\n { enabled: !!needAutoFind, isHorizontal, contentId: isWeapp ? contentId : undefined }\n )\n\n const effectiveScrollElement =\n scrollElement ??\n scrollElementCtx?.scrollRef ??\n (needAutoFind && autoFindStatus === 'found' ? autoFoundRef : null)\n\n const needMeasure =\n listType === 'nested' &&\n effectiveScrollElement &&\n isH5 &&\n startOffsetProp == null &&\n !hasExplicitCtxStartOffset\n const needMeasureWeapp =\n listType === 'nested' &&\n effectiveScrollElement &&\n isWeapp &&\n startOffsetProp == null &&\n !hasExplicitCtxStartOffset\n const effectiveStartOffsetRef = useRef(0)\n const measuredStartOffset = useMeasureStartOffset(\n effectiveScrollElement ?? EMPTY_SCROLL_REF,\n contentWrapperRef,\n { enabled: !!needMeasure, isHorizontal }\n )\n const measuredStartOffsetWeapp = useMeasureStartOffsetWeapp(\n effectiveScrollElement ?? EMPTY_SCROLL_REF,\n contentId,\n { enabled: !!needMeasureWeapp, isHorizontal, startOffsetRef: effectiveStartOffsetRef, contentWrapperRef }\n )\n\n const effectiveStartOffset =\n startOffsetProp ??\n (ctxStart != null && ctxStart > 0 ? ctxStart : null) ??\n measuredStartOffset ??\n measuredStartOffsetWeapp ??\n 0\n\n // needMeasureWeapp 时由 useMeasureStartOffsetWeapp 的 exec 回调更新 ref,不在此覆盖,避免 re-render 用 stale 0 覆盖已测量的值\n if (!needMeasureWeapp) {\n effectiveStartOffsetRef.current = effectiveStartOffset\n }\n\n const useScrollElementMode = listType === 'nested' && !!(effectiveScrollElement && (isH5 || isWeapp))\n\n if (listType === 'nested' && !effectiveScrollElement && (isH5 || isWeapp) && autoFindStatus === 'not-found') {\n // eslint-disable-next-line no-console\n console.warn('[List] nestedScroll 模式但无 scrollElement(props/Context/自动查找),回退为 default')\n }\n\n return {\n effectiveScrollElement,\n effectiveStartOffset,\n effectiveStartOffsetRef,\n useScrollElementMode,\n needAutoFind,\n autoFindStatus,\n contentWrapperRef,\n contentId,\n }\n}\n"],"names":[],"mappings":"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"}
@@ -6,9 +6,10 @@ import type { ListScrollElementAttachRefs } from './useListScrollElementAttach';
6
6
  *
7
7
  * 与 H5 版 useListScrollElementAttach 的区别:
8
8
  * - 容器尺寸通过 createSelectorQuery 测量(无 ResizeObserver)
9
+ * - SelectorQuery 使用 `createSelectorQueryForRef(effectiveScrollElement)`,由滚动容器 ref 的 `_scope` 推导 `.in`,无需业务传 scope
9
10
  * - 滚动事件通过 TaroElement.addEventListener,格式为 TaroEvent(detail 合并到 target 上)
10
11
  * - 若 scroll-view 无 id,自动分配临时 id 供 SelectorQuery 使用
11
12
  */
12
13
  export declare function useListScrollElementAttachWeapp(enabled: boolean, effectiveScrollElement: RefObject<HTMLElement | null> | null, effectiveStartOffsetRef: MutableRefObject<number>, effectiveStartOffset: number, isHorizontal: boolean, setContainerLength: (v: number) => void, updateRenderOffset: (offset: number, sync?: boolean, source?: string) => void, scrollRefProp: React.MutableRefObject<HTMLElement | null> | undefined, refsRef: RefObject<ListScrollElementAttachRefs>,
13
14
  /** 测量未就绪或失败时的容器长度兜底,宜与 initialContainerLength 一致 */
14
- fallbackContainerLength?: number, selectorQueryScope?: object): void;
15
+ fallbackContainerLength?: number): void;
@@ -1,5 +1,5 @@
1
1
  import { useRef, useEffect } from 'react';
2
- import { createSelectorQueryScoped } from '../utils.js';
2
+ import { createSelectorQueryForRef } from '../utils.js';
3
3
 
4
4
  /**
5
5
  * 小程序版 scrollElement 模式:监听外部 scroll-view 的滚动事件驱动 renderOffset,
@@ -7,12 +7,13 @@ import { createSelectorQueryScoped } from '../utils.js';
7
7
  *
8
8
  * 与 H5 版 useListScrollElementAttach 的区别:
9
9
  * - 容器尺寸通过 createSelectorQuery 测量(无 ResizeObserver)
10
+ * - SelectorQuery 使用 `createSelectorQueryForRef(effectiveScrollElement)`,由滚动容器 ref 的 `_scope` 推导 `.in`,无需业务传 scope
10
11
  * - 滚动事件通过 TaroElement.addEventListener,格式为 TaroEvent(detail 合并到 target 上)
11
12
  * - 若 scroll-view 无 id,自动分配临时 id 供 SelectorQuery 使用
12
13
  */
13
14
  function useListScrollElementAttachWeapp(enabled, effectiveScrollElement, effectiveStartOffsetRef, effectiveStartOffset, isHorizontal, setContainerLength, updateRenderOffset, scrollRefProp, refsRef,
14
15
  /** 测量未就绪或失败时的容器长度兜底,宜与 initialContainerLength 一致 */
15
- fallbackContainerLength, selectorQueryScope) {
16
+ fallbackContainerLength) {
16
17
  const containerLengthRef = useRef(0);
17
18
  const autoIdRef = useRef(`_ls_${Math.random().toString(36).slice(2, 9)}`);
18
19
  useEffect(() => {
@@ -28,7 +29,7 @@ fallbackContainerLength, selectorQueryScope) {
28
29
  }
29
30
  const scrollViewId = el.id;
30
31
  const measure = () => {
31
- const query = createSelectorQueryScoped(selectorQueryScope);
32
+ const query = createSelectorQueryForRef(effectiveScrollElement);
32
33
  query
33
34
  .select(`#${scrollViewId}`)
34
35
  .boundingClientRect()
@@ -52,7 +53,7 @@ fallbackContainerLength, selectorQueryScope) {
52
53
  measure();
53
54
  const interval = setInterval(measure, 150);
54
55
  return () => clearInterval(interval);
55
- }, [enabled, effectiveScrollElement, isHorizontal, scrollRefProp, setContainerLength, fallbackContainerLength, selectorQueryScope]);
56
+ }, [enabled, effectiveScrollElement, isHorizontal, scrollRefProp, setContainerLength, fallbackContainerLength]);
56
57
  useEffect(() => {
57
58
  if (!enabled || !effectiveScrollElement)
58
59
  return;
@@ -108,7 +109,7 @@ fallbackContainerLength, selectorQueryScope) {
108
109
  const scrollViewId = target.id || autoIdRef.current;
109
110
  if (!target.id)
110
111
  target.id = scrollViewId;
111
- const query = createSelectorQueryScoped(selectorQueryScope);
112
+ const query = createSelectorQueryForRef(effectiveScrollElement);
112
113
  query.select(`#${scrollViewId}`).scrollOffset().exec((res) => {
113
114
  var _a, _b;
114
115
  const info = res === null || res === void 0 ? void 0 : res[0];
@@ -127,7 +128,7 @@ fallbackContainerLength, selectorQueryScope) {
127
128
  cancelled = true;
128
129
  teardown === null || teardown === void 0 ? void 0 : teardown();
129
130
  };
130
- }, [enabled, effectiveScrollElement, isHorizontal, effectiveStartOffsetRef, effectiveStartOffset, updateRenderOffset, refsRef, fallbackContainerLength, selectorQueryScope]);
131
+ }, [enabled, effectiveScrollElement, isHorizontal, effectiveStartOffsetRef, effectiveStartOffset, updateRenderOffset, refsRef, fallbackContainerLength]);
131
132
  }
132
133
 
133
134
  export { useListScrollElementAttachWeapp };
@@ -1 +1 @@
1
- {"version":3,"file":"useListScrollElementAttachWeapp.js","sources":["../../../../src/components/list/hooks/useListScrollElementAttachWeapp.ts"],"sourcesContent":["import { useEffect, useRef } from 'react'\n\nimport { createSelectorQueryScoped } from '../utils'\n\nimport type { MutableRefObject, RefObject } from 'react'\nimport type { ListScrollElementAttachRefs } from './useListScrollElementAttach'\n\n/**\n * 小程序版 scrollElement 模式:监听外部 scroll-view 的滚动事件驱动 renderOffset,\n * 并通过 createSelectorQuery 测量容器尺寸。\n *\n * 与 H5 版 useListScrollElementAttach 的区别:\n * - 容器尺寸通过 createSelectorQuery 测量(无 ResizeObserver)\n * - 滚动事件通过 TaroElement.addEventListener,格式为 TaroEvent(detail 合并到 target 上)\n * - 若 scroll-view 无 id,自动分配临时 id 供 SelectorQuery 使用\n */\nexport function useListScrollElementAttachWeapp(\n enabled: boolean,\n effectiveScrollElement: RefObject<HTMLElement | null> | null,\n effectiveStartOffsetRef: MutableRefObject<number>,\n effectiveStartOffset: number,\n isHorizontal: boolean,\n setContainerLength: (v: number) => void,\n updateRenderOffset: (offset: number, sync?: boolean, source?: string) => void,\n scrollRefProp: React.MutableRefObject<HTMLElement | null> | undefined,\n refsRef: RefObject<ListScrollElementAttachRefs>,\n /** 测量未就绪或失败时的容器长度兜底,宜与 initialContainerLength 一致 */\n fallbackContainerLength?: number,\n selectorQueryScope?: object\n) {\n const containerLengthRef = useRef(0)\n const autoIdRef = useRef(`_ls_${Math.random().toString(36).slice(2, 9)}`)\n\n useEffect(() => {\n if (!enabled || !effectiveScrollElement) return\n const el = effectiveScrollElement.current as any\n if (!el) return\n if (scrollRefProp) scrollRefProp.current = el\n\n if (!el.id) {\n el.id = autoIdRef.current\n }\n const scrollViewId = el.id\n\n const measure = () => {\n const query = createSelectorQueryScoped(selectorQueryScope)\n query\n .select(`#${scrollViewId}`)\n .boundingClientRect()\n .exec((res) => {\n const rect = res?.[0]\n if (rect) {\n const measured = isHorizontal ? rect.width : rect.height\n if (measured > 0) {\n containerLengthRef.current = measured\n setContainerLength(measured)\n return\n }\n }\n // 兜底:rect 为空或 measured≤0 时,使用 fallback 避免 containerLengthRef 长期为 0\n if (fallbackContainerLength != null && fallbackContainerLength > 0) {\n containerLengthRef.current = fallbackContainerLength\n setContainerLength(fallbackContainerLength)\n }\n })\n }\n\n measure()\n const interval = setInterval(measure, 150)\n return () => clearInterval(interval)\n }, [enabled, effectiveScrollElement, isHorizontal, scrollRefProp, setContainerLength, fallbackContainerLength, selectorQueryScope])\n\n useEffect(() => {\n if (!enabled || !effectiveScrollElement) return\n\n let cancelled = false\n let teardown: (() => void) | null = null\n const maxRetries = 20\n\n const tryAttach = (retryCount = 0) => {\n if (cancelled) return\n const target = effectiveScrollElement.current as any\n if (!target) {\n if (retryCount < maxRetries) {\n setTimeout(() => tryAttach(retryCount + 1), 50)\n }\n return\n }\n\n let inUpperZone = true\n let inLowerZone = false\n\n const handler = (e: any) => {\n const r = refsRef.current\n if (!r) return\n\n const scrollPos = isHorizontal\n ? (e?.target?.scrollLeft ?? e?.mpEvent?.detail?.scrollLeft ?? 0)\n : (e?.target?.scrollTop ?? e?.mpEvent?.detail?.scrollTop ?? 0)\n const startOffset = effectiveStartOffsetRef.current\n const adjustedPos = scrollPos - startOffset\n const effectiveAdjusted = Math.max(0, adjustedPos)\n\n r.scrollCorrection.markUserScrolling()\n updateRenderOffset(effectiveAdjusted, false, 'scrollElement')\n const scrollTop = isHorizontal ? 0 : scrollPos\n const scrollLeft = isHorizontal ? scrollPos : 0\n r.onScroll?.({ scrollTop, scrollLeft, detail: { scrollTop, scrollLeft } })\n\n // 兜底:measure 未完成时 containerLengthRef 为 0,用 fallback 参与触顶/触底判断,避免漏触发\n const clientSize = containerLengthRef.current || fallbackContainerLength || 0\n if (clientSize > 0) {\n const { upper, lower } = r.threshold\n const innerContentLen = r.listContentLength\n const nowInUpper = effectiveAdjusted <= upper\n const nowInLower = innerContentLen > 0 && effectiveAdjusted + clientSize >= innerContentLen - lower\n if (nowInUpper && !inUpperZone) r.onScrollToUpper?.()\n if (nowInLower && !inLowerZone) r.onScrollToLower?.()\n inUpperZone = nowInUpper\n inLowerZone = nowInLower\n }\n }\n\n target.addEventListener('scroll', handler)\n teardown = () => target.removeEventListener('scroll', handler)\n\n // 初始 renderOffset:weapp 无法直接读 target.scrollTop,需通过 SelectorQuery 查询\n const scrollViewId = target.id || autoIdRef.current\n if (!target.id) target.id = scrollViewId\n const query = createSelectorQueryScoped(selectorQueryScope)\n query.select(`#${scrollViewId}`).scrollOffset().exec((res) => {\n const info = res?.[0]\n if (info) {\n const scrollTopVal = info.scrollTop ?? 0\n const scrollLeftVal = info.scrollLeft ?? 0\n const scrollPos = isHorizontal ? scrollLeftVal : scrollTopVal\n const startOffset = effectiveStartOffsetRef.current\n const initialAdjusted = Math.max(0, scrollPos - startOffset)\n updateRenderOffset(initialAdjusted, false, 'scrollElement')\n }\n })\n }\n\n tryAttach()\n return () => {\n cancelled = true\n teardown?.()\n }\n }, [enabled, effectiveScrollElement, isHorizontal, effectiveStartOffsetRef, effectiveStartOffset, updateRenderOffset, refsRef, fallbackContainerLength, selectorQueryScope])\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useListScrollElementAttachWeapp.js","sources":["../../../../src/components/list/hooks/useListScrollElementAttachWeapp.ts"],"sourcesContent":["import { useEffect, useRef } from 'react'\n\nimport { createSelectorQueryForRef } from '../utils'\n\nimport type { MutableRefObject, RefObject } from 'react'\nimport type { ListScrollElementAttachRefs } from './useListScrollElementAttach'\n\n/**\n * 小程序版 scrollElement 模式:监听外部 scroll-view 的滚动事件驱动 renderOffset,\n * 并通过 createSelectorQuery 测量容器尺寸。\n *\n * 与 H5 版 useListScrollElementAttach 的区别:\n * - 容器尺寸通过 createSelectorQuery 测量(无 ResizeObserver)\n * - SelectorQuery 使用 `createSelectorQueryForRef(effectiveScrollElement)`,由滚动容器 ref 的 `_scope` 推导 `.in`,无需业务传 scope\n * - 滚动事件通过 TaroElement.addEventListener,格式为 TaroEvent(detail 合并到 target 上)\n * - 若 scroll-view 无 id,自动分配临时 id 供 SelectorQuery 使用\n */\nexport function useListScrollElementAttachWeapp(\n enabled: boolean,\n effectiveScrollElement: RefObject<HTMLElement | null> | null,\n effectiveStartOffsetRef: MutableRefObject<number>,\n effectiveStartOffset: number,\n isHorizontal: boolean,\n setContainerLength: (v: number) => void,\n updateRenderOffset: (offset: number, sync?: boolean, source?: string) => void,\n scrollRefProp: React.MutableRefObject<HTMLElement | null> | undefined,\n refsRef: RefObject<ListScrollElementAttachRefs>,\n /** 测量未就绪或失败时的容器长度兜底,宜与 initialContainerLength 一致 */\n fallbackContainerLength?: number\n) {\n const containerLengthRef = useRef(0)\n const autoIdRef = useRef(`_ls_${Math.random().toString(36).slice(2, 9)}`)\n\n useEffect(() => {\n if (!enabled || !effectiveScrollElement) return\n const el = effectiveScrollElement.current as any\n if (!el) return\n if (scrollRefProp) scrollRefProp.current = el\n\n if (!el.id) {\n el.id = autoIdRef.current\n }\n const scrollViewId = el.id\n\n const measure = () => {\n const query = createSelectorQueryForRef(effectiveScrollElement)\n query\n .select(`#${scrollViewId}`)\n .boundingClientRect()\n .exec((res) => {\n const rect = res?.[0]\n if (rect) {\n const measured = isHorizontal ? rect.width : rect.height\n if (measured > 0) {\n containerLengthRef.current = measured\n setContainerLength(measured)\n return\n }\n }\n // 兜底:rect 为空或 measured≤0 时,使用 fallback 避免 containerLengthRef 长期为 0\n if (fallbackContainerLength != null && fallbackContainerLength > 0) {\n containerLengthRef.current = fallbackContainerLength\n setContainerLength(fallbackContainerLength)\n }\n })\n }\n\n measure()\n const interval = setInterval(measure, 150)\n return () => clearInterval(interval)\n }, [enabled, effectiveScrollElement, isHorizontal, scrollRefProp, setContainerLength, fallbackContainerLength])\n\n useEffect(() => {\n if (!enabled || !effectiveScrollElement) return\n\n let cancelled = false\n let teardown: (() => void) | null = null\n const maxRetries = 20\n\n const tryAttach = (retryCount = 0) => {\n if (cancelled) return\n const target = effectiveScrollElement.current as any\n if (!target) {\n if (retryCount < maxRetries) {\n setTimeout(() => tryAttach(retryCount + 1), 50)\n }\n return\n }\n\n let inUpperZone = true\n let inLowerZone = false\n\n const handler = (e: any) => {\n const r = refsRef.current\n if (!r) return\n\n const scrollPos = isHorizontal\n ? (e?.target?.scrollLeft ?? e?.mpEvent?.detail?.scrollLeft ?? 0)\n : (e?.target?.scrollTop ?? e?.mpEvent?.detail?.scrollTop ?? 0)\n const startOffset = effectiveStartOffsetRef.current\n const adjustedPos = scrollPos - startOffset\n const effectiveAdjusted = Math.max(0, adjustedPos)\n\n r.scrollCorrection.markUserScrolling()\n updateRenderOffset(effectiveAdjusted, false, 'scrollElement')\n const scrollTop = isHorizontal ? 0 : scrollPos\n const scrollLeft = isHorizontal ? scrollPos : 0\n r.onScroll?.({ scrollTop, scrollLeft, detail: { scrollTop, scrollLeft } })\n\n // 兜底:measure 未完成时 containerLengthRef 为 0,用 fallback 参与触顶/触底判断,避免漏触发\n const clientSize = containerLengthRef.current || fallbackContainerLength || 0\n if (clientSize > 0) {\n const { upper, lower } = r.threshold\n const innerContentLen = r.listContentLength\n const nowInUpper = effectiveAdjusted <= upper\n const nowInLower = innerContentLen > 0 && effectiveAdjusted + clientSize >= innerContentLen - lower\n if (nowInUpper && !inUpperZone) r.onScrollToUpper?.()\n if (nowInLower && !inLowerZone) r.onScrollToLower?.()\n inUpperZone = nowInUpper\n inLowerZone = nowInLower\n }\n }\n\n target.addEventListener('scroll', handler)\n teardown = () => target.removeEventListener('scroll', handler)\n\n // 初始 renderOffset:weapp 无法直接读 target.scrollTop,需通过 SelectorQuery 查询\n const scrollViewId = target.id || autoIdRef.current\n if (!target.id) target.id = scrollViewId\n const query = createSelectorQueryForRef(effectiveScrollElement)\n query.select(`#${scrollViewId}`).scrollOffset().exec((res) => {\n const info = res?.[0]\n if (info) {\n const scrollTopVal = info.scrollTop ?? 0\n const scrollLeftVal = info.scrollLeft ?? 0\n const scrollPos = isHorizontal ? scrollLeftVal : scrollTopVal\n const startOffset = effectiveStartOffsetRef.current\n const initialAdjusted = Math.max(0, scrollPos - startOffset)\n updateRenderOffset(initialAdjusted, false, 'scrollElement')\n }\n })\n }\n\n tryAttach()\n return () => {\n cancelled = true\n teardown?.()\n }\n }, [enabled, effectiveScrollElement, isHorizontal, effectiveStartOffsetRef, effectiveStartOffset, updateRenderOffset, refsRef, fallbackContainerLength])\n}\n"],"names":[],"mappings":"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"}
@@ -1,14 +1,14 @@
1
1
  import type { MutableRefObject, RefObject } from 'react';
2
2
  /**
3
- * 小程序版 startOffset 测量:通过 createSelectorQuery 获取 scroll-view content 的位置,
4
- * 计算 content 相对于 scroll 内容顶部的偏移。
3
+ * 小程序版 startOffset:对外层 scroll-view 与带 `contentId` 的外包各执行一次 SelectorQuery(各自 `weappScope(ref)`),
4
+ * 再合并结果;避免二者不在同一自定义组件时,单次 `in` 链式 `select` 查不全。
5
5
  *
6
6
  * 公式:startOffset = contentRect.top - scrollRect.top + scrollTop
7
- * (content 在屏幕上的 top - scroll 可视区 top + 已滚动距离)
8
7
  */
9
8
  export declare function useMeasureStartOffsetWeapp(scrollElRef: RefObject<HTMLElement | null>, contentId: string, options: {
10
9
  enabled: boolean;
11
10
  isHorizontal?: boolean;
12
11
  startOffsetRef?: MutableRefObject<number>;
13
- selectorQueryScope?: object;
12
+ /** 挂载 `id={contentId}` 的嵌套内容外包 View;第二次 query 用其 ref 取 content 侧 `_scope` */
13
+ contentWrapperRef: RefObject<HTMLElement | null>;
14
14
  }): number;
@@ -1,19 +1,18 @@
1
1
  import { useState, useRef, useEffect } from 'react';
2
- import { createSelectorQueryScoped } from '../utils.js';
2
+ import { createSelectorQueryForRef } from '../utils.js';
3
3
 
4
4
  const MAX_RETRY = 20;
5
5
  const RETRY_DELAY = 50;
6
6
  /** 与 useListScrollElementAttachWeapp 容器测量间隔一致(H5 无 interval,用 ResizeObserver+scroll 事件驱动) */
7
7
  const MEASURE_INTERVAL = 150;
8
8
  /**
9
- * 小程序版 startOffset 测量:通过 createSelectorQuery 获取 scroll-view content 的位置,
10
- * 计算 content 相对于 scroll 内容顶部的偏移。
9
+ * 小程序版 startOffset:对外层 scroll-view 与带 `contentId` 的外包各执行一次 SelectorQuery(各自 `weappScope(ref)`),
10
+ * 再合并结果;避免二者不在同一自定义组件时,单次 `in` 链式 `select` 查不全。
11
11
  *
12
12
  * 公式:startOffset = contentRect.top - scrollRect.top + scrollTop
13
- * (content 在屏幕上的 top - scroll 可视区 top + 已滚动距离)
14
13
  */
15
14
  function useMeasureStartOffsetWeapp(scrollElRef, contentId, options) {
16
- const { enabled, isHorizontal = false, startOffsetRef, selectorQueryScope } = options;
15
+ const { enabled, isHorizontal = false, startOffsetRef, contentWrapperRef } = options;
17
16
  const [measuredStartOffset, setMeasuredStartOffset] = useState(0);
18
17
  const [retryTrigger, setRetryTrigger] = useState(0);
19
18
  const retryCountRef = useRef(0);
@@ -23,6 +22,19 @@ function useMeasureStartOffsetWeapp(scrollElRef, contentId, options) {
23
22
  retryCountRef.current = 0;
24
23
  return;
25
24
  }
25
+ const applyRects = (scrollRect, scrollInfo, contentRect) => {
26
+ var _a, _b;
27
+ if (!scrollRect || !scrollInfo || !contentRect)
28
+ return;
29
+ const scrollTop = (_a = scrollInfo.scrollTop) !== null && _a !== void 0 ? _a : 0;
30
+ const scrollLeft = (_b = scrollInfo.scrollLeft) !== null && _b !== void 0 ? _b : 0;
31
+ const value = isHorizontal
32
+ ? Math.max(0, contentRect.left - scrollRect.left + scrollLeft)
33
+ : Math.max(0, contentRect.top - scrollRect.top + scrollTop);
34
+ if (startOffsetRef)
35
+ startOffsetRef.current = value;
36
+ setMeasuredStartOffset((prevVal) => (Math.abs(prevVal - value) < 1 ? prevVal : value));
37
+ };
26
38
  const measure = () => {
27
39
  const scrollEl = scrollElRef.current;
28
40
  if (!scrollEl)
@@ -31,28 +43,23 @@ function useMeasureStartOffsetWeapp(scrollElRef, contentId, options) {
31
43
  scrollEl.id = autoIdRef.current;
32
44
  }
33
45
  const scrollViewId = scrollEl.id;
34
- const query = createSelectorQueryScoped(selectorQueryScope);
35
- query
46
+ createSelectorQueryForRef(scrollElRef)
36
47
  .select(`#${scrollViewId}`)
37
48
  .boundingClientRect()
38
49
  .select(`#${scrollViewId}`)
39
50
  .scrollOffset()
40
- .select(`#${contentId}`)
41
- .boundingClientRect()
42
- .exec((res) => {
43
- var _a, _b;
44
- const scrollRect = res === null || res === void 0 ? void 0 : res[0];
45
- const scrollInfo = res === null || res === void 0 ? void 0 : res[1];
46
- const contentRect = res === null || res === void 0 ? void 0 : res[2];
47
- if (!scrollRect || !scrollInfo || !contentRect)
51
+ .exec((scrollRes) => {
52
+ const scrollRect = scrollRes === null || scrollRes === void 0 ? void 0 : scrollRes[0];
53
+ const scrollInfo = scrollRes === null || scrollRes === void 0 ? void 0 : scrollRes[1];
54
+ if (!scrollRect || !scrollInfo)
48
55
  return;
49
- const scrollTop = (_a = scrollInfo.scrollTop) !== null && _a !== void 0 ? _a : 0;
50
- const scrollLeft = (_b = scrollInfo.scrollLeft) !== null && _b !== void 0 ? _b : 0;
51
- const value = isHorizontal
52
- ? Math.max(0, contentRect.left - scrollRect.left + scrollLeft)
53
- : Math.max(0, contentRect.top - scrollRect.top + scrollTop);
54
- startOffsetRef && (startOffsetRef.current = value);
55
- setMeasuredStartOffset((prevVal) => (Math.abs(prevVal - value) < 1 ? prevVal : value));
56
+ createSelectorQueryForRef(contentWrapperRef)
57
+ .select(`#${contentId}`)
58
+ .boundingClientRect()
59
+ .exec((contentRes) => {
60
+ const contentRect = contentRes === null || contentRes === void 0 ? void 0 : contentRes[0];
61
+ applyRects(scrollRect, scrollInfo, contentRect);
62
+ });
56
63
  });
57
64
  };
58
65
  const scrollEl = scrollElRef.current;
@@ -66,15 +73,13 @@ function useMeasureStartOffsetWeapp(scrollElRef, contentId, options) {
66
73
  }
67
74
  retryCountRef.current = 0;
68
75
  measure();
69
- // 对标 H5:scroll 时触发测量(H5 用 scrollEl.addEventListener('scroll', measure))
70
76
  scrollEl.addEventListener('scroll', measure);
71
- // 无 ResizeObserver,用 interval 兜底布局变化
72
77
  const interval = setInterval(measure, MEASURE_INTERVAL);
73
78
  return () => {
74
79
  scrollEl.removeEventListener('scroll', measure);
75
80
  clearInterval(interval);
76
81
  };
77
- }, [enabled, scrollElRef, contentId, isHorizontal, retryTrigger, selectorQueryScope]);
82
+ }, [enabled, scrollElRef, contentId, contentWrapperRef, isHorizontal, retryTrigger]);
78
83
  return measuredStartOffset;
79
84
  }
80
85
 
@@ -1 +1 @@
1
- {"version":3,"file":"useMeasureStartOffsetWeapp.js","sources":["../../../../src/components/list/hooks/useMeasureStartOffsetWeapp.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react'\n\nimport { createSelectorQueryScoped } from '../utils'\n\nimport type { MutableRefObject, RefObject } from 'react'\n\nconst MAX_RETRY = 20\nconst RETRY_DELAY = 50\n/** 与 useListScrollElementAttachWeapp 容器测量间隔一致(H5 无 interval,用 ResizeObserver+scroll 事件驱动) */\nconst MEASURE_INTERVAL = 150\n\n/**\n * 小程序版 startOffset 测量:通过 createSelectorQuery 获取 scroll-view content 的位置,\n * 计算 content 相对于 scroll 内容顶部的偏移。\n *\n * 公式:startOffset = contentRect.top - scrollRect.top + scrollTop\n * (content 在屏幕上的 top - scroll 可视区 top + 已滚动距离)\n */\nexport function useMeasureStartOffsetWeapp(\n scrollElRef: RefObject<HTMLElement | null>,\n contentId: string,\n options: { enabled: boolean, isHorizontal?: boolean, startOffsetRef?: MutableRefObject<number>, selectorQueryScope?: object }\n): number {\n const { enabled, isHorizontal = false, startOffsetRef, selectorQueryScope } = options\n const [measuredStartOffset, setMeasuredStartOffset] = useState(0)\n const [retryTrigger, setRetryTrigger] = useState(0)\n const retryCountRef = useRef(0)\n const autoIdRef = useRef(`_ls_so_${Math.random().toString(36).slice(2, 9)}`)\n\n useEffect(() => {\n if (!enabled || !contentId) {\n retryCountRef.current = 0\n return\n }\n\n const measure = () => {\n const scrollEl = scrollElRef.current as any\n if (!scrollEl) return\n\n if (!scrollEl.id) {\n scrollEl.id = autoIdRef.current\n }\n const scrollViewId = scrollEl.id\n\n const query = createSelectorQueryScoped(selectorQueryScope)\n query\n .select(`#${scrollViewId}`)\n .boundingClientRect()\n .select(`#${scrollViewId}`)\n .scrollOffset()\n .select(`#${contentId}`)\n .boundingClientRect()\n .exec((res) => {\n const scrollRect = res?.[0]\n const scrollInfo = res?.[1]\n const contentRect = res?.[2]\n if (!scrollRect || !scrollInfo || !contentRect) return\n\n const scrollTop = scrollInfo.scrollTop ?? 0\n const scrollLeft = scrollInfo.scrollLeft ?? 0\n const value = isHorizontal\n ? Math.max(0, contentRect.left - scrollRect.left + scrollLeft)\n : Math.max(0, contentRect.top - scrollRect.top + scrollTop)\n startOffsetRef && (startOffsetRef.current = value)\n setMeasuredStartOffset((prevVal) => (Math.abs(prevVal - value) < 1 ? prevVal : value))\n })\n }\n\n const scrollEl = scrollElRef.current\n if (!scrollEl) {\n if (retryCountRef.current < MAX_RETRY) {\n retryCountRef.current += 1\n const id = setTimeout(() => setRetryTrigger((t) => t + 1), RETRY_DELAY)\n return () => clearTimeout(id)\n }\n return\n }\n retryCountRef.current = 0\n measure()\n // 对标 H5:scroll 时触发测量(H5 用 scrollEl.addEventListener('scroll', measure))\n scrollEl.addEventListener('scroll', measure)\n // 无 ResizeObserver,用 interval 兜底布局变化\n const interval = setInterval(measure, MEASURE_INTERVAL)\n return () => {\n scrollEl.removeEventListener('scroll', measure)\n clearInterval(interval)\n }\n }, [enabled, scrollElRef, contentId, isHorizontal, retryTrigger, selectorQueryScope])\n\n return measuredStartOffset\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useMeasureStartOffsetWeapp.js","sources":["../../../../src/components/list/hooks/useMeasureStartOffsetWeapp.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react'\n\nimport { createSelectorQueryForRef } from '../utils'\n\nimport type { MutableRefObject, RefObject } from 'react'\n\nconst MAX_RETRY = 20\nconst RETRY_DELAY = 50\n/** 与 useListScrollElementAttachWeapp 容器测量间隔一致(H5 无 interval,用 ResizeObserver+scroll 事件驱动) */\nconst MEASURE_INTERVAL = 150\n\n/**\n * 小程序版 startOffset:对外层 scroll-view 与带 `contentId` 的外包各执行一次 SelectorQuery(各自 `weappScope(ref)`),\n * 再合并结果;避免二者不在同一自定义组件时,单次 `in` 链式 `select` 查不全。\n *\n * 公式:startOffset = contentRect.top - scrollRect.top + scrollTop\n */\nexport function useMeasureStartOffsetWeapp(\n scrollElRef: RefObject<HTMLElement | null>,\n contentId: string,\n options: {\n enabled: boolean\n isHorizontal?: boolean\n startOffsetRef?: MutableRefObject<number>\n /** 挂载 `id={contentId}` 的嵌套内容外包 View;第二次 query 用其 ref 取 content 侧 `_scope` */\n contentWrapperRef: RefObject<HTMLElement | null>\n }\n): number {\n const { enabled, isHorizontal = false, startOffsetRef, contentWrapperRef } = options\n const [measuredStartOffset, setMeasuredStartOffset] = useState(0)\n const [retryTrigger, setRetryTrigger] = useState(0)\n const retryCountRef = useRef(0)\n const autoIdRef = useRef(`_ls_so_${Math.random().toString(36).slice(2, 9)}`)\n\n useEffect(() => {\n if (!enabled || !contentId) {\n retryCountRef.current = 0\n return\n }\n\n const applyRects = (scrollRect: any, scrollInfo: any, contentRect: any) => {\n if (!scrollRect || !scrollInfo || !contentRect) return\n const scrollTop = scrollInfo.scrollTop ?? 0\n const scrollLeft = scrollInfo.scrollLeft ?? 0\n const value = isHorizontal\n ? Math.max(0, contentRect.left - scrollRect.left + scrollLeft)\n : Math.max(0, contentRect.top - scrollRect.top + scrollTop)\n if (startOffsetRef) startOffsetRef.current = value\n setMeasuredStartOffset((prevVal) => (Math.abs(prevVal - value) < 1 ? prevVal : value))\n }\n\n const measure = () => {\n const scrollEl = scrollElRef.current as any\n if (!scrollEl) return\n\n if (!scrollEl.id) {\n scrollEl.id = autoIdRef.current\n }\n const scrollViewId = scrollEl.id\n\n createSelectorQueryForRef(scrollElRef)\n .select(`#${scrollViewId}`)\n .boundingClientRect()\n .select(`#${scrollViewId}`)\n .scrollOffset()\n .exec((scrollRes) => {\n const scrollRect = scrollRes?.[0]\n const scrollInfo = scrollRes?.[1]\n if (!scrollRect || !scrollInfo) return\n createSelectorQueryForRef(contentWrapperRef)\n .select(`#${contentId}`)\n .boundingClientRect()\n .exec((contentRes) => {\n const contentRect = contentRes?.[0]\n applyRects(scrollRect, scrollInfo, contentRect)\n })\n })\n }\n\n const scrollEl = scrollElRef.current\n if (!scrollEl) {\n if (retryCountRef.current < MAX_RETRY) {\n retryCountRef.current += 1\n const id = setTimeout(() => setRetryTrigger((t) => t + 1), RETRY_DELAY)\n return () => clearTimeout(id)\n }\n return\n }\n retryCountRef.current = 0\n measure()\n scrollEl.addEventListener('scroll', measure)\n const interval = setInterval(measure, MEASURE_INTERVAL)\n return () => {\n scrollEl.removeEventListener('scroll', measure)\n clearInterval(interval)\n }\n }, [enabled, scrollElRef, contentId, contentWrapperRef, isHorizontal, retryTrigger])\n\n return measuredStartOffset\n}\n"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { RefObject } from 'react';
1
2
  /**
2
3
  * useResizeObserver Hook - 尺寸变化监听(平台适配)
3
4
  *
@@ -9,9 +10,10 @@ interface UseResizeObserverOptions {
9
10
  enabled: boolean;
10
11
  /** 是否水平滚动(监听 width 还是 height) */
11
12
  isHorizontal: boolean;
12
- /** List 容器 ID(小程序用于 SelectorQuery) */
13
+ /** 小程序:ScrollView 上的随机 id 段(`id={listId}`),用于 `relativeTo('#'+listId)` 及 `#${listId}-list-item-inner-*` 等选择器 */
13
14
  listId: string;
14
- selectorQueryScope?: object;
15
+ /** 小程序:应指向带 `listId` 的 ScrollView;仅解析 IO 的组件实例(`weappScope`),不作为 `relativeTo` 的参数传入 */
16
+ listViewportRef: RefObject<HTMLElement | null>;
15
17
  /** 尺寸变化回调 */
16
18
  onResize: (index: number, size: number) => void;
17
19
  }
@@ -1,9 +1,9 @@
1
1
  import Taro from '@tarojs/taro';
2
2
  import { useRef, useCallback, useEffect } from 'react';
3
- import { getMiniProgramObserverScope, createSelectorQueryScoped, isH5, isMiniProgram } from '../utils.js';
3
+ import { getIntersectionObserverScopeForRef, createSelectorQueryForRef, isH5, isMiniProgram } from '../utils.js';
4
4
 
5
5
  function useResizeObserver(options) {
6
- const { enabled, isHorizontal, listId, onResize, selectorQueryScope } = options;
6
+ const { enabled, isHorizontal, listId, listViewportRef, onResize } = options;
7
7
  // H5: ResizeObserver 实例
8
8
  const observerRef = useRef(null);
9
9
  // 小程序: IntersectionObserver 实例 Map
@@ -55,16 +55,17 @@ function useResizeObserver(options) {
55
55
  : `#${listId}-list-header-inner-${-index - 1}`;
56
56
  const doObserve = () => {
57
57
  try {
58
- const observerScope = getMiniProgramObserverScope(selectorQueryScope);
58
+ const observerScope = getIntersectionObserverScopeForRef(listViewportRef);
59
59
  const observer = Taro.createIntersectionObserver(observerScope, {
60
60
  observeAll: true
61
61
  });
62
- // 相对于 List 容器
62
+ // 参照视口:仍为 `#${listId}` 字符串;与 `listViewportRef` 无 API 耦合,后者只影响上面 `createIntersectionObserver` 的首参
63
63
  observer.relativeTo(`#${listId}`);
64
64
  // 观察元素进入可见区域(唯一 id 避免跨 List 误命中)
65
65
  observer.observe(selector, (res) => {
66
66
  if (res.intersectionRatio > 0) {
67
- createSelectorQueryScoped(selectorQueryScope)
67
+ // 与 observe 目标同一节点,SelectorQuery 的 in(scope) 与该节点 _scope 一致
68
+ createSelectorQueryForRef({ current: _element })
68
69
  .select(selector)
69
70
  .boundingClientRect((rect) => {
70
71
  if (rect) {
@@ -82,7 +83,7 @@ function useResizeObserver(options) {
82
83
  }
83
84
  };
84
85
  Taro.nextTick(doObserve);
85
- }, [enabled, isHorizontal, listId, onResize, selectorQueryScope]);
86
+ }, [enabled, isHorizontal, listId, listViewportRef, onResize]);
86
87
  /**
87
88
  * 观察元素(平台自动适配)
88
89
  */
@@ -1 +1 @@
1
- {"version":3,"file":"useResizeObserver.js","sources":["../../../../src/components/list/hooks/useResizeObserver.ts"],"sourcesContent":["import Taro from '@tarojs/taro'\nimport { useCallback, useEffect, useRef } from 'react'\n\nimport { createSelectorQueryScoped, getMiniProgramObserverScope, isH5, isMiniProgram } from '../utils'\n\n/**\n * useResizeObserver Hook - 尺寸变化监听(平台适配)\n *\n * H5: 使用 ResizeObserver API\n * 小程序: 使用 IntersectionObserver + SelectorQuery\n */\n\ninterface UseResizeObserverOptions {\n /** 是否启用监听 */\n enabled: boolean\n\n /** 是否水平滚动(监听 width 还是 height) */\n isHorizontal: boolean\n\n /** List 容器 ID(小程序用于 SelectorQuery) */\n listId: string\n selectorQueryScope?: object\n\n /** 尺寸变化回调 */\n onResize: (index: number, size: number) => void\n}\n\ninterface UseResizeObserverReturn {\n /** 观察指定元素(传入 ref 和索引) */\n observe: (element: HTMLElement | null, index: number) => void\n\n /** 取消观察指定元素 */\n unobserve: (element: HTMLElement | null) => void\n\n /** 断开所有观察 */\n disconnect: () => void\n}\n\nexport function useResizeObserver(\n options: UseResizeObserverOptions\n): UseResizeObserverReturn {\n const { enabled, isHorizontal, listId, onResize, selectorQueryScope } = options\n\n // H5: ResizeObserver 实例\n const observerRef = useRef<ResizeObserver | null>(null)\n\n // 小程序: IntersectionObserver 实例 Map\n const intersectionObserversRef = useRef<Map<number, Taro.IntersectionObserver>>(new Map())\n\n // 已观察的元素 Map(用于去重)\n const observedElementsRef = useRef<Map<number, HTMLElement | null>>(new Map())\n\n /**\n * H5 实现:使用 ResizeObserver\n */\n const observeH5 = useCallback((element: HTMLElement | null, index: number) => {\n if (!element || !enabled) return\n\n // 避免重复观察\n if (observedElementsRef.current.has(index)) return\n\n // 创建 ResizeObserver(懒加载)\n if (!observerRef.current) {\n observerRef.current = new ResizeObserver((entries) => {\n entries.forEach((entry) => {\n const idx = Number(entry.target.getAttribute('data-index'))\n if (isNaN(idx)) return\n\n const size = isHorizontal\n ? entry.contentRect.width\n : entry.contentRect.height\n\n onResize(idx, size)\n })\n })\n }\n\n // 设置 data-index 属性\n element.setAttribute('data-index', String(index))\n\n // 开始观察\n observerRef.current.observe(element)\n observedElementsRef.current.set(index, element)\n }, [enabled, isHorizontal, onResize])\n\n /**\n * 小程序实现:使用 IntersectionObserver + SelectorQuery\n * 使用唯一 id 选择器,避免多 List 并存时误命中(index>=0 为 item,index<0 为 header)\n * 使用 Taro.nextTick 延后 observe,确保 setData 已提交、节点已挂载,避免 \"Node is not found\" 报错\n */\n const observeMiniProgram = useCallback((_element: any, index: number) => {\n if (!enabled) return\n\n // 避免重复观察\n if (intersectionObserversRef.current.has(index)) return\n\n const selector = index >= 0\n ? `#${listId}-list-item-inner-${index}`\n : `#${listId}-list-header-inner-${-index - 1}`\n\n const doObserve = () => {\n try {\n const observerScope = getMiniProgramObserverScope(selectorQueryScope)\n const observer = Taro.createIntersectionObserver(observerScope, {\n observeAll: true\n })\n\n // 相对于 List 容器\n observer.relativeTo(`#${listId}`)\n\n // 观察元素进入可见区域(唯一 id 避免跨 List 误命中)\n observer.observe(selector, (res) => {\n if (res.intersectionRatio > 0) {\n createSelectorQueryScoped(selectorQueryScope)\n .select(selector)\n .boundingClientRect((rect: any) => {\n if (rect) {\n const size = isHorizontal ? rect.width : rect.height\n onResize(index, size)\n }\n })\n .exec()\n }\n })\n\n intersectionObserversRef.current.set(index, observer)\n } catch {\n // ignore observe failure\n }\n }\n\n Taro.nextTick(doObserve)\n }, [enabled, isHorizontal, listId, onResize, selectorQueryScope])\n\n /**\n * 观察元素(平台自动适配)\n */\n const observe = useCallback((element: HTMLElement | null, index: number) => {\n if (!enabled) return\n\n if (isH5) {\n observeH5(element, index)\n } else if (isMiniProgram) {\n observeMiniProgram(element, index)\n }\n }, [enabled, observeH5, observeMiniProgram])\n\n /**\n * 取消观察元素\n */\n const unobserve = useCallback((element: HTMLElement | null) => {\n if (!element) return\n\n const index = Number(element.getAttribute('data-index'))\n if (isNaN(index)) return\n\n if (isH5 && observerRef.current) {\n observerRef.current.unobserve(element)\n observedElementsRef.current.delete(index)\n } else if (isMiniProgram) {\n const observer = intersectionObserversRef.current.get(index)\n if (observer) {\n observer.disconnect()\n intersectionObserversRef.current.delete(index)\n }\n }\n }, [])\n\n /**\n * 断开所有观察\n */\n const disconnect = useCallback(() => {\n if (isH5 && observerRef.current) {\n observerRef.current.disconnect()\n observerRef.current = null\n observedElementsRef.current.clear()\n } else if (isMiniProgram) {\n intersectionObserversRef.current.forEach((observer) => {\n observer.disconnect()\n })\n intersectionObserversRef.current.clear()\n }\n }, [])\n\n /**\n * 组件卸载时清理\n */\n useEffect(() => {\n return () => {\n disconnect()\n }\n }, [disconnect])\n\n return {\n observe,\n unobserve,\n disconnect\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useResizeObserver.js","sources":["../../../../src/components/list/hooks/useResizeObserver.ts"],"sourcesContent":["import Taro from '@tarojs/taro'\nimport { useCallback, useEffect, useRef } from 'react'\n\nimport { createSelectorQueryForRef, getIntersectionObserverScopeForRef, isH5, isMiniProgram } from '../utils'\n\nimport type { RefObject } from 'react'\n\n/**\n * useResizeObserver Hook - 尺寸变化监听(平台适配)\n *\n * H5: 使用 ResizeObserver API\n * 小程序: 使用 IntersectionObserver + SelectorQuery\n */\n\ninterface UseResizeObserverOptions {\n /** 是否启用监听 */\n enabled: boolean\n\n /** 是否水平滚动(监听 width 还是 height) */\n isHorizontal: boolean\n\n /** 小程序:ScrollView 上的随机 id 段(`id={listId}`),用于 `relativeTo('#'+listId)` 及 `#${listId}-list-item-inner-*` 等选择器 */\n listId: string\n\n /** 小程序:应指向带 `listId` 的 ScrollView;仅解析 IO 的组件实例(`weappScope`),不作为 `relativeTo` 的参数传入 */\n listViewportRef: RefObject<HTMLElement | null>\n\n /** 尺寸变化回调 */\n onResize: (index: number, size: number) => void\n}\n\ninterface UseResizeObserverReturn {\n /** 观察指定元素(传入 ref 和索引) */\n observe: (element: HTMLElement | null, index: number) => void\n\n /** 取消观察指定元素 */\n unobserve: (element: HTMLElement | null) => void\n\n /** 断开所有观察 */\n disconnect: () => void\n}\n\nexport function useResizeObserver(\n options: UseResizeObserverOptions\n): UseResizeObserverReturn {\n const { enabled, isHorizontal, listId, listViewportRef, onResize } = options\n\n // H5: ResizeObserver 实例\n const observerRef = useRef<ResizeObserver | null>(null)\n\n // 小程序: IntersectionObserver 实例 Map\n const intersectionObserversRef = useRef<Map<number, Taro.IntersectionObserver>>(new Map())\n\n // 已观察的元素 Map(用于去重)\n const observedElementsRef = useRef<Map<number, HTMLElement | null>>(new Map())\n\n /**\n * H5 实现:使用 ResizeObserver\n */\n const observeH5 = useCallback((element: HTMLElement | null, index: number) => {\n if (!element || !enabled) return\n\n // 避免重复观察\n if (observedElementsRef.current.has(index)) return\n\n // 创建 ResizeObserver(懒加载)\n if (!observerRef.current) {\n observerRef.current = new ResizeObserver((entries) => {\n entries.forEach((entry) => {\n const idx = Number(entry.target.getAttribute('data-index'))\n if (isNaN(idx)) return\n\n const size = isHorizontal\n ? entry.contentRect.width\n : entry.contentRect.height\n\n onResize(idx, size)\n })\n })\n }\n\n // 设置 data-index 属性\n element.setAttribute('data-index', String(index))\n\n // 开始观察\n observerRef.current.observe(element)\n observedElementsRef.current.set(index, element)\n }, [enabled, isHorizontal, onResize])\n\n /**\n * 小程序实现:使用 IntersectionObserver + SelectorQuery\n * 使用唯一 id 选择器,避免多 List 并存时误命中(index>=0 为 item,index<0 为 header)\n * 使用 Taro.nextTick 延后 observe,确保 setData 已提交、节点已挂载,避免 \"Node is not found\" 报错\n */\n const observeMiniProgram = useCallback((_element: any, index: number) => {\n if (!enabled) return\n\n // 避免重复观察\n if (intersectionObserversRef.current.has(index)) return\n\n const selector = index >= 0\n ? `#${listId}-list-item-inner-${index}`\n : `#${listId}-list-header-inner-${-index - 1}`\n\n const doObserve = () => {\n try {\n const observerScope = getIntersectionObserverScopeForRef(listViewportRef)\n const observer = Taro.createIntersectionObserver(observerScope, {\n observeAll: true\n })\n\n // 参照视口:仍为 `#${listId}` 字符串;与 `listViewportRef` 无 API 耦合,后者只影响上面 `createIntersectionObserver` 的首参\n observer.relativeTo(`#${listId}`)\n\n // 观察元素进入可见区域(唯一 id 避免跨 List 误命中)\n observer.observe(selector, (res) => {\n if (res.intersectionRatio > 0) {\n // 与 observe 目标同一节点,SelectorQuery 的 in(scope) 与该节点 _scope 一致\n createSelectorQueryForRef({ current: _element } as RefObject<any>)\n .select(selector)\n .boundingClientRect((rect: any) => {\n if (rect) {\n const size = isHorizontal ? rect.width : rect.height\n onResize(index, size)\n }\n })\n .exec()\n }\n })\n\n intersectionObserversRef.current.set(index, observer)\n } catch {\n // ignore observe failure\n }\n }\n\n Taro.nextTick(doObserve)\n }, [enabled, isHorizontal, listId, listViewportRef, onResize])\n\n /**\n * 观察元素(平台自动适配)\n */\n const observe = useCallback((element: HTMLElement | null, index: number) => {\n if (!enabled) return\n\n if (isH5) {\n observeH5(element, index)\n } else if (isMiniProgram) {\n observeMiniProgram(element, index)\n }\n }, [enabled, observeH5, observeMiniProgram])\n\n /**\n * 取消观察元素\n */\n const unobserve = useCallback((element: HTMLElement | null) => {\n if (!element) return\n\n const index = Number(element.getAttribute('data-index'))\n if (isNaN(index)) return\n\n if (isH5 && observerRef.current) {\n observerRef.current.unobserve(element)\n observedElementsRef.current.delete(index)\n } else if (isMiniProgram) {\n const observer = intersectionObserversRef.current.get(index)\n if (observer) {\n observer.disconnect()\n intersectionObserversRef.current.delete(index)\n }\n }\n }, [])\n\n /**\n * 断开所有观察\n */\n const disconnect = useCallback(() => {\n if (isH5 && observerRef.current) {\n observerRef.current.disconnect()\n observerRef.current = null\n observedElementsRef.current.clear()\n } else if (isMiniProgram) {\n intersectionObserversRef.current.forEach((observer) => {\n observer.disconnect()\n })\n intersectionObserversRef.current.clear()\n }\n }, [])\n\n /**\n * 组件卸载时清理\n */\n useEffect(() => {\n return () => {\n disconnect()\n }\n }, [disconnect])\n\n return {\n observe,\n unobserve,\n disconnect\n }\n}\n"],"names":[],"mappings":";;;;AA0CM,SAAU,iBAAiB,CAC/B,OAAiC,EAAA;AAEjC,IAAA,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,OAAO;;AAG5E,IAAA,MAAM,WAAW,GAAG,MAAM,CAAwB,IAAI,CAAC;;IAGvD,MAAM,wBAAwB,GAAG,MAAM,CAAyC,IAAI,GAAG,EAAE,CAAC;;IAG1F,MAAM,mBAAmB,GAAG,MAAM,CAAkC,IAAI,GAAG,EAAE,CAAC;AAE9E;;AAEG;IACH,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,OAA2B,EAAE,KAAa,KAAI;AAC3E,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO;YAAE;;AAG1B,QAAA,IAAI,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE;;AAG5C,QAAA,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE;YACxB,WAAW,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,CAAC,OAAO,KAAI;AACnD,gBAAA,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,KAAI;AACxB,oBAAA,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;oBAC3D,IAAI,KAAK,CAAC,GAAG,CAAC;wBAAE;oBAEhB,MAAM,IAAI,GAAG;AACX,0BAAE,KAAK,CAAC,WAAW,CAAC;AACpB,0BAAE,KAAK,CAAC,WAAW,CAAC,MAAM;AAE5B,oBAAA,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;AACrB,iBAAC,CAAC;AACJ,aAAC,CAAC;;;QAIJ,OAAO,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;;AAGjD,QAAA,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;QACpC,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC;KAChD,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;AAErC;;;;AAIG;IACH,MAAM,kBAAkB,GAAG,WAAW,CAAC,CAAC,QAAa,EAAE,KAAa,KAAI;AACtE,QAAA,IAAI,CAAC,OAAO;YAAE;;AAGd,QAAA,IAAI,wBAAwB,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;YAAE;AAEjD,QAAA,MAAM,QAAQ,GAAG,KAAK,IAAI;AACxB,cAAE,CAAA,CAAA,EAAI,MAAM,CAAA,iBAAA,EAAoB,KAAK,CAAE;cACrC,IAAI,MAAM,CAAA,mBAAA,EAAsB,CAAC,KAAK,GAAG,CAAC,CAAA,CAAE;QAEhD,MAAM,SAAS,GAAG,MAAK;AACrB,YAAA,IAAI;AACF,gBAAA,MAAM,aAAa,GAAG,kCAAkC,CAAC,eAAe,CAAC;AACzE,gBAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,0BAA0B,CAAC,aAAa,EAAE;AAC9D,oBAAA,UAAU,EAAE;AACb,iBAAA,CAAC;;AAGF,gBAAA,QAAQ,CAAC,UAAU,CAAC,IAAI,MAAM,CAAA,CAAE,CAAC;;gBAGjC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,GAAG,KAAI;AACjC,oBAAA,IAAI,GAAG,CAAC,iBAAiB,GAAG,CAAC,EAAE;;AAE7B,wBAAA,yBAAyB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAoB;6BAC9D,MAAM,CAAC,QAAQ;AACf,6BAAA,kBAAkB,CAAC,CAAC,IAAS,KAAI;4BAChC,IAAI,IAAI,EAAE;AACR,gCAAA,MAAM,IAAI,GAAG,YAAY,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM;AACpD,gCAAA,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;;AAEzB,yBAAC;AACA,6BAAA,IAAI,EAAE;;AAEb,iBAAC,CAAC;gBAEF,wBAAwB,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC;;AACrD,YAAA,OAAA,EAAA,EAAM;;;AAGV,SAAC;AAED,QAAA,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;AAC1B,KAAC,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC;AAE9D;;AAEG;IACH,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,OAA2B,EAAE,KAAa,KAAI;AACzE,QAAA,IAAI,CAAC,OAAO;YAAE;QAEd,IAAI,IAAI,EAAE;AACR,YAAA,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC;;aACpB,IAAI,aAAa,EAAE;AACxB,YAAA,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC;;KAErC,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAC;AAE5C;;AAEG;AACH,IAAA,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,OAA2B,KAAI;AAC5D,QAAA,IAAI,CAAC,OAAO;YAAE;QAEd,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QACxD,IAAI,KAAK,CAAC,KAAK,CAAC;YAAE;AAElB,QAAA,IAAI,IAAI,IAAI,WAAW,CAAC,OAAO,EAAE;AAC/B,YAAA,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC;AACtC,YAAA,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;;aACpC,IAAI,aAAa,EAAE;YACxB,MAAM,QAAQ,GAAG,wBAAwB,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;YAC5D,IAAI,QAAQ,EAAE;gBACZ,QAAQ,CAAC,UAAU,EAAE;AACrB,gBAAA,wBAAwB,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;;;KAGnD,EAAE,EAAE,CAAC;AAEN;;AAEG;AACH,IAAA,MAAM,UAAU,GAAG,WAAW,CAAC,MAAK;AAClC,QAAA,IAAI,IAAI,IAAI,WAAW,CAAC,OAAO,EAAE;AAC/B,YAAA,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE;AAChC,YAAA,WAAW,CAAC,OAAO,GAAG,IAAI;AAC1B,YAAA,mBAAmB,CAAC,OAAO,CAAC,KAAK,EAAE;;aAC9B,IAAI,aAAa,EAAE;YACxB,wBAAwB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,QAAQ,KAAI;gBACpD,QAAQ,CAAC,UAAU,EAAE;AACvB,aAAC,CAAC;AACF,YAAA,wBAAwB,CAAC,OAAO,CAAC,KAAK,EAAE;;KAE3C,EAAE,EAAE,CAAC;AAEN;;AAEG;IACH,SAAS,CAAC,MAAK;AACb,QAAA,OAAO,MAAK;AACV,YAAA,UAAU,EAAE;AACd,SAAC;AACH,KAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IAEhB,OAAO;QACL,OAAO;QACP,SAAS;QACT;KACD;AACH;;;;"}
@@ -77,8 +77,6 @@ export interface ListProps {
77
77
  scrollElement?: React.RefObject<HTMLElement | null>;
78
78
  /** 向外透出滚动容器,供子 List 作 scrollElement */
79
79
  scrollRef?: React.MutableRefObject<HTMLElement | null>;
80
- /** 仅小程序:SelectorQuery / IO 作用域(如自定义组件内传 `this`),未传则沿用 page */
81
- selectorQueryScope?: object;
82
80
  }
83
81
  export interface ListHandle {
84
82
  scroll: (options?: {
@@ -15,7 +15,7 @@ import { ListItem } from './ListItem.js';
15
15
  import { NoMore } from './NoMore.js';
16
16
  import { StickyHeader } from './StickyHeader.js';
17
17
  import { StickySection } from './StickySection.js';
18
- import { isWeapp, createSelectorQueryScoped, isH5, supportsNativeRefresher } from './utils.js';
18
+ import { isWeapp, createSelectorQueryForRef, isH5, supportsNativeRefresher } from './utils.js';
19
19
  import { getScrollViewContextNode } from '../../utils/dom.js';
20
20
 
21
21
  function accumulate(arr) {
@@ -69,7 +69,7 @@ const InnerList = (props, ref) => {
69
69
  const { stickyHeader = false, space = 0, height = 400, width = '100%', showScrollbar = true, scrollTop: controlledScrollTop, scrollX = false, scrollY = true, onScroll, onScrollToUpper, onScrollToLower, onScrollStart, onScrollEnd, upperThreshold = 50, lowerThreshold = 50, cacheCount = 2, cacheExtent, enableBackToTop, className, style, children, nestedScroll, scrollElement, scrollRef: scrollRefProp, } = props;
70
70
  const isHorizontal = scrollX === true;
71
71
  const listType = nestedScroll === true ? 'nested' : 'default';
72
- const { effectiveScrollElement, effectiveStartOffset, effectiveStartOffsetRef, useScrollElementMode, needAutoFind, autoFindStatus, contentWrapperRef, contentId, } = useListNestedScroll(listType, scrollElement, undefined, isHorizontal, props.selectorQueryScope);
72
+ const { effectiveScrollElement, effectiveStartOffset, effectiveStartOffsetRef, useScrollElementMode, needAutoFind, autoFindStatus, contentWrapperRef, contentId, } = useListNestedScroll(listType, scrollElement, undefined, isHorizontal);
73
73
  const DEFAULT_ITEM_WIDTH = 120;
74
74
  const DEFAULT_ITEM_HEIGHT = 40;
75
75
  const defaultItemSize = isHorizontal ? DEFAULT_ITEM_WIDTH : DEFAULT_ITEM_HEIGHT;
@@ -125,7 +125,7 @@ const InnerList = (props, ref) => {
125
125
  if (!isWeapp)
126
126
  return;
127
127
  Taro.nextTick(() => {
128
- createSelectorQueryScoped(props.selectorQueryScope)
128
+ createSelectorQueryForRef(containerRef)
129
129
  .select(`#${listId}`)
130
130
  .boundingClientRect((rect) => {
131
131
  const measured = isHorizontal ? rect === null || rect === void 0 ? void 0 : rect.width : rect === null || rect === void 0 ? void 0 : rect.height;
@@ -450,7 +450,7 @@ const InnerList = (props, ref) => {
450
450
  enabled: props.useResizeObserver === true,
451
451
  isHorizontal,
452
452
  listId,
453
- selectorQueryScope: props.selectorQueryScope,
453
+ listViewportRef: containerRef,
454
454
  onResize: (index, size) => {
455
455
  var _a;
456
456
  const oldSize = sizeCache.getItemSize(index);
@@ -889,7 +889,7 @@ const InnerList = (props, ref) => {
889
889
  listContentLength: listContentLengthRef.current,
890
890
  };
891
891
  useListScrollElementAttach(useScrollElementMode && isH5, effectiveScrollElement, effectiveStartOffset, isHorizontal, setContainerLength, updateRenderOffset, scrollRefProp, scrollAttachRefsRef);
892
- useListScrollElementAttachWeapp(useScrollElementMode && isWeapp, effectiveScrollElement, effectiveStartOffsetRef, effectiveStartOffset, isHorizontal, setContainerLength, updateRenderOffset, scrollRefProp, scrollAttachRefsRef, initialContainerLength, props.selectorQueryScope);
892
+ useListScrollElementAttachWeapp(useScrollElementMode && isWeapp, effectiveScrollElement, effectiveStartOffsetRef, effectiveStartOffset, isHorizontal, setContainerLength, updateRenderOffset, scrollRefProp, scrollAttachRefsRef, initialContainerLength);
893
893
  // 吸顶/吸左 header
894
894
  const stickyHeaderNode = React.useMemo(() => {
895
895
  if (!stickyHeader)
@@ -971,7 +971,7 @@ const InnerList = (props, ref) => {
971
971
  Taro.nextTick(() => {
972
972
  if (!headerRefsRef.current.has(sectionIndex))
973
973
  return;
974
- createSelectorQueryScoped(props.selectorQueryScope)
974
+ createSelectorQueryForRef({ current: el })
975
975
  .select(`#${listId}-list-header-inner-${sectionIndex}`)
976
976
  .boundingClientRect((rect) => {
977
977
  if (rect) {
@@ -1117,7 +1117,7 @@ const InnerList = (props, ref) => {
1117
1117
  Taro.nextTick(() => {
1118
1118
  if (!itemRefsRef.current.has(capturedIndex))
1119
1119
  return;
1120
- createSelectorQueryScoped(props.selectorQueryScope)
1120
+ createSelectorQueryForRef({ current: el })
1121
1121
  // 页面上可能同时存在多个 List,inner id 必须带 listId 前缀避免跨列表误命中
1122
1122
  .select(`#${listId}-list-item-inner-${capturedIndex}`)
1123
1123
  .boundingClientRect((rect) => {