@yuku123/z-frontend-common 1.1.3 → 1.1.4

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.
package/README.md CHANGED
@@ -15,7 +15,7 @@
15
15
  |------|-----|
16
16
  | 仓 | `z-opc-foundation/z-frontend-common`(本仓) |
17
17
  | npm 包 | `@yuku123/z-frontend-common`(scope 沿用 yuku123,与 0.1.x/0.2.x 旧线连续) |
18
- | 当前版本 | `1.1.3` —— 1.0 语义:§1-§16 规范化起点;1.1.x 在其上追加扁平 ui 组件桶。0.1.x 是 pre-§16 形态;0.2.x 内嵌 react-dom 已废弃 |
18
+ | 当前版本 | `1.1.4` —— 1.0 语义:§1-§16 规范化起点;1.1.x 在其上追加扁平 ui 组件桶。0.1.x 是 pre-§16 形态;0.2.x 内嵌 react-dom 已废弃 |
19
19
  | 技术栈 | React 19 + antd 6 + react-router-dom 7 + Vite 6(lead 005 §3.0 版本线单一尺子) |
20
20
  | 产物 | ESM **3 入口**(`formats: ['es']`):`dist/index.js`(主桶)+ `dist/ui.js`(扁平 ui 桶)+ `dist/ui-echarts.js`(`ui/echarts` 子路径) |
21
21
  | 打包策略 | external 精确 **9** 个包 + **1** 条前缀规则(`echarts/*`):react / react-dom / react-dom/client / react/jsx-runtime / react-router-dom / antd / @ant-design/icons / axios / echarts |
@@ -82,4 +82,5 @@ const MOCK_AUTH = { username: 'admin', password: '123456', user: { name: 'admin'
82
82
  - `1.0.0`:独立仓首版 —— 源码自 vendoring 迁入,API 契约兼容 0.1.1,AppLayout/LoginPage 升级 §1-§16 规范版
83
83
  - `1.1.1`:在 1.0.0 之上追加扁平 ui 组件桶(13 个 UI 组件 + design token)与 `ui/echarts` 子路径
84
84
  - `1.1.2`:ui 桶追加 `ComponentDoc`(§7 组件文档页:240px TOC + 正文两栏、滚动联动、锚点跳转、自带零依赖 markdown 引擎,宿主可注册 react-markdown 三件套升级为 GFM + Prism 高亮)
85
+ - `1.1.4`:ui 桶的 `ListTable` 支持 `cardExtra`(Card 动作按钮)与 `searchKeys`(过滤框)**并排**渲染 —— 原实现二选一,会把其中一个静默吞掉(页面同时有「搜索」和「新增」按钮时按钮消失)。
85
86
  - `1.1.3`:ui 桶追加 `useListFilter` / `filterRows`(§2 强制规则 3 的客户端过滤口径统一收在基座:大小写不敏感、多字段「或」匹配、null 字段不参与匹配、空关键字原样返回)与 `ListTable`(§2 规则 2/3/4 的成品件:分页三件套 + Card extra 过滤框 + EmptyState 空态一次到位)
@@ -1,7 +1,7 @@
1
1
  import { jsxs as m, jsx as t, Fragment as Ce } from "react/jsx-runtime";
2
- import { useState as z, useRef as H, useEffect as D, useMemo as q, useCallback as be, useLayoutEffect as Re, createElement as ae, Fragment as O } from "react";
2
+ import { useState as B, useRef as N, useEffect as L, useMemo as q, useCallback as be, useLayoutEffect as Re, createElement as ae, Fragment as O } from "react";
3
3
  import { Button as V, Skeleton as _, Input as Te, Card as me, Table as ye, Breadcrumb as Ee, Space as se, Tag as ce } from "antd";
4
- import { InboxOutlined as Ae, ExclamationCircleOutlined as Ie, ReloadOutlined as re, SearchOutlined as ze, ReadOutlined as Be } from "@ant-design/icons";
4
+ import { InboxOutlined as Ie, ExclamationCircleOutlined as Ae, ReloadOutlined as re, SearchOutlined as ze, ReadOutlined as Be } from "@ant-design/icons";
5
5
  import { useNavigate as xe, useInRouterContext as De } from "react-router-dom";
6
6
  const T = {
7
7
  // 主色 (蓝紫) - 顶导/重点按钮/链接
@@ -83,15 +83,15 @@ const T = {
83
83
  lg: 16,
84
84
  xl: 20,
85
85
  pill: 999
86
- }, B = {
86
+ }, D = {
87
87
  sm: "0 1px 2px 0 rgba(15, 23, 42, 0.04), 0 1px 3px 0 rgba(15, 23, 42, 0.06)",
88
88
  md: "0 2px 4px -1px rgba(15, 23, 42, 0.04), 0 4px 8px -1px rgba(15, 23, 42, 0.08)",
89
89
  lg: "0 4px 6px -2px rgba(15, 23, 42, 0.05), 0 12px 16px -4px rgba(15, 23, 42, 0.10)",
90
90
  xl: "0 8px 24px -6px rgba(15, 23, 42, 0.10), 0 24px 48px -12px rgba(15, 23, 42, 0.18)"
91
91
  }, at = {
92
- rest: B.md,
92
+ rest: D.md,
93
93
  hover: "0 8px 16px -4px rgba(15, 23, 42, 0.08), 0 20px 32px -8px rgba(15, 23, 42, 0.14)"
94
- }, N = {
94
+ }, P = {
95
95
  1: 4,
96
96
  2: 8,
97
97
  3: 12,
@@ -112,7 +112,7 @@ const T = {
112
112
  "2xl": 24,
113
113
  "3xl": 30,
114
114
  "4xl": 36
115
- }, M = {
115
+ }, H = {
116
116
  token: {
117
117
  // 主色
118
118
  colorPrimary: T.primary,
@@ -144,8 +144,8 @@ const T = {
144
144
  fontSize: de.base,
145
145
  fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif",
146
146
  // 阴影
147
- boxShadow: B.md,
148
- boxShadowSecondary: B.lg
147
+ boxShadow: D.md,
148
+ boxShadowSecondary: D.lg
149
149
  },
150
150
  components: {
151
151
  // Layout: 顶导白底更现代
@@ -169,7 +169,7 @@ const T = {
169
169
  // Card: 更柔和
170
170
  Card: {
171
171
  borderRadiusLG: C.lg,
172
- boxShadowTertiary: B.sm
172
+ boxShadowTertiary: D.sm
173
173
  },
174
174
  // Button: 主按钮圆角统一
175
175
  Button: {
@@ -200,28 +200,28 @@ function st({
200
200
  loading: l = !1,
201
201
  precision: i = 0
202
202
  }) {
203
- const d = E[c] || E.blue, [f, g] = z(0), p = H(0);
204
- D(() => {
203
+ const d = E[c] || E.blue, [f, g] = B(0), p = N(0);
204
+ L(() => {
205
205
  if (l || s == null) return;
206
206
  const b = p.current, S = Number(s) || 0;
207
207
  if (b === S) {
208
208
  g(S);
209
209
  return;
210
210
  }
211
- const w = 600, L = performance.now();
212
- let P;
211
+ const w = 600, A = performance.now();
212
+ let $;
213
213
  const G = (U) => {
214
- const j = Math.min(1, (U - L) / w), J = 1 - Math.pow(1 - j, 3), u = b + (S - b) * J;
215
- g(u), j < 1 ? P = requestAnimationFrame(G) : p.current = S;
214
+ const j = Math.min(1, (U - A) / w), J = 1 - Math.pow(1 - j, 3), u = b + (S - b) * J;
215
+ g(u), j < 1 ? $ = requestAnimationFrame(G) : p.current = S;
216
216
  };
217
- return P = requestAnimationFrame(G), () => P && cancelAnimationFrame(P);
217
+ return $ = requestAnimationFrame(G), () => $ && cancelAnimationFrame($);
218
218
  }, [s, l]);
219
219
  const h = () => {
220
220
  r && typeof window < "u" && (window.location.href = r);
221
221
  }, k = l ? "--" : Number(f).toLocaleString("zh-CN", {
222
222
  minimumFractionDigits: i,
223
223
  maximumFractionDigits: i
224
- }), v = a != null ? Number(a) : null, A = v != null && v >= 0;
224
+ }), v = a != null ? Number(a) : null, I = v != null && v >= 0;
225
225
  return /* @__PURE__ */ m(
226
226
  "div",
227
227
  {
@@ -230,10 +230,10 @@ function st({
230
230
  position: "relative",
231
231
  background: d.gradient,
232
232
  borderRadius: C.lg,
233
- padding: N[5],
233
+ padding: P[5],
234
234
  color: d.fg,
235
235
  cursor: r ? "pointer" : "default",
236
- boxShadow: B.md,
236
+ boxShadow: D.md,
237
237
  overflow: "hidden",
238
238
  transition: "transform 200ms ease, box-shadow 200ms ease",
239
239
  minHeight: 110,
@@ -242,10 +242,10 @@ function st({
242
242
  justifyContent: "space-between"
243
243
  },
244
244
  onMouseEnter: (b) => {
245
- b.currentTarget.style.transform = "translateY(-2px)", b.currentTarget.style.boxShadow = B.lg;
245
+ b.currentTarget.style.transform = "translateY(-2px)", b.currentTarget.style.boxShadow = D.lg;
246
246
  },
247
247
  onMouseLeave: (b) => {
248
- b.currentTarget.style.transform = "translateY(0)", b.currentTarget.style.boxShadow = B.md;
248
+ b.currentTarget.style.transform = "translateY(0)", b.currentTarget.style.boxShadow = D.md;
249
249
  },
250
250
  children: [
251
251
  /* @__PURE__ */ t(
@@ -266,7 +266,7 @@ function st({
266
266
  /* @__PURE__ */ m("div", { style: {
267
267
  display: "flex",
268
268
  alignItems: "center",
269
- gap: N[2],
269
+ gap: P[2],
270
270
  position: "relative"
271
271
  }, children: [
272
272
  /* @__PURE__ */ t("div", { style: {
@@ -289,9 +289,9 @@ function st({
289
289
  /* @__PURE__ */ m("div", { style: {
290
290
  display: "flex",
291
291
  alignItems: "baseline",
292
- gap: N[2],
292
+ gap: P[2],
293
293
  position: "relative",
294
- marginTop: N[3]
294
+ marginTop: P[3]
295
295
  }, children: [
296
296
  /* @__PURE__ */ t("div", { style: {
297
297
  fontSize: 30,
@@ -307,12 +307,12 @@ function st({
307
307
  fontWeight: 600,
308
308
  padding: "2px 8px",
309
309
  borderRadius: 999,
310
- background: A ? "rgba(255, 255, 255, 0.22)" : "rgba(0, 0, 0, 0.18)",
310
+ background: I ? "rgba(255, 255, 255, 0.22)" : "rgba(0, 0, 0, 0.18)",
311
311
  display: "flex",
312
312
  alignItems: "center",
313
313
  gap: 2
314
314
  }, children: [
315
- /* @__PURE__ */ t("span", { style: { fontSize: 10 }, children: A ? "▲" : "▼" }),
315
+ /* @__PURE__ */ t("span", { style: { fontSize: 10 }, children: I ? "▲" : "▼" }),
316
316
  Math.abs(v).toFixed(1),
317
317
  "%"
318
318
  ] })
@@ -406,7 +406,7 @@ function dt({
406
406
  href: l,
407
407
  extra: i
408
408
  }) {
409
- const d = E[c] || E.violet, [f, g] = z(!1);
409
+ const d = E[c] || E.violet, [f, g] = B(!1);
410
410
  return /* @__PURE__ */ m(
411
411
  "div",
412
412
  {
@@ -420,7 +420,7 @@ function dt({
420
420
  borderRadius: C.lg,
421
421
  overflow: "hidden",
422
422
  cursor: l ? "pointer" : "default",
423
- boxShadow: f ? B.lg : B.sm,
423
+ boxShadow: f ? D.lg : D.sm,
424
424
  transform: f ? "translateY(-2px)" : "translateY(0)",
425
425
  transition: "transform 200ms ease, box-shadow 200ms ease",
426
426
  border: "1px solid #f1f5f9",
@@ -469,10 +469,10 @@ function dt({
469
469
  }, children: i })
470
470
  ] }),
471
471
  /* @__PURE__ */ m("div", { style: {
472
- padding: N[4],
472
+ padding: P[4],
473
473
  display: "flex",
474
474
  flexDirection: "column",
475
- gap: N[2],
475
+ gap: P[2],
476
476
  flex: 1
477
477
  }, children: [
478
478
  a.length > 0 && /* @__PURE__ */ t("div", { style: {
@@ -523,7 +523,7 @@ function dt({
523
523
  fontSize: 11,
524
524
  color: "#9ca3af",
525
525
  marginTop: "auto",
526
- paddingTop: N[2],
526
+ paddingTop: P[2],
527
527
  borderTop: "1px dashed #f1f5f9"
528
528
  }, children: r })
529
529
  ] })
@@ -546,7 +546,7 @@ function ft({
546
546
  background: "linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #312e81 100%)",
547
547
  color: "#ffffff",
548
548
  overflow: "hidden",
549
- boxShadow: B.lg
549
+ boxShadow: D.lg
550
550
  }, children: [
551
551
  /* @__PURE__ */ t("div", { style: {
552
552
  position: "absolute",
@@ -670,7 +670,7 @@ function ne({
670
670
  marginBottom: 16,
671
671
  fontSize: 28,
672
672
  color: "#9ca3af"
673
- }, children: e || /* @__PURE__ */ t(Ae, {}) }),
673
+ }, children: e || /* @__PURE__ */ t(Ie, {}) }),
674
674
  /* @__PURE__ */ t("div", { style: {
675
675
  fontSize: i[a],
676
676
  fontWeight: 600,
@@ -741,7 +741,7 @@ function $e({
741
741
  color: "#dc2626",
742
742
  fontSize: l ? 28 : 18,
743
743
  flexShrink: 0
744
- }, children: /* @__PURE__ */ t(Ie, {}) }),
744
+ }, children: /* @__PURE__ */ t(Ae, {}) }),
745
745
  /* @__PURE__ */ m("div", { style: { flex: 1, minWidth: 0 }, children: [
746
746
  /* @__PURE__ */ t("div", { style: {
747
747
  fontSize: l ? 16 : 14,
@@ -872,10 +872,10 @@ function We({
872
872
  enterButton: l,
873
873
  ...i
874
874
  }) {
875
- const [d, f] = z(e || ""), g = H(null), p = H(e || "");
876
- D(() => {
875
+ const [d, f] = B(e || ""), g = N(null), p = N(e || "");
876
+ L(() => {
877
877
  e !== void 0 && e !== d && (f(e || ""), p.current = e || "");
878
- }, [e]), D(() => () => {
878
+ }, [e]), L(() => () => {
879
879
  g.current && clearTimeout(g.current);
880
880
  }, []);
881
881
  const h = (S) => {
@@ -923,7 +923,7 @@ function Me(e, n, s) {
923
923
  })) : o;
924
924
  }
925
925
  function He(e, n) {
926
- const [s, o] = z(""), c = (Array.isArray(n) ? n.join(",") : String(n || "")).trim(), a = q(
926
+ const [s, o] = B(""), c = (Array.isArray(n) ? n.join(",") : String(n || "")).trim(), a = q(
927
927
  () => Me(e, c, s),
928
928
  [e, c, s]
929
929
  ), r = be(() => o(""), []);
@@ -952,10 +952,9 @@ function ut({
952
952
  pagination: h = Ne,
953
953
  cardProps: k = {},
954
954
  tableProps: v = {},
955
- ...A
955
+ ...I
956
956
  }) {
957
- const { keyword: b, setKeyword: S, filtered: w } = He(e, c);
958
- return /* @__PURE__ */ t(me, { title: l, extra: (c ? /* @__PURE__ */ t(
957
+ const { keyword: b, setKeyword: S, filtered: w } = He(e, c), A = c ? /* @__PURE__ */ t(
959
958
  We,
960
959
  {
961
960
  allowClear: !0,
@@ -964,7 +963,11 @@ function ut({
964
963
  value: b,
965
964
  onChange: S
966
965
  }
967
- ) : null) || i, ...k, children: /* @__PURE__ */ t(
966
+ ) : null;
967
+ return /* @__PURE__ */ t(me, { title: l, extra: A && i ? /* @__PURE__ */ m("span", { style: { display: "inline-flex", alignItems: "center", gap: 8 }, children: [
968
+ A,
969
+ i
970
+ ] }) : A || i, ...k, children: /* @__PURE__ */ t(
968
971
  ye,
969
972
  {
970
973
  rowKey: s,
@@ -985,7 +988,7 @@ function ut({
985
988
  )
986
989
  },
987
990
  ...v,
988
- ...A
991
+ ...I
989
992
  }
990
993
  ) });
991
994
  }
@@ -1149,15 +1152,15 @@ function bt({ status: e, type: n = "task", mapping: s, ...o }) {
1149
1152
  return a ? /* @__PURE__ */ t(ce, { color: a.color, ...o, children: a.label }) : /* @__PURE__ */ t(ce, { ...o, children: String(e) });
1150
1153
  }
1151
1154
  function mt({ title: e, description: n, load: s, columns: o, rowKey: c = "id", extra: a, expandable: r }) {
1152
- const [l, i] = z([]), [d, f] = z({ current: 1, size: 10, total: null }), [g, p] = z(!1), [h, k] = z(null), v = be(async (b = d.current, S = d.size) => {
1155
+ const [l, i] = B([]), [d, f] = B({ current: 1, size: 10, total: null }), [g, p] = B(!1), [h, k] = B(null), v = be(async (b = d.current, S = d.size) => {
1153
1156
  p(!0), k(null);
1154
1157
  try {
1155
1158
  const w = await s(b, S);
1156
1159
  if (Array.isArray(w))
1157
1160
  i(w || []), f({ current: b, size: S, total: w.length });
1158
1161
  else {
1159
- const L = (w == null ? void 0 : w.records) || [];
1160
- i(L), f({ current: b, size: S, total: (w == null ? void 0 : w.total) == null ? null : Number(w.total) });
1162
+ const A = (w == null ? void 0 : w.records) || [];
1163
+ i(A), f({ current: b, size: S, total: (w == null ? void 0 : w.total) == null ? null : Number(w.total) });
1161
1164
  }
1162
1165
  } catch (w) {
1163
1166
  i([]), k(w);
@@ -1165,10 +1168,10 @@ function mt({ title: e, description: n, load: s, columns: o, rowKey: c = "id", e
1165
1168
  p(!1);
1166
1169
  }
1167
1170
  }, [s, d.current, d.size]);
1168
- D(() => {
1171
+ L(() => {
1169
1172
  v(1);
1170
1173
  }, []);
1171
- const A = d.total != null && d.total > 0;
1174
+ const I = d.total != null && d.total > 0;
1172
1175
  return /* @__PURE__ */ m("div", { children: [
1173
1176
  /* @__PURE__ */ t(ve, { title: e, subtitle: n }),
1174
1177
  /* @__PURE__ */ m(
@@ -1196,9 +1199,9 @@ function mt({ title: e, description: n, load: s, columns: o, rowKey: c = "id", e
1196
1199
  pagination: {
1197
1200
  current: d.current,
1198
1201
  pageSize: d.size,
1199
- total: A ? d.total : l.length,
1202
+ total: I ? d.total : l.length,
1200
1203
  showSizeChanger: !0,
1201
- showTotal: () => A ? `共 ${d.total} 条` : `本页 ${l.length} 条(接口 total 未返回有效值)`
1204
+ showTotal: () => I ? `共 ${d.total} 条` : `本页 ${l.length} 条(接口 total 未返回有效值)`
1202
1205
  },
1203
1206
  onChange: (b) => v(b.current, b.pageSize),
1204
1207
  expandable: r,
@@ -1357,7 +1360,7 @@ function we(e, n = !1) {
1357
1360
  }
1358
1361
  return s;
1359
1362
  }
1360
- const I = (e, n) => {
1363
+ const z = (e, n) => {
1361
1364
  const s = [];
1362
1365
  let o = 0, c = 0;
1363
1366
  const a = (r) => s.push(/* @__PURE__ */ t(O, { children: r }, `i${c++}`));
@@ -1366,10 +1369,10 @@ const I = (e, n) => {
1366
1369
  if (r[0].startsWith("!"))
1367
1370
  a(n.img ? n.img({ src: r[3], alt: r[2] }) : /* @__PURE__ */ t("img", { src: r[3], alt: r[2] || "" }));
1368
1371
  else {
1369
- const l = I(r[2], n);
1372
+ const l = z(r[2], n);
1370
1373
  a(n.a ? n.a({ href: r[3], children: l }) : /* @__PURE__ */ t("a", { href: r[3], children: l }));
1371
1374
  }
1372
- else r[4] !== void 0 ? a(n.code ? n.code({ children: r[4] }) : /* @__PURE__ */ t("code", { children: r[4] })) : r[5] !== void 0 ? a(/* @__PURE__ */ t("strong", { children: I(r[5], n) })) : r[6] !== void 0 ? a(/* @__PURE__ */ t("strong", { children: I(r[6], n) })) : r[7] !== void 0 ? a(/* @__PURE__ */ t("del", { children: I(r[7], n) })) : r[8] !== void 0 ? a(/* @__PURE__ */ t("em", { children: I(r[8], n) })) : r[9] !== void 0 && a(n.a ? n.a({ href: r[9], children: r[9] }) : /* @__PURE__ */ t("a", { href: r[9], children: r[9] }));
1375
+ else r[4] !== void 0 ? a(n.code ? n.code({ children: r[4] }) : /* @__PURE__ */ t("code", { children: r[4] })) : r[5] !== void 0 ? a(/* @__PURE__ */ t("strong", { children: z(r[5], n) })) : r[6] !== void 0 ? a(/* @__PURE__ */ t("strong", { children: z(r[6], n) })) : r[7] !== void 0 ? a(/* @__PURE__ */ t("del", { children: z(r[7], n) })) : r[8] !== void 0 ? a(/* @__PURE__ */ t("em", { children: z(r[8], n) })) : r[9] !== void 0 && a(n.a ? n.a({ href: r[9], children: r[9] }) : /* @__PURE__ */ t("a", { href: r[9], children: r[9] }));
1373
1376
  o = r.index + r[0].length;
1374
1377
  }
1375
1378
  return o < e.length && a(e.slice(o)), s;
@@ -1378,10 +1381,10 @@ const I = (e, n) => {
1378
1381
  return e.forEach((c, a) => {
1379
1382
  const r = `b${a}`, l = (i) => o.push(/* @__PURE__ */ t(O, { children: i }, r));
1380
1383
  if (c.type === "heading") {
1381
- const i = Math.min(c.level, 6), d = `h${i}`, f = n[d], g = I(c.text, n), p = i <= 3 ? s(ie(c.text)) : void 0;
1384
+ const i = Math.min(c.level, 6), d = `h${i}`, f = n[d], g = z(c.text, n), p = i <= 3 ? s(ie(c.text)) : void 0;
1382
1385
  l(f ? f({ children: g, id: p }) : ae(d, { id: p }, g));
1383
1386
  } else if (c.type === "paragraph") {
1384
- const i = I(c.text, n);
1387
+ const i = z(c.text, n);
1385
1388
  l(n.p ? n.p({ children: i }) : /* @__PURE__ */ t("p", { children: i }));
1386
1389
  } else if (c.type === "code") {
1387
1390
  const i = /* @__PURE__ */ t("code", { className: c.lang ? `language-${c.lang}` : void 0, children: c.text });
@@ -1394,16 +1397,16 @@ const I = (e, n) => {
1394
1397
  l(d ? d({ children: f }) : ae(i, null, f));
1395
1398
  } else if (c.type === "table") {
1396
1399
  const i = /* @__PURE__ */ t("thead", { children: /* @__PURE__ */ t("tr", { children: c.header.map((g, p) => {
1397
- const h = n.th ? n.th({ children: I(g, n), align: c.aligns[p] }) : /* @__PURE__ */ t("th", { children: g });
1400
+ const h = n.th ? n.th({ children: z(g, n), align: c.aligns[p] }) : /* @__PURE__ */ t("th", { children: g });
1398
1401
  return /* @__PURE__ */ t(O, { children: h }, `th${p}`);
1399
1402
  }) }) }, "thead"), d = /* @__PURE__ */ t("tbody", { children: c.rows.map((g, p) => /* @__PURE__ */ t("tr", { children: g.map((h, k) => {
1400
- const v = n.td ? n.td({ children: I(h, n), align: c.aligns[k] }) : /* @__PURE__ */ t("td", { children: h });
1403
+ const v = n.td ? n.td({ children: z(h, n), align: c.aligns[k] }) : /* @__PURE__ */ t("td", { children: h });
1401
1404
  return /* @__PURE__ */ t(O, { children: v }, `td${k}`);
1402
1405
  }) }, `tr${p}`)) }, "tbody"), f = n.table ? n.table({ children: [i, d] }) : /* @__PURE__ */ t("table", { children: [i, d] });
1403
1406
  l(f);
1404
1407
  } else if (c.type === "quote") {
1405
1408
  const i = c.lines.filter((d) => d.trim()).map((d, f) => {
1406
- const g = n.p ? n.p({ children: I(d, n) }) : /* @__PURE__ */ t("p", { children: d });
1409
+ const g = n.p ? n.p({ children: z(d, n) }) : /* @__PURE__ */ t("p", { children: d });
1407
1410
  return /* @__PURE__ */ t(O, { children: g }, `q${f}`);
1408
1411
  });
1409
1412
  l(n.blockquote ? n.blockquote({ children: i }) : /* @__PURE__ */ t("blockquote", { children: i }));
@@ -1451,7 +1454,7 @@ const he = /* @__PURE__ */ new Set(), tt = ({ navigate: e, Prism: n, oneDark: s,
1451
1454
  blockquote: ({ node: a, children: r, ...l }) => /* @__PURE__ */ t("blockquote", { ...l, style: {
1452
1455
  margin: "12px 0",
1453
1456
  padding: "8px 14px",
1454
- borderLeft: `3px solid ${M.token.colorPrimary}`,
1457
+ borderLeft: `3px solid ${H.token.colorPrimary}`,
1455
1458
  background: T.primarySoft,
1456
1459
  color: "#475569",
1457
1460
  borderRadius: 4
@@ -1500,7 +1503,7 @@ const he = /* @__PURE__ */ new Set(), tt = ({ navigate: e, Prism: n, oneDark: s,
1500
1503
  href: d,
1501
1504
  target: "_blank",
1502
1505
  rel: "noopener noreferrer",
1503
- style: { color: M.token.colorPrimary },
1506
+ style: { color: H.token.colorPrimary },
1504
1507
  children: l
1505
1508
  }
1506
1509
  ) : d.startsWith("#") ? /* @__PURE__ */ t(
@@ -1508,7 +1511,7 @@ const he = /* @__PURE__ */ new Set(), tt = ({ navigate: e, Prism: n, oneDark: s,
1508
1511
  {
1509
1512
  ...i,
1510
1513
  href: d,
1511
- style: { color: M.token.colorPrimary },
1514
+ style: { color: H.token.colorPrimary },
1512
1515
  onClick: (g) => o(g, d.slice(1)),
1513
1516
  children: l
1514
1517
  }
@@ -1517,13 +1520,13 @@ const he = /* @__PURE__ */ new Set(), tt = ({ navigate: e, Prism: n, oneDark: s,
1517
1520
  {
1518
1521
  ...i,
1519
1522
  href: d,
1520
- style: { color: M.token.colorPrimary },
1523
+ style: { color: H.token.colorPrimary },
1521
1524
  onClick: (g) => {
1522
1525
  g.preventDefault(), e ? e(d) : typeof window < "u" && (window.location.href = d);
1523
1526
  },
1524
1527
  children: l
1525
1528
  }
1526
- ) : /* @__PURE__ */ t("a", { ...i, href: d, style: { color: M.token.colorPrimary }, children: l });
1529
+ ) : /* @__PURE__ */ t("a", { ...i, href: d, style: { color: H.token.colorPrimary }, children: l });
1527
1530
  }
1528
1531
  };
1529
1532
  };
@@ -1536,12 +1539,12 @@ function yt({
1536
1539
  markdownComponents: a,
1537
1540
  renderMarkdown: r
1538
1541
  }) {
1539
- const i = De() ? xe() : null, d = H(null), f = H(null), g = H(""), p = H(null), [h, k] = z(""), [v, A] = z(0), b = q(() => Ve(e), [e]), S = q(
1542
+ const i = De() ? xe() : null, d = N(null), f = N(null), g = N(""), p = N(null), [h, k] = B(""), [v, I] = B(0), b = q(() => Ve(e), [e]), S = q(
1540
1543
  () => b.filter((u) => o.includes(u.level)),
1541
1544
  [b, o]
1542
1545
  );
1543
- D(() => {
1544
- const u = () => A((y) => y + 1);
1546
+ L(() => {
1547
+ const u = () => I((y) => y + 1);
1545
1548
  return he.add(u), () => {
1546
1549
  he.delete(u);
1547
1550
  };
@@ -1551,17 +1554,17 @@ function yt({
1551
1554
  g.current = "";
1552
1555
  }, 700);
1553
1556
  };
1554
- D(() => () => {
1557
+ L(() => () => {
1555
1558
  p.current && clearTimeout(p.current);
1556
1559
  }, []), Re(() => {
1557
1560
  const u = d.current;
1558
1561
  if (!u) return;
1559
1562
  const y = Array.from(u.querySelectorAll("h1, h2, h3"));
1560
- b.forEach((R, $) => {
1561
- const W = y[$];
1562
- W && (W.id !== R.id && (W.id = R.id), W.setAttribute("data-anchor", R.id));
1563
+ b.forEach((R, W) => {
1564
+ const M = y[W];
1565
+ M && (M.id !== R.id && (M.id = R.id), M.setAttribute("data-anchor", R.id));
1563
1566
  });
1564
- }, [b, v, r]), D(() => {
1567
+ }, [b, v, r]), L(() => {
1565
1568
  const u = d.current;
1566
1569
  if (!u) return;
1567
1570
  const y = Array.from(u.querySelectorAll("h1, h2, h3"));
@@ -1573,33 +1576,33 @@ function yt({
1573
1576
  if (le.getBoundingClientRect().top - Q <= fe) oe = le;
1574
1577
  else break;
1575
1578
  g.current || k(oe.id);
1576
- }, $ = new IntersectionObserver(R, {
1579
+ }, W = new IntersectionObserver(R, {
1577
1580
  root: u,
1578
1581
  rootMargin: `-${fe}px 0px 0px 0px`,
1579
1582
  threshold: 0
1580
1583
  });
1581
- y.forEach((Q) => $.observe(Q)), R();
1582
- const W = () => {
1584
+ y.forEach((Q) => W.observe(Q)), R();
1585
+ const M = () => {
1583
1586
  g.current = "";
1584
1587
  };
1585
- return u.addEventListener("scrollend", W), () => {
1586
- $.disconnect(), u.removeEventListener("scrollend", W);
1588
+ return u.addEventListener("scrollend", M), () => {
1589
+ W.disconnect(), u.removeEventListener("scrollend", M);
1587
1590
  };
1588
- }, [b, v, r]), D(() => {
1591
+ }, [b, v, r]), L(() => {
1589
1592
  const u = f.current;
1590
1593
  if (!u || !h) return;
1591
1594
  const y = u.querySelector(`[data-toc-id="${ge(h)}"]`);
1592
1595
  if (!y) return;
1593
- const R = u.getBoundingClientRect(), $ = y.getBoundingClientRect();
1594
- ($.top < R.top + 24 || $.bottom > R.bottom - 24) && y.scrollIntoView({ block: "nearest", behavior: "smooth" });
1596
+ const R = u.getBoundingClientRect(), W = y.getBoundingClientRect();
1597
+ (W.top < R.top + 24 || W.bottom > R.bottom - 24) && y.scrollIntoView({ block: "nearest", behavior: "smooth" });
1595
1598
  }, [h]);
1596
- const L = (u) => {
1599
+ const A = (u) => {
1597
1600
  const y = d.current;
1598
1601
  return y && y.querySelector(`[data-anchor="${ge(u)}"]`) || (typeof document < "u" ? document.getElementById(u) : null);
1599
- }, P = (u, y) => {
1600
- u.preventDefault(), w(y), ue(L(y)), k(y);
1602
+ }, $ = (u, y) => {
1603
+ u.preventDefault(), w(y), ue(A(y)), k(y);
1601
1604
  }, G = (u, y) => {
1602
- u.preventDefault(), w(y), ue(L(y)), k(y);
1605
+ u.preventDefault(), w(y), ue(A(y)), k(y);
1603
1606
  }, U = q(
1604
1607
  () => tt({
1605
1608
  navigate: i,
@@ -1659,13 +1662,13 @@ function yt({
1659
1662
  "a",
1660
1663
  {
1661
1664
  href: "#" + u.id,
1662
- onClick: (R) => P(R, u.id),
1665
+ onClick: (R) => $(R, u.id),
1663
1666
  style: {
1664
1667
  display: "block",
1665
1668
  padding: "6px 10px",
1666
- borderLeft: `3px solid ${y ? M.token.colorPrimary : "transparent"}`,
1669
+ borderLeft: `3px solid ${y ? H.token.colorPrimary : "transparent"}`,
1667
1670
  background: y ? T.primarySoft : "transparent",
1668
- color: y ? M.token.colorPrimary : "#475569",
1671
+ color: y ? H.token.colorPrimary : "#475569",
1669
1672
  fontWeight: y ? 600 : 400,
1670
1673
  fontSize: 13,
1671
1674
  lineHeight: 1.5,
@@ -1723,15 +1726,15 @@ export {
1723
1726
  mt as e,
1724
1727
  ct as f,
1725
1728
  bt as g,
1726
- M as h,
1729
+ H as h,
1727
1730
  T as i,
1728
1731
  Me as j,
1729
1732
  de as k,
1730
1733
  at as l,
1731
- N as m,
1734
+ P as m,
1732
1735
  x as n,
1733
1736
  E as p,
1734
1737
  C as r,
1735
- B as s,
1738
+ D as s,
1736
1739
  He as u
1737
1740
  };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as be, a as we, D as Ie, b as ke, E as Ce, c as Re, F as ve, G as Le, L as ze, d as Me, P as Be, e as Oe, R as Te, S as je, f as Ee, g as $e, T as De, h as Ke, i as Fe, j as Pe, k as qe, l as He, n as Ne, p as We, r as Ge, s as Je, m as _e, u as Ae } from "./ComponentDoc-CJL2TB6b.js";
1
+ import { C as be, a as we, D as Ie, b as ke, E as Ce, c as Re, F as ve, G as Le, L as ze, d as Me, P as Be, e as Oe, R as Te, S as je, f as Ee, g as $e, T as De, h as Ke, i as Fe, j as Pe, k as qe, l as He, n as Ne, p as We, r as Ge, s as Je, m as _e, u as Ae } from "./ComponentDoc-22ujWxLE.js";
2
2
  import { jsxs as h, jsx as r } from "react/jsx-runtime";
3
3
  import { Layout as I, Spin as j, Menu as E, Dropdown as $, Avatar as D, Button as k, Tooltip as K, Card as F, Alert as P, Form as x, Input as L, message as S, Tag as q, Result as H } from "antd";
4
4
  import { MenuUnfoldOutlined as N, MenuFoldOutlined as W, DownOutlined as G, LoginOutlined as J, UserOutlined as _, LockOutlined as A } from "@ant-design/icons";
package/dist/ui.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as e, a as t, D as r, b as o, E as n, c as d, F as i, G as l, L as S, d as u, P as T, e as p, R as b, S as f, f as g, g as c, T as h, h as m, i as C, j as D, k as L, l as E, n as F, p as P, r as A, s as B, m as G, u as I } from "./ComponentDoc-CJL2TB6b.js";
1
+ import { C as e, a as t, D as r, b as o, E as n, c as d, F as i, G as l, L as S, d as u, P as T, e as p, R as b, S as f, f as g, g as c, T as h, h as m, i as C, j as D, k as L, l as E, n as F, p as P, r as A, s as B, m as G, u as I } from "./ComponentDoc-22ujWxLE.js";
2
2
  export {
3
3
  e as CategoryDot,
4
4
  t as ComponentDoc,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuku123/z-frontend-common",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "z-opc 全仓共享前端基座 — AppLayout(§1/§11/§12/§15/§16) + LoginPage(mockAuth 双模式) + EmptyState/StatusTag/ErrorBoundary + createRequest 工厂。lead 008 前端开发规范唯一承载仓",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,6 +21,8 @@ import useListFilter from './useListFilter'
21
21
  *
22
22
  * 透传约定:
23
23
  * - `cardProps` → 传给外层 `<Card>`(如 `style` / `size` / `title`)
24
+ * - `cardExtra` → 传给外层 `<Card>` 的 `extra`(动作按钮)。若同时给了 `searchKeys`,
25
+ * 过滤框与 extra **并排**渲染,不会二选一吞掉另一个。
24
26
  * - `tableProps` → 传给内层 `<Table>`(如 `scroll` / `columns` 之外的表级属性)
25
27
  * - 其余 props → 直接给 `<Table>`(与 antd 一致)
26
28
  * - `pagination={false}` 仍然允许显式传(用于「数据已知 ≤10 行且不变」的豁免场景,
@@ -67,8 +69,19 @@ export default function ListTable({
67
69
  )
68
70
  : null
69
71
 
72
+ // Card 的 extra 可以同时挂「过滤框」和「动作按钮」(例如「关系」表既有搜索又有「新增」)。
73
+ // 二选一会把其中一个静默吞掉,所以这里两个都有就并排渲染。
74
+ const extra = (search && cardExtra)
75
+ ? (
76
+ <span style={{display: 'inline-flex', alignItems: 'center', gap: 8}}>
77
+ {search}
78
+ {cardExtra}
79
+ </span>
80
+ )
81
+ : (search || cardExtra)
82
+
70
83
  return (
71
- <Card title={cardTitle} extra={search || cardExtra} {...cardProps}>
84
+ <Card title={cardTitle} extra={extra} {...cardProps}>
72
85
  <Table
73
86
  rowKey={rowKey}
74
87
  columns={columns}