vane-waterfall 2.0.1 → 2.0.3

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 (134) hide show
  1. package/README.md +4 -4
  2. package/dist/chunks/WaterfallCore-EdAZuWAY.js +695 -0
  3. package/dist/chunks/doc-BAhVW3g8.js +150 -0
  4. package/dist/chunks/doc-BU0CKW63.js +156 -0
  5. package/dist/chunks/doc-BrEd0oZB.js +100 -0
  6. package/dist/chunks/{doc-bTHwfIVb.js → doc-Bud0hbaz.js} +39 -25
  7. package/dist/chunks/{doc-DukOmDCo.js → doc-C-B3zK2o.js} +52 -23
  8. package/dist/chunks/{doc-DElLNjIc.js → doc-C206ZwYC.js} +33 -24
  9. package/dist/chunks/doc-C2L8kkeI.js +112 -0
  10. package/dist/chunks/doc-CE1DGMBV.js +166 -0
  11. package/dist/chunks/{doc-BXSy2aPP.js → doc-CHbQXLwY.js} +33 -19
  12. package/dist/chunks/{doc-BfWnfTst.js → doc-CInpKZNU.js} +38 -24
  13. package/dist/chunks/{doc-gTAsLjVx.js → doc-CYxwSuG6.js} +30 -16
  14. package/dist/chunks/{doc-DzvTrZ13.js → doc-CaJ02INP.js} +25 -16
  15. package/dist/chunks/{doc-BXElhF2h.js → doc-CiCso5Ti.js} +44 -30
  16. package/dist/chunks/doc-CkuMr8Ca.js +118 -0
  17. package/dist/chunks/{doc-3Fpag2G8.js → doc-D7m1OFCW.js} +38 -24
  18. package/dist/chunks/doc-DEN2WTDh.js +153 -0
  19. package/dist/chunks/{doc-C5xrHNoC.js → doc-DhICh9S2.js} +37 -23
  20. package/dist/chunks/doc-DlJICsyN.js +100 -0
  21. package/dist/chunks/{doc-BtzhgTYj.js → doc-DtxS1-P0.js} +35 -26
  22. package/dist/chunks/{doc-BIzjYAZW.js → doc-DudYCn_-.js} +25 -16
  23. package/dist/chunks/doc-HoyAFR_m.js +101 -0
  24. package/dist/chunks/doc-RlBMCMNs.js +170 -0
  25. package/dist/chunks/doc-RwKQqySd.js +102 -0
  26. package/dist/chunks/{doc-CTUoMe7o.js → doc-eYhNJy97.js} +31 -22
  27. package/dist/chunks/{doc-CcPFavOs.js → doc-i6FY1We1.js} +27 -13
  28. package/dist/chunks/doc-skPl6ZMP.js +101 -0
  29. package/dist/chunks/index-8gEIzUxi.js +15 -0
  30. package/dist/chunks/index-B96I5CKE.js +21 -0
  31. package/dist/chunks/index-Bjmhy8jW.js +11 -0
  32. package/dist/chunks/index-Cuq0ofv-.js +13 -0
  33. package/dist/chunks/{index-BAWlVYr3.js → index-Cz4YEqRF.js} +1 -1
  34. package/dist/chunks/{index-wLI6UXkY.js → index-FBJVUYmH.js} +1 -1
  35. package/dist/chunks/withPlugins-BOeDFhof.js +743 -0
  36. package/dist/components/WaterfallPlugin/WaterfallCore.d.ts +19 -0
  37. package/dist/components/WaterfallPlugin/WaterfallCore.d.ts.map +1 -1
  38. package/dist/components/WaterfallPlugin/layout.d.ts +7 -0
  39. package/dist/components/WaterfallPlugin/layout.d.ts.map +1 -1
  40. package/dist/components/WaterfallPlugin/plugins/types.d.ts +3 -0
  41. package/dist/components/WaterfallPlugin/plugins/types.d.ts.map +1 -1
  42. package/dist/components/WaterfallPlugin/withPlugins.d.ts.map +1 -1
  43. package/dist/custom-plugins/A11yPlugin/create.d.ts.map +1 -1
  44. package/dist/custom-plugins/A11yPlugin/doc.json.d.ts +64 -40
  45. package/dist/custom-plugins/A11yPlugin/index.js +1 -1
  46. package/dist/custom-plugins/AlignmentPlugin/doc.json.d.ts +42 -28
  47. package/dist/custom-plugins/AlignmentPlugin/index.js +1 -1
  48. package/dist/custom-plugins/AutoColumnPlugin/doc.json.d.ts +53 -44
  49. package/dist/custom-plugins/AutoColumnPlugin/index.js +1 -1
  50. package/dist/custom-plugins/BookmarkPlugin/create.d.ts.map +1 -1
  51. package/dist/custom-plugins/BookmarkPlugin/doc.json.d.ts +44 -35
  52. package/dist/custom-plugins/BookmarkPlugin/index.js +1 -1
  53. package/dist/custom-plugins/ClickAnalyticsPlugin/create.d.ts +2 -0
  54. package/dist/custom-plugins/ClickAnalyticsPlugin/create.d.ts.map +1 -1
  55. package/dist/custom-plugins/ClickAnalyticsPlugin/doc.json.d.ts +29 -0
  56. package/dist/custom-plugins/ClickAnalyticsPlugin/index.js +1 -1
  57. package/dist/custom-plugins/DebounceLayoutPlugin/doc.json.d.ts +37 -28
  58. package/dist/custom-plugins/DebounceLayoutPlugin/index.js +1 -1
  59. package/dist/custom-plugins/DragReorderPlugin/doc.json.d.ts +14 -0
  60. package/dist/custom-plugins/DragReorderPlugin/index.js +1 -1
  61. package/dist/custom-plugins/FilterPlugin/doc.json.d.ts +53 -39
  62. package/dist/custom-plugins/FilterPlugin/index.js +1 -1
  63. package/dist/custom-plugins/FixedHeightPlugin/doc.json.d.ts +42 -28
  64. package/dist/custom-plugins/FixedHeightPlugin/index.js +1 -1
  65. package/dist/custom-plugins/GapPlugin/create.d.ts.map +1 -1
  66. package/dist/custom-plugins/GapPlugin/doc.json.d.ts +61 -37
  67. package/dist/custom-plugins/GapPlugin/index.js +1 -1
  68. package/dist/custom-plugins/GroupingPlugin/create.d.ts.map +1 -1
  69. package/dist/custom-plugins/GroupingPlugin/doc.json.d.ts +61 -32
  70. package/dist/custom-plugins/GroupingPlugin/index.js +1 -1
  71. package/dist/custom-plugins/HeatmapAnalyticsPlugin/create.d.ts +2 -0
  72. package/dist/custom-plugins/HeatmapAnalyticsPlugin/create.d.ts.map +1 -1
  73. package/dist/custom-plugins/HeatmapAnalyticsPlugin/doc.json.d.ts +24 -0
  74. package/dist/custom-plugins/HeatmapAnalyticsPlugin/index.js +1 -1
  75. package/dist/custom-plugins/InfiniteScrollPlugin/create.d.ts.map +1 -1
  76. package/dist/custom-plugins/InfiniteScrollPlugin/doc.json.d.ts +55 -36
  77. package/dist/custom-plugins/InfiniteScrollPlugin/index.js +1 -1
  78. package/dist/custom-plugins/PaginationPlugin/create.d.ts.map +1 -1
  79. package/dist/custom-plugins/PaginationPlugin/doc.json.d.ts +56 -42
  80. package/dist/custom-plugins/PaginationPlugin/index.js +1 -1
  81. package/dist/custom-plugins/PinItemPlugin/doc.json.d.ts +49 -35
  82. package/dist/custom-plugins/PinItemPlugin/index.js +1 -1
  83. package/dist/custom-plugins/RecyclePlugin/create.d.ts.map +1 -1
  84. package/dist/custom-plugins/RecyclePlugin/doc.json.d.ts +57 -28
  85. package/dist/custom-plugins/RecyclePlugin/index.js +1 -1
  86. package/dist/custom-plugins/ReducedMotionPlugin/doc.json.d.ts +29 -0
  87. package/dist/custom-plugins/ReducedMotionPlugin/index.js +1 -1
  88. package/dist/custom-plugins/ResponsiveColumnsPlugin/doc.json.d.ts +40 -31
  89. package/dist/custom-plugins/ResponsiveColumnsPlugin/index.js +1 -1
  90. package/dist/custom-plugins/ScrollAnchorPlugin/doc.json.d.ts +42 -28
  91. package/dist/custom-plugins/ScrollAnchorPlugin/index.js +1 -1
  92. package/dist/custom-plugins/SearchPlugin/doc.json.d.ts +53 -39
  93. package/dist/custom-plugins/SearchPlugin/index.js +1 -1
  94. package/dist/custom-plugins/SortPlugin/doc.json.d.ts +52 -38
  95. package/dist/custom-plugins/SortPlugin/index.js +1 -1
  96. package/dist/custom-plugins/StatePersistencePlugin/create.d.ts.map +1 -1
  97. package/dist/custom-plugins/StatePersistencePlugin/doc.json.d.ts +71 -37
  98. package/dist/custom-plugins/StatePersistencePlugin/index.js +1 -1
  99. package/dist/custom-plugins/StickyHeaderPlugin/create.d.ts.map +1 -1
  100. package/dist/custom-plugins/StickyHeaderPlugin/doc.json.d.ts +43 -34
  101. package/dist/custom-plugins/StickyHeaderPlugin/index.js +1 -1
  102. package/dist/custom-plugins/ThrottlePlugin/doc.json.d.ts +43 -34
  103. package/dist/custom-plugins/ThrottlePlugin/index.js +1 -1
  104. package/dist/custom-plugins/TransitionPlugin/doc.json.d.ts +49 -35
  105. package/dist/custom-plugins/TransitionPlugin/index.js +1 -1
  106. package/dist/custom-plugins/URLSyncPlugin/create.d.ts.map +1 -1
  107. package/dist/custom-plugins/URLSyncPlugin/doc.json.d.ts +57 -33
  108. package/dist/custom-plugins/URLSyncPlugin/index.js +1 -1
  109. package/dist/custom-plugins/index.js +6 -6
  110. package/dist/entries/core.js +1 -1
  111. package/dist/entries/plugins.js +7 -7
  112. package/dist/index.js +2 -2
  113. package/dist/presets/dashboard/index.js +2 -2
  114. package/dist/presets/photo-feed/index.js +3 -3
  115. package/dist/presets/product-feed/index.js +2 -2
  116. package/package.json +16 -8
  117. package/dist/chunks/WaterfallCore-BSXw7bl_.js +0 -581
  118. package/dist/chunks/doc-78xF08vt.js +0 -82
  119. package/dist/chunks/doc-B-7dugGv.js +0 -79
  120. package/dist/chunks/doc-B6kLfMPv.js +0 -121
  121. package/dist/chunks/doc-BCGQ8Cp5.js +0 -114
  122. package/dist/chunks/doc-BP0DmB7-.js +0 -91
  123. package/dist/chunks/doc-CBHjiDG7.js +0 -88
  124. package/dist/chunks/doc-CraXjOaA.js +0 -68
  125. package/dist/chunks/doc-DJjxOYzW.js +0 -111
  126. package/dist/chunks/doc-NhL4Ux8q.js +0 -125
  127. package/dist/chunks/doc-f4Uijujv.js +0 -102
  128. package/dist/chunks/doc-j4W9SUrY.js +0 -76
  129. package/dist/chunks/doc-kTbJE7rY.js +0 -92
  130. package/dist/chunks/index-COaun3nf.js +0 -15
  131. package/dist/chunks/index-DXAtA2f6.js +0 -11
  132. package/dist/chunks/index-DsRLmBW-.js +0 -13
  133. package/dist/chunks/index-gjoCq0yC.js +0 -21
  134. package/dist/chunks/withPlugins-DLoKg4AP.js +0 -559
@@ -1,4 +1,4 @@
1
- function m(e) {
1
+ function h(e) {
2
2
  return {
3
3
  name: "ThrottlePlugin",
4
4
  priority: 80,
@@ -12,10 +12,16 @@ function m(e) {
12
12
  }
13
13
  };
14
14
  }
15
- const n = "ThrottlePlugin", s = "接管 Core 的 throttleDelay(滚动回调节流)与 debounceDelay(尺寸变化后多久重排)。默认 16ms / 150ms,长列表滚动卡顿时可以放宽到 32 / 300。", o = "2.0.0", r = [
15
+ const s = "ThrottlePlugin", n = "接管 Core 的 throttleDelay(滚动回调节流)与 debounceDelay(尺寸变化后多久重排)。默认 16ms / 150ms,长列表滚动卡顿时可以放宽到 32 / 300。", o = "2.0.0", r = [
16
16
  "perf",
17
17
  "性能"
18
18
  ], a = [
19
+ {
20
+ name: "transformProps",
21
+ when: "渲染前链式改写瀑布流 props",
22
+ description: "补 gap / columns 默认值、按断点覆盖配置"
23
+ }
24
+ ], c = [], l = "只读取 context 字段(props / state / data),不调用上下文方法", i = [
19
25
  {
20
26
  name: "scroll",
21
27
  type: "number",
@@ -28,33 +34,36 @@ const n = "ThrottlePlugin", s = "接管 Core 的 throttleDelay(滚动回调节
28
34
  default: "props.debounceDelay",
29
35
  description: "布局防抖 ms"
30
36
  }
31
- ], l = `// 调整滚动节流与尺寸防抖,弱网/低端机可放宽。
37
+ ], m = `// 调整滚动节流与尺寸防抖,弱网/低端机可放宽。
32
38
  const Waterfall = withPlugins(WaterfallCore, [
33
39
  createThrottlePlugin(),
34
40
  ]);
35
41
 
36
- <Waterfall items={items} renderItem={(item) => <Card data={item} />} />;`, c = [
42
+ <Waterfall items={items} renderItem={(item) => <Card data={item} />} />;`, u = [
37
43
  "滚动节流与布局防抖分开调",
38
44
  "只改 props,不改算法",
39
45
  "与 DebounceLayoutPlugin 叠加时后者优先"
40
- ], i = [
46
+ ], d = [
41
47
  "低端安卓机长列表",
42
48
  "滚动时 CPU 占用过高",
43
49
  "拖拽侧栏时减少重排"
44
- ], u = [
50
+ ], p = [
45
51
  "scroll 低于 16ms 没有意义(浏览器帧率上限)。"
46
- ], d = {
47
- name: n,
48
- description: s,
52
+ ], f = {
53
+ name: s,
54
+ description: n,
49
55
  since: o,
50
56
  tags: r,
51
- config: a,
52
- example: l,
53
- features: c,
54
- useCases: i,
55
- notes: u
57
+ events: a,
58
+ methods: c,
59
+ methodsNote: l,
60
+ config: i,
61
+ example: m,
62
+ features: u,
63
+ useCases: d,
64
+ notes: p
56
65
  };
57
66
  export {
58
- m as c,
59
- d
67
+ h as c,
68
+ f as d
60
69
  };
@@ -1,48 +1,48 @@
1
1
  import { jsx as E } from "react/jsx-runtime";
2
2
  const i = "data-drag-over";
3
- function y(s, l) {
3
+ function w(a, c) {
4
4
  if (typeof document > "u") return null;
5
- const c = document.elementFromPoint(s, l)?.closest?.("[data-index]");
6
- if (!c) return null;
7
- const d = Number(c.getAttribute("data-index"));
5
+ const l = document.elementFromPoint(a, c)?.closest?.("[data-index]");
6
+ if (!l) return null;
7
+ const d = Number(l.getAttribute("data-index"));
8
8
  return Number.isFinite(d) ? d : null;
9
9
  }
10
- function C(s = {}) {
11
- const l = s.enabled ?? !0, g = s.showHandle ?? !1, c = s.touchHoldMs ?? 180, d = (t, n, r) => {
10
+ function O(a = {}) {
11
+ const c = a.enabled ?? !0, g = a.showHandle ?? !1, l = a.touchHoldMs ?? 180, d = (t, n, r) => {
12
12
  const e = Number(r);
13
13
  if (!Number.isFinite(e) || e === n) return;
14
14
  t.sharedData.set("drag-from", e), t.sharedData.set("drag-to", n), t.bus.emit("drag:reorder", { from: e, to: n });
15
- const f = t.props.items;
16
- s.onReorder?.(e, n, f?.[e]);
17
- }, b = () => {
15
+ const p = t.props.items;
16
+ a.onReorder?.(e, n, p?.[e]);
17
+ }, h = () => {
18
18
  document.querySelectorAll(`[${i}]`).forEach((t) => t.removeAttribute(i));
19
19
  }, m = () => {
20
- typeof document > "u" || (b(), document.body.style.userSelect = "", document.body.style.cursor = "");
21
- }, w = (t, n, r) => {
20
+ typeof document > "u" || (h(), document.body.style.userSelect = "", document.body.style.cursor = "");
21
+ }, y = (t, n, r) => {
22
22
  if (t.pointerType === "mouse") return;
23
- const e = t.clientX, f = t.clientY, R = Date.now();
24
- let p = !1, h = null;
23
+ const e = t.clientX, p = t.clientY, R = Date.now();
24
+ let f = !1, b = null;
25
25
  const v = (o) => {
26
- if (!p) {
27
- const D = Date.now() - R >= c, H = Math.hypot(o.clientX - e, o.clientY - f) >= 6;
26
+ if (!f) {
27
+ const D = Date.now() - R >= l, H = Math.hypot(o.clientX - e, o.clientY - p) >= 6;
28
28
  if (!D || !H) return;
29
- p = !0, document.body.style.userSelect = "none", document.body.style.cursor = "grabbing";
29
+ f = !0, document.body.style.userSelect = "none", document.body.style.cursor = "grabbing";
30
30
  }
31
31
  o.preventDefault();
32
- const a = y(o.clientX, o.clientY);
33
- a !== h && (b(), h = a, a != null && document.querySelector(`[data-index="${a}"]`)?.setAttribute(i, ""));
32
+ const s = w(o.clientX, o.clientY);
33
+ s !== b && (h(), b = s, s != null && document.querySelector(`[data-index="${s}"]`)?.setAttribute(i, ""));
34
34
  }, u = (o) => {
35
- if (window.removeEventListener("pointermove", v), window.removeEventListener("pointerup", u), window.removeEventListener("pointercancel", u), m(), !p) return;
36
- const a = y(o.clientX, o.clientY);
37
- a != null && d(r, a, String(n));
35
+ if (window.removeEventListener("pointermove", v), window.removeEventListener("pointerup", u), window.removeEventListener("pointercancel", u), m(), !f) return;
36
+ const s = w(o.clientX, o.clientY);
37
+ s != null && d(r, s, String(n));
38
38
  };
39
39
  window.addEventListener("pointermove", v, { passive: !1 }), window.addEventListener("pointerup", u), window.addEventListener("pointercancel", u);
40
40
  };
41
41
  return {
42
42
  name: "DragReorderPlugin",
43
- enabled: l,
43
+ enabled: c,
44
44
  hooks: {
45
- renderItemWrapper: (t, n, r) => l ? /* @__PURE__ */ E(
45
+ renderItemWrapper: (t, n, r) => c ? /* @__PURE__ */ E(
46
46
  "div",
47
47
  {
48
48
  draggable: !0,
@@ -62,7 +62,7 @@ function C(s = {}) {
62
62
  e.preventDefault(), m(), d(t, r, e.dataTransfer?.getData("text/plain") ?? "");
63
63
  },
64
64
  onDragEnd: m,
65
- onPointerDown: (e) => w(e, r, t),
65
+ onPointerDown: (e) => y(e, r, t),
66
66
  style: {
67
67
  cursor: "grab",
68
68
  ...g ? { border: "1px dashed #bdbdbd", borderRadius: 6 } : null
@@ -77,6 +77,17 @@ const L = "DragReorderPlugin", M = "给每个项加拖拽能力,松手时回
77
77
  "interaction",
78
78
  "拖拽"
79
79
  ], S = [
80
+ {
81
+ name: "renderItemWrapper",
82
+ when: "渲染每个卡片时包裹其内容",
83
+ description: "给单卡加包裹层(拖拽、无障碍语义、占位骨架)"
84
+ },
85
+ {
86
+ name: "drag:reorder",
87
+ when: "拖拽排序完成后",
88
+ description: "广播 { from, to },供业务层同步顺序"
89
+ }
90
+ ], T = [], N = "只读取 context 字段(props / state / data),不调用上下文方法", x = [
80
91
  {
81
92
  name: "enabled",
82
93
  type: "boolean",
@@ -101,7 +112,7 @@ const L = "DragReorderPlugin", M = "给每个项加拖拽能力,松手时回
101
112
  default: "180",
102
113
  description: "触屏长按多久进入拖拽(ms),0 表示不需要长按"
103
114
  }
104
- ], T = `// 鼠标走 HTML5 draggable,触屏走长按 + pointer,松手时回调 onReorder(from, to)。
115
+ ], W = `// 鼠标走 HTML5 draggable,触屏走长按 + pointer,松手时回调 onReorder(from, to)。
105
116
  const Waterfall = withPlugins(WaterfallCore, [
106
117
  createDragReorderPlugin({
107
118
  enabled: true,
@@ -121,18 +132,21 @@ const Waterfall = withPlugins(WaterfallCore, [
121
132
  ], q = [
122
133
  "插件只负责「拖」和「告诉你从哪到哪」,数组重排由调用方在 onReorder 里做。",
123
134
  "触屏用长按区分「想滚」和「想拖」:不这样做,手指一滑就变成拖拽,页面滚不动。"
124
- ], N = {
135
+ ], $ = {
125
136
  name: L,
126
137
  description: M,
127
138
  since: A,
128
139
  tags: P,
129
- config: S,
130
- example: T,
140
+ events: S,
141
+ methods: T,
142
+ methodsNote: N,
143
+ config: x,
144
+ example: W,
131
145
  features: X,
132
146
  useCases: Y,
133
147
  notes: q
134
148
  };
135
149
  export {
136
- C as c,
137
- N as d
150
+ O as c,
151
+ $ as d
138
152
  };
@@ -0,0 +1,118 @@
1
+ import { jsx as u } from "react/jsx-runtime";
2
+ function w(n = {}) {
3
+ const l = n.containerRole ?? "list", c = n.itemRole ?? "listitem", m = n.enableTabIndex ?? !0, d = n.containerLabel ?? "Waterfall list", a = /* @__PURE__ */ new WeakMap(), s = (e) => e.containerRef?.current ?? e.bus, i = (e) => a.get(s(e)) ?? 0, o = (e) => {
4
+ const t = e.containerRef.current;
5
+ t && (t.setAttribute("role", l), t.setAttribute("aria-label", d), t.setAttribute("aria-busy", e.isLayouting ? "true" : "false"));
6
+ };
7
+ return {
8
+ name: "A11yPlugin",
9
+ enabled: !0,
10
+ hooks: {
11
+ onMount: (e) => {
12
+ o(e);
13
+ },
14
+ onLayoutComplete: (e) => {
15
+ o(e);
16
+ },
17
+ onItemClick: (e, t) => {
18
+ i(e) !== t && (a.set(s(e), t), e.forceUpdate?.());
19
+ },
20
+ renderItemWrapper: (e, t, r) => /* @__PURE__ */ u(
21
+ "div",
22
+ {
23
+ role: c,
24
+ "aria-posinset": r + 1,
25
+ "aria-setsize": e.itemCount,
26
+ tabIndex: m ? r === i(e) ? 0 : -1 : void 0,
27
+ children: t
28
+ }
29
+ )
30
+ }
31
+ };
32
+ }
33
+ const p = "A11yPlugin", b = "把瀑布流补成读屏可理解的列表:容器 `role=list` + `aria-label`,每项 `role=listitem` + `aria-posinset` / `aria-setsize`,并可选加 `tabIndex` 让键盘能逐项聚焦。", f = "2.0.0", y = [
34
+ "ui",
35
+ "a11y"
36
+ ], I = [
37
+ {
38
+ name: "onMount",
39
+ when: "瀑布流挂载完成",
40
+ description: "初始化观察器与滚动监听,返回清理函数"
41
+ },
42
+ {
43
+ name: "onItemClick",
44
+ when: "单个卡片被点击",
45
+ description: "卡片级跳转与点击埋点"
46
+ },
47
+ {
48
+ name: "onLayoutComplete",
49
+ when: "DOM 落位完成(可安全测量)",
50
+ description: "测量真实高度、懒加载判定、曝光上报"
51
+ },
52
+ {
53
+ name: "renderItemWrapper",
54
+ when: "渲染每个卡片时包裹其内容",
55
+ description: "给单卡加包裹层(拖拽、无障碍语义、占位骨架)"
56
+ }
57
+ ], g = [], R = "只读取 context 字段(props / state / data),不调用上下文方法", h = [
58
+ {
59
+ name: "containerRole",
60
+ type: "string",
61
+ default: '"list"',
62
+ description: "容器 role"
63
+ },
64
+ {
65
+ name: "itemRole",
66
+ type: "string",
67
+ default: '"listitem"',
68
+ description: "项 role"
69
+ },
70
+ {
71
+ name: "enableTabIndex",
72
+ type: "boolean",
73
+ default: "true",
74
+ description: "项是否可 Tab 聚焦"
75
+ },
76
+ {
77
+ name: "containerLabel",
78
+ type: "string",
79
+ default: '"Waterfall list"',
80
+ description: "容器 aria-label"
81
+ }
82
+ ], C = `// 给容器与项补 ARIA role / label / posinset,支持键盘 Tab 遍历。
83
+ const Waterfall = withPlugins(WaterfallCore, [
84
+ createA11yPlugin({
85
+ containerRole: "list",
86
+ itemRole: "listitem",
87
+ enableTabIndex: true,
88
+ }),
89
+ ]);
90
+
91
+ <Waterfall items={items} renderItem={(item) => <Card data={item} />} />;`, A = [
92
+ "容器 / 项 role 成对补齐",
93
+ "aria-posinset + aria-setsize 正确标注序号",
94
+ "键盘可逐项聚焦"
95
+ ], W = [
96
+ "政务 / 金融等合规站点",
97
+ "读屏用户可用的信息流",
98
+ "键盘操作优先的桌面端"
99
+ ], T = [
100
+ "项数很多时 `tabIndex=0` 会让 Tab 变长,建议配合「跳转主内容」链接使用。"
101
+ ], x = {
102
+ name: p,
103
+ description: b,
104
+ since: f,
105
+ tags: y,
106
+ events: I,
107
+ methods: g,
108
+ methodsNote: R,
109
+ config: h,
110
+ example: C,
111
+ features: A,
112
+ useCases: W,
113
+ notes: T
114
+ };
115
+ export {
116
+ w as c,
117
+ x as d
118
+ };
@@ -1,4 +1,4 @@
1
- function g(o = {}) {
1
+ function v(o = {}) {
2
2
  return {
3
3
  name: "FilterPlugin",
4
4
  priority: 40,
@@ -7,9 +7,9 @@ function g(o = {}) {
7
7
  transformProps: (e) => {
8
8
  const n = Array.isArray(e.items) ? e.items : [], t = e.filterFn || o.predicate;
9
9
  if (typeof t != "function") return e;
10
- const r = n.filter((a, i) => {
10
+ const r = n.filter((s, a) => {
11
11
  try {
12
- return !!t(a, i);
12
+ return !!t(s, a);
13
13
  } catch {
14
14
  return !0;
15
15
  }
@@ -17,19 +17,30 @@ function g(o = {}) {
17
17
  return { ...e, items: r };
18
18
  },
19
19
  onPropsChange: (e, n, t) => {
20
- const r = n?.filterFn, a = t?.filterFn;
21
- if (((typeof t?.scrollToTopOnFilterChange == "boolean" ? t.scrollToTopOnFilterChange : void 0) ?? !!o.scrollToTop) && r !== a) {
22
- const l = t?.scrollToTopBehavior ?? o.scrollBehavior ?? "auto";
23
- e.scrollToTop?.({ behavior: l });
20
+ const r = n?.filterFn, s = t?.filterFn;
21
+ if (((typeof t?.scrollToTopOnFilterChange == "boolean" ? t.scrollToTopOnFilterChange : void 0) ?? !!o.scrollToTop) && r !== s) {
22
+ const i = t?.scrollToTopBehavior ?? o.scrollBehavior ?? "auto";
23
+ e.scrollToTop?.({ behavior: i });
24
24
  }
25
25
  }
26
26
  }
27
27
  };
28
28
  }
29
- const s = "FilterPlugin", c = "用谓词函数过滤数据,优先读 `props.filterFn`,没有就用工厂里传入的 predicate。过滤条件变了可以自动滚回顶部(默认不开)。", u = "2.0.0", f = [
29
+ const l = "FilterPlugin", c = "用谓词函数过滤数据,优先读 `props.filterFn`,没有就用工厂里传入的 predicate。过滤条件变了可以自动滚回顶部(默认不开)。", p = "2.0.0", d = [
30
30
  "data",
31
31
  "数据管线"
32
- ], d = [
32
+ ], m = [
33
+ {
34
+ name: "onPropsChange",
35
+ when: "props 变化后",
36
+ description: "数据或配置变化时请求重排"
37
+ },
38
+ {
39
+ name: "transformProps",
40
+ when: "渲染前链式改写瀑布流 props",
41
+ description: "补 gap / columns 默认值、按断点覆盖配置"
42
+ }
43
+ ], u = [], f = "只读取 context 字段(props / state / data),不调用上下文方法", h = [
33
44
  {
34
45
  name: "predicate",
35
46
  type: "(item, index) => boolean",
@@ -48,7 +59,7 @@ const s = "FilterPlugin", c = "用谓词函数过滤数据,优先读 `props.fi
48
59
  default: '"auto"',
49
60
  description: "回顶行为"
50
61
  }
51
- ], p = `// 按谓词过滤 items,参数变化可自动回顶。
62
+ ], F = `// 按谓词过滤 items,参数变化可自动回顶。
52
63
  const Waterfall = withPlugins(WaterfallCore, [
53
64
  createFilterPlugin({
54
65
  scrollToTop: false,
@@ -56,29 +67,32 @@ const Waterfall = withPlugins(WaterfallCore, [
56
67
  }),
57
68
  ]);
58
69
 
59
- <Waterfall items={items} renderItem={(item) => <Card data={item} />} />;`, m = [
70
+ <Waterfall items={items} renderItem={(item) => <Card data={item} />} />;`, T = [
60
71
  "谓词抛错时按「保留」处理,不会整表消失",
61
72
  "props.filterFn 优先,便于页面动态换过滤条件",
62
73
  "可与 Sort / Search / Pagination 串联"
63
- ], F = [
74
+ ], g = [
64
75
  "分类 Tab 切换",
65
76
  "只看有货 / 只看促销",
66
77
  "价格区间筛选"
67
- ], h = [
78
+ ], y = [
68
79
  "数据管线的执行顺序由 priority 决定:Filter(40) → Sort(30) → Search(20) → Pagination(10)。",
69
80
  "先过滤再分页,页码总数才是过滤后的总数——顺序反了会出现「第 2 页空」。"
70
- ], y = {
71
- name: s,
81
+ ], b = {
82
+ name: l,
72
83
  description: c,
73
- since: u,
74
- tags: f,
75
- config: d,
76
- example: p,
77
- features: m,
78
- useCases: F,
79
- notes: h
84
+ since: p,
85
+ tags: d,
86
+ events: m,
87
+ methods: u,
88
+ methodsNote: f,
89
+ config: h,
90
+ example: F,
91
+ features: T,
92
+ useCases: g,
93
+ notes: y
80
94
  };
81
95
  export {
82
- g as c,
83
- y as d
96
+ v as c,
97
+ b as d
84
98
  };
@@ -0,0 +1,153 @@
1
+ import { jsxs as g, jsx as h } from "react/jsx-runtime";
2
+ function W(u = {}) {
3
+ const { log: m = !1, showOverlay: p = !1 } = u, n = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map();
4
+ let i = null;
5
+ const l = () => Array.from(n.values()).reduce((e, t) => e + t, 0), y = (e, t, s) => {
6
+ try {
7
+ const o = e.props?.keyExtractor?.(t, s);
8
+ if (o != null) return String(o);
9
+ } catch {
10
+ }
11
+ return `#${s}`;
12
+ }, d = (e) => {
13
+ const t = e.items;
14
+ (i === null || t !== i) && (i = t, n.clear(), c.clear(), e.sharedData?.set("click-count", 0));
15
+ };
16
+ return {
17
+ name: "ClickAnalyticsPlugin",
18
+ enabled: !0,
19
+ getStats: () => ({
20
+ total: l(),
21
+ byIndex: Array.from(n.entries()).map(([e, t]) => ({
22
+ index: c.get(e) ?? 0,
23
+ key: e,
24
+ clicks: t
25
+ })).sort((e, t) => e.index - t.index || e.key.localeCompare(t.key))
26
+ }),
27
+ hooks: {
28
+ onMount: (e) => {
29
+ e.sharedData?.set("click-count", l());
30
+ },
31
+ onLayoutComplete: (e) => {
32
+ d(e);
33
+ },
34
+ onItemClick: (e, t, s, o) => {
35
+ d(e);
36
+ const a = y(e, s, t);
37
+ c.set(a, t);
38
+ const f = (n.get(a) ?? 0) + 1;
39
+ n.set(a, f);
40
+ const r = l();
41
+ e.sharedData?.set("click-count", r), e.bus?.emit("analytics:click", { index: t, key: a, item: s, event: o, total: r }), e.forceUpdate?.(), m && console.log(`[ClickAnalytics] item=${t} total=${r}`);
42
+ },
43
+ renderOverlay: (e) => {
44
+ if (!p) return null;
45
+ const t = e.sharedData?.get("click-count") || 0;
46
+ return /* @__PURE__ */ g(
47
+ "div",
48
+ {
49
+ style: {
50
+ position: "absolute",
51
+ top: 12,
52
+ right: 12,
53
+ padding: "10px 12px",
54
+ background: "#222",
55
+ color: "#fff",
56
+ borderRadius: 8,
57
+ fontSize: 14,
58
+ fontWeight: 600,
59
+ boxShadow: "0 4px 12px rgba(0,0,0,0.25)",
60
+ border: "1px solid rgba(255,255,255,0.15)",
61
+ pointerEvents: "none",
62
+ zIndex: 99
63
+ },
64
+ children: [
65
+ "点击次数:",
66
+ t,
67
+ /* @__PURE__ */ h("div", { style: { fontSize: 12, fontWeight: 400, opacity: 0.85, marginTop: 4 }, children: "提示:点击任意卡片观察计数变化" })
68
+ ]
69
+ }
70
+ );
71
+ }
72
+ }
73
+ };
74
+ }
75
+ const k = "ClickAnalyticsPlugin", x = "统计每次项点击并累计总数,向 bus 发 `analytics:click`(带 index / item / total),`getStats()` 可随时取出按 index 的计数。默认只上报不显示角标,接入真实版式时不会被调试面板盖住内容。", b = "2.0.0", C = [
76
+ "interaction",
77
+ "埋点"
78
+ ], v = [
79
+ {
80
+ name: "onMount",
81
+ when: "瀑布流挂载完成",
82
+ description: "初始化观察器与滚动监听,返回清理函数"
83
+ },
84
+ {
85
+ name: "onItemClick",
86
+ when: "单个卡片被点击",
87
+ description: "卡片级跳转与点击埋点"
88
+ },
89
+ {
90
+ name: "onLayoutComplete",
91
+ when: "DOM 落位完成(可安全测量)",
92
+ description: "测量真实高度、懒加载判定、曝光上报"
93
+ },
94
+ {
95
+ name: "renderOverlay",
96
+ when: "每次渲染,滚动容器内的内容层之上",
97
+ description: "回到顶部、加载提示、浮层工具"
98
+ },
99
+ {
100
+ name: "analytics:click",
101
+ when: "卡片点击后",
102
+ description: "广播 { index, key, item, event, total } 点击埋点"
103
+ }
104
+ ], w = [], S = "只读取 context 字段(props / state / data),不调用上下文方法", A = [
105
+ {
106
+ name: "log",
107
+ type: "boolean",
108
+ default: "false",
109
+ description: "是否在控制台打印每次点击"
110
+ },
111
+ {
112
+ name: "showOverlay",
113
+ type: "boolean",
114
+ default: "false",
115
+ description: "是否显示右上角计数角标"
116
+ }
117
+ ], D = `// 统计项点击次数,发 \`analytics:click\` 事件,可选角标与日志。
118
+ const Waterfall = withPlugins(WaterfallCore, [
119
+ createClickAnalyticsPlugin({
120
+ log: false,
121
+ showOverlay: false,
122
+ }),
123
+ ]);
124
+
125
+ <Waterfall items={items} renderItem={(item) => <Card data={item} />} />;`, O = [
126
+ "点击总量 + 按 index 明细(getStats)",
127
+ "bus 事件可被外部订阅上报",
128
+ "角标默认关闭"
129
+ ], I = [
130
+ "内容流点击率统计",
131
+ "AB 实验埋点",
132
+ "调试点击行为"
133
+ ], M = [
134
+ "生产环境请把数据从 bus 事件或 getStats() 接到自己的埋点 SDK,不要让插件直接打日志。",
135
+ "计数只在内存里,刷新即清零 —— 想持久化要自己定时取 getStats() 上报。"
136
+ ], z = {
137
+ name: k,
138
+ description: x,
139
+ since: b,
140
+ tags: C,
141
+ events: v,
142
+ methods: w,
143
+ methodsNote: S,
144
+ config: A,
145
+ example: D,
146
+ features: O,
147
+ useCases: I,
148
+ notes: M
149
+ };
150
+ export {
151
+ W as c,
152
+ z as d
153
+ };