@tarojs/components-advanced 4.1.0-alpha.1 → 4.1.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/components/index.d.ts +1 -0
  2. package/dist/components/index.js +4 -0
  3. package/dist/components/index.js.map +1 -1
  4. package/dist/components/water-flow/flow-item.d.ts +11 -0
  5. package/dist/components/water-flow/flow-item.js +70 -0
  6. package/dist/components/water-flow/flow-item.js.map +1 -0
  7. package/dist/components/water-flow/flow-section.d.ts +7 -0
  8. package/dist/components/water-flow/flow-section.js +66 -0
  9. package/dist/components/water-flow/flow-section.js.map +1 -0
  10. package/dist/components/water-flow/index.d.ts +4 -0
  11. package/dist/components/water-flow/index.js +4 -0
  12. package/dist/components/water-flow/index.js.map +1 -0
  13. package/dist/components/water-flow/interface.d.ts +54 -0
  14. package/dist/components/water-flow/node.d.ts +63 -0
  15. package/dist/components/water-flow/node.js +99 -0
  16. package/dist/components/water-flow/node.js.map +1 -0
  17. package/dist/components/water-flow/root.d.ts +144 -0
  18. package/dist/components/water-flow/root.js +395 -0
  19. package/dist/components/water-flow/root.js.map +1 -0
  20. package/dist/components/water-flow/section.d.ts +110 -0
  21. package/dist/components/water-flow/section.js +226 -0
  22. package/dist/components/water-flow/section.js.map +1 -0
  23. package/dist/components/water-flow/stateful-event-bus.d.ts +33 -0
  24. package/dist/components/water-flow/stateful-event-bus.js +70 -0
  25. package/dist/components/water-flow/stateful-event-bus.js.map +1 -0
  26. package/dist/components/water-flow/use-memoized-fn.d.ts +4 -0
  27. package/dist/components/water-flow/use-memoized-fn.js +16 -0
  28. package/dist/components/water-flow/use-memoized-fn.js.map +1 -0
  29. package/dist/components/water-flow/use-observed-attr.d.ts +2 -0
  30. package/dist/components/water-flow/use-observed-attr.js +20 -0
  31. package/dist/components/water-flow/use-observed-attr.js.map +1 -0
  32. package/dist/components/water-flow/use-unmount.d.ts +1 -0
  33. package/dist/components/water-flow/utils.d.ts +31 -0
  34. package/dist/components/water-flow/utils.js +45 -0
  35. package/dist/components/water-flow/utils.js.map +1 -0
  36. package/dist/components/water-flow/water-flow.d.ts +4 -0
  37. package/dist/components/water-flow/water-flow.js +146 -0
  38. package/dist/components/water-flow/water-flow.js.map +1 -0
  39. package/dist/index.js +3 -0
  40. package/dist/index.js.map +1 -1
  41. package/package.json +8 -8
@@ -1,2 +1,3 @@
1
1
  export * from './virtual-list';
2
2
  export * from './virtual-waterfall';
3
+ export * from './water-flow';
@@ -1,3 +1,7 @@
1
1
  export { VirtualList } from './virtual-list/index.js';
2
2
  export { VirtualWaterfall } from './virtual-waterfall/index.js';
3
+ import './water-flow/index.js';
4
+ export { FlowItem, useFlowItemPositioner } from './water-flow/flow-item.js';
5
+ export { FlowSection } from './water-flow/flow-section.js';
6
+ export { WaterFlow } from './water-flow/water-flow.js';
3
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
@@ -0,0 +1,11 @@
1
+ import { type PropsWithChildren } from 'react';
2
+ import type { FlowItemContainerProps } from './interface';
3
+ export declare const useFlowItemPositioner: () => {
4
+ resize: (this: unknown) => void;
5
+ top: number;
6
+ scrollTop: number;
7
+ width: number;
8
+ height: number;
9
+ };
10
+ export declare function FlowItemContainer({ children, ...props }: PropsWithChildren<FlowItemContainerProps>): import("react").ReactElement<import("@tarojs/components").ViewProps, string | import("react").JSXElementConstructor<any>>;
11
+ export declare function FlowItem(props: PropsWithChildren): import("react").ReactNode;
@@ -0,0 +1,70 @@
1
+ import { __rest } from 'tslib';
2
+ import { View } from '@tarojs/components';
3
+ import { createContext, useContext, useRef, useMemo, useEffect, useLayoutEffect, createElement } from 'react';
4
+ import { NodeEvents } from './node.js';
5
+ import { useMemoizedFn } from './use-memoized-fn.js';
6
+ import { useObservedAttr } from './use-observed-attr.js';
7
+ import { isWeb } from './utils.js';
8
+
9
+ const FlowItemContext = createContext(Object.create(null));
10
+ const useFlowItemPositioner = () => {
11
+ const nodeModel = useContext(FlowItemContext).node;
12
+ const width$ = useObservedAttr(nodeModel, 'width');
13
+ const height$ = useObservedAttr(nodeModel, 'height');
14
+ const top$ = useObservedAttr(nodeModel, 'top');
15
+ const scrollTop$ = useObservedAttr(nodeModel, 'scrollTop');
16
+ return {
17
+ resize: useMemoizedFn(() => {
18
+ if (!isWeb()) {
19
+ nodeModel.pub(NodeEvents.Resize);
20
+ }
21
+ }),
22
+ top: top$,
23
+ scrollTop: scrollTop$,
24
+ width: width$,
25
+ height: height$,
26
+ };
27
+ };
28
+ function FlowItemContainer(_a) {
29
+ var { children } = _a, props = __rest(_a, ["children"]);
30
+ const { node } = props;
31
+ const layouted$ = useObservedAttr(node, 'layouted');
32
+ const top$ = useObservedAttr(node, 'top');
33
+ const height$ = useObservedAttr(node, 'height');
34
+ const refFlowItem = useRef();
35
+ const itemStyle = useMemo(() => {
36
+ const baseStyle = {
37
+ width: '100%',
38
+ minHeight: node.section.defaultSize,
39
+ };
40
+ if (!layouted$) {
41
+ return baseStyle;
42
+ }
43
+ Reflect.deleteProperty(baseStyle, 'minHeight');
44
+ return Object.assign(Object.assign({}, baseStyle), { height: height$, transition: 'transform 20ms cubic-bezier(0.075, 0.82, 0.165, 1)', willChange: 'transform', position: 'absolute', top: 0, left: 0, transform: `translate3d(0px, ${top$}px, 0px)` });
45
+ }, [top$, layouted$, height$]);
46
+ useEffect(() => {
47
+ let observer;
48
+ if (isWeb() && typeof ResizeObserver !== 'undefined') {
49
+ observer = new ResizeObserver(() => {
50
+ node.pub(NodeEvents.Resize);
51
+ });
52
+ observer.observe(refFlowItem.current);
53
+ }
54
+ return () => {
55
+ if (observer) {
56
+ observer.disconnect();
57
+ }
58
+ };
59
+ }, [node]);
60
+ useLayoutEffect(() => {
61
+ node.measure();
62
+ }, [node]);
63
+ return createElement(View, { style: itemStyle, key: node.id }, createElement(View, { id: node.id, ref: refFlowItem }, createElement(FlowItemContext.Provider, { value: { node } }, children)));
64
+ }
65
+ function FlowItem(props) {
66
+ return props.children;
67
+ }
68
+
69
+ export { FlowItem, FlowItemContainer, useFlowItemPositioner };
70
+ //# sourceMappingURL=flow-item.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-item.js","sources":["../../../src/components/water-flow/flow-item.ts"],"sourcesContent":["import { View } from '@tarojs/components'\nimport {\n type CSSProperties,\n type PropsWithChildren,\n createContext,\n createElement,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n} from 'react'\n\nimport { Node, NodeEvents } from './node'\nimport { useMemoizedFn } from './use-memoized-fn'\nimport { useObservedAttr } from './use-observed-attr'\nimport { isWeb } from './utils'\n\nimport type { FlowItemContainerProps } from './interface'\n\nconst FlowItemContext = createContext<{ node: Node }>(Object.create(null))\nexport const useFlowItemPositioner = () => {\n const nodeModel = useContext(FlowItemContext).node\n const width$ = useObservedAttr(nodeModel, 'width')\n const height$ = useObservedAttr(nodeModel, 'height')\n const top$ = useObservedAttr(nodeModel, 'top')\n const scrollTop$ = useObservedAttr(nodeModel, 'scrollTop')\n\n return {\n resize: useMemoizedFn(() => {\n if (!isWeb()) {\n nodeModel.pub(NodeEvents.Resize)\n }\n }),\n top: top$,\n scrollTop: scrollTop$,\n width: width$,\n height: height$,\n }\n}\n\nexport function FlowItemContainer({\n children,\n ...props\n}: PropsWithChildren<FlowItemContainerProps>) {\n const { node } = props\n const layouted$ = useObservedAttr(node, 'layouted')\n const top$ = useObservedAttr(node, 'top')\n const height$ = useObservedAttr(node, 'height')\n const refFlowItem = useRef<HTMLElement>()\n\n const itemStyle: CSSProperties = useMemo(() => {\n const baseStyle: CSSProperties = {\n width: '100%',\n minHeight: node.section.defaultSize,\n }\n if (!layouted$) {\n return baseStyle\n }\n Reflect.deleteProperty(baseStyle, 'minHeight')\n return {\n ...baseStyle,\n height: height$,\n transition: 'transform 20ms cubic-bezier(0.075, 0.82, 0.165, 1)',\n willChange: 'transform',\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `translate3d(0px, ${top$}px, 0px)`,\n }\n }, [top$, layouted$, height$])\n\n useEffect(() => {\n let observer: ResizeObserver\n if (isWeb() && typeof ResizeObserver !== 'undefined') {\n observer = new ResizeObserver(() => {\n node.pub(NodeEvents.Resize)\n })\n observer.observe(refFlowItem.current!)\n }\n return () => {\n if (observer) {\n observer.disconnect()\n }\n }\n }, [node])\n\n useLayoutEffect(() => {\n node.measure()\n }, [node])\n\n return createElement(\n View,\n { style: itemStyle, key: node.id },\n createElement(\n View,\n { id: node.id, ref: refFlowItem },\n createElement(FlowItemContext.Provider, { value: { node } }, children)\n )\n )\n}\n\nexport function FlowItem(props: PropsWithChildren) {\n return props.children\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { type PropsWithChildren } from 'react';
2
+ import { Section } from './section';
3
+ import type { FlowSectionProps } from './interface';
4
+ export interface _FlowSectionProps extends FlowSectionProps {
5
+ section: Section;
6
+ }
7
+ export declare function FlowSection({ children, ...props }: PropsWithChildren<FlowSectionProps>): import("react").ReactElement<import("@tarojs/components").ViewProps, string | import("react").JSXElementConstructor<any>>;
@@ -0,0 +1,66 @@
1
+ import { __rest } from 'tslib';
2
+ import { View } from '@tarojs/components';
3
+ import { useMemo, Children, createElement } from 'react';
4
+ import { FlowItemContainer } from './flow-item.js';
5
+ import { useObservedAttr } from './use-observed-attr.js';
6
+
7
+ function FlowSection(_a) {
8
+ var { children } = _a, props = __rest(_a, ["children"]);
9
+ const { id, className, style, section, rowGap = 0, columnGap = 0, } = props;
10
+ const layouted$ = useObservedAttr(section, 'layouted');
11
+ const height$ = useObservedAttr(section, 'height');
12
+ const renderRange$ = useObservedAttr(section, 'renderRange');
13
+ const scrollTop$ = useObservedAttr(section, 'scrollTop');
14
+ const sectionStyle = useMemo(() => {
15
+ const baseStyle = Object.assign({ display: 'flex', flexDirection: 'row', width: '100%', height: height$, gap: columnGap, visibility: layouted$ ? 'visible' : 'hidden' }, style);
16
+ if (!layouted$) {
17
+ return baseStyle;
18
+ }
19
+ return Object.assign(Object.assign({}, baseStyle), { position: 'absolute', top: 0, transform: `translate3d(0px, ${scrollTop$}px, 0px)`, left: 0 });
20
+ }, [height$, style, layouted$, scrollTop$, columnGap]);
21
+ const columns = useMemo(() => {
22
+ const childNodes = Children.toArray(children);
23
+ const columnStyle = {
24
+ position: 'relative',
25
+ display: 'flex',
26
+ flexDirection: 'column',
27
+ gap: rowGap,
28
+ flex: 1,
29
+ };
30
+ /** 已经完成布局计算,使用虚拟滚动 */
31
+ if (layouted$) {
32
+ return renderRange$.map(([startIndex, endIndex], colIndex) => {
33
+ const columnId = `col-${colIndex}`;
34
+ return createElement(View, {
35
+ style: columnStyle,
36
+ id: columnId,
37
+ key: columnId,
38
+ }, section.columnMap[colIndex]
39
+ .slice(startIndex, endIndex + 1)
40
+ .map((node) => {
41
+ const childNode = childNodes[node.childIndex];
42
+ const columnProps = {
43
+ node,
44
+ key: `${id}-item-${node.childIndex}`,
45
+ };
46
+ return createElement(FlowItemContainer, columnProps, childNode);
47
+ }));
48
+ });
49
+ }
50
+ return section.columnMap.map((column, colIndex) => {
51
+ const columnId = `col-${colIndex}`;
52
+ return createElement(View, { style: columnStyle, id: columnId, key: columnId }, column.map((node) => {
53
+ const childNode = childNodes[node.childIndex];
54
+ const columnProps = {
55
+ node,
56
+ key: `${id}-item-${node.childIndex}`,
57
+ };
58
+ return createElement(FlowItemContainer, columnProps, childNode);
59
+ }));
60
+ });
61
+ }, [children, layouted$, section.columnMap, renderRange$, id]);
62
+ return createElement(View, { style: sectionStyle, className, id: id !== null && id !== void 0 ? id : section.id }, columns);
63
+ }
64
+
65
+ export { FlowSection };
66
+ //# sourceMappingURL=flow-section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow-section.js","sources":["../../../src/components/water-flow/flow-section.ts"],"sourcesContent":["import { View } from '@tarojs/components'\nimport {\n type CSSProperties,\n type PropsWithChildren,\n Children,\n createElement,\n useMemo,\n} from 'react'\n\nimport { FlowItemContainer } from './flow-item'\nimport { Section } from './section'\nimport { useObservedAttr } from './use-observed-attr'\n\nimport type { FlowSectionProps } from './interface'\n\nexport interface _FlowSectionProps extends FlowSectionProps {\n section: Section\n}\n\nexport function FlowSection({\n children,\n ...props\n}: PropsWithChildren<FlowSectionProps>) {\n const {\n id,\n className,\n style,\n section,\n rowGap = 0,\n columnGap = 0,\n } = props as _FlowSectionProps\n const layouted$ = useObservedAttr(section, 'layouted')\n const height$ = useObservedAttr(section, 'height')\n const renderRange$ = useObservedAttr(section, 'renderRange')\n const scrollTop$ = useObservedAttr(section, 'scrollTop')\n\n const sectionStyle: CSSProperties = useMemo(() => {\n const baseStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'row',\n width: '100%',\n height: height$,\n gap: columnGap,\n visibility: layouted$ ? 'visible' : 'hidden',\n ...style,\n }\n\n if (!layouted$) {\n return baseStyle\n }\n\n return {\n ...baseStyle,\n position: 'absolute',\n top: 0,\n transform: `translate3d(0px, ${scrollTop$}px, 0px)`,\n left: 0,\n }\n }, [height$, style, layouted$, scrollTop$, columnGap])\n\n const columns = useMemo(() => {\n const childNodes = Children.toArray(children)\n const columnStyle: CSSProperties = {\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n gap: rowGap,\n flex: 1,\n }\n /** 已经完成布局计算,使用虚拟滚动 */\n if (layouted$) {\n return renderRange$.map(([startIndex, endIndex], colIndex) => {\n const columnId = `col-${colIndex}`\n return createElement(\n View,\n {\n style: columnStyle,\n id: columnId,\n key: columnId,\n },\n section.columnMap[colIndex]\n .slice(startIndex, endIndex + 1)\n .map((node) => {\n const childNode = childNodes[node.childIndex]\n const columnProps: any = {\n node,\n key: `${id}-item-${node.childIndex}`,\n }\n return createElement(FlowItemContainer, columnProps, childNode)\n })\n )\n })\n }\n\n return section.columnMap.map((column, colIndex) => {\n const columnId = `col-${colIndex}`\n return createElement(\n View,\n { style: columnStyle, id: columnId, key: columnId },\n column.map((node) => {\n const childNode = childNodes[node.childIndex]\n const columnProps: any = {\n node,\n key: `${id}-item-${node.childIndex}`,\n }\n return createElement(FlowItemContainer, columnProps, childNode)\n })\n )\n })\n }, [children, layouted$, section.columnMap, renderRange$, id])\n\n return createElement(\n View,\n { style: sectionStyle, className, id: id ?? section.id },\n columns\n )\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { FlowItem, useFlowItemPositioner } from './flow-item';
2
+ export { FlowSection } from './flow-section';
3
+ export type { FlowSectionProps, WaterFlowProps } from './interface';
4
+ export { WaterFlow } from './water-flow';
@@ -0,0 +1,4 @@
1
+ export { FlowItem, useFlowItemPositioner } from './flow-item.js';
2
+ export { FlowSection } from './flow-section.js';
3
+ export { WaterFlow } from './water-flow.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -0,0 +1,54 @@
1
+ import { ScrollViewProps } from '@tarojs/components';
2
+ import { Node } from './node';
3
+ import type { CSSProperties } from 'react';
4
+ export interface BaseProps {
5
+ id?: string;
6
+ className?: string;
7
+ style?: CSSProperties;
8
+ }
9
+ export interface WaterFlowProps extends Omit<ScrollViewProps, 'cacheExtent' | 'upperThreshold' | 'lowerThreshold' | 'style'>, Pick<BaseProps, 'style'> {
10
+ /**
11
+ * 距顶部多少个FlowItem时,触发 scrolltoupper 事件
12
+ * @default 0
13
+ */
14
+ upperThresholdCount?: number;
15
+ /**
16
+ * @default 0
17
+ * 距底部多少个 FlowItem时,触发 scrolltolower 事件
18
+ */
19
+ lowerThresholdCount?: number;
20
+ /**
21
+ * 设置预加载的 Item 条数。
22
+ * @default 50
23
+ */
24
+ cacheCount?: number;
25
+ }
26
+ export interface FlowSectionProps extends BaseProps {
27
+ /**
28
+ * 列数
29
+ */
30
+ column?: number;
31
+ /**
32
+ * 该分组的行间距
33
+ */
34
+ rowGap?: number;
35
+ /**
36
+ * 该分组的列间距
37
+ */
38
+ columnGap?: number;
39
+ }
40
+ export interface FlowItemContainerProps extends BaseProps {
41
+ node: Node;
42
+ }
43
+ export interface Size {
44
+ width: number;
45
+ height: number;
46
+ }
47
+ /**
48
+ * 滚动方向
49
+ *
50
+ * - forward 向下滚动
51
+ *
52
+ * - backward 向上滚动
53
+ */
54
+ export type ScrollDirection = 'forward' | 'backward';
@@ -0,0 +1,63 @@
1
+ import { Root } from './root';
2
+ import { Section } from './section';
3
+ import { StatefulEventBus } from './stateful-event-bus';
4
+ interface NodeProps {
5
+ /**
6
+ * 原始索引,即一维数组中的索引
7
+ */
8
+ childIndex: number;
9
+ /**
10
+ * 在列里的顺序
11
+ */
12
+ order: number;
13
+ /**
14
+ * 位于哪一列
15
+ */
16
+ col: number;
17
+ height: number;
18
+ }
19
+ type NodeState = {
20
+ top: number;
21
+ width: number;
22
+ height: number;
23
+ layouted: boolean;
24
+ scrollTop: number;
25
+ };
26
+ export declare const NodeEvents: {
27
+ Resize: symbol;
28
+ };
29
+ export declare class Node extends StatefulEventBus<NodeState> {
30
+ root: Root;
31
+ section: Section;
32
+ id: string;
33
+ /**
34
+ * 原始索引,即一维数组中的索引
35
+ */
36
+ childIndex: number;
37
+ /**
38
+ * 在列里的顺序
39
+ */
40
+ order: number;
41
+ /**
42
+ * 位于哪一列
43
+ */
44
+ col: number;
45
+ constructor(root: Root, section: Section, props: NodeProps);
46
+ private setupSubscriptions;
47
+ /**
48
+ * 测量节点的尺寸信息
49
+ */
50
+ measure(): Promise<{
51
+ width: number;
52
+ height: number;
53
+ }>;
54
+ /**
55
+ * 更新节点所在列后面的节点的位置
56
+ */
57
+ updateBehindNodesPosition(): void;
58
+ /**
59
+ * 节点是否可见
60
+ */
61
+ get isInRange(): boolean;
62
+ }
63
+ export {};
@@ -0,0 +1,99 @@
1
+ import '../../utils/index.js';
2
+ import { SectionEvents } from './section.js';
3
+ import { StatefulEventBus } from './stateful-event-bus.js';
4
+ import { getRectSizeSync } from '../../utils/dom.js';
5
+
6
+ const NodeEvents = {
7
+ Resize: Symbol.for('resize'),
8
+ };
9
+ class Node extends StatefulEventBus {
10
+ constructor(root, section, props) {
11
+ const { height, childIndex, order, col } = props;
12
+ super({
13
+ top: 0,
14
+ width: 0,
15
+ height,
16
+ scrollTop: 0,
17
+ layouted: false,
18
+ });
19
+ this.root = root;
20
+ this.section = section;
21
+ const nodeId = `${root.id}-${section.id}-item-${childIndex}`;
22
+ Object.assign(this, { id: nodeId, childIndex, order, col });
23
+ this.setupSubscriptions();
24
+ }
25
+ setupSubscriptions() {
26
+ this.sub('layouted', () => {
27
+ /**
28
+ * 如果当前分组所有的节点都完成布局计算,那么向分组推送 `AllNodesLayouted` 事件,section会在这个时机做一些计算
29
+ */
30
+ if ([...this.section.nodes.values()].every((node) => node.getState().layouted)) {
31
+ this.section.notify(SectionEvents.AllNodesLayouted);
32
+ }
33
+ });
34
+ /**
35
+ * 如果节点的尺寸发生了变化(这通常出现在节点内容包含网络数据的情况下,比如图片,这时要求用户调用 useFlowItemPositioner 返回的 resize 方法通知数据模型去重新计算布局)
36
+ *
37
+ * - 更新当前节点所在列之后的所有节点的位置信息
38
+ *
39
+ * - 通知 section 更新布局
40
+ */
41
+ this.sub(NodeEvents.Resize, async () => {
42
+ const { width, height } = this.getState();
43
+ const newSize = await this.measure();
44
+ if (newSize.height === height && newSize.width === width) {
45
+ return;
46
+ }
47
+ this.updateBehindNodesPosition();
48
+ this.section.pub(SectionEvents.Resize, {
49
+ node: this,
50
+ newSize,
51
+ originalSize: { width, height },
52
+ });
53
+ });
54
+ }
55
+ /**
56
+ * 测量节点的尺寸信息
57
+ */
58
+ async measure() {
59
+ const { height, width } = await getRectSizeSync(`#${this.id}`, 100, 3);
60
+ this.setStateBatch({
61
+ width,
62
+ height,
63
+ layouted: true,
64
+ });
65
+ return { width, height };
66
+ }
67
+ /**
68
+ * 更新节点所在列后面的节点的位置
69
+ */
70
+ updateBehindNodesPosition() {
71
+ const currentColumn = this.section.columnMap[this.col];
72
+ let start = this.order + 1;
73
+ if (start > currentColumn.length - 1) {
74
+ return;
75
+ }
76
+ for (; start < currentColumn.length; start++) {
77
+ const node = currentColumn[start];
78
+ const previousNode = currentColumn[start - 1];
79
+ const { top: previousNodeTop, height: previousNodeHeight, scrollTop: previousNodeScrollTop, } = previousNode.getState();
80
+ const rowGap = this.section.rowGap;
81
+ node.setStateBatch({
82
+ top: previousNodeTop + previousNodeHeight + rowGap,
83
+ scrollTop: previousNodeScrollTop + previousNodeHeight + rowGap,
84
+ });
85
+ }
86
+ }
87
+ /**
88
+ * 节点是否可见
89
+ */
90
+ get isInRange() {
91
+ const { scrollBoundaryStart, scrollBoundaryEnd } = this.root;
92
+ const { height: nodeHeight, scrollTop: nodeScrollTop } = this.getState();
93
+ return (nodeScrollTop < scrollBoundaryEnd &&
94
+ nodeScrollTop + nodeHeight > scrollBoundaryStart);
95
+ }
96
+ }
97
+
98
+ export { Node, NodeEvents };
99
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sources":["../../../src/components/water-flow/node.ts"],"sourcesContent":["import { getRectSizeSync } from '../../utils'\nimport { Root } from './root'\nimport { Section, SectionEvents } from './section'\nimport { StatefulEventBus } from './stateful-event-bus'\n\ninterface NodeProps {\n /**\n * 原始索引,即一维数组中的索引\n */\n childIndex: number\n /**\n * 在列里的顺序\n */\n order: number\n /**\n * 位于哪一列\n */\n col: number\n height: number\n}\n\ntype NodeState = {\n top: number\n width: number\n height: number\n layouted: boolean\n scrollTop: number\n};\n\nexport const NodeEvents = {\n Resize: Symbol.for('resize'),\n}\n\nexport class Node extends StatefulEventBus<NodeState> {\n id: string\n /**\n * 原始索引,即一维数组中的索引\n */\n childIndex: number\n /**\n * 在列里的顺序\n */\n order: number\n /**\n * 位于哪一列\n */\n col: number\n constructor(public root: Root, public section: Section, props: NodeProps) {\n const { height, childIndex, order, col } = props\n super({\n top: 0,\n width: 0,\n height,\n scrollTop: 0,\n layouted: false,\n })\n const nodeId = `${root.id}-${section.id}-item-${childIndex}`\n Object.assign(this, { id: nodeId, childIndex, order, col })\n this.setupSubscriptions()\n }\n\n private setupSubscriptions() {\n this.sub('layouted', () => {\n /**\n * 如果当前分组所有的节点都完成布局计算,那么向分组推送 `AllNodesLayouted` 事件,section会在这个时机做一些计算\n */\n if (\n [...this.section.nodes.values()].every(\n (node) => node.getState().layouted\n )\n ) {\n this.section.notify(SectionEvents.AllNodesLayouted)\n }\n })\n\n /**\n * 如果节点的尺寸发生了变化(这通常出现在节点内容包含网络数据的情况下,比如图片,这时要求用户调用 useFlowItemPositioner 返回的 resize 方法通知数据模型去重新计算布局)\n *\n * - 更新当前节点所在列之后的所有节点的位置信息\n *\n * - 通知 section 更新布局\n */\n this.sub(NodeEvents.Resize, async () => {\n const { width, height } = this.getState()\n const newSize = await this.measure()\n if (newSize.height === height && newSize.width === width) {\n return\n }\n this.updateBehindNodesPosition()\n this.section.pub(SectionEvents.Resize, {\n node: this,\n newSize,\n originalSize: { width, height },\n })\n })\n }\n\n /**\n * 测量节点的尺寸信息\n */\n public async measure() {\n const { height, width } = await getRectSizeSync(`#${this.id}`, 100, 3)\n this.setStateBatch({\n width,\n height,\n layouted: true,\n })\n return { width, height }\n }\n\n /**\n * 更新节点所在列后面的节点的位置\n */\n updateBehindNodesPosition() {\n const currentColumn = this.section.columnMap[this.col]\n let start = this.order + 1\n\n if (start > currentColumn.length - 1) {\n return\n }\n for (; start < currentColumn.length; start++) {\n const node = currentColumn[start]\n const previousNode = currentColumn[start - 1]\n const {\n top: previousNodeTop,\n height: previousNodeHeight,\n scrollTop: previousNodeScrollTop,\n } = previousNode.getState()\n const rowGap = this.section.rowGap\n node.setStateBatch({\n top: previousNodeTop + previousNodeHeight + rowGap,\n scrollTop: previousNodeScrollTop + previousNodeHeight + rowGap,\n })\n }\n }\n\n /**\n * 节点是否可见\n */\n get isInRange() {\n const { scrollBoundaryStart, scrollBoundaryEnd } = this.root\n const { height: nodeHeight, scrollTop: nodeScrollTop } = this.getState()\n return (\n nodeScrollTop < scrollBoundaryEnd &&\n nodeScrollTop + nodeHeight > scrollBoundaryStart\n )\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ import { Node } from './node';
2
+ import { Section } from './section';
3
+ import { StatefulEventBus } from './stateful-event-bus';
4
+ import type { BaseProps, ScrollDirection, Size, WaterFlowProps } from './interface';
5
+ export type RootProps = Pick<WaterFlowProps, 'cacheCount' | 'lowerThresholdCount' | 'upperThresholdCount'> & Required<Pick<BaseProps, 'id'>>;
6
+ type RootState = {
7
+ /** 是否在滚动中 */
8
+ isScrolling: boolean;
9
+ /** 滚动偏移量 */
10
+ scrollOffset: number;
11
+ /**
12
+ * 滚动方向
13
+ *
14
+ * - forward 向下滚动
15
+ *
16
+ * - backward 向上滚动
17
+ */
18
+ scrollDirection: ScrollDirection;
19
+ /** 滚动高度 */
20
+ scrollHeight: number;
21
+ /** 容器的尺寸信息 */
22
+ containerSize: Size;
23
+ /** 渲染的分组区间范围 */
24
+ renderRange: [number, number];
25
+ };
26
+ export declare const RootEvents: {
27
+ ReachUpperThreshold: symbol;
28
+ ReachLowerThreshold: symbol;
29
+ Resize: symbol;
30
+ AllSectionsLayouted: symbol;
31
+ InitialRenderCompleted: symbol;
32
+ };
33
+ type Events = keyof typeof RootEvents;
34
+ /**
35
+ * 数据模型继承自有状态的事件总线,便于在节点之间通信,以及通过 useSyncExternalStore 关联 React 视图
36
+ */
37
+ export declare class Root extends StatefulEventBus<RootState, Events> {
38
+ /**
39
+ * 瀑布流根节点唯一标识
40
+ */
41
+ id: string;
42
+ /**
43
+ * 分组映射表,便于查找分组
44
+ */
45
+ sectionMap: Map<string, Section>;
46
+ /**
47
+ * 节点映射表,便于查找节点
48
+ */
49
+ nodeMap: Map<string, Node>;
50
+ /**
51
+ * 分组列表,基于计算出的渲染的分组区间范围 sections.slice(start, end + 1) 进行渲染
52
+ */
53
+ sections: Section[];
54
+ /**
55
+ * 设置预加载的 Item 条数。
56
+ */
57
+ cacheCount: number;
58
+ upperThresholdCount: number;
59
+ lowerThresholdCount: number;
60
+ /**
61
+ * 触发滚动阈值对应的 scrollTop 值
62
+ */
63
+ upperThresholdScrollTop: number;
64
+ /**
65
+ * 触发滚动阈值对应的 scrollTop 值
66
+ */
67
+ lowerThresholdScrollTop: number;
68
+ constructor(props: RootProps);
69
+ /**
70
+ * 设置订阅事件
71
+ */
72
+ private setupSubscriptions;
73
+ /**
74
+ * 渐进式渲染
75
+ *
76
+ * 因为初始没法知道每个分组的高度信息,不知道渲染边界,所以需要渐进式渲染
77
+ *
78
+ * 当目前的渲染批次的首个分组的scrollTop大于容器的高度,说明容器可视区域已经填满,没必要再往下渲染了
79
+ *
80
+ * @param [i=0] 从第几个分组开始渲染
81
+ *
82
+ */
83
+ renderInitialLayout(i?: number): void;
84
+ /**
85
+ * 计算滚动阈值对应的 scrollTop 并设置 upperThresholdScrollTop
86
+ * 当距顶部还有 upperThresholdCount 个 FlowItem 时的 scrollTop 值
87
+ */
88
+ private setUpperThresholdScrollTop;
89
+ /**
90
+ * 计算滚动阈值对应的 scrollTop 并设置 lowerThresholdScrollTop
91
+ * 当距底部还有 lowerThresholdCount 个 FlowItem 时的 scrollTop 值
92
+ */
93
+ private setLowerThresholdScrollTop;
94
+ /**
95
+ * 处理滚动到阈值的情况
96
+ * 检测当前滚动位置是否达到了上下阈值,并触发相应的事件
97
+ */
98
+ private handleReachThreshold;
99
+ /**
100
+ * 容器的滚动上边界
101
+ */
102
+ get scrollBoundaryStart(): number;
103
+ /**
104
+ * 容器的滚动下边界
105
+ */
106
+ get scrollBoundaryEnd(): number;
107
+ /**
108
+ * 计算每个section的底部位置
109
+ *
110
+ * sectionBottomRange = [ [section1.top, section1.bottom], [section2.top, section2.bottom], ..., [sectionN.top, sectionN.bottom] ]
111
+ *
112
+ * @returns [number,number][]
113
+ */
114
+ get sectionRange(): number[][];
115
+ /**
116
+ * 计算滚动高度
117
+ */
118
+ private updateScrollHeight;
119
+ /**
120
+ * 注册分组
121
+ */
122
+ registerSection(section: Section): void;
123
+ /**
124
+ * 注册节点
125
+ */
126
+ registerNode(node: Node): void;
127
+ /**
128
+ * 查找分组
129
+ */
130
+ findSection(id: string): Section;
131
+ /**
132
+ * 查找节点
133
+ */
134
+ findNode(id: string): Node;
135
+ /**
136
+ * 获取分组渲染区间
137
+ */
138
+ getSectionRenderRange(): [number, number];
139
+ /**
140
+ * 计算预渲染的分组个数
141
+ */
142
+ private calcCacheSection;
143
+ }
144
+ export {};