vane-waterfall 2.0.2 → 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 (102) hide show
  1. package/dist/chunks/doc-BAhVW3g8.js +150 -0
  2. package/dist/chunks/{doc-BXaJl1By.js → doc-BU0CKW63.js} +64 -35
  3. package/dist/chunks/{doc-D_ozEn0Q.js → doc-BrEd0oZB.js} +41 -32
  4. package/dist/chunks/{doc-bTHwfIVb.js → doc-Bud0hbaz.js} +39 -25
  5. package/dist/chunks/{doc-DukOmDCo.js → doc-C-B3zK2o.js} +52 -23
  6. package/dist/chunks/{doc-DElLNjIc.js → doc-C206ZwYC.js} +33 -24
  7. package/dist/chunks/{doc-BSnWbrkH.js → doc-C2L8kkeI.js} +49 -25
  8. package/dist/chunks/{doc-a0MK2S3n.js → doc-CE1DGMBV.js} +62 -38
  9. package/dist/chunks/{doc-BXSy2aPP.js → doc-CHbQXLwY.js} +33 -19
  10. package/dist/chunks/{doc-BfWnfTst.js → doc-CInpKZNU.js} +38 -24
  11. package/dist/chunks/{doc-gTAsLjVx.js → doc-CYxwSuG6.js} +30 -16
  12. package/dist/chunks/{doc-DzvTrZ13.js → doc-CaJ02INP.js} +25 -16
  13. package/dist/chunks/{doc-BXElhF2h.js → doc-CiCso5Ti.js} +44 -30
  14. package/dist/chunks/{doc-BCmEnh39.js → doc-CkuMr8Ca.js} +49 -25
  15. package/dist/chunks/{doc-3Fpag2G8.js → doc-D7m1OFCW.js} +38 -24
  16. package/dist/chunks/doc-DEN2WTDh.js +153 -0
  17. package/dist/chunks/{doc-C5xrHNoC.js → doc-DhICh9S2.js} +37 -23
  18. package/dist/chunks/{doc-DAieSXLy.js → doc-DlJICsyN.js} +41 -27
  19. package/dist/chunks/{doc-CN4edvn_.js → doc-DtxS1-P0.js} +32 -23
  20. package/dist/chunks/{doc-BIzjYAZW.js → doc-DudYCn_-.js} +25 -16
  21. package/dist/chunks/{doc-BmoijI6q.js → doc-HoyAFR_m.js} +43 -24
  22. package/dist/chunks/doc-RlBMCMNs.js +170 -0
  23. package/dist/chunks/doc-RwKQqySd.js +102 -0
  24. package/dist/chunks/{doc-CTUoMe7o.js → doc-eYhNJy97.js} +31 -22
  25. package/dist/chunks/{doc-CcPFavOs.js → doc-i6FY1We1.js} +27 -13
  26. package/dist/chunks/doc-skPl6ZMP.js +101 -0
  27. package/dist/chunks/index-8gEIzUxi.js +15 -0
  28. package/dist/chunks/index-B96I5CKE.js +21 -0
  29. package/dist/chunks/index-Bjmhy8jW.js +11 -0
  30. package/dist/chunks/index-Cuq0ofv-.js +13 -0
  31. package/dist/chunks/{index-BAWlVYr3.js → index-Cz4YEqRF.js} +1 -1
  32. package/dist/chunks/{index-CF0tYRop.js → index-FBJVUYmH.js} +1 -1
  33. package/dist/chunks/withPlugins-BOeDFhof.js +743 -0
  34. package/dist/custom-plugins/A11yPlugin/doc.json.d.ts +64 -40
  35. package/dist/custom-plugins/A11yPlugin/index.js +1 -1
  36. package/dist/custom-plugins/AlignmentPlugin/doc.json.d.ts +42 -28
  37. package/dist/custom-plugins/AlignmentPlugin/index.js +1 -1
  38. package/dist/custom-plugins/AutoColumnPlugin/doc.json.d.ts +53 -44
  39. package/dist/custom-plugins/AutoColumnPlugin/index.js +1 -1
  40. package/dist/custom-plugins/BookmarkPlugin/doc.json.d.ts +44 -35
  41. package/dist/custom-plugins/BookmarkPlugin/index.js +1 -1
  42. package/dist/custom-plugins/ClickAnalyticsPlugin/doc.json.d.ts +29 -0
  43. package/dist/custom-plugins/ClickAnalyticsPlugin/index.js +1 -1
  44. package/dist/custom-plugins/DebounceLayoutPlugin/doc.json.d.ts +37 -28
  45. package/dist/custom-plugins/DebounceLayoutPlugin/index.js +1 -1
  46. package/dist/custom-plugins/DragReorderPlugin/doc.json.d.ts +14 -0
  47. package/dist/custom-plugins/DragReorderPlugin/index.js +1 -1
  48. package/dist/custom-plugins/FilterPlugin/doc.json.d.ts +53 -39
  49. package/dist/custom-plugins/FilterPlugin/index.js +1 -1
  50. package/dist/custom-plugins/FixedHeightPlugin/doc.json.d.ts +42 -28
  51. package/dist/custom-plugins/FixedHeightPlugin/index.js +1 -1
  52. package/dist/custom-plugins/GapPlugin/doc.json.d.ts +61 -37
  53. package/dist/custom-plugins/GapPlugin/index.js +1 -1
  54. package/dist/custom-plugins/GroupingPlugin/doc.json.d.ts +61 -32
  55. package/dist/custom-plugins/GroupingPlugin/index.js +1 -1
  56. package/dist/custom-plugins/HeatmapAnalyticsPlugin/doc.json.d.ts +24 -0
  57. package/dist/custom-plugins/HeatmapAnalyticsPlugin/index.js +1 -1
  58. package/dist/custom-plugins/InfiniteScrollPlugin/doc.json.d.ts +55 -36
  59. package/dist/custom-plugins/InfiniteScrollPlugin/index.js +1 -1
  60. package/dist/custom-plugins/PaginationPlugin/doc.json.d.ts +56 -42
  61. package/dist/custom-plugins/PaginationPlugin/index.js +1 -1
  62. package/dist/custom-plugins/PinItemPlugin/doc.json.d.ts +49 -35
  63. package/dist/custom-plugins/PinItemPlugin/index.js +1 -1
  64. package/dist/custom-plugins/RecyclePlugin/doc.json.d.ts +57 -28
  65. package/dist/custom-plugins/RecyclePlugin/index.js +1 -1
  66. package/dist/custom-plugins/ReducedMotionPlugin/doc.json.d.ts +29 -0
  67. package/dist/custom-plugins/ReducedMotionPlugin/index.js +1 -1
  68. package/dist/custom-plugins/ResponsiveColumnsPlugin/doc.json.d.ts +40 -31
  69. package/dist/custom-plugins/ResponsiveColumnsPlugin/index.js +1 -1
  70. package/dist/custom-plugins/ScrollAnchorPlugin/doc.json.d.ts +42 -28
  71. package/dist/custom-plugins/ScrollAnchorPlugin/index.js +1 -1
  72. package/dist/custom-plugins/SearchPlugin/doc.json.d.ts +53 -39
  73. package/dist/custom-plugins/SearchPlugin/index.js +1 -1
  74. package/dist/custom-plugins/SortPlugin/doc.json.d.ts +52 -38
  75. package/dist/custom-plugins/SortPlugin/index.js +1 -1
  76. package/dist/custom-plugins/StatePersistencePlugin/doc.json.d.ts +71 -37
  77. package/dist/custom-plugins/StatePersistencePlugin/index.js +1 -1
  78. package/dist/custom-plugins/StickyHeaderPlugin/doc.json.d.ts +43 -34
  79. package/dist/custom-plugins/StickyHeaderPlugin/index.js +1 -1
  80. package/dist/custom-plugins/ThrottlePlugin/doc.json.d.ts +43 -34
  81. package/dist/custom-plugins/ThrottlePlugin/index.js +1 -1
  82. package/dist/custom-plugins/TransitionPlugin/doc.json.d.ts +49 -35
  83. package/dist/custom-plugins/TransitionPlugin/index.js +1 -1
  84. package/dist/custom-plugins/URLSyncPlugin/doc.json.d.ts +57 -33
  85. package/dist/custom-plugins/URLSyncPlugin/index.js +1 -1
  86. package/dist/custom-plugins/index.js +6 -6
  87. package/dist/entries/plugins.js +7 -7
  88. package/dist/index.js +1 -1
  89. package/dist/presets/dashboard/index.js +2 -2
  90. package/dist/presets/photo-feed/index.js +3 -3
  91. package/dist/presets/product-feed/index.js +2 -2
  92. package/package.json +26 -26
  93. package/dist/chunks/doc-BQQoKNto.js +0 -126
  94. package/dist/chunks/doc-BindRMfO.js +0 -72
  95. package/dist/chunks/doc-CBHjiDG7.js +0 -88
  96. package/dist/chunks/doc-CkU5GtLw.js +0 -136
  97. package/dist/chunks/doc-KN6Bvmty.js +0 -124
  98. package/dist/chunks/index-B8o6R4RZ.js +0 -15
  99. package/dist/chunks/index-BFyYpEY_.js +0 -11
  100. package/dist/chunks/index-CJR0Buju.js +0 -21
  101. package/dist/chunks/index-DHTB3QEP.js +0 -13
  102. package/dist/chunks/withPlugins-DG3YpSgL.js +0 -655
@@ -1,10 +1,10 @@
1
- import { w as r } from "../chunks/withPlugins-DG3YpSgL.js";
2
- import { c as i } from "../chunks/index-CF0tYRop.js";
3
- import { c, a as l, b as s, d as u, e as g, f as o, g as P, h as m, i as p } from "../chunks/index-CJR0Buju.js";
4
- import { c as d, a as x, b as y, d as S } from "../chunks/index-BFyYpEY_.js";
5
- import { c as A, a as b, b as R, d as k, e as C } from "../chunks/index-DHTB3QEP.js";
6
- import { c as w, a as D, b as F, d as G, e as I, f as L } from "../chunks/index-B8o6R4RZ.js";
7
- import { c as v } from "../chunks/index-BAWlVYr3.js";
1
+ import { w as r } from "../chunks/withPlugins-BOeDFhof.js";
2
+ import { c as i } from "../chunks/index-FBJVUYmH.js";
3
+ import { c, a as l, b as s, d as u, e as g, f as o, g as P, h as m, i as p } from "../chunks/index-B96I5CKE.js";
4
+ import { c as d, a as x, b as y, d as S } from "../chunks/index-Bjmhy8jW.js";
5
+ import { c as A, a as b, b as R, d as k, e as C } from "../chunks/index-Cuq0ofv-.js";
6
+ import { c as w, a as D, b as F, d as G, e as I, f as L } from "../chunks/index-8gEIzUxi.js";
7
+ import { c as v } from "../chunks/index-Cz4YEqRF.js";
8
8
  export {
9
9
  i as createA11yPlugin,
10
10
  c as createAlignmentPlugin,
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { W as o, c as t, b as r } from "./chunks/WaterfallCore-EdAZuWAY.js";
2
- import { w as i } from "./chunks/withPlugins-DG3YpSgL.js";
2
+ import { w as i } from "./chunks/withPlugins-BOeDFhof.js";
3
3
  export {
4
4
  o as WaterfallCore,
5
5
  t as computeLayout,
@@ -1,5 +1,5 @@
1
- import { e as s, a as c, b as l, d as n, c as i } from "../../chunks/index-DHTB3QEP.js";
2
- import { c as u } from "../../chunks/index-CF0tYRop.js";
1
+ import { e as s, a as c, b as l, d as n, c as i } from "../../chunks/index-Cuq0ofv-.js";
2
+ import { c as u } from "../../chunks/index-FBJVUYmH.js";
3
3
  function P(r = {}) {
4
4
  const {
5
5
  scrollThrottle: t = 24,
@@ -1,6 +1,6 @@
1
- import { c as r } from "../../chunks/index-CF0tYRop.js";
2
- import { c as i, a as l, d as u, b as c } from "../../chunks/index-BFyYpEY_.js";
3
- import { c as m } from "../../chunks/index-BAWlVYr3.js";
1
+ import { c as r } from "../../chunks/index-FBJVUYmH.js";
2
+ import { c as i, a as l, d as u, b as c } from "../../chunks/index-Bjmhy8jW.js";
3
+ import { c as m } from "../../chunks/index-Cz4YEqRF.js";
4
4
  function g(a = {}) {
5
5
  const { minColumnWidth: n = 240, maxColumns: o = 4, gap: e = 16, threshold: t = 400 } = a;
6
6
  return [
@@ -1,5 +1,5 @@
1
- import { e as o, b as r, a, f as n, d as l, c as s } from "../../chunks/index-B8o6R4RZ.js";
2
- import { c } from "../../chunks/index-BAWlVYr3.js";
1
+ import { e as o, b as r, a, f as n, d as l, c as s } from "../../chunks/index-8gEIzUxi.js";
2
+ import { c } from "../../chunks/index-Cz4YEqRF.js";
3
3
  function p(e = {}) {
4
4
  const { itemHeight: t = 300, pageSize: i = 24 } = e;
5
5
  return [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vane-waterfall",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "description": "React 瀑布流布局组件:插件化、可变高、虚拟化,27 个领域插件",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -168,22 +168,6 @@
168
168
  "url": "https://github.com/frankvane/vane-components/issues"
169
169
  },
170
170
  "homepage": "https://github.com/frankvane/vane-components/tree/main/packages/vane-waterfall#readme",
171
- "scripts": {
172
- "dev": "vite --config demo/vite.config.ts",
173
- "build": "vite build --mode lib",
174
- "build:demo": "vite build --config demo/vite.config.ts",
175
- "typecheck": "tsc --noEmit -p tsconfig.json",
176
- "test": "vitest run",
177
- "lint": "eslint .",
178
- "sync:exports": "node ../../scripts/sync-exports.mjs",
179
- "docs:plugins": "node ../../scripts/generate-plugin-docs.mjs",
180
- "verify:scenarios": "node scripts/verify-scenarios.mjs",
181
- "audit:demos": "node scripts/audit-demos.mjs",
182
- "serve:demo": "node scripts/serve-demo.cjs",
183
- "demo": "pnpm build:demo && node scripts/serve-demo.cjs",
184
- "prepublishOnly": "npm run build",
185
- "audit:controls": "node scripts/audit-controls.mjs"
186
- },
187
171
  "peerDependencies": {
188
172
  "react": ">=16.8.0",
189
173
  "react-dom": ">=16.8.0"
@@ -193,11 +177,6 @@
193
177
  "@types/react": "^18.3.3",
194
178
  "@types/react-dom": "^18.3.0",
195
179
  "@types/react-syntax-highlighter": "^15.5.13",
196
- "@vane/build-config": "*",
197
- "@vane/eslint-config": "*",
198
- "vane-plugin-core": "*",
199
- "@vane/tsconfig": "*",
200
- "@vane/vitest-config": "*",
201
180
  "@vitejs/plugin-react": "^4.3.1",
202
181
  "happy-dom": "^15.11.7",
203
182
  "react": "^18.3.1",
@@ -207,7 +186,12 @@
207
186
  "typescript": "^5.5.3",
208
187
  "vite": "^5.4.1",
209
188
  "vite-plugin-dts": "^4.5.4",
210
- "vitest": "^2.1.9"
189
+ "vitest": "^2.1.9",
190
+ "@vane/build-config": "0.1.0",
191
+ "@vane/tsconfig": "0.1.0",
192
+ "@vane/eslint-config": "0.1.0",
193
+ "@vane/vitest-config": "0.1.0",
194
+ "vane-plugin-core": "0.1.2"
211
195
  },
212
196
  "vane": {
213
197
  "demo": {
@@ -217,13 +201,29 @@
217
201
  "accent": "#ccf24b",
218
202
  "bg": "#080a09"
219
203
  },
220
- "sizeBudgetKb": 14,
221
- "coreSizeBudgetKb": 12
204
+ "sizeBudgetKb": 14.9,
205
+ "coreSizeBudgetKb": 12,
206
+ "sizeBudgetNote": "【2026-11-04 内核修复批次:14→14.9KB】入口实测 14.46KB=内核 withPlugins 共享块 8.24KB(devDep 内联)+ 瀑布流核心/领域槽;内核自 0.1.1 累计 gzip +1.33KB(本轮 +117B)。是否可裁:否——67 个 js 全部可达、0 重复内容。按实测 +3.0% 余量(上限),后续新增功能需先压回或走预算评审。"
222
207
  },
223
208
  "engines": {
224
209
  "node": ">=18"
225
210
  },
226
211
  "publishConfig": {
227
212
  "access": "public"
213
+ },
214
+ "scripts": {
215
+ "dev": "vite --config demo/vite.config.ts",
216
+ "build": "vite build --mode lib",
217
+ "build:demo": "vite build --config demo/vite.config.ts",
218
+ "typecheck": "tsc --noEmit -p tsconfig.json",
219
+ "test": "vitest run",
220
+ "lint": "eslint .",
221
+ "sync:exports": "node ../../scripts/sync-exports.mjs",
222
+ "docs:plugins": "node ../../scripts/generate-plugin-docs.mjs",
223
+ "verify:scenarios": "node scripts/verify-scenarios.mjs",
224
+ "audit:demos": "node scripts/audit-demos.mjs",
225
+ "serve:demo": "node scripts/serve-demo.cjs",
226
+ "demo": "pnpm build:demo && node scripts/serve-demo.cjs",
227
+ "audit:controls": "node scripts/audit-controls.mjs"
228
228
  }
229
- }
229
+ }
@@ -1,126 +0,0 @@
1
- function $(u = {}) {
2
- const p = u.mode || "hash", o = u.keys || ["pageIndex", "pageSize", "searchQuery"];
3
- let h = null, d = !1;
4
- const l = () => (h === null && (h = m()), h);
5
- function m() {
6
- try {
7
- if (p === "hash") {
8
- const a = window.location.hash || "", s = a.indexOf("?"), n = s >= 0 ? a.slice(s + 1) : a.replace(/^#/, ""), e = new URLSearchParams(n), t = {};
9
- return o.forEach((c) => {
10
- const r = e.get(c);
11
- r !== null && (t[c] = r);
12
- }), t;
13
- } else {
14
- const a = new URLSearchParams(window.location.search), s = {};
15
- return o.forEach((n) => {
16
- const e = a.get(n);
17
- e !== null && (s[n] = e);
18
- }), s;
19
- }
20
- } catch {
21
- return {};
22
- }
23
- }
24
- function g(a) {
25
- try {
26
- const s = new URLSearchParams();
27
- o.forEach((e) => {
28
- const t = a[e];
29
- t != null && String(t).length > 0 && s.set(e, String(t));
30
- });
31
- const n = s.toString();
32
- if (p === "hash") {
33
- const e = window.location.hash || "", r = `#${e.replace(/^#/, "").split("?")[0] || ""}${n ? `?${n}` : ""}`;
34
- e !== r && history.replaceState(
35
- null,
36
- "",
37
- `${window.location.pathname}${window.location.search}${r}`
38
- );
39
- } else {
40
- const t = window.location.pathname + (n ? `?${n}` : "") + (window.location.hash || "");
41
- history.replaceState(null, "", t);
42
- }
43
- } catch {
44
- }
45
- }
46
- return {
47
- name: "URLSyncPlugin",
48
- enabled: !0,
49
- hooks: {
50
- // 首次渲染就把 URL 里的值注入 props:旧实现只广播 `urlsync:init`,
51
- // 页面不手动订阅时深链参数根本不会生效(「只写不读」,P2-6)
52
- transformProps: (a) => {
53
- if (d) return a;
54
- const s = l(), n = { ...a };
55
- let e = !1;
56
- return o.forEach((t) => {
57
- s[t] !== void 0 && (n[t] = s[t], e = !0);
58
- }), e && (d = !0), n;
59
- },
60
- onMount: (a) => {
61
- a.bus?.emit("urlsync:init", l());
62
- },
63
- onPropsChange: (a, s, n) => {
64
- const e = {}, t = n ?? {};
65
- o.forEach((i) => {
66
- const f = t[i];
67
- f !== void 0 && (e[i] = f);
68
- });
69
- const c = l();
70
- o.some(
71
- (i) => String(e[i] ?? "") !== String(c[i] ?? "")
72
- ) && g(e);
73
- }
74
- }
75
- };
76
- }
77
- const w = "URLSyncPlugin", S = "props 变化时把指定键写进 URL(hash 或 search),挂载时读出来广播 `urlsync:init`。刷新与分享都能还原筛选状态。", y = "2.0.0", R = [
78
- "ui",
79
- "URL",
80
- "可分享"
81
- ], L = [
82
- {
83
- name: "mode",
84
- type: '"hash" | "search"',
85
- default: '"hash"',
86
- description: "写 hash 还是 search"
87
- },
88
- {
89
- name: "keys",
90
- type: "string[]",
91
- default: '["pageIndex","pageSize","searchQuery"]',
92
- description: "要同步的 props 键"
93
- }
94
- ], P = `// 把分页/搜索/排序同步进 URL(hash 或 search),链接可分享。
95
- const Waterfall = withPlugins(WaterfallCore, [
96
- createURLSyncPlugin({
97
- mode: "hash",
98
- keys: ["pageIndex","pageSize","searchQuery"],
99
- }),
100
- ]);
101
-
102
- <Waterfall items={items} renderItem={(item) => <Card data={item} />} />;`, U = [
103
- "hash 模式会保留已有路由路径",
104
- "用 replaceState,不污染后退栈",
105
- "SSR 安全:无 window 时直接跳过"
106
- ], x = [
107
- "搜索结果可分享",
108
- "后台筛选状态可刷新",
109
- "带参数的深链"
110
- ], v = [
111
- "只做单向同步(props → URL)与初始读取;URL 前进后退的监听请页面自己做。"
112
- ], I = {
113
- name: w,
114
- description: S,
115
- since: y,
116
- tags: R,
117
- config: L,
118
- example: P,
119
- features: U,
120
- useCases: x,
121
- notes: v
122
- };
123
- export {
124
- $ as c,
125
- I as d
126
- };
@@ -1,72 +0,0 @@
1
- function v(s) {
2
- const i = /* @__PURE__ */ new Set(), o = (n) => {
3
- if (i.size <= s.poolSize) return;
4
- const e = i.values().next().value;
5
- if (typeof e == "number") {
6
- i.delete(e);
7
- const t = n.getItemRef(e);
8
- t && (t.style.visibility = "hidden");
9
- }
10
- };
11
- return {
12
- name: "RecyclePlugin",
13
- enabled: !0,
14
- hooks: {
15
- onItemEnterViewport: (n, e) => {
16
- const t = n.getItemRef(e);
17
- t && (t.style.visibility = "visible"), i.add(e), o(n);
18
- },
19
- onItemLeaveViewport: (n, e) => {
20
- const t = n.getItemRef(e);
21
- t && (t.style.visibility = "hidden"), i.delete(e);
22
- },
23
- onItemUnmount: (n, e) => {
24
- i.delete(e);
25
- },
26
- onUnmount: () => {
27
- i.clear();
28
- }
29
- }
30
- };
31
- }
32
- const l = "RecyclePlugin", c = "纯绘制层优化:项离开视口就 `visibility: hidden`,回来再显示。DOM 节点不销毁,滚动位置与已加载的图片都保留,适合「项里有视频/Canvas,重建代价高」的场景。", a = "2.0.0", r = [
33
- "interaction",
34
- "性能"
35
- ], m = [
36
- {
37
- name: "poolSize",
38
- type: "number",
39
- default: "—",
40
- description: "同时保持可见的项数上限(超出则回收最早的)"
41
- }
42
- ], u = `// 视口外的项设 \`visibility: hidden\`,降低长列表的绘制压力。
43
- const Waterfall = withPlugins(WaterfallCore, [
44
- createRecyclePlugin(),
45
- ]);
46
-
47
- <Waterfall items={items} renderItem={(item) => <Card data={item} />} />;`, d = [
48
- "不销毁 DOM,只隐藏",
49
- "项内媒体不重新加载",
50
- "与虚拟化正交(一个省绘制、一个省节点)"
51
- ], f = [
52
- "项内含视频 / canvas",
53
- "长列表滚动发虚",
54
- "低端设备省电"
55
- ], y = [
56
- "与 Core 的 `virtualize` 同开会让项被卸载又隐藏,收益互相抵消,建议只选一个。",
57
- "只改 visibility 不改布局,所以不会引起重排。"
58
- ], g = {
59
- name: l,
60
- description: c,
61
- since: a,
62
- tags: r,
63
- config: m,
64
- example: u,
65
- features: d,
66
- useCases: f,
67
- notes: y
68
- };
69
- export {
70
- v as c,
71
- g as d
72
- };
@@ -1,88 +0,0 @@
1
- function C(t = {}) {
2
- const c = t.fields ?? [];
3
- return {
4
- name: "SearchPlugin",
5
- priority: 20,
6
- enabled: !0,
7
- hooks: {
8
- transformProps: (e) => {
9
- const s = String(e.searchQuery ?? "").trim(), o = Array.isArray(e.items) ? e.items : [];
10
- if (!s) return e;
11
- const n = s.toLowerCase(), a = o.filter((r) => {
12
- if (typeof r != "object" || r === null) return !1;
13
- const i = c.length > 0 ? c : Object.keys(r);
14
- for (const l of i) {
15
- const u = r[l];
16
- if (u != null && String(u).toLowerCase().includes(n)) return !0;
17
- }
18
- return !1;
19
- });
20
- return { ...e, items: a };
21
- },
22
- onPropsChange: (e, s, o) => {
23
- const n = String(s?.searchQuery ?? ""), a = String(o?.searchQuery ?? "");
24
- if (((typeof o?.scrollToTopOnSearchChange == "boolean" ? o.scrollToTopOnSearchChange : void 0) ?? !!t.scrollToTop) && n !== a) {
25
- const l = o?.scrollToTopBehavior ?? t.scrollBehavior ?? "auto";
26
- e.scrollToTop?.({ behavior: l });
27
- }
28
- }
29
- }
30
- };
31
- }
32
- const f = "SearchPlugin", d = "读取 `props.searchQuery`,在指定字段上做大小写不敏感的 `includes` 匹配。没指定字段就对对象的全部自有字段匹配。", h = "2.0.0", m = [
33
- "data",
34
- "数据管线",
35
- "搜索"
36
- ], p = [
37
- {
38
- name: "fields",
39
- type: "(keyof T)[]",
40
- default: "[]",
41
- description: "参与匹配的字段;空则匹配全部自有字段"
42
- },
43
- {
44
- name: "scrollToTop",
45
- type: "boolean",
46
- default: "false",
47
- description: "关键词变化后回顶"
48
- },
49
- {
50
- name: "scrollBehavior",
51
- type: '"auto" | "smooth"',
52
- default: '"auto"',
53
- description: "回顶行为"
54
- }
55
- ], y = `// 按 props.searchQuery 做大小写不敏感的多字段包含匹配。
56
- const Waterfall = withPlugins(WaterfallCore, [
57
- createSearchPlugin({
58
- fields: [],
59
- scrollToTop: false,
60
- scrollBehavior: "auto",
61
- }),
62
- ]);
63
-
64
- <Waterfall items={items} renderItem={(item) => <Card data={item} />} />;`, g = [
65
- "大小写不敏感",
66
- "多字段 OR 匹配",
67
- "空关键词直接放行(不触发过滤)"
68
- ], T = [
69
- "站内搜索结果页",
70
- "后台列表即时搜索",
71
- "商品名 / 店铺名联合搜索"
72
- ], S = [
73
- "纯前端 `includes`,不排序也不做拼音;要相关性排序请在 Search 之后接 SortPlugin。"
74
- ], b = {
75
- name: f,
76
- description: d,
77
- since: h,
78
- tags: m,
79
- config: p,
80
- example: y,
81
- features: g,
82
- useCases: T,
83
- notes: S
84
- };
85
- export {
86
- C as c,
87
- b as d
88
- };
@@ -1,136 +0,0 @@
1
- function x(c = {}) {
2
- const l = c.storageKey || "waterfall-state", u = c.persistScroll ?? !0, a = c.persistKeys || ["pageIndex", "pageSize", "searchQuery"];
3
- let p = !1;
4
- const f = 1, i = /* @__PURE__ */ new WeakSet(), S = (t) => t.containerRef?.current ?? t.bus;
5
- function o() {
6
- try {
7
- const t = localStorage.getItem(l);
8
- if (!t) return null;
9
- const e = JSON.parse(t);
10
- return !e || e.version !== f || typeof e.state != "object" ? null : e.state;
11
- } catch {
12
- return null;
13
- }
14
- }
15
- function d(t) {
16
- try {
17
- localStorage.setItem(l, JSON.stringify({ version: f, state: t }));
18
- } catch {
19
- }
20
- }
21
- return {
22
- name: "StatePersistencePlugin",
23
- enabled: !0,
24
- hooks: {
25
- // 首次渲染时,尽量将本地快照中的分页/查询键注入到 props,便于核心按恢复后的状态渲染
26
- transformProps: (t) => {
27
- if (p) return t;
28
- const e = o();
29
- if (!e) return t;
30
- const n = { ...t };
31
- let s = !1;
32
- return a.forEach((r) => {
33
- e[r] !== void 0 && (n[r] = e[r], s = !0);
34
- }), s && (p = !0), n;
35
- },
36
- onMount: (t) => {
37
- const e = o();
38
- if (!e) return;
39
- const n = {};
40
- if (a.forEach((s) => {
41
- e[s] !== void 0 && (n[s] = e[s]);
42
- }), Object.keys(n).length > 0 && (t.bus?.emit("state:restored", n), typeof window < "u"))
43
- try {
44
- window.dispatchEvent(new CustomEvent("waterfall:state-restored", { detail: n }));
45
- } catch {
46
- }
47
- },
48
- onLayoutComplete: (t) => {
49
- if (!u) return;
50
- const e = S(t);
51
- if (i.has(e)) return;
52
- const n = o(), s = Number(n?.scrollTop ?? 0);
53
- if (!Number.isFinite(s) || s <= 0) {
54
- i.add(e);
55
- return;
56
- }
57
- const r = t.containerRef.current;
58
- r && (r.scrollTo({ top: s, behavior: "auto" }), i.add(e));
59
- },
60
- // props 变化时,增量更新快照(立即持久化分页/查询键)
61
- onPropsChange: (t, e, n) => {
62
- const r = { ...o() || {} }, m = n ?? {};
63
- a.forEach((g) => {
64
- const y = m[g];
65
- y !== void 0 && (r[g] = y);
66
- }), d(r);
67
- },
68
- onUnmount: (t) => {
69
- const e = {};
70
- u && (e.scrollTop = t.containerRef.current?.scrollTop || 0);
71
- const n = t.props ?? {};
72
- a.forEach((s) => {
73
- const r = n[s];
74
- r !== void 0 && (e[s] = r);
75
- }), d(e);
76
- }
77
- }
78
- };
79
- }
80
- const h = "StatePersistencePlugin", w = "三个时机各做一件事:首次渲染把快照里的 pageIndex / searchQuery 注入 props;挂载后恢复 scrollTop;props 变化与卸载时写回快照。刷新页面不丢进度。", v = "2.0.0", P = [
81
- "ui",
82
- "持久化"
83
- ], b = [
84
- {
85
- name: "storageKey",
86
- type: "string",
87
- default: '"waterfall-state"',
88
- description: "localStorage 键名"
89
- },
90
- {
91
- name: "persistScroll",
92
- type: "boolean",
93
- default: "true",
94
- description: "是否持久化滚动位置"
95
- },
96
- {
97
- name: "persistKeys",
98
- type: "string[]",
99
- default: '["pageIndex","pageSize","searchQuery"]',
100
- description: "要持久化的 props 键"
101
- }
102
- ], I = `// 把滚动位置与分页/查询状态存 localStorage,回来时恢复。
103
- const Waterfall = withPlugins(WaterfallCore, [
104
- createStatePersistencePlugin({
105
- storageKey: "waterfall-state",
106
- persistScroll: true,
107
- persistKeys: ["pageIndex","pageSize","searchQuery"],
108
- }),
109
- ]);
110
-
111
- <Waterfall items={items} renderItem={(item) => <Card data={item} />} />;`, C = [
112
- "滚动位置 + 分页/查询一起存",
113
- "首帧注入只做一次,不会覆盖用户操作",
114
- "SSR / 隐私模式下降级为不持久化"
115
- ], E = [
116
- "后台列表刷新不丢页",
117
- "搜索结果返回定位",
118
- "移动端来回切换页面"
119
- ], K = [
120
- "只能恢复「值」,不能替你把它写回 React state——页面应订阅 `state:restored` 事件或读 bus。",
121
- "localStorage 不可用(隐私模式/配额满)时静默跳过,不会抛错。"
122
- ], R = {
123
- name: h,
124
- description: w,
125
- since: v,
126
- tags: P,
127
- config: b,
128
- example: I,
129
- features: C,
130
- useCases: E,
131
- notes: K
132
- };
133
- export {
134
- x as c,
135
- R as d
136
- };