@will-ui/vue 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/dist/components/btn/Btn.d.ts +4 -7
  2. package/dist/components/btn/Btn.js +1 -0
  3. package/dist/components/btn/Btn.js.map +1 -1
  4. package/dist/components/cascade/Cascade.d.ts +1 -1
  5. package/dist/components/choose/Choose.d.ts +4 -2
  6. package/dist/components/choose2/Choose2.d.ts +1 -1
  7. package/dist/components/confirm/index.d.ts +3 -4
  8. package/dist/components/confirm/index.js.map +1 -1
  9. package/dist/components/copy/Copy.d.ts +8 -8
  10. package/dist/components/copy/Copy.js +3 -2
  11. package/dist/components/copy/Copy.js.map +1 -1
  12. package/dist/components/cornerEars/CornerEars.d.ts +4 -7
  13. package/dist/components/cornerEars/CornerEars.js +1 -0
  14. package/dist/components/cornerEars/CornerEars.js.map +1 -1
  15. package/dist/components/date/DatePanel.d.ts +4 -0
  16. package/dist/components/date/DatePanel.js +2 -2
  17. package/dist/components/date/DatePanel.js.map +1 -1
  18. package/dist/components/date/DatePicker.d.ts +1 -1
  19. package/dist/components/date/DatePicker.js +4 -4
  20. package/dist/components/date/DatePicker.js.map +1 -1
  21. package/dist/components/date/Days.d.ts +2 -4
  22. package/dist/components/date/Days.js +1 -3
  23. package/dist/components/date/Days.js.map +1 -1
  24. package/dist/components/date/Months.d.ts +2 -4
  25. package/dist/components/date/Months.js +1 -3
  26. package/dist/components/date/Months.js.map +1 -1
  27. package/dist/components/date/QuickDate.d.ts +2 -12
  28. package/dist/components/date/QuickDate.js +1 -1
  29. package/dist/components/date/QuickDate.js.map +1 -1
  30. package/dist/components/date/Years.d.ts +3 -6
  31. package/dist/components/date/Years.js +1 -8
  32. package/dist/components/date/Years.js.map +1 -1
  33. package/dist/components/form/_use/formRules.d.ts +1 -1
  34. package/dist/components/form/_use/formRules.js.map +1 -1
  35. package/dist/components/formItem/FormItem.js.map +1 -1
  36. package/dist/components/image/Image.d.ts +5 -7
  37. package/dist/components/image/Image.js +3 -2
  38. package/dist/components/image/Image.js.map +1 -1
  39. package/dist/components/index.js +9 -9
  40. package/dist/components/modal/Modal.d.ts +1 -1
  41. package/dist/components/modal/Modal.js +29 -24
  42. package/dist/components/modal/Modal.js.map +1 -1
  43. package/dist/components/notice/src/_util/index.d.ts +1 -1
  44. package/dist/components/notice/src/_util/index.js.map +1 -1
  45. package/dist/components/number/Number copy.d.ts +1 -1
  46. package/dist/components/number/Number.d.ts +1 -1
  47. package/dist/components/pagination/src/Pagination.d.ts +6 -4
  48. package/dist/components/picture/Picture.d.ts +5 -7
  49. package/dist/components/picture/Picture.js +6 -5
  50. package/dist/components/picture/Picture.js.map +1 -1
  51. package/dist/components/picture/PictureViewport.js +22 -32
  52. package/dist/components/picture/PictureViewport.js.map +1 -1
  53. package/dist/components/progress/Progress.d.ts +1 -1
  54. package/dist/components/scrollbar/Scrollbar.js +61 -78
  55. package/dist/components/scrollbar/Scrollbar.js.map +1 -1
  56. package/dist/components/sheet/Sheet.d.ts +3 -1
  57. package/dist/components/sheet/_cell.js +16 -27
  58. package/dist/components/sheet/_cell.js.map +1 -1
  59. package/dist/components/slider/Slider.d.ts +2 -2
  60. package/dist/components/slider/Slider.js +24 -41
  61. package/dist/components/slider/Slider.js.map +1 -1
  62. package/dist/components/tab/Tab.d.ts +3 -3
  63. package/dist/components/tab/Tab.js +6 -0
  64. package/dist/components/tab/Tab.js.map +1 -1
  65. package/dist/components/textarea/Textarea.d.ts +5 -13
  66. package/dist/components/textarea/Textarea.js +3 -2
  67. package/dist/components/textarea/Textarea.js.map +1 -1
  68. package/dist/components/time/Dial.js.map +1 -1
  69. package/dist/components/time/Dial.vue_vue_type_script_setup_true_lang.js.map +1 -1
  70. package/dist/components/time/TimePicker.d.ts +14 -2
  71. package/dist/components/tree-choose/TreeChoose.d.ts +1 -1
  72. package/dist/components/tree-choose/TreeChoose.js.map +1 -1
  73. package/dist/components/virtual/Virtual.d.ts +5 -5
  74. package/dist/components/virtual/Virtual.js +6 -0
  75. package/dist/components/virtual/Virtual.js.map +1 -1
  76. package/dist/index.d.ts +20 -15
  77. package/dist/index.js +6 -5
  78. package/dist/use/index.d.ts +2 -0
  79. package/dist/use/useChildComponentsCollector.d.ts +5 -0
  80. package/dist/use/useChildComponentsCollector.js.map +1 -1
  81. package/dist/use/usePercentDrag.d.ts +1 -1
  82. package/dist/use/usePercentDrag.js +19 -29
  83. package/dist/use/usePercentDrag.js.map +1 -1
  84. package/dist/use/usePointerDrag.d.ts +50 -0
  85. package/dist/use/usePointerDrag.js +143 -0
  86. package/dist/use/usePointerDrag.js.map +1 -0
  87. package/dist/use/useUII18n.d.ts +10 -0
  88. package/dist/use/useUII18n.js.map +1 -1
  89. package/dist/use/useUpload.js +1 -1
  90. package/dist/use/useUpload.js.map +1 -1
  91. package/package.json +79 -88
  92. package/dist/use/useDrag.d.ts +0 -17
@@ -0,0 +1,50 @@
1
+ export type DragPointerLike = PointerEvent | MouseEvent;
2
+ export interface PointerDragCtx {
3
+ /** pointer 模式为 pointerId;mouse 模式为 null */
4
+ pointerId: number | null;
5
+ startX: number;
6
+ startY: number;
7
+ deltaX: number;
8
+ deltaY: number;
9
+ /** 会话期可变袋,供组件存放 disX / scrollStart 等 */
10
+ data: Record<string, unknown>;
11
+ }
12
+ export interface UsePointerDragOptions {
13
+ disabled?: () => boolean;
14
+ /**
15
+ * 事件模型。默认 `pointer`。
16
+ * 迁移旧 mouse 路径时用 `mouse`,避免改交互面。
17
+ */
18
+ events?: 'pointer' | 'mouse';
19
+ /**
20
+ * move/up 挂载位置:
21
+ * - `capture`:setPointerCapture,并由返回的 onPointerMove/Up 在元素上处理(对齐 Slider)
22
+ * - `document` / `window`:全局监听(对齐 Modal / Scrollbar / Progress)
23
+ * mouse 默认 `document`;pointer 默认 `capture`
24
+ */
25
+ bind?: 'capture' | 'document' | 'window';
26
+ /** 拖拽中设置 body.cursor;不传则不改(对齐 Modal / Progress) */
27
+ cursor?: string;
28
+ /** 拖拽中 body.userSelect = 'none';默认 false */
29
+ lockUserSelect?: boolean;
30
+ /**
31
+ * onStart 返回 false 则取消本次拖拽(未进入 dragging)。
32
+ * preventDefault / stopPropagation 由调用方自行处理,以保持各组件原逻辑。
33
+ */
34
+ onStart?: (e: DragPointerLike, ctx: PointerDragCtx) => void | false;
35
+ onMove?: (e: DragPointerLike, ctx: PointerDragCtx) => void;
36
+ onEnd?: (e: DragPointerLike | null, ctx: PointerDragCtx) => void;
37
+ }
38
+ /**
39
+ * 指针拖拽会话:start / move / end、可选 capture、body 样式、卸载清理。
40
+ * 坐标→业务值的换算仍由组件在 onStart/onMove/onEnd 中完成。
41
+ */
42
+ export default function usePointerDrag(options: UsePointerDragOptions): {
43
+ dragging: import('vue').Ref<boolean, boolean>;
44
+ onPointerDown: (e: PointerEvent) => void;
45
+ onPointerMove: (e: PointerEvent) => void;
46
+ onPointerUp: (e: PointerEvent) => void;
47
+ onMouseDown: (e: MouseEvent) => void;
48
+ /** 主动结束(极少用) */
49
+ end: () => void;
50
+ };
@@ -0,0 +1,143 @@
1
+ import { onBeforeUnmount, ref } from "vue";
2
+ //#region use/usePointerDrag.ts
3
+ function resolveBind(events, bind) {
4
+ if (bind) return bind;
5
+ return events === "pointer" ? "capture" : "document";
6
+ }
7
+ /**
8
+ * 指针拖拽会话:start / move / end、可选 capture、body 样式、卸载清理。
9
+ * 坐标→业务值的换算仍由组件在 onStart/onMove/onEnd 中完成。
10
+ */
11
+ function usePointerDrag(options) {
12
+ const dragging = ref(false);
13
+ let active = false;
14
+ let ctx = null;
15
+ let captureEl = null;
16
+ let moveTarget = null;
17
+ let eventsMode = "pointer";
18
+ function applyBodyLock(on) {
19
+ if (options.lockUserSelect) document.body.style.userSelect = on ? "none" : "";
20
+ if (options.cursor !== void 0) document.body.style.cursor = on ? options.cursor : "";
21
+ }
22
+ function syncDelta(e) {
23
+ if (!ctx) return;
24
+ ctx.deltaX = e.clientX - ctx.startX;
25
+ ctx.deltaY = e.clientY - ctx.startY;
26
+ }
27
+ function detachGlobal() {
28
+ if (!moveTarget) return;
29
+ if (eventsMode === "mouse") {
30
+ moveTarget.removeEventListener("mousemove", onGlobalMove);
31
+ moveTarget.removeEventListener("mouseup", onGlobalUp);
32
+ } else {
33
+ moveTarget.removeEventListener("pointermove", onGlobalMove);
34
+ moveTarget.removeEventListener("pointerup", onGlobalUp);
35
+ moveTarget.removeEventListener("pointercancel", onGlobalUp);
36
+ }
37
+ moveTarget = null;
38
+ }
39
+ function releaseCapture() {
40
+ if (captureEl && ctx?.pointerId != null && captureEl.hasPointerCapture?.(ctx.pointerId)) try {
41
+ captureEl.releasePointerCapture(ctx.pointerId);
42
+ } catch {}
43
+ captureEl = null;
44
+ }
45
+ function finish(e) {
46
+ if (!active || !ctx) return;
47
+ active = false;
48
+ dragging.value = false;
49
+ const ended = ctx;
50
+ detachGlobal();
51
+ releaseCapture();
52
+ applyBodyLock(false);
53
+ options.onEnd?.(e, ended);
54
+ ctx = null;
55
+ }
56
+ function onGlobalMove(e) {
57
+ if (!active || !ctx) return;
58
+ const ev = e;
59
+ if (ctx.pointerId != null && "pointerId" in ev && ev.pointerId !== ctx.pointerId) return;
60
+ syncDelta(ev);
61
+ options.onMove?.(ev, ctx);
62
+ }
63
+ function onGlobalUp(e) {
64
+ if (!active || !ctx) return;
65
+ const ev = e;
66
+ if (ctx.pointerId != null && "pointerId" in ev && ev.pointerId !== ctx.pointerId) return;
67
+ syncDelta(ev);
68
+ finish(ev);
69
+ }
70
+ function begin(e, mode) {
71
+ if (options.disabled?.()) return;
72
+ if (active) return;
73
+ eventsMode = mode;
74
+ const bind = resolveBind(mode, options.bind);
75
+ const next = {
76
+ pointerId: mode === "pointer" ? e.pointerId : null,
77
+ startX: e.clientX,
78
+ startY: e.clientY,
79
+ deltaX: 0,
80
+ deltaY: 0,
81
+ data: {}
82
+ };
83
+ if (options.onStart?.(e, next) === false) return;
84
+ ctx = next;
85
+ active = true;
86
+ dragging.value = true;
87
+ applyBodyLock(true);
88
+ if (bind === "capture" && mode === "pointer") {
89
+ const el = e.currentTarget;
90
+ captureEl = el;
91
+ if (el && next.pointerId != null) try {
92
+ el.setPointerCapture(next.pointerId);
93
+ } catch {}
94
+ return;
95
+ }
96
+ const root = bind === "window" ? window : document;
97
+ moveTarget = root;
98
+ if (mode === "mouse") {
99
+ root.addEventListener("mousemove", onGlobalMove);
100
+ root.addEventListener("mouseup", onGlobalUp);
101
+ } else {
102
+ root.addEventListener("pointermove", onGlobalMove, { passive: false });
103
+ root.addEventListener("pointerup", onGlobalUp);
104
+ root.addEventListener("pointercancel", onGlobalUp);
105
+ }
106
+ }
107
+ function onPointerDown(e) {
108
+ if (options.events === "mouse") return;
109
+ begin(e, "pointer");
110
+ }
111
+ function onMouseDown(e) {
112
+ if (options.events === "pointer") return;
113
+ begin(e, "mouse");
114
+ }
115
+ function onPointerMove(e) {
116
+ if (!active || !ctx) return;
117
+ if (ctx.pointerId != null && e.pointerId !== ctx.pointerId) return;
118
+ syncDelta(e);
119
+ options.onMove?.(e, ctx);
120
+ }
121
+ function onPointerUp(e) {
122
+ if (!active || !ctx) return;
123
+ if (ctx.pointerId != null && e.pointerId !== ctx.pointerId) return;
124
+ syncDelta(e);
125
+ finish(e);
126
+ }
127
+ onBeforeUnmount(() => {
128
+ if (active) finish(null);
129
+ });
130
+ return {
131
+ dragging,
132
+ onPointerDown,
133
+ onPointerMove,
134
+ onPointerUp,
135
+ onMouseDown,
136
+ /** 主动结束(极少用) */
137
+ end: () => finish(null)
138
+ };
139
+ }
140
+ //#endregion
141
+ export { usePointerDrag as default };
142
+
143
+ //# sourceMappingURL=usePointerDrag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePointerDrag.js","names":[],"sources":["../../use/usePointerDrag.ts"],"sourcesContent":["import { onBeforeUnmount, ref } from 'vue'\r\n\r\nexport type DragPointerLike = PointerEvent | MouseEvent\r\n\r\nexport interface PointerDragCtx {\r\n /** pointer 模式为 pointerId;mouse 模式为 null */\r\n pointerId: number | null\r\n startX: number\r\n startY: number\r\n deltaX: number\r\n deltaY: number\r\n /** 会话期可变袋,供组件存放 disX / scrollStart 等 */\r\n data: Record<string, unknown>\r\n}\r\n\r\nexport interface UsePointerDragOptions {\r\n disabled?: () => boolean\r\n /**\r\n * 事件模型。默认 `pointer`。\r\n * 迁移旧 mouse 路径时用 `mouse`,避免改交互面。\r\n */\r\n events?: 'pointer' | 'mouse'\r\n /**\r\n * move/up 挂载位置:\r\n * - `capture`:setPointerCapture,并由返回的 onPointerMove/Up 在元素上处理(对齐 Slider)\r\n * - `document` / `window`:全局监听(对齐 Modal / Scrollbar / Progress)\r\n * mouse 默认 `document`;pointer 默认 `capture`\r\n */\r\n bind?: 'capture' | 'document' | 'window'\r\n /** 拖拽中设置 body.cursor;不传则不改(对齐 Modal / Progress) */\r\n cursor?: string\r\n /** 拖拽中 body.userSelect = 'none';默认 false */\r\n lockUserSelect?: boolean\r\n /**\r\n * onStart 返回 false 则取消本次拖拽(未进入 dragging)。\r\n * preventDefault / stopPropagation 由调用方自行处理,以保持各组件原逻辑。\r\n */\r\n onStart?: (e: DragPointerLike, ctx: PointerDragCtx) => void | false\r\n onMove?: (e: DragPointerLike, ctx: PointerDragCtx) => void\r\n onEnd?: (e: DragPointerLike | null, ctx: PointerDragCtx) => void\r\n}\r\n\r\nfunction resolveBind(\r\n events: 'pointer' | 'mouse',\r\n bind?: UsePointerDragOptions['bind'],\r\n): 'capture' | 'document' | 'window' {\r\n if (bind) return bind\r\n return events === 'pointer' ? 'capture' : 'document'\r\n}\r\n\r\n/**\r\n * 指针拖拽会话:start / move / end、可选 capture、body 样式、卸载清理。\r\n * 坐标→业务值的换算仍由组件在 onStart/onMove/onEnd 中完成。\r\n */\r\nexport default function usePointerDrag(options: UsePointerDragOptions) {\r\n const dragging = ref(false)\r\n let active = false\r\n let ctx: PointerDragCtx | null = null\r\n let captureEl: HTMLElement | null = null\r\n let moveTarget: Document | Window | null = null\r\n let eventsMode: 'pointer' | 'mouse' = 'pointer'\r\n\r\n function applyBodyLock(on: boolean) {\r\n if (options.lockUserSelect) {\r\n document.body.style.userSelect = on ? 'none' : ''\r\n }\r\n if (options.cursor !== undefined) {\r\n document.body.style.cursor = on ? options.cursor : ''\r\n }\r\n }\r\n\r\n function syncDelta(e: DragPointerLike) {\r\n if (!ctx) return\r\n ctx.deltaX = e.clientX - ctx.startX\r\n ctx.deltaY = e.clientY - ctx.startY\r\n }\r\n\r\n function detachGlobal() {\r\n if (!moveTarget) return\r\n if (eventsMode === 'mouse') {\r\n moveTarget.removeEventListener('mousemove', onGlobalMove as EventListener)\r\n moveTarget.removeEventListener('mouseup', onGlobalUp as EventListener)\r\n } else {\r\n moveTarget.removeEventListener(\r\n 'pointermove',\r\n onGlobalMove as EventListener,\r\n )\r\n moveTarget.removeEventListener('pointerup', onGlobalUp as EventListener)\r\n moveTarget.removeEventListener(\r\n 'pointercancel',\r\n onGlobalUp as EventListener,\r\n )\r\n }\r\n moveTarget = null\r\n }\r\n\r\n function releaseCapture() {\r\n if (\r\n captureEl &&\r\n ctx?.pointerId != null &&\r\n captureEl.hasPointerCapture?.(ctx.pointerId)\r\n ) {\r\n try {\r\n captureEl.releasePointerCapture(ctx.pointerId)\r\n } catch {\r\n /* ignore */\r\n }\r\n }\r\n captureEl = null\r\n }\r\n\r\n function finish(e: DragPointerLike | null) {\r\n if (!active || !ctx) return\r\n active = false\r\n dragging.value = false\r\n const ended = ctx\r\n detachGlobal()\r\n releaseCapture()\r\n applyBodyLock(false)\r\n options.onEnd?.(e, ended)\r\n ctx = null\r\n }\r\n\r\n function onGlobalMove(e: Event) {\r\n if (!active || !ctx) return\r\n const ev = e as DragPointerLike\r\n if (\r\n ctx.pointerId != null &&\r\n 'pointerId' in ev &&\r\n ev.pointerId !== ctx.pointerId\r\n ) {\r\n return\r\n }\r\n syncDelta(ev)\r\n options.onMove?.(ev, ctx)\r\n }\r\n\r\n function onGlobalUp(e: Event) {\r\n if (!active || !ctx) return\r\n const ev = e as DragPointerLike\r\n if (\r\n ctx.pointerId != null &&\r\n 'pointerId' in ev &&\r\n ev.pointerId !== ctx.pointerId\r\n ) {\r\n return\r\n }\r\n syncDelta(ev)\r\n finish(ev)\r\n }\r\n\r\n function begin(e: DragPointerLike, mode: 'pointer' | 'mouse') {\r\n if (options.disabled?.()) return\r\n if (active) return\r\n\r\n eventsMode = mode\r\n const bind = resolveBind(mode, options.bind)\r\n const next: PointerDragCtx = {\r\n pointerId: mode === 'pointer' ? (e as PointerEvent).pointerId : null,\r\n startX: e.clientX,\r\n startY: e.clientY,\r\n deltaX: 0,\r\n deltaY: 0,\r\n data: {},\r\n }\r\n\r\n const startResult = options.onStart?.(e, next)\r\n if (startResult === false) return\r\n\r\n ctx = next\r\n active = true\r\n dragging.value = true\r\n applyBodyLock(true)\r\n\r\n if (bind === 'capture' && mode === 'pointer') {\r\n const el = e.currentTarget as HTMLElement | null\r\n captureEl = el\r\n if (el && next.pointerId != null) {\r\n try {\r\n el.setPointerCapture(next.pointerId)\r\n } catch {\r\n /* ignore */\r\n }\r\n }\r\n // move/up 由返回的 onPointerMove / onPointerUp 处理(对齐 Slider JSX)\r\n return\r\n }\r\n\r\n const root: Document | Window =\r\n bind === 'window' ? window : document\r\n moveTarget = root\r\n if (mode === 'mouse') {\r\n root.addEventListener('mousemove', onGlobalMove as EventListener)\r\n root.addEventListener('mouseup', onGlobalUp as EventListener)\r\n } else {\r\n root.addEventListener('pointermove', onGlobalMove as EventListener, {\r\n passive: false,\r\n } as AddEventListenerOptions)\r\n root.addEventListener('pointerup', onGlobalUp as EventListener)\r\n root.addEventListener('pointercancel', onGlobalUp as EventListener)\r\n }\r\n }\r\n\r\n function onPointerDown(e: PointerEvent) {\r\n if (options.events === 'mouse') return\r\n begin(e, 'pointer')\r\n }\r\n\r\n function onMouseDown(e: MouseEvent) {\r\n // events === 'pointer' 时禁用 mouse;undefined / 'mouse' 走 mouse(Progress)\r\n if (options.events === 'pointer') return\r\n begin(e, 'mouse')\r\n }\r\n\r\n function onPointerMove(e: PointerEvent) {\r\n if (!active || !ctx) return\r\n if (ctx.pointerId != null && e.pointerId !== ctx.pointerId) return\r\n syncDelta(e)\r\n options.onMove?.(e, ctx)\r\n }\r\n\r\n function onPointerUp(e: PointerEvent) {\r\n if (!active || !ctx) return\r\n if (ctx.pointerId != null && e.pointerId !== ctx.pointerId) return\r\n syncDelta(e)\r\n finish(e)\r\n }\r\n\r\n onBeforeUnmount(() => {\r\n if (active) finish(null)\r\n })\r\n\r\n return {\r\n dragging,\r\n onPointerDown,\r\n onPointerMove,\r\n onPointerUp,\r\n onMouseDown,\r\n /** 主动结束(极少用) */\r\n end: () => finish(null),\r\n }\r\n}\r\n"],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * UI 组件通用国际化 Hook
3
+ * 提供独立于项目主 i18n 的国际化能力
4
+ *
5
+ * @returns 安全的国际化方法,即使初始化失败也不会报错
6
+ */
7
+ export declare function useUII18n(): {
8
+ t: (key: string, ...args: any[]) => string;
9
+ locale: any;
10
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"useUII18n.js","names":[],"sources":["../../use/useUII18n.ts"],"sourcesContent":["import { useI18n } from \"vue-i18n\"\r\nimport { uiI18n } from \"../config/i18n\"\r\n\r\n/**\r\n * UI 组件通用国际化 Hook\r\n * 提供独立于项目主 i18n 的国际化能力\r\n *\r\n * @returns 安全的国际化方法,即使初始化失败也不会报错\r\n */\r\nexport function useUII18n() {\r\n // 安全检查:确保 uiI18n 已正确初始化\r\n if (!uiI18n || !uiI18n.global || !uiI18n.global.t) {\r\n console.warn(\r\n \"[UII18n] UI i18n instance not properly initialized, using fallback\"\r\n )\r\n // 返回降级方案:直接返回 key 的函数\r\n const fallbackT = (key: string, params?: Record<string, any>) => key\r\n return {\r\n t: fallbackT,\r\n locale: { value: \"zh-CN\" },\r\n }\r\n }\r\n\r\n return {\r\n t: uiI18n.global.t,\r\n locale: uiI18n.global.locale,\r\n }\r\n}\r\n"],"mappings":";;;;;;;;AASA,SAAgB,YAAY;CAE1B,IAAI,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,OAAO,OAAO,GAAG;EACjD,QAAQ,KACN,oEACF;EAEA,MAAM,aAAa,KAAa,WAAiC;EACjE,OAAO;GACL,GAAG;GACH,QAAQ,EAAE,OAAO,QAAQ;EAC3B;CACF;CAEA,OAAO;EACL,GAAG,OAAO,OAAO;EACjB,QAAQ,OAAO,OAAO;CACxB;AACF"}
1
+ {"version":3,"file":"useUII18n.js","names":[],"sources":["../../use/useUII18n.ts"],"sourcesContent":["import { useI18n } from \"vue-i18n\"\r\nimport { uiI18n } from \"../config/i18n\"\r\n\r\n/**\r\n * UI 组件通用国际化 Hook\r\n * 提供独立于项目主 i18n 的国际化能力\r\n *\r\n * @returns 安全的国际化方法,即使初始化失败也不会报错\r\n */\r\nexport function useUII18n(): {\r\n t: (key: string, ...args: any[]) => string\r\n locale: any\r\n} {\r\n // 安全检查:确保 uiI18n 已正确初始化\r\n if (!uiI18n || !uiI18n.global || !uiI18n.global.t) {\r\n console.warn(\r\n \"[UII18n] UI i18n instance not properly initialized, using fallback\"\r\n )\r\n // 返回降级方案:直接返回 key 的函数\r\n const fallbackT = (key: string, params?: Record<string, any>) => key\r\n return {\r\n t: fallbackT,\r\n locale: { value: \"zh-CN\" },\r\n }\r\n }\r\n\r\n return {\r\n t: uiI18n.global.t,\r\n locale: uiI18n.global.locale,\r\n }\r\n}\r\n"],"mappings":";;;;;;;;AASA,SAAgB,YAGd;CAEA,IAAI,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,OAAO,OAAO,GAAG;EACjD,QAAQ,KACN,oEACF;EAEA,MAAM,aAAa,KAAa,WAAiC;EACjE,OAAO;GACL,GAAG;GACH,QAAQ,EAAE,OAAO,QAAQ;EAC3B;CACF;CAEA,OAAO;EACL,GAAG,OAAO,OAAO;EACjB,QAAQ,OAAO,OAAO;CACxB;AACF"}
@@ -266,7 +266,7 @@ function useUpload(options) {
266
266
  options.onError?.(error, latest, fileList.value);
267
267
  }
268
268
  });
269
- if (handle?.abort) abortMap.set(uid, handle.abort);
269
+ if (handle && typeof handle === "object" && handle.abort) abortMap.set(uid, handle.abort);
270
270
  }
271
271
  function upload(uid) {
272
272
  if (uid) {
@@ -1 +1 @@
1
- {"version":3,"file":"useUpload.js","names":[],"sources":["../../use/useUpload.ts"],"sourcesContent":["import {\r\n computed,\r\n onUnmounted,\r\n ref,\r\n unref,\r\n watch,\r\n type ComputedRef,\r\n type MaybeRef,\r\n type Ref,\r\n} from 'vue'\r\nimport type {\r\n UploadBeforeRemove,\r\n UploadBeforeUpload,\r\n UploadFile,\r\n UploadHttpRequest,\r\n UploadHttpRequestOptions,\r\n} from '../components/upload/types'\r\n\r\nlet uidSeed = 0\r\nfunction nextUid() {\r\n uidSeed += 1\r\n return `upload-${Date.now()}-${uidSeed}`\r\n}\r\n\r\nconst IMAGE_EXT = new Set([\r\n 'jpg',\r\n 'jpeg',\r\n 'png',\r\n 'gif',\r\n 'bmp',\r\n 'webp',\r\n 'svg',\r\n 'ico',\r\n 'avif',\r\n])\r\n\r\nexport function isImageFile(file: Pick<UploadFile, 'name' | 'type' | 'url'>) {\r\n if (file.type?.startsWith('image/')) return true\r\n const name = file.name || file.url || ''\r\n const ext = name.split('?')[0].split('.').pop()?.toLowerCase()\r\n return ext ? IMAGE_EXT.has(ext) : false\r\n}\r\n\r\nexport function formatFileSize(size?: number) {\r\n if (size == null || Number.isNaN(size)) return ''\r\n if (size < 1024) return `${size}B`\r\n if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)}KB`\r\n return `${(size / 1024 / 1024).toFixed(1)}MB`\r\n}\r\n\r\nfunction matchAccept(file: File, accept: string): boolean {\r\n const raw = accept.trim()\r\n if (!raw || raw === '*') return true\r\n const tokens = raw.split(',').map((s) => s.trim().toLowerCase()).filter(Boolean)\r\n if (!tokens.length) return true\r\n const fileName = file.name.toLowerCase()\r\n const mime = (file.type || '').toLowerCase()\r\n return tokens.some((token) => {\r\n if (token.startsWith('.')) {\r\n return fileName.endsWith(token)\r\n }\r\n if (token.endsWith('/*')) {\r\n const prefix = token.slice(0, -1) // e.g. image/\r\n return mime.startsWith(prefix)\r\n }\r\n return mime === token\r\n })\r\n}\r\n\r\nfunction defaultXhrRequest(options: UploadHttpRequestOptions) {\r\n const {\r\n action,\r\n file,\r\n filename,\r\n data,\r\n headers,\r\n withCredentials,\r\n onProgress,\r\n onSuccess,\r\n onError,\r\n } = options\r\n\r\n if (!action) {\r\n onError(new Error('Upload action is required'))\r\n return\r\n }\r\n\r\n const xhr = new XMLHttpRequest()\r\n const form = new FormData()\r\n form.append(filename, file, file.name)\r\n if (data) {\r\n Object.keys(data).forEach((key) => {\r\n const value = data[key]\r\n if (value == null) return\r\n form.append(key, value instanceof Blob ? value : String(value))\r\n })\r\n }\r\n\r\n if (xhr.upload) {\r\n xhr.upload.onprogress = (e) => {\r\n if (e.total > 0) {\r\n onProgress({ percent: Math.min(100, Math.round((e.loaded / e.total) * 100)) })\r\n }\r\n }\r\n }\r\n\r\n xhr.onerror = () => {\r\n onError(new Error('Upload network error'))\r\n }\r\n\r\n xhr.onload = () => {\r\n if (xhr.status >= 200 && xhr.status < 300) {\r\n let response: unknown = xhr.responseText\r\n try {\r\n response = JSON.parse(xhr.responseText)\r\n } catch {\r\n // keep text\r\n }\r\n onSuccess(response)\r\n } else {\r\n onError(new Error(`Upload failed with status ${xhr.status}`))\r\n }\r\n }\r\n\r\n xhr.open('POST', action, true)\r\n if (withCredentials) {\r\n xhr.withCredentials = true\r\n }\r\n if (headers) {\r\n Object.keys(headers).forEach((key) => {\r\n const value = headers[key]\r\n if (value != null) xhr.setRequestHeader(key, value)\r\n })\r\n }\r\n xhr.send(form)\r\n\r\n return {\r\n abort: () => xhr.abort(),\r\n }\r\n}\r\n\r\nexport interface UseUploadOptions {\r\n modelValue?: MaybeRef<UploadFile[] | undefined>\r\n accept?: MaybeRef<string>\r\n multiple?: MaybeRef<boolean>\r\n disabled?: MaybeRef<boolean>\r\n maxSize?: MaybeRef<number>\r\n maxCount?: MaybeRef<number>\r\n autoUpload?: MaybeRef<boolean>\r\n drag?: MaybeRef<boolean>\r\n paste?: MaybeRef<boolean>\r\n action?: MaybeRef<string | undefined>\r\n httpRequest?: MaybeRef<UploadHttpRequest | undefined>\r\n data?: MaybeRef<Record<string, unknown> | undefined>\r\n headers?: MaybeRef<Record<string, string> | undefined>\r\n withCredentials?: MaybeRef<boolean | undefined>\r\n name?: MaybeRef<string>\r\n beforeUpload?: UploadBeforeUpload\r\n beforeRemove?: UploadBeforeRemove\r\n t: (key: string, params?: Record<string, string | number>) => string\r\n onUpdateModelValue?: (list: UploadFile[]) => void\r\n onChange?: (file: UploadFile, fileList: UploadFile[]) => void\r\n onRemove?: (file: UploadFile, fileList: UploadFile[]) => void\r\n onError?: (error: Error, file?: UploadFile, fileList?: UploadFile[]) => void\r\n onProgress?: (file: UploadFile, fileList: UploadFile[]) => void\r\n onSuccess?: (response: unknown, file: UploadFile, fileList: UploadFile[]) => void\r\n onExceed?: (files: File[], fileList: UploadFile[]) => void\r\n}\r\n\r\nexport interface UseUploadReturn {\r\n fileList: ComputedRef<UploadFile[]>\r\n isDragging: Ref<boolean>\r\n addFiles: (files: File[] | FileList | null | undefined) => Promise<void>\r\n remove: (uid: string) => Promise<void>\r\n clear: () => void\r\n upload: (uid?: string) => void\r\n uploadAll: () => void\r\n abort: (uid?: string) => void\r\n retry: (uid: string) => void\r\n handleDragEnter: (e: DragEvent) => void\r\n handleDragOver: (e: DragEvent) => void\r\n handleDragLeave: (e: DragEvent) => void\r\n handleDrop: (e: DragEvent) => void\r\n handlePaste: (e: ClipboardEvent) => void\r\n canAddMore: ComputedRef<boolean>\r\n}\r\n\r\nexport default function useUpload(options: UseUploadOptions): UseUploadReturn {\r\n const innerList = ref<UploadFile[]>([])\r\n const isDragging = ref(false)\r\n const dragCounter = ref(0)\r\n /** 本组件创建的 blob URL,卸载时释放 */\r\n const localObjectUrls = new Set<string>()\r\n const abortMap = new Map<string, () => void>()\r\n\r\n const fileList = computed(() => innerList.value)\r\n\r\n watch(\r\n () => unref(options.modelValue),\r\n (val) => {\r\n // 同引用说明是我们刚 emit 出去的,避免进度连发时被旧值回写覆盖\r\n if (val !== undefined && val !== innerList.value) {\r\n innerList.value = val\r\n }\r\n },\r\n { immediate: true },\r\n )\r\n\r\n function emitList(next: UploadFile[]) {\r\n const list = next.slice()\r\n innerList.value = list\r\n options.onUpdateModelValue?.(list)\r\n }\r\n\r\n function patchFile(uid: string, patch: Partial<UploadFile>) {\r\n const list = fileList.value\r\n const idx = list.findIndex((f) => f.uid === uid)\r\n if (idx < 0) return\r\n const next = list.slice()\r\n next[idx] = { ...next[idx], ...patch }\r\n emitList(next)\r\n }\r\n\r\n function getFile(uid: string) {\r\n return fileList.value.find((f) => f.uid === uid)\r\n }\r\n\r\n function revokeUrl(url?: string) {\r\n if (!url || !localObjectUrls.has(url)) return\r\n URL.revokeObjectURL(url)\r\n localObjectUrls.delete(url)\r\n }\r\n\r\n function createPreviewUrl(file: File): string | undefined {\r\n if (!file.type.startsWith('image/') && !isImageFile({ name: file.name, type: file.type })) {\r\n return undefined\r\n }\r\n const url = URL.createObjectURL(file)\r\n localObjectUrls.add(url)\r\n return url\r\n }\r\n\r\n function validateFile(file: File): Error | null {\r\n const accept = unref(options.accept) ?? '*'\r\n const maxSize = unref(options.maxSize) ?? Infinity\r\n if (!matchAccept(file, accept)) {\r\n return new Error(\r\n options.t('upload.invalidType', { name: file.name, accept }),\r\n )\r\n }\r\n if (file.size > maxSize) {\r\n return new Error(\r\n options.t('upload.fileSizeExceeded', {\r\n name: file.name,\r\n size: (maxSize / 1024 / 1024).toFixed(1),\r\n }),\r\n )\r\n }\r\n return null\r\n }\r\n\r\n const canAddMore = computed(() => {\r\n const maxCount = unref(options.maxCount) ?? Infinity\r\n const multiple = unref(options.multiple) ?? false\r\n if (!multiple) return fileList.value.length < 1\r\n return fileList.value.length < maxCount\r\n })\r\n\r\n async function addFiles(input: File[] | FileList | null | undefined) {\r\n if (unref(options.disabled)) return\r\n if (!input || (input as FileList).length === 0) return\r\n\r\n const incoming = Array.from(input as FileList | File[])\r\n const multiple = unref(options.multiple) ?? false\r\n const maxCount = unref(options.maxCount) ?? Infinity\r\n let current = fileList.value.slice()\r\n\r\n if (!multiple) {\r\n // 单选:清空现有并替换\r\n current.forEach((f) => {\r\n abortMap.get(f.uid)?.()\r\n abortMap.delete(f.uid)\r\n revokeUrl(f.url)\r\n })\r\n current = []\r\n }\r\n\r\n const remain = multiple\r\n ? Math.max(0, maxCount - current.length)\r\n : 1\r\n\r\n if (remain <= 0 || incoming.length > remain) {\r\n options.onExceed?.(incoming, fileList.value)\r\n if (remain <= 0) {\r\n options.onError?.(\r\n new Error(\r\n options.t('upload.fileCountExceeded', { count: maxCount }),\r\n ),\r\n )\r\n return\r\n }\r\n }\r\n\r\n const take = incoming.slice(0, remain)\r\n if (incoming.length > remain) {\r\n options.onExceed?.(incoming, fileList.value)\r\n options.onError?.(\r\n new Error(options.t('upload.fileCountExceeded', { count: maxCount })),\r\n )\r\n }\r\n\r\n const created: UploadFile[] = []\r\n\r\n for (const raw of take) {\r\n let file: File = raw\r\n const err = validateFile(file)\r\n if (err) {\r\n options.onError?.(err)\r\n continue\r\n }\r\n\r\n if (options.beforeUpload) {\r\n try {\r\n const result = await options.beforeUpload(file)\r\n if (result === false) continue\r\n if (result instanceof File) file = result\r\n } catch (e) {\r\n options.onError?.(e instanceof Error ? e : new Error(String(e)))\r\n continue\r\n }\r\n }\r\n\r\n const item: UploadFile = {\r\n uid: nextUid(),\r\n name: file.name,\r\n size: file.size,\r\n type: file.type,\r\n status: 'ready',\r\n percent: 0,\r\n url: createPreviewUrl(file),\r\n raw: file,\r\n }\r\n created.push(item)\r\n current.push(item)\r\n }\r\n\r\n if (!created.length) return\r\n\r\n emitList(current)\r\n created.forEach((f) => options.onChange?.(f, fileList.value))\r\n\r\n if (unref(options.autoUpload)) {\r\n created.forEach((f) => startUpload(f.uid))\r\n }\r\n }\r\n\r\n function resolveRequest(): UploadHttpRequest | null {\r\n const custom = unref(options.httpRequest)\r\n if (custom) return custom\r\n const action = unref(options.action)\r\n if (action) return defaultXhrRequest\r\n return null\r\n }\r\n\r\n function startUpload(uid: string) {\r\n const file = getFile(uid)\r\n if (!file?.raw) return\r\n if (file.status === 'uploading') return\r\n\r\n const request = resolveRequest()\r\n if (!request) {\r\n // 无上传实现:保持 ready,由业务自行处理\r\n return\r\n }\r\n\r\n abortMap.get(uid)?.()\r\n abortMap.delete(uid)\r\n\r\n patchFile(uid, { status: 'uploading', percent: 0, error: undefined })\r\n\r\n const handle = request({\r\n file: file.raw,\r\n filename: unref(options.name) ?? 'file',\r\n data: unref(options.data),\r\n headers: unref(options.headers),\r\n withCredentials: unref(options.withCredentials),\r\n action: unref(options.action),\r\n onProgress: ({ percent }) => {\r\n patchFile(uid, { percent, status: 'uploading' })\r\n const latest = getFile(uid)\r\n if (latest) options.onProgress?.(latest, fileList.value)\r\n },\r\n onSuccess: (response) => {\r\n abortMap.delete(uid)\r\n const patch: Partial<UploadFile> = {\r\n status: 'success',\r\n percent: 100,\r\n response,\r\n error: undefined,\r\n }\r\n // 若响应里带 url 可覆盖预览\r\n if (\r\n response &&\r\n typeof response === 'object' &&\r\n 'url' in response &&\r\n typeof (response as { url: unknown }).url === 'string'\r\n ) {\r\n const nextUrl = (response as { url: string }).url\r\n revokeUrl(file.url)\r\n patch.url = nextUrl\r\n }\r\n patchFile(uid, patch)\r\n const latest = getFile(uid)\r\n if (latest) options.onSuccess?.(response, latest, fileList.value)\r\n },\r\n onError: (error) => {\r\n abortMap.delete(uid)\r\n patchFile(uid, { status: 'error', error })\r\n const latest = getFile(uid)\r\n options.onError?.(error, latest, fileList.value)\r\n },\r\n })\r\n\r\n if (handle?.abort) {\r\n abortMap.set(uid, handle.abort)\r\n }\r\n }\r\n\r\n function upload(uid?: string) {\r\n if (uid) {\r\n startUpload(uid)\r\n return\r\n }\r\n uploadAll()\r\n }\r\n\r\n function uploadAll() {\r\n fileList.value\r\n .filter((f) => f.raw && (f.status === 'ready' || f.status === 'error'))\r\n .forEach((f) => startUpload(f.uid))\r\n }\r\n\r\n function abort(uid?: string) {\r\n if (uid) {\r\n abortMap.get(uid)?.()\r\n abortMap.delete(uid)\r\n const f = getFile(uid)\r\n if (f?.status === 'uploading') {\r\n patchFile(uid, { status: 'ready', percent: 0 })\r\n }\r\n return\r\n }\r\n abortMap.forEach((fn) => fn())\r\n abortMap.clear()\r\n emitList(\r\n fileList.value.map((f) =>\r\n f.status === 'uploading' ? { ...f, status: 'ready', percent: 0 } : f,\r\n ),\r\n )\r\n }\r\n\r\n function retry(uid: string) {\r\n const f = getFile(uid)\r\n if (!f?.raw) return\r\n patchFile(uid, { status: 'ready', percent: 0, error: undefined })\r\n startUpload(uid)\r\n }\r\n\r\n async function remove(uid: string) {\r\n if (unref(options.disabled)) return\r\n const file = getFile(uid)\r\n if (!file) return\r\n\r\n if (options.beforeRemove) {\r\n try {\r\n const ok = await options.beforeRemove(file)\r\n if (!ok) return\r\n } catch {\r\n return\r\n }\r\n }\r\n\r\n abortMap.get(uid)?.()\r\n abortMap.delete(uid)\r\n revokeUrl(file.url)\r\n\r\n const next = fileList.value.filter((f) => f.uid !== uid)\r\n emitList(next)\r\n options.onRemove?.(file, next)\r\n }\r\n\r\n function clear() {\r\n fileList.value.forEach((f) => {\r\n abortMap.get(f.uid)?.()\r\n revokeUrl(f.url)\r\n })\r\n abortMap.clear()\r\n emitList([])\r\n }\r\n\r\n function handleDragEnter(e: DragEvent) {\r\n if (unref(options.disabled) || !unref(options.drag)) return\r\n e.preventDefault()\r\n e.stopPropagation()\r\n dragCounter.value += 1\r\n isDragging.value = true\r\n }\r\n\r\n function handleDragOver(e: DragEvent) {\r\n if (unref(options.disabled) || !unref(options.drag)) return\r\n e.preventDefault()\r\n e.stopPropagation()\r\n }\r\n\r\n function handleDragLeave(e: DragEvent) {\r\n if (unref(options.disabled) || !unref(options.drag)) return\r\n e.preventDefault()\r\n e.stopPropagation()\r\n dragCounter.value -= 1\r\n if (dragCounter.value <= 0) {\r\n dragCounter.value = 0\r\n isDragging.value = false\r\n }\r\n }\r\n\r\n function handleDrop(e: DragEvent) {\r\n if (unref(options.disabled) || !unref(options.drag)) return\r\n e.preventDefault()\r\n e.stopPropagation()\r\n dragCounter.value = 0\r\n isDragging.value = false\r\n void addFiles(e.dataTransfer?.files)\r\n }\r\n\r\n function handlePaste(e: ClipboardEvent) {\r\n if (unref(options.disabled) || !unref(options.paste)) return\r\n const files = e.clipboardData?.files\r\n if (!files?.length) return\r\n e.preventDefault()\r\n void addFiles(files)\r\n }\r\n\r\n onUnmounted(() => {\r\n abortMap.forEach((fn) => fn())\r\n abortMap.clear()\r\n localObjectUrls.forEach((url) => URL.revokeObjectURL(url))\r\n localObjectUrls.clear()\r\n })\r\n\r\n return {\r\n fileList,\r\n isDragging,\r\n addFiles,\r\n remove,\r\n clear,\r\n upload,\r\n uploadAll,\r\n abort,\r\n retry,\r\n handleDragEnter,\r\n handleDragOver,\r\n handleDragLeave,\r\n handleDrop,\r\n handlePaste,\r\n canAddMore,\r\n }\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"useUpload.js","names":[],"sources":["../../use/useUpload.ts"],"sourcesContent":["import {\r\n computed,\r\n onUnmounted,\r\n ref,\r\n unref,\r\n watch,\r\n type ComputedRef,\r\n type MaybeRef,\r\n type Ref,\r\n} from 'vue'\r\nimport type {\r\n UploadBeforeRemove,\r\n UploadBeforeUpload,\r\n UploadFile,\r\n UploadHttpRequest,\r\n UploadHttpRequestOptions,\r\n} from '../components/upload/types'\r\n\r\nlet uidSeed = 0\r\nfunction nextUid() {\r\n uidSeed += 1\r\n return `upload-${Date.now()}-${uidSeed}`\r\n}\r\n\r\nconst IMAGE_EXT = new Set([\r\n 'jpg',\r\n 'jpeg',\r\n 'png',\r\n 'gif',\r\n 'bmp',\r\n 'webp',\r\n 'svg',\r\n 'ico',\r\n 'avif',\r\n])\r\n\r\nexport function isImageFile(file: Pick<UploadFile, 'name' | 'type' | 'url'>) {\r\n if (file.type?.startsWith('image/')) return true\r\n const name = file.name || file.url || ''\r\n const ext = name.split('?')[0].split('.').pop()?.toLowerCase()\r\n return ext ? IMAGE_EXT.has(ext) : false\r\n}\r\n\r\nexport function formatFileSize(size?: number) {\r\n if (size == null || Number.isNaN(size)) return ''\r\n if (size < 1024) return `${size}B`\r\n if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)}KB`\r\n return `${(size / 1024 / 1024).toFixed(1)}MB`\r\n}\r\n\r\nfunction matchAccept(file: File, accept: string): boolean {\r\n const raw = accept.trim()\r\n if (!raw || raw === '*') return true\r\n const tokens = raw.split(',').map((s) => s.trim().toLowerCase()).filter(Boolean)\r\n if (!tokens.length) return true\r\n const fileName = file.name.toLowerCase()\r\n const mime = (file.type || '').toLowerCase()\r\n return tokens.some((token) => {\r\n if (token.startsWith('.')) {\r\n return fileName.endsWith(token)\r\n }\r\n if (token.endsWith('/*')) {\r\n const prefix = token.slice(0, -1) // e.g. image/\r\n return mime.startsWith(prefix)\r\n }\r\n return mime === token\r\n })\r\n}\r\n\r\nfunction defaultXhrRequest(options: UploadHttpRequestOptions) {\r\n const {\r\n action,\r\n file,\r\n filename,\r\n data,\r\n headers,\r\n withCredentials,\r\n onProgress,\r\n onSuccess,\r\n onError,\r\n } = options\r\n\r\n if (!action) {\r\n onError(new Error('Upload action is required'))\r\n return\r\n }\r\n\r\n const xhr = new XMLHttpRequest()\r\n const form = new FormData()\r\n form.append(filename, file, file.name)\r\n if (data) {\r\n Object.keys(data).forEach((key) => {\r\n const value = data[key]\r\n if (value == null) return\r\n form.append(key, value instanceof Blob ? value : String(value))\r\n })\r\n }\r\n\r\n if (xhr.upload) {\r\n xhr.upload.onprogress = (e) => {\r\n if (e.total > 0) {\r\n onProgress({ percent: Math.min(100, Math.round((e.loaded / e.total) * 100)) })\r\n }\r\n }\r\n }\r\n\r\n xhr.onerror = () => {\r\n onError(new Error('Upload network error'))\r\n }\r\n\r\n xhr.onload = () => {\r\n if (xhr.status >= 200 && xhr.status < 300) {\r\n let response: unknown = xhr.responseText\r\n try {\r\n response = JSON.parse(xhr.responseText)\r\n } catch {\r\n // keep text\r\n }\r\n onSuccess(response)\r\n } else {\r\n onError(new Error(`Upload failed with status ${xhr.status}`))\r\n }\r\n }\r\n\r\n xhr.open('POST', action, true)\r\n if (withCredentials) {\r\n xhr.withCredentials = true\r\n }\r\n if (headers) {\r\n Object.keys(headers).forEach((key) => {\r\n const value = headers[key]\r\n if (value != null) xhr.setRequestHeader(key, value)\r\n })\r\n }\r\n xhr.send(form)\r\n\r\n return {\r\n abort: () => xhr.abort(),\r\n }\r\n}\r\n\r\nexport interface UseUploadOptions {\r\n modelValue?: MaybeRef<UploadFile[] | undefined>\r\n accept?: MaybeRef<string>\r\n multiple?: MaybeRef<boolean>\r\n disabled?: MaybeRef<boolean>\r\n maxSize?: MaybeRef<number>\r\n maxCount?: MaybeRef<number>\r\n autoUpload?: MaybeRef<boolean>\r\n drag?: MaybeRef<boolean>\r\n paste?: MaybeRef<boolean>\r\n action?: MaybeRef<string | undefined>\r\n httpRequest?: MaybeRef<UploadHttpRequest | undefined>\r\n data?: MaybeRef<Record<string, unknown> | undefined>\r\n headers?: MaybeRef<Record<string, string> | undefined>\r\n withCredentials?: MaybeRef<boolean | undefined>\r\n name?: MaybeRef<string>\r\n beforeUpload?: UploadBeforeUpload\r\n beforeRemove?: UploadBeforeRemove\r\n t: (key: string, params?: Record<string, string | number>) => string\r\n onUpdateModelValue?: (list: UploadFile[]) => void\r\n onChange?: (file: UploadFile, fileList: UploadFile[]) => void\r\n onRemove?: (file: UploadFile, fileList: UploadFile[]) => void\r\n onError?: (error: Error, file?: UploadFile, fileList?: UploadFile[]) => void\r\n onProgress?: (file: UploadFile, fileList: UploadFile[]) => void\r\n onSuccess?: (response: unknown, file: UploadFile, fileList: UploadFile[]) => void\r\n onExceed?: (files: File[], fileList: UploadFile[]) => void\r\n}\r\n\r\nexport interface UseUploadReturn {\r\n fileList: ComputedRef<UploadFile[]>\r\n isDragging: Ref<boolean>\r\n addFiles: (files: File[] | FileList | null | undefined) => Promise<void>\r\n remove: (uid: string) => Promise<void>\r\n clear: () => void\r\n upload: (uid?: string) => void\r\n uploadAll: () => void\r\n abort: (uid?: string) => void\r\n retry: (uid: string) => void\r\n handleDragEnter: (e: DragEvent) => void\r\n handleDragOver: (e: DragEvent) => void\r\n handleDragLeave: (e: DragEvent) => void\r\n handleDrop: (e: DragEvent) => void\r\n handlePaste: (e: ClipboardEvent) => void\r\n canAddMore: ComputedRef<boolean>\r\n}\r\n\r\nexport default function useUpload(options: UseUploadOptions): UseUploadReturn {\r\n const innerList = ref<UploadFile[]>([])\r\n const isDragging = ref(false)\r\n const dragCounter = ref(0)\r\n /** 本组件创建的 blob URL,卸载时释放 */\r\n const localObjectUrls = new Set<string>()\r\n const abortMap = new Map<string, () => void>()\r\n\r\n const fileList = computed(() => innerList.value)\r\n\r\n watch(\r\n () => unref(options.modelValue),\r\n (val) => {\r\n // 同引用说明是我们刚 emit 出去的,避免进度连发时被旧值回写覆盖\r\n if (val !== undefined && val !== innerList.value) {\r\n innerList.value = val\r\n }\r\n },\r\n { immediate: true },\r\n )\r\n\r\n function emitList(next: UploadFile[]) {\r\n const list = next.slice()\r\n innerList.value = list\r\n options.onUpdateModelValue?.(list)\r\n }\r\n\r\n function patchFile(uid: string, patch: Partial<UploadFile>) {\r\n const list = fileList.value\r\n const idx = list.findIndex((f) => f.uid === uid)\r\n if (idx < 0) return\r\n const next = list.slice()\r\n next[idx] = { ...next[idx], ...patch }\r\n emitList(next)\r\n }\r\n\r\n function getFile(uid: string) {\r\n return fileList.value.find((f) => f.uid === uid)\r\n }\r\n\r\n function revokeUrl(url?: string) {\r\n if (!url || !localObjectUrls.has(url)) return\r\n URL.revokeObjectURL(url)\r\n localObjectUrls.delete(url)\r\n }\r\n\r\n function createPreviewUrl(file: File): string | undefined {\r\n if (!file.type.startsWith('image/') && !isImageFile({ name: file.name, type: file.type })) {\r\n return undefined\r\n }\r\n const url = URL.createObjectURL(file)\r\n localObjectUrls.add(url)\r\n return url\r\n }\r\n\r\n function validateFile(file: File): Error | null {\r\n const accept = unref(options.accept) ?? '*'\r\n const maxSize = unref(options.maxSize) ?? Infinity\r\n if (!matchAccept(file, accept)) {\r\n return new Error(\r\n options.t('upload.invalidType', { name: file.name, accept }),\r\n )\r\n }\r\n if (file.size > maxSize) {\r\n return new Error(\r\n options.t('upload.fileSizeExceeded', {\r\n name: file.name,\r\n size: (maxSize / 1024 / 1024).toFixed(1),\r\n }),\r\n )\r\n }\r\n return null\r\n }\r\n\r\n const canAddMore = computed(() => {\r\n const maxCount = unref(options.maxCount) ?? Infinity\r\n const multiple = unref(options.multiple) ?? false\r\n if (!multiple) return fileList.value.length < 1\r\n return fileList.value.length < maxCount\r\n })\r\n\r\n async function addFiles(input: File[] | FileList | null | undefined) {\r\n if (unref(options.disabled)) return\r\n if (!input || (input as FileList).length === 0) return\r\n\r\n const incoming = Array.from(input as FileList | File[])\r\n const multiple = unref(options.multiple) ?? false\r\n const maxCount = unref(options.maxCount) ?? Infinity\r\n let current = fileList.value.slice()\r\n\r\n if (!multiple) {\r\n // 单选:清空现有并替换\r\n current.forEach((f) => {\r\n abortMap.get(f.uid)?.()\r\n abortMap.delete(f.uid)\r\n revokeUrl(f.url)\r\n })\r\n current = []\r\n }\r\n\r\n const remain = multiple\r\n ? Math.max(0, maxCount - current.length)\r\n : 1\r\n\r\n if (remain <= 0 || incoming.length > remain) {\r\n options.onExceed?.(incoming, fileList.value)\r\n if (remain <= 0) {\r\n options.onError?.(\r\n new Error(\r\n options.t('upload.fileCountExceeded', { count: maxCount }),\r\n ),\r\n )\r\n return\r\n }\r\n }\r\n\r\n const take = incoming.slice(0, remain)\r\n if (incoming.length > remain) {\r\n options.onExceed?.(incoming, fileList.value)\r\n options.onError?.(\r\n new Error(options.t('upload.fileCountExceeded', { count: maxCount })),\r\n )\r\n }\r\n\r\n const created: UploadFile[] = []\r\n\r\n for (const raw of take) {\r\n let file: File = raw\r\n const err = validateFile(file)\r\n if (err) {\r\n options.onError?.(err)\r\n continue\r\n }\r\n\r\n if (options.beforeUpload) {\r\n try {\r\n const result = await options.beforeUpload(file)\r\n if (result === false) continue\r\n if (result instanceof File) file = result\r\n } catch (e) {\r\n options.onError?.(e instanceof Error ? e : new Error(String(e)))\r\n continue\r\n }\r\n }\r\n\r\n const item: UploadFile = {\r\n uid: nextUid(),\r\n name: file.name,\r\n size: file.size,\r\n type: file.type,\r\n status: 'ready',\r\n percent: 0,\r\n url: createPreviewUrl(file),\r\n raw: file,\r\n }\r\n created.push(item)\r\n current.push(item)\r\n }\r\n\r\n if (!created.length) return\r\n\r\n emitList(current)\r\n created.forEach((f) => options.onChange?.(f, fileList.value))\r\n\r\n if (unref(options.autoUpload)) {\r\n created.forEach((f) => startUpload(f.uid))\r\n }\r\n }\r\n\r\n function resolveRequest(): UploadHttpRequest | null {\r\n const custom = unref(options.httpRequest)\r\n if (custom) return custom\r\n const action = unref(options.action)\r\n if (action) return defaultXhrRequest\r\n return null\r\n }\r\n\r\n function startUpload(uid: string) {\r\n const file = getFile(uid)\r\n if (!file?.raw) return\r\n if (file.status === 'uploading') return\r\n\r\n const request = resolveRequest()\r\n if (!request) {\r\n // 无上传实现:保持 ready,由业务自行处理\r\n return\r\n }\r\n\r\n abortMap.get(uid)?.()\r\n abortMap.delete(uid)\r\n\r\n patchFile(uid, { status: 'uploading', percent: 0, error: undefined })\r\n\r\n const handle = request({\r\n file: file.raw,\r\n filename: unref(options.name) ?? 'file',\r\n data: unref(options.data),\r\n headers: unref(options.headers),\r\n withCredentials: unref(options.withCredentials),\r\n action: unref(options.action),\r\n onProgress: ({ percent }) => {\r\n patchFile(uid, { percent, status: 'uploading' })\r\n const latest = getFile(uid)\r\n if (latest) options.onProgress?.(latest, fileList.value)\r\n },\r\n onSuccess: (response) => {\r\n abortMap.delete(uid)\r\n const patch: Partial<UploadFile> = {\r\n status: 'success',\r\n percent: 100,\r\n response,\r\n error: undefined,\r\n }\r\n // 若响应里带 url 可覆盖预览\r\n if (\r\n response &&\r\n typeof response === 'object' &&\r\n 'url' in response &&\r\n typeof (response as { url: unknown }).url === 'string'\r\n ) {\r\n const nextUrl = (response as { url: string }).url\r\n revokeUrl(file.url)\r\n patch.url = nextUrl\r\n }\r\n patchFile(uid, patch)\r\n const latest = getFile(uid)\r\n if (latest) options.onSuccess?.(response, latest, fileList.value)\r\n },\r\n onError: (error) => {\r\n abortMap.delete(uid)\r\n patchFile(uid, { status: 'error', error })\r\n const latest = getFile(uid)\r\n options.onError?.(error, latest, fileList.value)\r\n },\r\n })\r\n\r\n if (handle && typeof handle === 'object' && handle.abort) {\r\n abortMap.set(uid, handle.abort)\r\n }\r\n }\r\n\r\n function upload(uid?: string) {\r\n if (uid) {\r\n startUpload(uid)\r\n return\r\n }\r\n uploadAll()\r\n }\r\n\r\n function uploadAll() {\r\n fileList.value\r\n .filter((f) => f.raw && (f.status === 'ready' || f.status === 'error'))\r\n .forEach((f) => startUpload(f.uid))\r\n }\r\n\r\n function abort(uid?: string) {\r\n if (uid) {\r\n abortMap.get(uid)?.()\r\n abortMap.delete(uid)\r\n const f = getFile(uid)\r\n if (f?.status === 'uploading') {\r\n patchFile(uid, { status: 'ready', percent: 0 })\r\n }\r\n return\r\n }\r\n abortMap.forEach((fn) => fn())\r\n abortMap.clear()\r\n emitList(\r\n fileList.value.map((f) =>\r\n f.status === 'uploading' ? { ...f, status: 'ready', percent: 0 } : f,\r\n ),\r\n )\r\n }\r\n\r\n function retry(uid: string) {\r\n const f = getFile(uid)\r\n if (!f?.raw) return\r\n patchFile(uid, { status: 'ready', percent: 0, error: undefined })\r\n startUpload(uid)\r\n }\r\n\r\n async function remove(uid: string) {\r\n if (unref(options.disabled)) return\r\n const file = getFile(uid)\r\n if (!file) return\r\n\r\n if (options.beforeRemove) {\r\n try {\r\n const ok = await options.beforeRemove(file)\r\n if (!ok) return\r\n } catch {\r\n return\r\n }\r\n }\r\n\r\n abortMap.get(uid)?.()\r\n abortMap.delete(uid)\r\n revokeUrl(file.url)\r\n\r\n const next = fileList.value.filter((f) => f.uid !== uid)\r\n emitList(next)\r\n options.onRemove?.(file, next)\r\n }\r\n\r\n function clear() {\r\n fileList.value.forEach((f) => {\r\n abortMap.get(f.uid)?.()\r\n revokeUrl(f.url)\r\n })\r\n abortMap.clear()\r\n emitList([])\r\n }\r\n\r\n function handleDragEnter(e: DragEvent) {\r\n if (unref(options.disabled) || !unref(options.drag)) return\r\n e.preventDefault()\r\n e.stopPropagation()\r\n dragCounter.value += 1\r\n isDragging.value = true\r\n }\r\n\r\n function handleDragOver(e: DragEvent) {\r\n if (unref(options.disabled) || !unref(options.drag)) return\r\n e.preventDefault()\r\n e.stopPropagation()\r\n }\r\n\r\n function handleDragLeave(e: DragEvent) {\r\n if (unref(options.disabled) || !unref(options.drag)) return\r\n e.preventDefault()\r\n e.stopPropagation()\r\n dragCounter.value -= 1\r\n if (dragCounter.value <= 0) {\r\n dragCounter.value = 0\r\n isDragging.value = false\r\n }\r\n }\r\n\r\n function handleDrop(e: DragEvent) {\r\n if (unref(options.disabled) || !unref(options.drag)) return\r\n e.preventDefault()\r\n e.stopPropagation()\r\n dragCounter.value = 0\r\n isDragging.value = false\r\n void addFiles(e.dataTransfer?.files)\r\n }\r\n\r\n function handlePaste(e: ClipboardEvent) {\r\n if (unref(options.disabled) || !unref(options.paste)) return\r\n const files = e.clipboardData?.files\r\n if (!files?.length) return\r\n e.preventDefault()\r\n void addFiles(files)\r\n }\r\n\r\n onUnmounted(() => {\r\n abortMap.forEach((fn) => fn())\r\n abortMap.clear()\r\n localObjectUrls.forEach((url) => URL.revokeObjectURL(url))\r\n localObjectUrls.clear()\r\n })\r\n\r\n return {\r\n fileList,\r\n isDragging,\r\n addFiles,\r\n remove,\r\n clear,\r\n upload,\r\n uploadAll,\r\n abort,\r\n retry,\r\n handleDragEnter,\r\n handleDragOver,\r\n handleDragLeave,\r\n handleDrop,\r\n handlePaste,\r\n canAddMore,\r\n }\r\n}\r\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,88 +1,79 @@
1
- {
2
- "name": "@will-ui/vue",
3
- "version": "1.0.1",
4
- "description": "Vue 3 UI component library (TypeScript + JSX)",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "module": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
- "exports": {
10
- ".": {
11
- "types": "./dist/index.d.ts",
12
- "development": "./index.ts",
13
- "import": "./dist/index.js",
14
- "default": "./dist/index.js"
15
- },
16
- "./style.css": {
17
- "development": "./styles/index.css",
18
- "default": "./dist/styles/index.css"
19
- },
20
- "./theme.css": {
21
- "development": "./theme/index.css",
22
- "default": "./dist/theme/index.css"
23
- },
24
- "./theme/*": "./dist/theme/tokens/*",
25
- "./components/*": {
26
- "types": "./dist/components/*/index.d.ts",
27
- "development": "./components/*/index.ts",
28
- "import": "./dist/components/*/index.js",
29
- "default": "./dist/components/*/index.js"
30
- },
31
- "./package.json": "./package.json"
32
- },
33
- "publishConfig": {
34
- "registry": "https://registry.npmjs.org/",
35
- "access": "public"
36
- },
37
- "files": [
38
- "dist",
39
- "README.md",
40
- "TAILWIND.md",
41
- "LICENSE"
42
- ],
43
- "sideEffects": [
44
- "*.css"
45
- ],
46
- "scripts": {
47
- "dev": "vite",
48
- "build": "vite build && node ../../scripts/embed-theme.mjs packages/ui",
49
- "type-check": "vue-tsc --noEmit",
50
- "prepublishOnly": "pnpm run build"
51
- },
52
- "peerDependencies": {
53
- "vue": "^3.5.0",
54
- "vue-i18n": "^9.0.0 || ^10.0.0"
55
- },
56
- "peerDependenciesMeta": {
57
- "vue-i18n": {
58
- "optional": false
59
- }
60
- },
61
- "dependencies": {
62
- "async-validator": "^4.2.5",
63
- "date-fns": "^3.6.0"
64
- },
65
- "devDependencies": {
66
- "@mono/theme": "workspace:*",
67
- "@types/node": "^25.9.2",
68
- "@vitejs/plugin-vue": "^6.0.8",
69
- "@vitejs/plugin-vue-jsx": "^5.1.6",
70
- "postcss": "^8.5.15",
71
- "typescript": "^5.9.3",
72
- "vite": "^8.2.1",
73
- "vite-plugin-dts": "^5.0.3",
74
- "vue": "^3.5.35",
75
- "vue-i18n": "^9.14.4",
76
- "vue-tsc": "^2.2.12"
77
- },
78
- "keywords": [
79
- "vue",
80
- "vue3",
81
- "ui",
82
- "component",
83
- "typescript",
84
- "jsx",
85
- "will-ui"
86
- ],
87
- "license": "MIT"
88
- }
1
+ {
2
+ "name": "@will-ui/vue",
3
+ "version": "1.0.2",
4
+ "description": "Vue 3 UI component library (TypeScript + JSX)",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "./style.css": "./dist/styles/index.css",
16
+ "./theme.css": "./dist/theme/index.css",
17
+ "./theme/*": "./dist/theme/tokens/*",
18
+ "./components/*": {
19
+ "types": "./dist/components/*/index.d.ts",
20
+ "import": "./dist/components/*/index.js",
21
+ "default": "./dist/components/*/index.js"
22
+ },
23
+ "./package.json": "./package.json"
24
+ },
25
+ "publishConfig": {
26
+ "registry": "https://registry.npmjs.org/",
27
+ "access": "public"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "README.md",
32
+ "TAILWIND.md",
33
+ "LICENSE"
34
+ ],
35
+ "sideEffects": [
36
+ "*.css"
37
+ ],
38
+ "peerDependencies": {
39
+ "vue": "^3.5.0",
40
+ "vue-i18n": "^9.0.0 || ^10.0.0"
41
+ },
42
+ "peerDependenciesMeta": {
43
+ "vue-i18n": {
44
+ "optional": false
45
+ }
46
+ },
47
+ "dependencies": {
48
+ "async-validator": "^4.2.5",
49
+ "date-fns": "^3.6.0"
50
+ },
51
+ "devDependencies": {
52
+ "@types/node": "^25.9.2",
53
+ "@vitejs/plugin-vue": "^6.0.8",
54
+ "@vitejs/plugin-vue-jsx": "^5.1.6",
55
+ "postcss": "^8.5.15",
56
+ "typescript": "^5.9.3",
57
+ "vite": "^8.2.1",
58
+ "vite-plugin-dts": "^5.0.3",
59
+ "vue": "^3.5.35",
60
+ "vue-i18n": "^9.14.4",
61
+ "vue-tsc": "^2.2.12",
62
+ "@mono/theme": "1.0.0"
63
+ },
64
+ "keywords": [
65
+ "vue",
66
+ "vue3",
67
+ "ui",
68
+ "component",
69
+ "typescript",
70
+ "jsx",
71
+ "will-ui"
72
+ ],
73
+ "license": "MIT",
74
+ "scripts": {
75
+ "dev": "vite",
76
+ "build": "vite build && node ../../scripts/embed-theme.mjs packages/ui",
77
+ "type-check": "vue-tsc --noEmit"
78
+ }
79
+ }
@@ -1,17 +0,0 @@
1
- import { Ref } from 'vue';
2
- type MaybeElement = HTMLElement | Ref<HTMLElement>;
3
- interface DragOptions {
4
- handler: MaybeElement;
5
- parent?: MaybeElement;
6
- direction: {
7
- x: boolean;
8
- y: boolean;
9
- };
10
- pos?: {
11
- left?: number;
12
- top?: number;
13
- };
14
- handleDragging: () => void;
15
- }
16
- export default function useDrag(options: DragOptions): void;
17
- export {};