weifuwu 0.36.2 → 0.38.0

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 (51) hide show
  1. package/README.md +141 -3
  2. package/dist/client/app.d.ts +4 -7
  3. package/dist/client/confirm.d.ts +26 -0
  4. package/dist/client/focus-trap.d.ts +4 -0
  5. package/dist/client/i18n.d.ts +27 -0
  6. package/dist/client/index.d.ts +8 -0
  7. package/dist/client/index.js +322 -60
  8. package/dist/client/locale/en_US.d.ts +34 -0
  9. package/dist/client/locale/zh_CN.d.ts +34 -0
  10. package/dist/client/scroll-lock.d.ts +5 -0
  11. package/dist/components/Accordion/Accordion.d.ts +11 -0
  12. package/dist/components/Alert/Alert.d.ts +9 -0
  13. package/dist/components/Avatar/Avatar.d.ts +7 -0
  14. package/dist/components/Badge/Badge.d.ts +8 -0
  15. package/dist/components/Breadcrumb/Breadcrumb.d.ts +9 -0
  16. package/dist/components/Button/Button.d.ts +12 -0
  17. package/dist/components/Card/Card.d.ts +9 -0
  18. package/dist/components/Checkbox/Checkbox.d.ts +8 -0
  19. package/dist/components/Divider/Divider.d.ts +6 -0
  20. package/dist/components/Drawer/Drawer.d.ts +14 -0
  21. package/dist/components/Dropdown/Dropdown.d.ts +14 -0
  22. package/dist/components/EmptyState/EmptyState.d.ts +8 -0
  23. package/dist/components/Field/Field.d.ts +9 -0
  24. package/dist/components/FileUpload/FileUpload.d.ts +13 -0
  25. package/dist/components/Form/Form.d.ts +6 -0
  26. package/dist/components/Img/Img.d.ts +17 -0
  27. package/dist/components/Input/Input.d.ts +14 -0
  28. package/dist/components/Loading/Loading.d.ts +5 -0
  29. package/dist/components/Modal/Modal.d.ts +12 -0
  30. package/dist/components/PageHeader/PageHeader.d.ts +7 -0
  31. package/dist/components/Pagination/Pagination.d.ts +8 -0
  32. package/dist/components/Popover/Popover.d.ts +26 -0
  33. package/dist/components/ProgressBar/ProgressBar.d.ts +8 -0
  34. package/dist/components/RadioGroup/RadioGroup.d.ts +14 -0
  35. package/dist/components/SearchInput/SearchInput.d.ts +8 -0
  36. package/dist/components/Select/Select.d.ts +18 -0
  37. package/dist/components/Skeleton/Skeleton.d.ts +21 -0
  38. package/dist/components/Slider/Slider.d.ts +10 -0
  39. package/dist/components/StatCard/StatCard.d.ts +9 -0
  40. package/dist/components/Steps/Steps.d.ts +12 -0
  41. package/dist/components/Switch/Switch.d.ts +8 -0
  42. package/dist/components/Table/Table.d.ts +13 -0
  43. package/dist/components/Tabs/Tabs.d.ts +12 -0
  44. package/dist/components/Tag/Tag.d.ts +8 -0
  45. package/dist/components/Textarea/Textarea.d.ts +13 -0
  46. package/dist/components/Toast/Toast.d.ts +12 -0
  47. package/dist/components/Tooltip/Tooltip.d.ts +9 -0
  48. package/dist/components/index.d.ts +81 -0
  49. package/dist/components/index.js +1064 -0
  50. package/dist/components/style.css +2005 -0
  51. package/package.json +7 -2
@@ -29,6 +29,58 @@ function normalizeProps(props) {
29
29
  }
30
30
 
31
31
  // src/client/render.ts
32
+ var mutationMethods = ["push", "pop", "splice", "shift", "unshift", "sort", "reverse"];
33
+ var wrappedCache = /* @__PURE__ */ new WeakMap();
34
+ function wrapDeep(val, dirty) {
35
+ if (val === null || typeof val !== "object") return val;
36
+ if (val instanceof Node) return val;
37
+ if (typeof Blob !== "undefined" && val instanceof Blob) return val;
38
+ if (wrappedCache.has(val)) return wrappedCache.get(val);
39
+ const handler = Array.isArray(val) ? {
40
+ get(target, key, receiver) {
41
+ const v = Reflect.get(target, key, receiver);
42
+ if (typeof key === "string" && mutationMethods.includes(key) && typeof v === "function") {
43
+ return function(...args) {
44
+ const r = v.apply(target, args);
45
+ dirty();
46
+ return r;
47
+ };
48
+ }
49
+ return wrapDeep(v, dirty);
50
+ },
51
+ set(target, key, v) {
52
+ Reflect.set(target, key, wrapDeep(v, dirty));
53
+ dirty();
54
+ return true;
55
+ }
56
+ } : {
57
+ get(_target, key, receiver) {
58
+ const v = Reflect.get(_target, key, receiver);
59
+ return wrapDeep(v, dirty);
60
+ },
61
+ set(target, key, v) {
62
+ Reflect.set(target, key, wrapDeep(v, dirty));
63
+ dirty();
64
+ return true;
65
+ }
66
+ };
67
+ const proxy = new Proxy(val, handler);
68
+ wrappedCache.set(val, proxy);
69
+ return proxy;
70
+ }
71
+ function createComponentProxy(target, dirty) {
72
+ return new Proxy(target, {
73
+ set(t, k, v) {
74
+ if (t[k] === v) return true;
75
+ t[k] = wrapDeep(v, dirty);
76
+ dirty();
77
+ return true;
78
+ },
79
+ get(t, k) {
80
+ return wrapDeep(t[k], dirty);
81
+ }
82
+ });
83
+ }
32
84
  function render(input, ctx) {
33
85
  return renderValue(input, ctx);
34
86
  }
@@ -66,6 +118,8 @@ function renderComponent(Comp, props, vnode, ctx) {
66
118
  if (!prev$) vnode._$ = {};
67
119
  ctx.ui = ctx.ui ?? {};
68
120
  ctx.ui.ready = !!prev$;
121
+ const _target = vnode._$;
122
+ ctx.ui.$ = createComponentProxy(_target, () => ctx.ui?.dirty?.());
69
123
  let childVNode;
70
124
  try {
71
125
  childVNode = Comp(props, ctx);
@@ -169,6 +223,8 @@ function patchValue(parent, oldNode, oldInput, newInput, ctx) {
169
223
  if (oldV._$) newV._$ = oldV._$;
170
224
  ctx.ui = ctx.ui ?? {};
171
225
  ctx.ui.ready = !!newV._$;
226
+ const _tgt = newV._$;
227
+ ctx.ui.$ = createComponentProxy(_tgt, () => ctx.ui?.dirty?.());
172
228
  const childNew = comp(newV.props, ctx);
173
229
  newV._child = childNew;
174
230
  return patchValue(parent, oldNode, oldV._child, childNew, ctx);
@@ -211,7 +267,9 @@ function patchProps(el, oldProps, newProps) {
211
267
  const newKeys = newProps ? Object.keys(newProps).filter((k) => k !== "children" && k !== "key" && k !== "ref") : [];
212
268
  for (const key of oldKeys) {
213
269
  if (!newKeys.includes(key)) {
214
- if (key === "value" && (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement)) {
270
+ if (key.startsWith("on") && typeof oldProps[key] === "function") {
271
+ el.removeEventListener(key.slice(2).toLowerCase(), oldProps[key]);
272
+ } else if (key === "value" && (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement)) {
215
273
  ;
216
274
  el.value = "";
217
275
  } else {
@@ -277,6 +335,14 @@ function normalize(children) {
277
335
  return result;
278
336
  }
279
337
  function patchSimpleChildren(parent, oldChildren, newChildren, ctx) {
338
+ for (let i = oldChildren.length - 1; i >= newChildren.length; i--) {
339
+ const oldChild = oldChildren[i];
340
+ const node = parent.childNodes[i];
341
+ if (node) {
342
+ callRefCleanup(oldChild);
343
+ node.remove();
344
+ }
345
+ }
280
346
  const max = Math.max(oldChildren.length, newChildren.length);
281
347
  for (let i = 0; i < max; i++) {
282
348
  const oldChild = oldChildren[i];
@@ -285,12 +351,7 @@ function patchSimpleChildren(parent, oldChildren, newChildren, ctx) {
285
351
  if (oldChild === void 0 && newChild !== void 0) {
286
352
  const node = renderValue(newChild, ctx);
287
353
  parent.appendChild(node);
288
- } else if (newChild === void 0) {
289
- if (existingNode) {
290
- callRefCleanup(oldChild);
291
- existingNode.remove();
292
- }
293
- } else {
354
+ } else if (oldChild !== void 0 && newChild !== void 0) {
294
355
  patchValue(parent, existingNode, oldChild, newChild, ctx);
295
356
  }
296
357
  }
@@ -413,18 +474,21 @@ function router(opts) {
413
474
  params[match.keys[i]] = decodeURIComponent(m[i + 1]);
414
475
  }
415
476
  }
477
+ const last = match.chain[match.chain.length - 1];
416
478
  return {
417
479
  path: match.def.path,
418
480
  params,
419
481
  query: Object.fromEntries(new URLSearchParams(window.location.search)),
420
- chain: match.chain
482
+ chain: match.chain,
483
+ title: last?.title ?? ""
421
484
  };
422
485
  }
423
- return { path, params: {}, query: {}, chain: [] };
486
+ return { path, params: {}, query: {}, chain: [], title: "" };
424
487
  }
425
488
  return (ctx) => {
426
489
  const resolved = resolve(getPath());
427
490
  ctx.route = resolved;
491
+ if (resolved.title) document.title = resolved.title;
428
492
  if (!ctx.app) ctx.app = {};
429
493
  ctx.app.navigate = (path) => {
430
494
  if (mode === "hash") {
@@ -436,11 +500,13 @@ function router(opts) {
436
500
  const resolved2 = resolve(path);
437
501
  ctx.route = resolved2;
438
502
  }
503
+ if (ctx.route?.title) document.title = ctx.route.title;
439
504
  ctx.ui?.render();
440
505
  };
441
506
  const onPop = () => {
442
507
  const resolved2 = resolve(getPath());
443
508
  ctx.route = resolved2;
509
+ if (ctx.route?.title) document.title = ctx.route.title;
444
510
  ctx.ui?.render();
445
511
  };
446
512
  window.addEventListener("popstate", onPop);
@@ -466,48 +532,6 @@ function RouteView(_props, ctx) {
466
532
  }
467
533
 
468
534
  // src/client/app.ts
469
- var mutationMethods = ["push", "pop", "splice", "shift", "unshift", "sort", "reverse"];
470
- var wrappedCache = /* @__PURE__ */ new WeakMap();
471
- function wrapDeep(val, dirty) {
472
- if (val === null || typeof val !== "object") return val;
473
- if (val instanceof Node) return val;
474
- if (wrappedCache.has(val)) return wrappedCache.get(val);
475
- let proxy;
476
- if (Array.isArray(val)) {
477
- proxy = new Proxy(val, {
478
- get(target, key, receiver) {
479
- const v = Reflect.get(target, key, receiver);
480
- if (typeof key === "string" && mutationMethods.includes(key) && typeof v === "function") {
481
- return function(...args) {
482
- const r = v.apply(target, args);
483
- dirty();
484
- return r;
485
- };
486
- }
487
- return wrapDeep(v, dirty);
488
- },
489
- set(target, key, val2) {
490
- target[key] = wrapDeep(val2, dirty);
491
- dirty();
492
- return true;
493
- }
494
- });
495
- } else {
496
- proxy = new Proxy(val, {
497
- get(_target, key, receiver) {
498
- const v = Reflect.get(_target, key, receiver);
499
- return wrapDeep(v, dirty);
500
- },
501
- set(target, key, val2) {
502
- target[key] = wrapDeep(val2, dirty);
503
- dirty();
504
- return true;
505
- }
506
- });
507
- }
508
- wrappedCache.set(val, proxy);
509
- return proxy;
510
- }
511
535
  function createApp() {
512
536
  const middlewares = [];
513
537
  let ctx = {};
@@ -542,7 +566,7 @@ function createApp() {
542
566
  ctx.ui.render();
543
567
  });
544
568
  }
545
- const $target = {};
569
+ ;
546
570
  ctx.ui = {
547
571
  render: () => {
548
572
  if (!container || !rootComponent || !oldVNode) return;
@@ -559,13 +583,11 @@ function createApp() {
559
583
  dirty: () => {
560
584
  scheduleRender();
561
585
  },
562
- $: new Proxy($target, {
563
- set(_target, key, val) {
564
- _target[key] = wrapDeep(val, scheduleRender);
565
- scheduleRender();
566
- return true;
567
- }
568
- }),
586
+ /**
587
+ * 组件级 $ — 在 renderComponent 中被覆盖为每个组件独立的 Proxy。
588
+ * 这里保留占位,组件实际使用 ctx.ui.$ 时拿到的是 vnode._$ 上的 Proxy。
589
+ */
590
+ $: {},
569
591
  ready: false
570
592
  };
571
593
  oldVNode = wrapComponent(RootComponent, ctx);
@@ -875,6 +897,239 @@ function ErrorBoundary(props, ctx) {
875
897
  return fb ?? null;
876
898
  }
877
899
  }
900
+
901
+ // src/client/locale/zh_CN.ts
902
+ var zhCN = {
903
+ components: {
904
+ Button: { loading: "\u52A0\u8F7D\u4E2D..." },
905
+ FileUpload: {
906
+ placeholder: "\u70B9\u51FB\u6216\u62D6\u62FD\u4E0A\u4F20\u6587\u4EF6",
907
+ supportedFormats: "\u652F\u6301\u683C\u5F0F: ",
908
+ maxSize: "\u6700\u5927 ",
909
+ remove: "\u5220\u9664"
910
+ },
911
+ Pagination: { ariaLabel: "\u5206\u9875" },
912
+ ProgressBar: { ariaLabel: "\u8FDB\u5EA6" },
913
+ Switch: { ariaLabel: "\u5207\u6362" },
914
+ Breadcrumb: { ariaLabel: "\u9762\u5305\u5C51" },
915
+ Modal: { ariaLabel: "\u5F39\u7A97" },
916
+ Drawer: { ariaLabel: "\u4FA7\u8FB9\u9762\u677F" }
917
+ }
918
+ };
919
+
920
+ // src/client/locale/en_US.ts
921
+ var enUS = {
922
+ components: {
923
+ Button: { loading: "Loading..." },
924
+ FileUpload: {
925
+ placeholder: "Click or drag to upload",
926
+ supportedFormats: "Supported formats: ",
927
+ maxSize: "Max size: ",
928
+ remove: "Remove"
929
+ },
930
+ Pagination: { ariaLabel: "Pagination" },
931
+ ProgressBar: { ariaLabel: "Progress" },
932
+ Switch: { ariaLabel: "Toggle" },
933
+ Breadcrumb: { ariaLabel: "Breadcrumb" },
934
+ Modal: { ariaLabel: "Dialog" },
935
+ Drawer: { ariaLabel: "Panel" }
936
+ }
937
+ };
938
+
939
+ // src/client/i18n.ts
940
+ var LOCALE_PACKAGES = {
941
+ "zh-CN": zhCN,
942
+ "en-US": enUS
943
+ };
944
+ function resolveLang(locale) {
945
+ if (LOCALE_PACKAGES[locale]) return locale;
946
+ const prefix = locale.split("-")[0];
947
+ const match = Object.keys(LOCALE_PACKAGES).find((k) => k.startsWith(prefix));
948
+ return match ?? "zh-CN";
949
+ }
950
+ function i18n(opts = {}) {
951
+ const { locale: raw = "zh-CN", messages = {}, components = {} } = opts;
952
+ const lang = resolveLang(raw);
953
+ const pkg = LOCALE_PACKAGES[lang];
954
+ let merged = mergeLocales(pkg, messages, components);
955
+ const state = {
956
+ locale: lang,
957
+ t: (key, fallback) => merged.messages?.[key] ?? fallback ?? key,
958
+ setLocale: () => {
959
+ },
960
+ components: merged.components
961
+ };
962
+ return (ctx) => {
963
+ ;
964
+ ctx.i18n = state;
965
+ state.setLocale = (raw2) => {
966
+ const lang2 = resolveLang(raw2);
967
+ const pkg2 = LOCALE_PACKAGES[lang2];
968
+ if (!pkg2) return;
969
+ merged = mergeLocales(pkg2, messages, components);
970
+ state.locale = lang2;
971
+ state.components = merged.components;
972
+ ctx?.ui?.render();
973
+ };
974
+ return ctx;
975
+ };
976
+ }
977
+ function mergeLocales(pkg, userMessages, userComponents) {
978
+ return {
979
+ messages: { ...pkg?.messages, ...userMessages },
980
+ components: deepMerge(pkg?.components ?? {}, userComponents)
981
+ };
982
+ }
983
+ function deepMerge(a, b) {
984
+ const result = { ...a };
985
+ for (const key of Object.keys(b)) {
986
+ if (typeof b[key] === "object" && b[key] !== null && typeof result[key] === "object") {
987
+ result[key] = { ...result[key], ...b[key] };
988
+ } else {
989
+ result[key] = b[key];
990
+ }
991
+ }
992
+ return result;
993
+ }
994
+
995
+ // src/client/scroll-lock.ts
996
+ var lockedCount = 0;
997
+ var originalOverflow = "";
998
+ var originalPosition = "";
999
+ var originalTop = "";
1000
+ var originalWidth = "";
1001
+ var scrollY = 0;
1002
+ function canLock() {
1003
+ return typeof window !== "undefined" && typeof document !== "undefined";
1004
+ }
1005
+ function lockScroll() {
1006
+ lockedCount++;
1007
+ if (lockedCount > 1) return;
1008
+ if (!canLock()) return;
1009
+ scrollY = window.scrollY;
1010
+ const body = document.body;
1011
+ originalOverflow = body.style.overflow;
1012
+ originalPosition = body.style.position;
1013
+ originalTop = body.style.top;
1014
+ originalWidth = body.style.width;
1015
+ body.style.overflow = "hidden";
1016
+ const isIOS = /iPhone|iPad|iPod/.test(navigator.platform) || /Mac/.test(navigator.platform) && "ontouchend" in document;
1017
+ if (isIOS) {
1018
+ body.style.position = "fixed";
1019
+ body.style.top = `-${scrollY}px`;
1020
+ body.style.width = "100%";
1021
+ }
1022
+ }
1023
+ function unlockScroll() {
1024
+ lockedCount--;
1025
+ if (lockedCount > 0) return;
1026
+ if (!canLock()) return;
1027
+ const body = document.body;
1028
+ body.style.overflow = originalOverflow;
1029
+ body.style.position = originalPosition;
1030
+ body.style.top = originalTop;
1031
+ body.style.width = originalWidth;
1032
+ if (scrollY > 0) window.scrollTo(0, scrollY);
1033
+ }
1034
+
1035
+ // src/client/focus-trap.ts
1036
+ var FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
1037
+ function trapFocus(container) {
1038
+ const focusable = container.querySelectorAll(FOCUSABLE);
1039
+ if (focusable.length === 0) return () => {
1040
+ };
1041
+ const first = focusable[0];
1042
+ const last = focusable[focusable.length - 1];
1043
+ const handler = (e) => {
1044
+ if (e.key !== "Tab") return;
1045
+ if (e.shiftKey && document.activeElement === first) {
1046
+ e.preventDefault();
1047
+ last.focus();
1048
+ } else if (!e.shiftKey && document.activeElement === last) {
1049
+ e.preventDefault();
1050
+ first.focus();
1051
+ }
1052
+ };
1053
+ const prevFocused = document.activeElement;
1054
+ first.focus();
1055
+ container.addEventListener("keydown", handler);
1056
+ return () => {
1057
+ container.removeEventListener("keydown", handler);
1058
+ prevFocused?.focus();
1059
+ };
1060
+ }
1061
+
1062
+ // src/client/confirm.ts
1063
+ function createConfirmModal(message, options) {
1064
+ return new Promise((resolve) => {
1065
+ const {
1066
+ title = "\u786E\u8BA4\u64CD\u4F5C",
1067
+ confirmText = "\u786E\u5B9A",
1068
+ cancelText = "\u53D6\u6D88",
1069
+ variant = "primary"
1070
+ } = options;
1071
+ const overlay = document.createElement("div");
1072
+ overlay.className = "wf-modal";
1073
+ overlay.style.cssText = "position:fixed;inset:0;z-index:10000;display:flex;align-items:center;justify-content:center";
1074
+ const bg = document.createElement("div");
1075
+ bg.style.cssText = "position:fixed;inset:0;background:rgba(0,0,0,0.4);z-index:-1";
1076
+ const box = document.createElement("div");
1077
+ box.style.cssText = `background:var(--wf-color-bg,#fff);border-radius:var(--wf-radius-md,8px);box-shadow:var(--wf-shadow-lg,0 4px 24px rgba(0,0,0,0.12));min-width:360px;max-width:90vw;z-index:1`;
1078
+ if (title) {
1079
+ const header = document.createElement("div");
1080
+ header.style.cssText = "display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--wf-color-border,#e5e7eb);font-family:var(--wf-font-sans);font-size:var(--wf-font-size-lg);font-weight:var(--wf-font-weight-semibold);color:var(--wf-color-text);line-height:1.4";
1081
+ header.textContent = title;
1082
+ box.appendChild(header);
1083
+ }
1084
+ const body = document.createElement("div");
1085
+ body.style.cssText = "padding:20px;font-family:var(--wf-font-sans);font-size:var(--wf-font-size-sm);color:var(--wf-color-text);line-height:var(--wf-line-height-normal)";
1086
+ body.textContent = message;
1087
+ box.appendChild(body);
1088
+ const footer = document.createElement("div");
1089
+ footer.style.cssText = "display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:12px 20px;border-top:1px solid var(--wf-color-border,#e5e7eb)";
1090
+ const cancelBtn = document.createElement("button");
1091
+ cancelBtn.className = "wf-btn wf-btn--secondary wf-btn--md";
1092
+ cancelBtn.textContent = cancelText;
1093
+ const confirmBtn = document.createElement("button");
1094
+ confirmBtn.className = `wf-btn wf-btn--${variant} wf-btn--md`;
1095
+ confirmBtn.textContent = confirmText;
1096
+ footer.appendChild(cancelBtn);
1097
+ footer.appendChild(confirmBtn);
1098
+ box.appendChild(footer);
1099
+ overlay.appendChild(bg);
1100
+ overlay.appendChild(box);
1101
+ document.body.appendChild(overlay);
1102
+ lockScroll();
1103
+ const close = (result) => {
1104
+ unlockScroll();
1105
+ overlay.remove();
1106
+ resolve(result);
1107
+ };
1108
+ const onKeyDown = (e) => {
1109
+ if (e.key === "Escape") close(false);
1110
+ };
1111
+ document.addEventListener("keydown", onKeyDown);
1112
+ cancelBtn.onclick = () => {
1113
+ document.removeEventListener("keydown", onKeyDown);
1114
+ close(false);
1115
+ };
1116
+ confirmBtn.onclick = () => {
1117
+ document.removeEventListener("keydown", onKeyDown);
1118
+ close(true);
1119
+ };
1120
+ bg.onclick = () => {
1121
+ document.removeEventListener("keydown", onKeyDown);
1122
+ close(false);
1123
+ };
1124
+ });
1125
+ }
1126
+ function confirm() {
1127
+ return (ctx) => {
1128
+ ;
1129
+ ctx.confirm = (message, options) => createConfirmModal(message, options ?? {});
1130
+ return ctx;
1131
+ };
1132
+ }
878
1133
  export {
879
1134
  ApiError,
880
1135
  ErrorBoundary,
@@ -882,12 +1137,19 @@ export {
882
1137
  RouteView,
883
1138
  api,
884
1139
  auth,
1140
+ confirm,
885
1141
  createApp,
1142
+ enUS,
886
1143
  extendCtx,
887
1144
  h,
1145
+ i18n,
888
1146
  jsx,
889
1147
  jsxDEV,
890
1148
  jsxs,
1149
+ lockScroll,
891
1150
  router,
892
- ws
1151
+ trapFocus,
1152
+ unlockScroll,
1153
+ ws,
1154
+ zhCN
893
1155
  };
@@ -0,0 +1,34 @@
1
+ /**
2
+ * weifuwu i18n — 英文组件文案
3
+ */
4
+ export declare const enUS: {
5
+ components: {
6
+ Button: {
7
+ loading: string;
8
+ };
9
+ FileUpload: {
10
+ placeholder: string;
11
+ supportedFormats: string;
12
+ maxSize: string;
13
+ remove: string;
14
+ };
15
+ Pagination: {
16
+ ariaLabel: string;
17
+ };
18
+ ProgressBar: {
19
+ ariaLabel: string;
20
+ };
21
+ Switch: {
22
+ ariaLabel: string;
23
+ };
24
+ Breadcrumb: {
25
+ ariaLabel: string;
26
+ };
27
+ Modal: {
28
+ ariaLabel: string;
29
+ };
30
+ Drawer: {
31
+ ariaLabel: string;
32
+ };
33
+ };
34
+ };
@@ -0,0 +1,34 @@
1
+ /**
2
+ * weifuwu i18n — 中文组件文案(缺省值)
3
+ */
4
+ export declare const zhCN: {
5
+ components: {
6
+ Button: {
7
+ loading: string;
8
+ };
9
+ FileUpload: {
10
+ placeholder: string;
11
+ supportedFormats: string;
12
+ maxSize: string;
13
+ remove: string;
14
+ };
15
+ Pagination: {
16
+ ariaLabel: string;
17
+ };
18
+ ProgressBar: {
19
+ ariaLabel: string;
20
+ };
21
+ Switch: {
22
+ ariaLabel: string;
23
+ };
24
+ Breadcrumb: {
25
+ ariaLabel: string;
26
+ };
27
+ Modal: {
28
+ ariaLabel: string;
29
+ };
30
+ Drawer: {
31
+ ariaLabel: string;
32
+ };
33
+ };
34
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * weifuwu/client — ScrollLock
3
+ */
4
+ export declare function lockScroll(): void;
5
+ export declare function unlockScroll(): void;
@@ -0,0 +1,11 @@
1
+ import type { Component } from '../../client/vnode.ts';
2
+ export interface AccordionItem {
3
+ key: string;
4
+ title: string;
5
+ content?: any;
6
+ }
7
+ export interface AccordionProps {
8
+ items?: AccordionItem[];
9
+ multiple?: boolean;
10
+ }
11
+ export declare const Accordion: Component<AccordionProps>;
@@ -0,0 +1,9 @@
1
+ import type { Component } from '../../client/vnode.ts';
2
+ export type AlertVariant = 'info' | 'success' | 'warning' | 'error';
3
+ export interface AlertProps {
4
+ variant?: AlertVariant;
5
+ closable?: boolean;
6
+ onClose?: () => void;
7
+ children?: any;
8
+ }
9
+ export declare const Alert: Component<AlertProps>;
@@ -0,0 +1,7 @@
1
+ import type { Component } from '../../client/vnode.ts';
2
+ export interface AvatarProps {
3
+ name?: string;
4
+ src?: string;
5
+ size?: 'sm' | 'md' | 'lg';
6
+ }
7
+ export declare const Avatar: Component<AvatarProps>;
@@ -0,0 +1,8 @@
1
+ import type { Component } from '../../client/vnode.ts';
2
+ export type BadgeVariant = 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info';
3
+ export interface BadgeProps {
4
+ variant?: BadgeVariant;
5
+ dot?: boolean;
6
+ children?: any;
7
+ }
8
+ export declare const Badge: Component<BadgeProps>;
@@ -0,0 +1,9 @@
1
+ import type { Component } from '../../client/vnode.ts';
2
+ export interface BreadcrumbItem {
3
+ label: string;
4
+ href?: string;
5
+ }
6
+ export interface BreadcrumbProps {
7
+ items: BreadcrumbItem[];
8
+ }
9
+ export declare const Breadcrumb: Component<BreadcrumbProps>;
@@ -0,0 +1,12 @@
1
+ import type { Component } from '../../client/vnode.ts';
2
+ export interface ButtonProps {
3
+ variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
4
+ size?: 'sm' | 'md' | 'lg';
5
+ block?: boolean;
6
+ loading?: boolean;
7
+ disabled?: boolean;
8
+ type?: 'button' | 'submit';
9
+ onClick?: (e: MouseEvent) => void;
10
+ children?: any;
11
+ }
12
+ export declare const Button: Component<ButtonProps>;
@@ -0,0 +1,9 @@
1
+ import type { Component } from '../../client/vnode.ts';
2
+ export interface CardProps {
3
+ variant?: 'default' | 'outlined';
4
+ padding?: 'sm' | 'md' | 'lg';
5
+ clickable?: boolean;
6
+ onClick?: () => void;
7
+ children?: any;
8
+ }
9
+ export declare const Card: Component<CardProps>;
@@ -0,0 +1,8 @@
1
+ import type { Component } from '../../client/vnode.ts';
2
+ export interface CheckboxProps {
3
+ label?: string;
4
+ checked?: boolean;
5
+ disabled?: boolean;
6
+ onChange?: (checked: boolean) => void;
7
+ }
8
+ export declare const Checkbox: Component<CheckboxProps>;
@@ -0,0 +1,6 @@
1
+ import type { Component } from '../../client/vnode.ts';
2
+ export interface DividerProps {
3
+ vertical?: boolean;
4
+ children?: any;
5
+ }
6
+ export declare const Divider: Component<DividerProps>;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * weifuwu/components — Drawer
3
+ */
4
+ import type { Component } from '../../client/vnode.ts';
5
+ export type DrawerPosition = 'left' | 'right';
6
+ export interface DrawerProps {
7
+ open?: boolean;
8
+ title?: string;
9
+ position?: DrawerPosition;
10
+ onClose?: () => void;
11
+ children?: any;
12
+ footer?: any;
13
+ }
14
+ export declare const Drawer: Component<DrawerProps>;
@@ -0,0 +1,14 @@
1
+ import type { Component } from '../../client/vnode.ts';
2
+ export interface DropdownItem {
3
+ label: string;
4
+ value?: string;
5
+ disabled?: boolean;
6
+ variant?: 'default' | 'danger';
7
+ onClick?: () => void;
8
+ }
9
+ export interface DropdownProps {
10
+ trigger: any;
11
+ items?: DropdownItem[];
12
+ open?: boolean;
13
+ }
14
+ export declare const Dropdown: Component<DropdownProps>;