weifuwu 0.60.0 → 0.61.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 (38) hide show
  1. package/README.md +23 -7
  2. package/dist/ai/agent.d.ts +29 -1
  3. package/dist/ai/client.d.ts +15 -0
  4. package/dist/ai/index.d.ts +2 -1
  5. package/dist/client/diff.d.ts +15 -0
  6. package/dist/client/hydration.d.ts +13 -0
  7. package/dist/client/index.d.ts +4 -0
  8. package/dist/client/index.js +3 -2214
  9. package/dist/client/middleware/api.d.ts +2 -0
  10. package/dist/client/motion.d.ts +8 -0
  11. package/dist/client/registry.d.ts +34 -0
  12. package/dist/client/render.d.ts +13 -14
  13. package/dist/client/types.d.ts +28 -0
  14. package/dist/client/ui.d.ts +56 -0
  15. package/dist/components/Badge/Badge.d.ts +1 -1
  16. package/dist/components/Button/Button.d.ts +3 -0
  17. package/dist/components/Card/Card.d.ts +2 -0
  18. package/dist/components/Confirm/Confirm.d.ts +8 -1
  19. package/dist/components/Dropdown/Dropdown.d.ts +2 -0
  20. package/dist/components/Icon/Icon.d.ts +19 -0
  21. package/dist/components/Input/Input.d.ts +5 -0
  22. package/dist/components/Modal/Modal.d.ts +2 -0
  23. package/dist/components/PageHeader/PageHeader.d.ts +2 -0
  24. package/dist/components/StatCard/StatCard.d.ts +2 -0
  25. package/dist/components/Table/Table.d.ts +4 -0
  26. package/dist/components/Toast/Toast.d.ts +13 -1
  27. package/dist/components/index.d.ts +2 -0
  28. package/dist/components/index.js +1 -3381
  29. package/dist/components/style.css +282 -134
  30. package/dist/core/router.d.ts +10 -10
  31. package/dist/core/serve.d.ts +1 -1
  32. package/dist/index.d.ts +3 -1
  33. package/dist/index.js +523 -11
  34. package/dist/layout/weifuwu-layout.css +106 -17
  35. package/dist/messager/index.d.ts +107 -0
  36. package/dist/types.d.ts +2 -2
  37. package/dist/user/index.d.ts +3 -2
  38. package/package.json +1 -1
@@ -1,3381 +1 @@
1
- // src/client/vnode.ts
2
- var ASYNC_MARK = "__wfAsyncComponent";
3
- function isAsyncComponent(type) {
4
- return typeof type === "function" && type?.[ASYNC_MARK] === true;
5
- }
6
- var Fragment = /* @__PURE__ */ Symbol("Fragment");
7
- var Portal = /* @__PURE__ */ Symbol("Portal");
8
- function h(type, props, ...children) {
9
- const p = normalizeProps(props ?? {});
10
- if (children.length > 0) {
11
- p.children = children.length === 1 ? children[0] : children;
12
- }
13
- return { type, props: p, key: props?.key ?? void 0 };
14
- }
15
- function normalizeProps(props) {
16
- if (!props) return {};
17
- const result = {};
18
- for (const key of Object.keys(props)) {
19
- if (key === "key") continue;
20
- result[key] = props[key];
21
- }
22
- return result;
23
- }
24
- function createPortal(children, portalKey) {
25
- return {
26
- type: Portal,
27
- props: { children, portalKey },
28
- key: portalKey ?? void 0,
29
- _placement: "remote"
30
- };
31
- }
32
-
33
- // src/components/Button/Button.ts
34
- var Button = (_init, ctx) => (props) => {
35
- const { variant = "primary", size = "md", block, loading, disabled, type, onClick, children } = props;
36
- const cls = [
37
- "wf-btn",
38
- `wf-btn--${variant}`,
39
- `wf-btn--${size}`,
40
- block && "wf-btn--block",
41
- loading && "wf-btn--loading"
42
- ].filter(Boolean).join(" ");
43
- const L = ctx?.i18n?.components?.Button ?? {};
44
- return h("button", {
45
- class: cls,
46
- type: type ?? "button",
47
- disabled: disabled || loading || void 0,
48
- "aria-busy": loading || void 0,
49
- onClick
50
- }, loading ? L.loading ?? "\u52A0\u8F7D\u4E2D..." : children);
51
- };
52
-
53
- // src/components/Input/Input.ts
54
- var Input = (_init) => (props) => {
55
- const { label, name, type = "text", value, placeholder, required, disabled, error, hint, variant = "default", onInput, onChange } = props;
56
- const inputEl = h("input", {
57
- class: `wf-input${variant === "borderless" ? " wf-input--borderless" : ""}`,
58
- name: name || void 0,
59
- type,
60
- value: value ?? "",
61
- placeholder,
62
- required: required || void 0,
63
- disabled: disabled || void 0,
64
- onInput,
65
- onChange
66
- });
67
- if (!label && !error && !hint) return inputEl;
68
- const children = [];
69
- if (label) {
70
- const labelContent = [label];
71
- if (required) labelContent.push(h("span", { class: "wf-input-req" }, "*"));
72
- children.push(h("label", { class: "wf-input-label" }, labelContent));
73
- }
74
- children.push(inputEl);
75
- if (error) children.push(h("div", { class: "wf-input-err" }, error));
76
- if (hint && !error) children.push(h("div", { class: "wf-input-hint" }, hint));
77
- return h("div", { class: `wf-input-wrap${error ? " wf-input--err" : ""}` }, children);
78
- };
79
-
80
- // src/components/Textarea/Textarea.ts
81
- var Textarea = (_init, _ctx) => (props) => {
82
- const { label, value, placeholder, required, disabled, error, hint, rows = 3, maxLength, showCount, onInput } = props;
83
- const textareaEl = h("textarea", {
84
- class: "wf-textarea",
85
- value: value ?? "",
86
- placeholder,
87
- required: required || void 0,
88
- disabled: disabled || void 0,
89
- rows,
90
- maxLength,
91
- onInput
92
- });
93
- const children = [];
94
- if (label) {
95
- const labelContent = [label];
96
- if (required) labelContent.push(h("span", { class: "wf-textarea-req" }, "*"));
97
- children.push(h("label", { class: "wf-textarea-label" }, labelContent));
98
- }
99
- children.push(textareaEl);
100
- if (showCount) {
101
- const len = (value ?? "").length;
102
- const over = maxLength != null && len > maxLength;
103
- children.push(h("div", {
104
- class: `wf-textarea-count${over ? " wf-textarea-count--over" : ""}`,
105
- "aria-live": "polite"
106
- }, maxLength != null ? `${len}/${maxLength}` : String(len)));
107
- }
108
- if (error) children.push(h("div", { class: "wf-textarea-err" }, error));
109
- if (hint && !error) children.push(h("div", { class: "wf-textarea-hint" }, hint));
110
- return h("div", { class: `wf-textarea-wrap${error ? " wf-textarea--err" : ""}` }, children);
111
- };
112
-
113
- // src/components/Select/Select.ts
114
- var SelectNative = (_init, _ctx) => (props) => {
115
- const { label, value, options, placeholder, required, disabled, error, onChange, children } = props;
116
- const optionEls = [];
117
- if (placeholder) {
118
- optionEls.push(h("option", { value: "", disabled: true }, placeholder));
119
- }
120
- if (options) {
121
- for (const opt of options) {
122
- optionEls.push(h("option", { value: opt.value, disabled: opt.disabled }, opt.label));
123
- }
124
- }
125
- const selectEl = h("select", {
126
- class: "wf-select",
127
- value: value ?? "",
128
- required: required || void 0,
129
- disabled: disabled || void 0,
130
- onChange: (e) => onChange?.(e.target.value)
131
- }, children ?? optionEls);
132
- const wrapChildren = [];
133
- if (label) {
134
- const labelContent = [label];
135
- if (required) labelContent.push(h("span", { class: "wf-select-req" }, "*"));
136
- wrapChildren.push(h("label", { class: "wf-select-label" }, labelContent));
137
- }
138
- wrapChildren.push(selectEl);
139
- if (error) wrapChildren.push(h("div", { class: "wf-select-err" }, error));
140
- return h("div", { class: `wf-select-wrap${error ? " wf-select--err" : ""}` }, wrapChildren);
141
- };
142
- var SelectSearchable = (_init, ctx) => {
143
- const $ = ctx.ui.$();
144
- $.open = false;
145
- $.keyword = "";
146
- $.filteredOptions = [];
147
- return (props) => {
148
- const { label, value, options = [], placeholder, required, disabled, error, onChange, onSearch } = props;
149
- const filtered = $.keyword ? options.filter((o) => o.label.toLowerCase().includes($.keyword.toLowerCase())) : options;
150
- const selectedOption = options.find((o) => o.value === value);
151
- const handleInput = async (keyword) => {
152
- $.keyword = keyword;
153
- $.open = true;
154
- if (onSearch && keyword) {
155
- const result = await onSearch(keyword);
156
- if (result) $.filteredOptions = result;
157
- }
158
- };
159
- const handleSelect = (opt) => {
160
- if (opt.disabled) return;
161
- $.keyword = "";
162
- $.open = false;
163
- onChange?.(opt.value);
164
- };
165
- const trigger = h("div", {
166
- class: `wf-select-search-trigger${disabled ? " wf-select-search--disabled" : ""}${error ? " wf-select--err" : ""}`,
167
- onClick: disabled ? void 0 : () => {
168
- $.open = !$.open;
169
- }
170
- }, [
171
- h("input", {
172
- class: "wf-select-search-input",
173
- type: "text",
174
- value: $.open ? $.keyword : selectedOption?.label ?? "",
175
- placeholder: selectedOption ? void 0 : placeholder ?? "",
176
- disabled,
177
- readOnly: !$.open || void 0,
178
- onInput: (e) => handleInput(e.target.value),
179
- onFocus: () => {
180
- if (!disabled) $.open = true;
181
- },
182
- onBlur: () => {
183
- setTimeout(() => {
184
- $.open = false;
185
- $.keyword = "";
186
- }, 150);
187
- }
188
- })
189
- ]);
190
- const wrapChildren = [];
191
- if (label) {
192
- const labelContent = [label];
193
- if (required) labelContent.push(h("span", { class: "wf-select-req" }, "*"));
194
- wrapChildren.push(h("label", { class: "wf-select-label" }, labelContent));
195
- }
196
- const displayOptions = $.keyword && onSearch && $.filteredOptions.length > 0 ? $.filteredOptions : filtered;
197
- const menuChildren = displayOptions.length > 0 ? displayOptions.map(
198
- (opt) => h("div", {
199
- class: `wf-select-search-opt${opt.value === value ? " wf-select-search-opt--sel" : ""}${opt.disabled ? " wf-select-search-opt--dis" : ""}`,
200
- key: opt.value,
201
- onMouseDown: (e) => {
202
- e.preventDefault();
203
- handleSelect(opt);
204
- }
205
- }, opt.label)
206
- ) : $.keyword ? [h("div", { class: "wf-select-search-empty" }, "\u65E0\u5339\u914D")] : [];
207
- const menu = $.open ? h("div", { class: "wf-select-search-menu" }, menuChildren) : null;
208
- wrapChildren.push(h("div", { class: "wf-select-search" }, [trigger, menu].filter(Boolean)));
209
- if (error) wrapChildren.push(h("div", { class: "wf-select-err" }, error));
210
- return h("div", { class: `wf-select-wrap${error ? " wf-select--err" : ""}` }, wrapChildren);
211
- };
212
- };
213
- var Select = (_init, ctx) => {
214
- const nativeRender = SelectNative(_init, ctx);
215
- const searchableRender = SelectSearchable(_init, ctx);
216
- return (props) => props.searchable ? searchableRender(props) : nativeRender(props);
217
- };
218
-
219
- // src/components/Checkbox/Checkbox.ts
220
- var Checkbox = (_init, _ctx) => (props) => {
221
- const { label, checked, disabled, onChange } = props;
222
- const input = h("input", {
223
- type: "checkbox",
224
- class: "wf-checkbox-input",
225
- checked: checked || void 0,
226
- disabled: disabled || void 0,
227
- onChange: onChange ? (e) => onChange(e.target.checked) : void 0
228
- });
229
- const visual = h("span", { class: "wf-checkbox-visual" });
230
- if (!label) return h("label", { class: "wf-checkbox" }, [input, visual]);
231
- return h("label", { class: "wf-checkbox" }, [
232
- input,
233
- visual,
234
- h("span", { class: "wf-checkbox-label" }, label)
235
- ]);
236
- };
237
-
238
- // src/components/Switch/Switch.ts
239
- var Switch = (_init, ctx) => (props) => {
240
- const { label, checked, disabled, onChange } = props;
241
- const input = h("input", {
242
- type: "checkbox",
243
- class: "wf-switch-input",
244
- checked: checked || void 0,
245
- disabled: disabled || void 0,
246
- role: "switch",
247
- "aria-checked": String(!!checked),
248
- onChange: onChange ? (e) => onChange(e.target.checked) : void 0
249
- });
250
- const track = h("span", { class: "wf-switch-track" });
251
- const SL = ctx?.i18n?.components?.Switch ?? {};
252
- if (!label) return h("label", { class: "wf-switch", "aria-label": SL.ariaLabel ?? "\u5207\u6362" }, [input, track]);
253
- return h("label", { class: "wf-switch" }, [
254
- input,
255
- track,
256
- h("span", { class: "wf-switch-label" }, label)
257
- ]);
258
- };
259
-
260
- // src/components/RadioGroup/RadioGroup.ts
261
- var RadioGroup = (_init, _ctx) => (props) => {
262
- const { name, value, options = [], inline, onChange } = props;
263
- const radios = options.map((opt) => {
264
- const input = h("input", {
265
- type: "radio",
266
- class: "wf-radio-input",
267
- name: name ?? "radio",
268
- value: opt.value,
269
- checked: value === opt.value || void 0,
270
- disabled: opt.disabled || void 0,
271
- onChange: onChange ? () => onChange(opt.value) : void 0
272
- });
273
- const visual = h("span", { class: "wf-radio-visual" });
274
- const label = h("span", { class: "wf-radio-label-text" }, opt.label);
275
- return h("label", {
276
- class: "wf-radio",
277
- key: opt.value
278
- }, [input, visual, label]);
279
- });
280
- return h("div", {
281
- class: `wf-radio-group${inline ? " wf-radio-group--inline" : ""}`
282
- }, radios);
283
- };
284
-
285
- // src/components/Table/Table.ts
286
- function sortData(data, columns, sortKey, sortOrder) {
287
- if (!sortKey || !sortOrder) return data;
288
- const col = columns.find((c) => c.key === sortKey);
289
- if (!col || !col.sortable) return data;
290
- const sorted = [...data];
291
- sorted.sort((a, b) => {
292
- const va = a[sortKey];
293
- const vb = b[sortKey];
294
- const result = col.sorter ? col.sorter(va, vb) : String(va ?? "").localeCompare(String(vb ?? ""));
295
- return sortOrder === "desc" ? -result : result;
296
- });
297
- return sorted;
298
- }
299
- var Table = (_init, _ctx) => (props) => {
300
- const { data = [], columns, onRowClick, sortKey, sortOrder, onSort, emptyText } = props;
301
- const sortedData = sortData(data, columns, sortKey, sortOrder);
302
- const headerCells = columns.map((col) => {
303
- const isSorted = col.key === sortKey && sortOrder;
304
- const isAsc = sortOrder === "asc";
305
- let label = col.label;
306
- if (col.sortable) {
307
- label += isSorted ? isAsc ? " \u25B2" : " \u25BC" : " \u21C5";
308
- }
309
- return h("th", {
310
- class: `wf-table-th${col.sortable ? " wf-table-th--sortable" : ""}${isSorted ? " wf-table-th--sorted" : ""}`,
311
- scope: "col",
312
- tabindex: col.sortable ? 0 : void 0,
313
- style: col.width ? { width: col.width } : void 0,
314
- onClick: col.sortable && onSort ? () => onSort(col.key, isSorted && isAsc ? "desc" : "asc") : void 0
315
- }, label);
316
- });
317
- const headerRow = h("tr", { class: "wf-table-tr" }, headerCells);
318
- const thead = h("thead", { class: "wf-table-thead" }, headerRow);
319
- let bodyRows;
320
- if (sortedData.length === 0 && emptyText) {
321
- const colspan = columns.length;
322
- bodyRows = [
323
- h(
324
- "tr",
325
- { class: "wf-table-tr" },
326
- h("td", { class: "wf-table-td wf-table-empty", colspan, style: { textAlign: "center" } }, emptyText)
327
- )
328
- ];
329
- } else {
330
- bodyRows = sortedData.map((row, i) => {
331
- const cells = columns.map((col) => {
332
- const val = row[col.key];
333
- const content = col.render ? col.render(val, row, i) : String(val ?? "");
334
- return h("td", { class: "wf-table-td" }, content);
335
- });
336
- return h("tr", {
337
- class: "wf-table-tr",
338
- onClick: onRowClick ? () => onRowClick(row, i) : void 0,
339
- style: onRowClick ? { cursor: "pointer" } : void 0
340
- }, cells);
341
- });
342
- }
343
- const tbody = h("tbody", { class: "wf-table-tbody" }, bodyRows);
344
- const table = h("table", {
345
- class: "wf-table",
346
- style: props.minWidth ? { minWidth: props.minWidth } : void 0
347
- }, [thead, tbody]);
348
- return h("div", { class: "wf-table-wrap" }, table);
349
- };
350
-
351
- // src/client/scroll-lock.ts
352
- var lockedCount = 0;
353
- var originalOverflow = "";
354
- var originalPosition = "";
355
- var originalTop = "";
356
- var originalWidth = "";
357
- var scrollY = 0;
358
- function canLock() {
359
- return typeof window !== "undefined" && typeof document !== "undefined";
360
- }
361
- function lockScroll() {
362
- lockedCount++;
363
- if (lockedCount > 1) return;
364
- if (!canLock()) return;
365
- scrollY = window.scrollY;
366
- const body = document.body;
367
- originalOverflow = body.style.overflow;
368
- originalPosition = body.style.position;
369
- originalTop = body.style.top;
370
- originalWidth = body.style.width;
371
- body.style.overflow = "hidden";
372
- const isIOS = /iPhone|iPad|iPod/.test(navigator.platform) || /Mac/.test(navigator.platform) && "ontouchend" in document;
373
- if (isIOS) {
374
- body.style.position = "fixed";
375
- body.style.top = `-${scrollY}px`;
376
- body.style.width = "100%";
377
- }
378
- }
379
- function unlockScroll() {
380
- lockedCount--;
381
- if (lockedCount > 0) return;
382
- if (!canLock()) return;
383
- const body = document.body;
384
- body.style.overflow = originalOverflow;
385
- body.style.position = originalPosition;
386
- body.style.top = originalTop;
387
- body.style.width = originalWidth;
388
- if (scrollY > 0) window.scrollTo(0, scrollY);
389
- }
390
-
391
- // src/client/focus-trap.ts
392
- var FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
393
- function trapFocus(container) {
394
- const focusable = container.querySelectorAll(FOCUSABLE);
395
- if (focusable.length === 0) return () => {
396
- };
397
- const first = focusable[0];
398
- const last = focusable[focusable.length - 1];
399
- const handler = (e) => {
400
- if (e.key !== "Tab") return;
401
- if (e.shiftKey && document.activeElement === first) {
402
- e.preventDefault();
403
- last.focus();
404
- } else if (!e.shiftKey && document.activeElement === last) {
405
- e.preventDefault();
406
- first.focus();
407
- }
408
- };
409
- const prevFocused = document.activeElement;
410
- first.focus();
411
- container.addEventListener("keydown", handler);
412
- return () => {
413
- container.removeEventListener("keydown", handler);
414
- prevFocused?.focus();
415
- };
416
- }
417
-
418
- // src/components/Modal/Modal.ts
419
- var Modal = (_props, ctx) => {
420
- let prevOpen;
421
- let focusCleanup;
422
- const rootRef = (el) => {
423
- if (el) {
424
- lockScroll();
425
- const modalEl = el.querySelector(".wf-modal") ?? el;
426
- focusCleanup = trapFocus(modalEl);
427
- } else {
428
- unlockScroll();
429
- focusCleanup?.();
430
- }
431
- };
432
- return (props) => {
433
- const { open, title, onClose, children, footer, width, closable = true } = props;
434
- const ML = ctx?.i18n?.components?.Modal ?? {};
435
- if (prevOpen !== open) {
436
- prevOpen = open;
437
- }
438
- if (!open) return null;
439
- const overlay = h("div", {
440
- class: "wf-modal-overlay",
441
- onClick: onClose
442
- });
443
- const closeBtn = closable ? h("button", {
444
- class: "wf-modal-close",
445
- onClick: onClose,
446
- type: "button"
447
- }, "\u2715") : null;
448
- const titleEl = title ? h("div", { class: "wf-modal-header" }, [title, closeBtn].filter(Boolean)) : null;
449
- const bodyEl = h("div", { class: "wf-modal-body" }, children);
450
- const footerEl = footer ? h("div", { class: "wf-modal-footer" }, footer) : null;
451
- const content = h("div", {
452
- class: "wf-modal-content",
453
- onClick: (e) => e.stopPropagation(),
454
- style: width ? { minWidth: width, maxWidth: width } : void 0
455
- }, [titleEl, bodyEl, footerEl].filter(Boolean));
456
- const root = h("div", {
457
- ref: rootRef,
458
- class: "wf-modal wf-modal--enter",
459
- role: "dialog",
460
- "aria-modal": "true",
461
- "aria-label": title ?? (ML.ariaLabel ?? "\u5F39\u7A97")
462
- }, [overlay, content]);
463
- return createPortal(root, "modal");
464
- };
465
- };
466
-
467
- // src/client/render.ts
468
- var SVG_NS = "http://www.w3.org/2000/svg";
469
- var SVG_TAGS = /* @__PURE__ */ new Set(["svg", "path", "circle", "line", "rect", "text", "g", "polyline", "polygon", "ellipse", "defs", "use", "clipPath", "mask", "linearGradient", "radialGradient", "stop", "tspan"]);
470
- var _idCounter = 0;
471
- var idRegistry = /* @__PURE__ */ new Map();
472
- function renderValue(v, ctx) {
473
- if (v == null || typeof v === "boolean") return null;
474
- if (typeof v === "string" || typeof v === "number") return document.createTextNode(String(v));
475
- if (Array.isArray(v)) return renderArray(v, ctx);
476
- const vnode = v;
477
- if (vnode.type === Portal) {
478
- renderPortal(vnode, ctx);
479
- return null;
480
- }
481
- if (vnode.type === Fragment) {
482
- const frag = document.createDocumentFragment();
483
- const children = vnode.props?.children == null ? [] : Array.isArray(vnode.props.children) ? vnode.props.children : [vnode.props.children];
484
- for (const child of children) {
485
- const node = renderValue(child, ctx);
486
- if (node != null) frag.appendChild(node);
487
- }
488
- return frag;
489
- }
490
- if (typeof vnode.type === "function") {
491
- return renderComponent(vnode.type, vnode.props, vnode, ctx);
492
- }
493
- const tag = vnode.type;
494
- const el = SVG_TAGS.has(tag) ? document.createElementNS(SVG_NS, tag) : document.createElement(tag);
495
- vnode.el = el;
496
- let selectValue;
497
- for (const [key, value] of Object.entries(vnode.props ?? {})) {
498
- if (key === "children" || key === "key" || key === "value" || key === "innerHTML") continue;
499
- setProp(el, key, value);
500
- }
501
- if ("value" in (vnode.props ?? {}) && el instanceof HTMLSelectElement) {
502
- selectValue = vnode.props.value;
503
- } else if ("value" in (vnode.props ?? {})) {
504
- setProp(el, "value", vnode.props.value);
505
- }
506
- if ("innerHTML" in (vnode.props ?? {})) {
507
- el.innerHTML = String(vnode.props.innerHTML ?? "");
508
- } else {
509
- const flatChildren = flattenChildren(vnode.props?.children);
510
- for (const child of flatChildren) {
511
- const childNode = renderValue(child, ctx);
512
- if (childNode == null) continue;
513
- el.appendChild(childNode);
514
- if (child && typeof child === "object" && typeof child.type === "function") {
515
- const childVNode = child;
516
- if (!childVNode._parentNode) {
517
- childVNode._parentNode = el;
518
- childVNode._refNode = childNode;
519
- }
520
- }
521
- }
522
- }
523
- if (selectValue !== void 0) {
524
- ;
525
- el.value = String(selectValue);
526
- }
527
- if (typeof vnode.props?.ref === "function") vnode.props.ref(el);
528
- return el;
529
- }
530
- var asyncFactoryCache = /* @__PURE__ */ new WeakMap();
531
- function startAsyncFactory(Comp, ctx) {
532
- const existing = asyncFactoryCache.get(Comp);
533
- if (existing) return existing;
534
- const entry = { promise: null };
535
- entry.promise = Promise.resolve().then(() => Comp(ctx)).then((def) => {
536
- if (typeof def !== "function") {
537
- throw new Error(
538
- `asyncComponent factory <${Comp.name || "anonymous"}> must return a Component (initProps, ctx) => (props) => VNode.`
539
- );
540
- }
541
- entry.resolved = def;
542
- return def;
543
- });
544
- asyncFactoryCache.set(Comp, entry);
545
- return entry;
546
- }
547
- function resolveAsyncFactorySync(Comp) {
548
- return asyncFactoryCache.get(Comp)?.resolved;
549
- }
550
- function scheduleFullReRender(ctx) {
551
- const ui = ctx.ui;
552
- if (ui && typeof ui.render === "function") ui.render(["_wf_root"]);
553
- }
554
- function mountComponent(Comp, props, vnode, ctx) {
555
- let def;
556
- if (isAsyncComponent(Comp)) {
557
- def = resolveAsyncFactorySync(Comp);
558
- if (!def) {
559
- void startAsyncFactory(Comp, ctx).promise.then(
560
- () => scheduleFullReRender(ctx),
561
- () => {
562
- }
563
- );
564
- return null;
565
- }
566
- } else {
567
- def = Comp;
568
- }
569
- let childVNode = def(props, ctx);
570
- if (typeof childVNode !== "function") {
571
- throw new Error(
572
- `Component ${Comp.name || "anonymous"} must return a render function. Use (init_props, ctx) => (props) => VNode pattern.`
573
- );
574
- }
575
- vnode._render = childVNode;
576
- return childVNode(props);
577
- }
578
- function renderComponent(Comp, props, vnode, ctx) {
579
- ;
580
- ctx.ui = ctx.ui ?? {};
581
- if (!vnode._id) {
582
- vnode._id = `_wf_${_idCounter++}`;
583
- idRegistry.set(vnode._id, vnode);
584
- }
585
- const childCtx = Object.create(ctx);
586
- childCtx.ui = Object.create(ctx.ui);
587
- childCtx.ui._selfId = vnode._id;
588
- childCtx.ui._selfVNode = vnode;
589
- vnode._ctxVersion = childCtx.ui._ctxVersion ?? 0;
590
- let childVNode;
591
- try {
592
- childVNode = mountComponent(Comp, props, vnode, childCtx);
593
- } catch (e) {
594
- const errHandler = ctx.ui?._errorHandler;
595
- if (errHandler) {
596
- errHandler(e);
597
- childVNode = null;
598
- } else {
599
- console.error(
600
- `[weifuwu] Component render error in <${Comp.name || "anonymous"}> (id: ${vnode._id ?? "?"}, phase: mount)`,
601
- e
602
- );
603
- childVNode = null;
604
- }
605
- }
606
- if (childVNode == null) {
607
- vnode._child = null;
608
- return null;
609
- }
610
- vnode._child = childVNode;
611
- const domNode = renderValue(childVNode, childCtx);
612
- if (!vnode._refNode) {
613
- ;
614
- vnode._refNode = domNode;
615
- }
616
- return domNode;
617
- }
618
- function renderArray(arr, ctx) {
619
- const frag = document.createDocumentFragment();
620
- for (const item of arr) {
621
- const node = renderValue(item, ctx);
622
- if (node != null) frag.appendChild(node);
623
- }
624
- return frag;
625
- }
626
- function ensurePortalContainer() {
627
- let c = document.getElementById("__wf_portal");
628
- if (!c) {
629
- c = document.createElement("div");
630
- c.id = "__wf_portal";
631
- c.style.cssText = "position:fixed;inset:0;pointer-events:none;z-index:9999";
632
- document.body.appendChild(c);
633
- }
634
- return c;
635
- }
636
- function renderPortal(vnode, ctx) {
637
- const container = ensurePortalContainer();
638
- const sub = document.createElement("div");
639
- sub.style.pointerEvents = "auto";
640
- container.appendChild(sub);
641
- vnode._remoteEl = sub;
642
- const children = normalize(vnode.props?.children);
643
- vnode._child = children;
644
- for (const child of children) {
645
- const node = renderValue(child, ctx);
646
- if (node != null) sub.appendChild(node);
647
- }
648
- }
649
- function flattenChildren(children) {
650
- if (children == null) return [];
651
- if (!Array.isArray(children)) return [children];
652
- const result = [];
653
- for (const child of children) {
654
- if (Array.isArray(child)) {
655
- result.push(...child);
656
- } else {
657
- result.push(child);
658
- }
659
- }
660
- return result;
661
- }
662
- function setProp(el, key, value) {
663
- if (key === "class" || key === "className") {
664
- if (el instanceof SVGElement) el.setAttribute("class", String(value ?? ""));
665
- else el.className = String(value ?? "");
666
- } else if (key === "style" && typeof value === "object" && value !== null) {
667
- const st = el.style;
668
- for (const sk of Object.keys(value)) {
669
- const sv = value[sk];
670
- if (sv != null) st[sk] = typeof sv === "number" ? sv + "px" : String(sv);
671
- }
672
- } else if (key.startsWith("on") && typeof value === "function") {
673
- el.addEventListener(key.slice(2).toLowerCase(), value);
674
- } else if (key === "value" && (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement)) {
675
- ;
676
- el.value = String(value ?? "");
677
- } else if (value === true) {
678
- el.setAttribute(key, "");
679
- } else if (value != null && value !== false) {
680
- el.setAttribute(key, String(value));
681
- }
682
- }
683
- function normalize(children) {
684
- if (children == null) return [];
685
- if (!Array.isArray(children)) return [children];
686
- const result = [];
687
- for (const child of children) {
688
- if (Array.isArray(child)) {
689
- result.push(...child);
690
- } else {
691
- result.push(child);
692
- }
693
- }
694
- return result;
695
- }
696
- function cleanupPortalChildren(vnode) {
697
- const child = vnode._child;
698
- if (child == null) return;
699
- if (Array.isArray(child)) {
700
- for (const c of child) {
701
- if (c && typeof c === "object") callRefCleanup(c);
702
- }
703
- } else if (typeof child === "object") {
704
- callRefCleanup(child);
705
- }
706
- }
707
- function callRefCleanup(input) {
708
- if (input == null || typeof input !== "object") return;
709
- const vnode = input;
710
- if (vnode._id) {
711
- if (vnode._customId) idRegistry.delete(vnode._customId);
712
- idRegistry.delete(vnode._id);
713
- vnode._id = void 0;
714
- vnode._customId = void 0;
715
- vnode._render = void 0;
716
- vnode._parentNode = void 0;
717
- vnode._refNode = void 0;
718
- }
719
- if (vnode._child != null) {
720
- if (Array.isArray(vnode._child)) {
721
- for (const child of vnode._child) {
722
- if (child && typeof child === "object") callRefCleanup(child);
723
- }
724
- } else {
725
- callRefCleanup(vnode._child);
726
- }
727
- vnode._child = void 0;
728
- }
729
- if (vnode.props?.children && typeof vnode.type === "string") {
730
- const children = Array.isArray(vnode.props.children) ? vnode.props.children : [vnode.props.children];
731
- for (const child of children) {
732
- if (child && typeof child === "object") callRefCleanup(child);
733
- }
734
- }
735
- if (typeof vnode.props?.ref === "function") vnode.props.ref(null);
736
- if (vnode._remoteEl) {
737
- cleanupPortalChildren(vnode);
738
- vnode._remoteEl.remove();
739
- vnode._remoteEl = void 0;
740
- }
741
- }
742
- function mountVNode(container, vnode, ctx) {
743
- container.innerHTML = "";
744
- const node = renderValue(vnode, ctx);
745
- if (node instanceof Node) container.appendChild(node);
746
- else if (Array.isArray(node)) node.forEach((n) => container.appendChild(n));
747
- }
748
-
749
- // src/components/Confirm/Confirm.ts
750
- function confirm() {
751
- return (ctx) => {
752
- ;
753
- ctx.confirm = (message, options) => createConfirm(message, options ?? {}, ctx);
754
- return ctx;
755
- };
756
- }
757
- function createConfirm(message, options, ctx) {
758
- return new Promise((resolve) => {
759
- const container = document.createElement("div");
760
- document.body.appendChild(container);
761
- let settled = false;
762
- const vnode = h(Confirm, {
763
- open: true,
764
- title: options.title,
765
- message,
766
- confirmText: options.confirmText,
767
- cancelText: options.cancelText,
768
- variant: options.variant,
769
- width: options.width,
770
- onConfirm: () => finish(true),
771
- onCancel: () => finish(false)
772
- });
773
- const finish = (result) => {
774
- if (settled) return;
775
- settled = true;
776
- callRefCleanup(vnode);
777
- container.remove();
778
- resolve(result);
779
- };
780
- mountVNode(container, vnode, ctx);
781
- });
782
- }
783
- var Confirm = (_init, ctx) => {
784
- let prevOpen = false;
785
- let escCleanup;
786
- return (props) => {
787
- const { open = false, title, message, confirmText, cancelText, variant = "primary", width, onConfirm, onCancel } = props;
788
- const CL = ctx?.i18n?.components?.Confirm ?? {};
789
- if (open && !prevOpen) {
790
- const onKeyDown = (e) => {
791
- if (e.key === "Escape") onCancel?.();
792
- };
793
- document.addEventListener("keydown", onKeyDown);
794
- escCleanup = () => document.removeEventListener("keydown", onKeyDown);
795
- } else if (!open && prevOpen) {
796
- escCleanup?.();
797
- escCleanup = void 0;
798
- }
799
- prevOpen = open;
800
- const footer = [
801
- h(
802
- Button,
803
- { variant: "secondary", size: "md", onClick: () => onCancel?.() },
804
- cancelText ?? CL.cancelText ?? "\u53D6\u6D88"
805
- ),
806
- h(
807
- Button,
808
- { variant, size: "md", onClick: () => onConfirm?.() },
809
- confirmText ?? CL.confirmText ?? "\u786E\u5B9A"
810
- )
811
- ];
812
- return h(Modal, {
813
- open,
814
- title,
815
- onClose: onCancel,
816
- // 遮罩点击 = 取消
817
- footer,
818
- width,
819
- closable: false
820
- // 确认对话框无 ✕ 关闭按钮
821
- }, message);
822
- };
823
- };
824
-
825
- // src/components/Toast/Toast.ts
826
- function positionClass(pos) {
827
- const map = {
828
- "top-right": "wf-toast--tr",
829
- "top-left": "wf-toast--tl",
830
- "bottom-right": "wf-toast--br",
831
- "bottom-left": "wf-toast--bl",
832
- "top-center": "wf-toast--tc"
833
- };
834
- return map[pos] ?? "wf-toast--tr";
835
- }
836
- var Toast = (_init, ctx) => (props) => {
837
- const { toasts = [], onRemove, position = "top-right", duration = 0, max = 0 } = props;
838
- const visible = max > 0 && toasts.length > max ? toasts.slice(-max) : toasts;
839
- if (visible.length === 0) return null;
840
- const items = visible.map(
841
- (t) => h("div", {
842
- class: `wf-toast wf-toast--${t.type}`,
843
- key: t.id,
844
- "data-duration": (t.duration ?? duration) || void 0,
845
- onClick: onRemove ? () => onRemove(t.id) : void 0
846
- }, [
847
- h("span", { class: "wf-toast-icon" }, iconFor(t.type)),
848
- h("span", { class: "wf-toast-msg" }, t.message)
849
- ])
850
- );
851
- return createPortal(
852
- h("div", {
853
- class: `wf-toast-container ${positionClass(position)}`,
854
- "data-max": max || void 0
855
- }, items),
856
- "toast"
857
- );
858
- };
859
- function iconFor(type) {
860
- switch (type) {
861
- case "success":
862
- return "\u2713";
863
- case "error":
864
- return "\u2715";
865
- case "warning":
866
- return "\u26A0";
867
- case "info":
868
- return "\u2139";
869
- }
870
- }
871
- function toast(opts) {
872
- const defaults = {
873
- position: opts?.position ?? "top-right",
874
- duration: opts?.duration ?? 3e3,
875
- max: opts?.max ?? 3
876
- };
877
- let hostApi = null;
878
- let ctxRef = null;
879
- let seq = 0;
880
- const ToastHost = (_init, ctx) => {
881
- const $ = ctx.ui.$();
882
- $.toasts = [];
883
- hostApi = {
884
- add: (item) => {
885
- $.toasts = [...$.toasts, item];
886
- },
887
- remove: (id) => {
888
- $.toasts = $.toasts.filter((t) => t.id !== id);
889
- }
890
- };
891
- return () => h("div", { class: "wf-toast-host" }, [
892
- h(Toast, {
893
- toasts: $.toasts,
894
- position: defaults.position,
895
- duration: defaults.duration,
896
- max: defaults.max,
897
- onRemove: (id) => hostApi?.remove(id)
898
- })
899
- ]);
900
- };
901
- const ensureHost = () => {
902
- if (hostApi || !ctxRef) return;
903
- const container = document.createElement("div");
904
- document.body.appendChild(container);
905
- mountVNode(container, h(ToastHost, {}), ctxRef);
906
- };
907
- return (ctx) => {
908
- ctxRef = ctx;
909
- ctx.toast = (message, type = "info", duration) => {
910
- ensureHost();
911
- const id = String(++seq);
912
- hostApi?.add({ id, type, message, duration });
913
- const t = duration ?? defaults.duration;
914
- if (t > 0) {
915
- setTimeout(() => hostApi?.remove(id), t);
916
- }
917
- };
918
- return ctx;
919
- };
920
- }
921
-
922
- // src/components/Alert/Alert.ts
923
- var Alert = (_init, _ctx) => (props) => {
924
- const { variant = "info", closable, onClose, children } = props;
925
- if (!children) return null;
926
- const icon = h("span", { class: "wf-alert-icon" }, iconFor2(variant));
927
- const closeBtn = closable ? h("button", { class: "wf-alert-close", onClick: onClose, type: "button" }, "\u2715") : null;
928
- const msg = h("span", { class: "wf-alert-msg" }, children);
929
- return h("div", { class: `wf-alert wf-alert--${variant}`, role: "alert" }, [icon, msg, closeBtn].filter(Boolean));
930
- };
931
- function iconFor2(variant) {
932
- switch (variant) {
933
- case "success":
934
- return "\u2713";
935
- case "error":
936
- return "\u2715";
937
- case "warning":
938
- return "\u26A0";
939
- case "info":
940
- return "\u2139";
941
- }
942
- }
943
-
944
- // src/components/Loading/Loading.ts
945
- var Loading = (_init, _ctx) => (props) => {
946
- const { text = "\u52A0\u8F7D\u4E2D..." } = props;
947
- return h("div", { class: "wf-loading", role: "status", "aria-live": "polite" }, [
948
- h("div", { class: "wf-loading-spinner" }),
949
- h("span", { class: "wf-loading-text" }, text)
950
- ]);
951
- };
952
-
953
- // src/components/EmptyState/EmptyState.ts
954
- var EmptyState = (_init, _ctx) => (props) => {
955
- const { icon = "\u{1F4E6}", text = "\u6682\u65E0\u6570\u636E", hint, children } = props;
956
- const parts = [
957
- h("div", { class: "wf-empty-icon" }, icon),
958
- h("div", { class: "wf-empty-text" }, text)
959
- ];
960
- if (hint) parts.push(h("div", { class: "wf-empty-hint" }, hint));
961
- if (children) parts.push(h("div", { class: "wf-empty-action" }, children));
962
- return h("div", { class: "wf-empty", role: "status" }, parts);
963
- };
964
-
965
- // src/components/Tabs/Tabs.ts
966
- var Tabs = (_init, _ctx) => (props) => {
967
- const { items = [], active, onChange } = props;
968
- if (items.length === 0) return null;
969
- const activeKey = active ?? items[0].key;
970
- const tabList = items.map(
971
- (tab) => h("button", {
972
- class: `wf-tab${tab.key === activeKey ? " wf-tab--active" : ""}`,
973
- key: tab.key,
974
- role: "tab",
975
- "aria-selected": tab.key === activeKey ? "true" : "false",
976
- onClick: tab.key !== activeKey && onChange ? () => onChange(tab.key) : void 0
977
- }, tab.label)
978
- );
979
- const activeTab = items.find((t) => t.key === activeKey);
980
- const content = activeTab?.content ? h("div", { class: "wf-tab-content" }, activeTab.content) : null;
981
- return h("div", { class: "wf-tabs", role: "tablist" }, [
982
- h("div", { class: "wf-tab-list" }, tabList),
983
- content
984
- ].filter(Boolean));
985
- };
986
-
987
- // src/components/Dropdown/Dropdown.ts
988
- var Dropdown = (_init, ctx) => {
989
- let wrapEl = null;
990
- let latestOpen = false;
991
- let prevOpen = false;
992
- const pos = ctx.ui.usePopupPosition({
993
- el: () => wrapEl,
994
- isOpen: () => latestOpen,
995
- compute: (r) => ({ top: r.bottom + 4, left: r.left })
996
- });
997
- return (props) => {
998
- const { trigger, items = [], open } = props;
999
- latestOpen = !!open;
1000
- if (latestOpen && !prevOpen) pos.refresh();
1001
- prevOpen = latestOpen;
1002
- const menuItems = items.map(
1003
- (item, i) => h("button", {
1004
- class: `wf-dropdown-item${item.variant === "danger" ? " wf-dropdown-item--danger" : ""}`,
1005
- key: item.value ?? i,
1006
- disabled: item.disabled || void 0,
1007
- role: "menuitem",
1008
- onClick: item.onClick
1009
- }, item.label)
1010
- );
1011
- const menu = open ? h("div", {
1012
- class: "wf-dropdown-menu",
1013
- role: "menu",
1014
- style: { top: pos.top, left: pos.left }
1015
- }, menuItems) : null;
1016
- const portalContent = open ? createPortal(menu, "dropdown") : null;
1017
- return h("div", {
1018
- class: `wf-dropdown${open ? " wf-dropdown--open" : ""}`,
1019
- ref: (el) => {
1020
- wrapEl = el;
1021
- }
1022
- }, [trigger, portalContent].filter(Boolean));
1023
- };
1024
- };
1025
-
1026
- // src/components/Pagination/Pagination.ts
1027
- var Pagination = (_init, ctx) => (props) => {
1028
- const { total, page = 1, pageSize = 20, onChange } = props;
1029
- const totalPages = Math.max(1, Math.ceil(total / pageSize));
1030
- if (totalPages <= 1) return null;
1031
- const pages = [];
1032
- pages.push(h("button", {
1033
- class: `wf-page-btn${page <= 1 ? " wf-page-btn--disabled" : ""}`,
1034
- disabled: page <= 1,
1035
- onClick: page > 1 && onChange ? () => onChange(page - 1) : void 0
1036
- }, "\u2039"));
1037
- const range = getPageRange(page, totalPages);
1038
- for (const p of range) {
1039
- if (p === "...") {
1040
- pages.push(h("span", { class: "wf-page-ellipsis" }, "..."));
1041
- } else {
1042
- pages.push(h("button", {
1043
- class: `wf-page-btn${p === page ? " wf-page-btn--active" : ""}`,
1044
- "aria-current": p === page ? "page" : void 0,
1045
- onClick: p !== page && onChange ? () => onChange(p) : void 0
1046
- }, String(p)));
1047
- }
1048
- }
1049
- pages.push(h("button", {
1050
- class: `wf-page-btn${page >= totalPages ? " wf-page-btn--disabled" : ""}`,
1051
- disabled: page >= totalPages,
1052
- onClick: page < totalPages && onChange ? () => onChange(page + 1) : void 0
1053
- }, "\u203A"));
1054
- const PL = ctx?.i18n?.components?.Pagination ?? {};
1055
- return h("nav", { class: "wf-pagination", "aria-label": PL.ariaLabel ?? "\u5206\u9875" }, pages);
1056
- };
1057
- function getPageRange(current, total) {
1058
- if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1);
1059
- const pages = [1];
1060
- if (current > 3) pages.push("...");
1061
- const start = Math.max(2, current - 1);
1062
- const end = Math.min(total - 1, current + 1);
1063
- for (let i = start; i <= end; i++) pages.push(i);
1064
- if (current < total - 2) pages.push("...");
1065
- pages.push(total);
1066
- return pages;
1067
- }
1068
-
1069
- // src/components/Card/Card.ts
1070
- var Card = (_init, _ctx) => (props) => {
1071
- const { variant = "default", padding = "md", clickable, hover, active, onClick, children } = props;
1072
- const cls = [
1073
- "wf-card",
1074
- `wf-card--${variant}`,
1075
- `wf-card--pad-${padding}`,
1076
- clickable && "wf-card--clickable",
1077
- hover && "wf-card--hover",
1078
- active && "wf-card--active"
1079
- ].filter(Boolean).join(" ");
1080
- return h("div", { class: cls, onClick, role: clickable ? "button" : void 0, tabindex: clickable ? 0 : void 0 }, children);
1081
- };
1082
-
1083
- // src/components/Badge/Badge.ts
1084
- var Badge = (_init, _ctx) => (props) => {
1085
- const { variant = "default", dot, children } = props;
1086
- if (dot) {
1087
- return h("span", { class: `wf-badge-dot wf-badge-dot--${variant}` });
1088
- }
1089
- return h("span", { class: `wf-badge wf-badge--${variant}` }, children ?? "");
1090
- };
1091
-
1092
- // src/components/Avatar/Avatar.ts
1093
- var COLORS = ["#4f6ef7", "#22c55e", "#f59e0b", "#ef4444", "#8b5cf6", "#06b6d4", "#ec4899"];
1094
- function hashColor(name) {
1095
- let hash = 0;
1096
- for (let i = 0; i < name.length; i++) hash = name.charCodeAt(i) + ((hash << 5) - hash);
1097
- return COLORS[Math.abs(hash) % COLORS.length];
1098
- }
1099
- var Avatar = (_init, _ctx) => (props) => {
1100
- const { name = "", src, size = "md", color } = props;
1101
- const initial = name.trim()[0]?.toUpperCase() ?? "?";
1102
- if (src) {
1103
- return h("img", {
1104
- class: `wf-avatar wf-avatar--${size}`,
1105
- src,
1106
- alt: name
1107
- });
1108
- }
1109
- return h("div", {
1110
- class: `wf-avatar wf-avatar--${size}`,
1111
- style: { background: color ?? hashColor(name) }
1112
- }, initial);
1113
- };
1114
-
1115
- // src/components/Tag/Tag.ts
1116
- var Tag = (_init, _ctx) => (props) => {
1117
- const { closable, onClose, variant = "default", children } = props;
1118
- const closeBtn = closable ? h("button", { class: "wf-tag-close", onClick: onClose, type: "button" }, "\u2715") : null;
1119
- return h("span", { class: `wf-tag wf-tag--${variant}` }, [
1120
- h("span", { class: "wf-tag-text" }, children),
1121
- closeBtn
1122
- ].filter(Boolean));
1123
- };
1124
-
1125
- // src/components/StatCard/StatCard.ts
1126
- var StatCard = (_init, _ctx) => (props) => {
1127
- const { label, value, trend, trendLabel, icon, onClick } = props;
1128
- const children = [];
1129
- if (icon) children.push(h("div", { class: "wf-stat-icon" }, icon));
1130
- children.push(h("div", { class: "wf-stat-value" }, String(value)));
1131
- children.push(h("div", { class: "wf-stat-label" }, label));
1132
- if (trend) {
1133
- children.push(h("div", {
1134
- class: `wf-stat-trend wf-stat-trend--${trend}`
1135
- }, [
1136
- h("span", { class: "wf-stat-trend-arrow" }, trend === "up" ? "\u2191" : "\u2193"),
1137
- trendLabel ? h("span", { class: "wf-stat-trend-label" }, trendLabel) : null
1138
- ].filter(Boolean)));
1139
- }
1140
- return h("div", {
1141
- class: `wf-stat${onClick ? " wf-stat--clickable" : ""}`,
1142
- onClick,
1143
- role: onClick ? "button" : void 0,
1144
- tabindex: onClick ? 0 : void 0
1145
- }, children);
1146
- };
1147
-
1148
- // src/components/Steps/Steps.ts
1149
- var Steps = (_init, _ctx) => (props) => {
1150
- const { items = [], active, current = 0 } = props;
1151
- const activeKey = active ?? items[current]?.key;
1152
- const steps = items.map((item, i) => {
1153
- const idx = items.findIndex((s) => s.key === activeKey);
1154
- const isDone = i < idx;
1155
- const isCurrent = i === idx;
1156
- const cls = [
1157
- "wf-step",
1158
- isDone && "wf-step--done",
1159
- isCurrent && "wf-step--current"
1160
- ].filter(Boolean).join(" ");
1161
- const num = isDone ? h("span", { class: "wf-step-num" }, "\u2713") : h("span", { class: "wf-step-num" }, String(i + 1));
1162
- const label = h("span", { class: "wf-step-label" }, item.label);
1163
- const desc = item.description ? h("span", { class: "wf-step-desc" }, item.description) : null;
1164
- const connector = i < items.length - 1 ? h("span", { class: `wf-step-connector${isDone ? " wf-step-connector--done" : ""}` }) : null;
1165
- return h("div", { class: cls, key: item.key }, [
1166
- num,
1167
- label,
1168
- desc,
1169
- connector
1170
- ].filter(Boolean));
1171
- });
1172
- return h("div", { class: "wf-steps" }, steps);
1173
- };
1174
-
1175
- // src/components/Form/Form.ts
1176
- async function validateValues(values, rules) {
1177
- const errors = {};
1178
- for (const [field, fieldRules] of Object.entries(rules)) {
1179
- const val = values[field] ?? "";
1180
- for (const rule of fieldRules) {
1181
- if (rule.required && !String(val).trim()) {
1182
- errors[field] = rule.message;
1183
- break;
1184
- }
1185
- if (rule.pattern && !rule.pattern.test(String(val))) {
1186
- errors[field] = rule.message;
1187
- break;
1188
- }
1189
- if (rule.minLength != null && String(val).length < rule.minLength) {
1190
- errors[field] = rule.message;
1191
- break;
1192
- }
1193
- if (rule.maxLength != null && String(val).length > rule.maxLength) {
1194
- errors[field] = rule.message;
1195
- break;
1196
- }
1197
- if (rule.validator) {
1198
- const result = await rule.validator(val);
1199
- if (result !== true) {
1200
- errors[field] = typeof result === "string" ? result : rule.message;
1201
- break;
1202
- }
1203
- }
1204
- }
1205
- }
1206
- return errors;
1207
- }
1208
- var Form = (_init, _ctx) => (props) => {
1209
- const { validation, onSubmit, onError, children } = props;
1210
- const handleSubmit = async (e) => {
1211
- e.preventDefault();
1212
- const form = e.target;
1213
- const data = new FormData(form);
1214
- const values = {};
1215
- for (const [key, val] of data.entries()) {
1216
- if (key in values) {
1217
- const prev = values[key];
1218
- values[key] = Array.isArray(prev) ? [...prev, val] : [prev, val];
1219
- } else {
1220
- values[key] = val;
1221
- }
1222
- }
1223
- if (validation) {
1224
- const errors = await validateValues(values, validation);
1225
- if (Object.keys(errors).length > 0) {
1226
- onError?.(errors);
1227
- return;
1228
- }
1229
- onError?.({});
1230
- }
1231
- await onSubmit?.(values);
1232
- };
1233
- return h("form", {
1234
- class: "wf-form",
1235
- onSubmit: handleSubmit,
1236
- noValidate: validation ? true : void 0
1237
- }, children);
1238
- };
1239
-
1240
- // src/components/Field/Field.ts
1241
- var Field = (_init, _ctx) => (props) => {
1242
- const { label, required, error, hint, children } = props;
1243
- const parts = [];
1244
- if (label) {
1245
- const labelContent = [label];
1246
- if (required) labelContent.push(h("span", { class: "wf-field-req" }, "*"));
1247
- parts.push(h("label", { class: "wf-field-label" }, labelContent));
1248
- }
1249
- parts.push(children);
1250
- if (error) parts.push(h("div", { class: "wf-field-err" }, error));
1251
- if (hint && !error) parts.push(h("div", { class: "wf-field-hint" }, hint));
1252
- return h("div", { class: `wf-field${error ? " wf-field--err" : ""}` }, parts);
1253
- };
1254
-
1255
- // src/components/Slider/Slider.ts
1256
- var Slider = (_init, _ctx) => (props) => {
1257
- const { label, value = 0, min = 0, max = 100, step = 1, onChange } = props;
1258
- const numVal = Number(value);
1259
- const input = h("input", {
1260
- type: "range",
1261
- class: "wf-slider-input",
1262
- value: numVal,
1263
- min,
1264
- max,
1265
- step,
1266
- onChange: onChange ? (e) => onChange(Number(e.target.value)) : void 0
1267
- });
1268
- const display = h("span", { class: "wf-slider-value" }, String(numVal));
1269
- if (!label) return h("div", { class: "wf-slider" }, [input, display]);
1270
- return h("div", { class: "wf-slider-wrap" }, [
1271
- h("label", { class: "wf-slider-label" }, label),
1272
- h("div", { class: "wf-slider" }, [input, display])
1273
- ]);
1274
- };
1275
-
1276
- // src/components/SearchInput/SearchInput.ts
1277
- var SearchInput = (_init, _ctx) => (props) => {
1278
- const { value = "", placeholder = "\u641C\u7D22...", onInput, onClear } = props;
1279
- const clearBtn = value && onClear ? h("button", {
1280
- class: "wf-search-clear",
1281
- type: "button",
1282
- onClick: onClear
1283
- }, "\u2715") : null;
1284
- const icon = h("span", { class: "wf-search-icon" }, "\u{1F50D}");
1285
- return h("div", { class: "wf-search" }, [
1286
- icon,
1287
- h("input", {
1288
- class: "wf-search-input",
1289
- type: "search",
1290
- value,
1291
- placeholder,
1292
- onInput
1293
- }),
1294
- clearBtn
1295
- ].filter(Boolean));
1296
- };
1297
-
1298
- // src/components/SegmentedControl/SegmentedControl.ts
1299
- var SegmentedControl = (_init, _ctx) => (props) => {
1300
- const { options, value, onChange, size = "md", block, ariaLabel } = props;
1301
- const cls = [
1302
- "wf-segmented",
1303
- size === "sm" && "wf-segmented--sm",
1304
- block && "wf-segmented--block"
1305
- ].filter(Boolean).join(" ");
1306
- return h(
1307
- "div",
1308
- { class: cls, role: "group", "aria-label": ariaLabel },
1309
- options.map((opt) => h("button", {
1310
- type: "button",
1311
- class: `wf-segmented-option${opt.value === value ? " wf-segmented-option--active" : ""}`,
1312
- "aria-pressed": opt.value === value ? "true" : "false",
1313
- disabled: opt.disabled || void 0,
1314
- onClick: opt.disabled ? void 0 : () => onChange?.(opt.value)
1315
- }, opt.label))
1316
- );
1317
- };
1318
-
1319
- // src/components/ProgressBar/ProgressBar.ts
1320
- var ProgressBar = (_init, ctx) => (props) => {
1321
- const { value = 0, max = 100, label, showValue } = props;
1322
- const pct = Math.min(100, Math.max(0, value / max * 100));
1323
- const PBL = ctx?.i18n?.components?.ProgressBar ?? {};
1324
- const bar = h("div", {
1325
- class: "wf-progress",
1326
- role: "progressbar",
1327
- "aria-valuenow": Math.round(value),
1328
- "aria-valuemin": 0,
1329
- "aria-valuemax": Math.round(max),
1330
- "aria-label": label ?? (PBL.ariaLabel ?? "\u8FDB\u5EA6")
1331
- }, [
1332
- h("div", {
1333
- class: "wf-progress-fill",
1334
- style: { width: `${pct}%` }
1335
- })
1336
- ]);
1337
- if (!label && !showValue) return bar;
1338
- const parts = [];
1339
- if (label) parts.push(h("span", { class: "wf-progress-label" }, label));
1340
- parts.push(bar);
1341
- if (showValue) parts.push(h("span", { class: "wf-progress-value" }, `${Math.round(pct)}%`));
1342
- return h("div", { class: "wf-progress-wrap" }, parts);
1343
- };
1344
-
1345
- // src/components/Accordion/Accordion.ts
1346
- var Accordion = (_init, _ctx) => (props) => {
1347
- const { items = [], multiple } = props;
1348
- if (items.length === 0) return null;
1349
- const panels = items.map(
1350
- (item) => h("details", { class: "wf-accordion-item", key: item.key, open: true }, [
1351
- h("summary", { class: "wf-accordion-summary", "aria-expanded": "true" }, item.title),
1352
- item.content ? h("div", { class: "wf-accordion-content" }, item.content) : null
1353
- ].filter(Boolean))
1354
- );
1355
- return h("div", { class: "wf-accordion" }, panels);
1356
- };
1357
-
1358
- // src/components/PageHeader/PageHeader.ts
1359
- var PageHeader = (_init, _ctx) => (props) => {
1360
- const { title, sub, children } = props;
1361
- return h("div", { class: "wf-page-head" }, [
1362
- h("div", { class: "wf-page-head-left" }, [
1363
- h("h2", { class: "wf-page-title" }, title),
1364
- sub ? h("p", { class: "wf-page-sub" }, sub) : null
1365
- ].filter(Boolean)),
1366
- children ? h("div", { class: "wf-page-head-actions" }, children) : null
1367
- ].filter(Boolean));
1368
- };
1369
-
1370
- // src/components/Breadcrumb/Breadcrumb.ts
1371
- var Breadcrumb = (_init, _ctx) => (props) => {
1372
- const { items } = props;
1373
- const children = items.flatMap((item, i) => {
1374
- const isLast = i === items.length - 1;
1375
- const el = isLast ? h("span", { class: "wf-breadcrumb-current", "aria-current": "page" }, item.label) : item.href ? h("a", { class: "wf-breadcrumb-link", href: item.href }, item.label) : h("span", { class: "wf-breadcrumb-text" }, item.label);
1376
- if (isLast) return el;
1377
- return [el, h("span", { class: "wf-breadcrumb-sep", "aria-hidden": "true" }, "/")];
1378
- });
1379
- const BL = _ctx?.i18n?.components?.Breadcrumb ?? {};
1380
- return h("nav", { class: "wf-breadcrumb", "aria-label": BL.ariaLabel ?? "\u9762\u5305\u5C51" }, children);
1381
- };
1382
-
1383
- // src/components/Divider/Divider.ts
1384
- var Divider = (_init, _ctx) => (props) => {
1385
- const { vertical, children } = props;
1386
- if (vertical) {
1387
- return h("div", { class: "wf-divider wf-divider--vertical", role: "separator" });
1388
- }
1389
- const cls = children ? "wf-divider wf-divider--with-text" : "wf-divider";
1390
- return h(
1391
- "div",
1392
- { class: cls, role: "separator" },
1393
- children ? h("span", { class: "wf-divider-text" }, children) : void 0
1394
- );
1395
- };
1396
-
1397
- // src/components/FileUpload/FileUpload.ts
1398
- function formatSize(bytes) {
1399
- if (bytes < 1024) return `${bytes}B`;
1400
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
1401
- return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
1402
- }
1403
- var FileUpload = (_init, ctx) => {
1404
- const FL = ctx?.i18n?.components?.FileUpload ?? {};
1405
- return (props) => {
1406
- const { accept, multiple, maxSize, disabled, error, hint, value, onChange, children } = props;
1407
- const files = value ?? [];
1408
- const handleChange = (e) => {
1409
- const input = e.target;
1410
- const selected = Array.from(input.files ?? []);
1411
- if (maxSize) {
1412
- const oversized = selected.filter((f) => f.size > maxSize);
1413
- if (oversized.length > 0) return;
1414
- }
1415
- onChange?.(selected);
1416
- input.value = "";
1417
- };
1418
- const dragRef = (el) => {
1419
- if (!el || disabled) return;
1420
- const onDrop = (e) => {
1421
- e.preventDefault();
1422
- el.classList.remove("wf-upload-zone--drag");
1423
- if (disabled) return;
1424
- const dropped = Array.from(e.dataTransfer?.files ?? []);
1425
- if (maxSize) {
1426
- const oversized = dropped.filter((f) => f.size > maxSize);
1427
- if (oversized.length > 0) return;
1428
- }
1429
- onChange?.(dropped);
1430
- };
1431
- const onDragOver = (e) => {
1432
- e.preventDefault();
1433
- el.classList.add("wf-upload-zone--drag");
1434
- };
1435
- const onDragLeave = () => el.classList.remove("wf-upload-zone--drag");
1436
- el.addEventListener("drop", onDrop);
1437
- el.addEventListener("dragover", onDragOver);
1438
- el.addEventListener("dragleave", onDragLeave);
1439
- return () => {
1440
- el.removeEventListener("drop", onDrop);
1441
- el.removeEventListener("dragover", onDragOver);
1442
- el.removeEventListener("dragleave", onDragLeave);
1443
- };
1444
- };
1445
- const handleRemove = (i) => {
1446
- const updated = files.filter((_, idx) => idx !== i);
1447
- onChange?.(updated);
1448
- };
1449
- let fileInput = null;
1450
- const inputEl = h("input", {
1451
- type: "file",
1452
- class: "wf-upload-input",
1453
- accept: accept || void 0,
1454
- multiple: multiple || void 0,
1455
- disabled: disabled || void 0,
1456
- onChange: handleChange,
1457
- style: { display: "none" },
1458
- ref: (el) => {
1459
- if (el) fileInput = el;
1460
- }
1461
- });
1462
- const dropZone = h("div", {
1463
- class: `wf-upload-zone${disabled ? " wf-upload-zone--disabled" : ""}${error ? " wf-upload-zone--err" : ""}`,
1464
- onClick: disabled ? void 0 : () => fileInput?.click(),
1465
- ref: dragRef
1466
- }, children ?? h("div", { class: "wf-upload-placeholder" }, [
1467
- h("span", { class: "wf-upload-icon" }, "\u{1F4C1}"),
1468
- h("span", { class: "wf-upload-text" }, FL.placeholder ?? "\u70B9\u51FB\u6216\u62D6\u62FD\u4E0A\u4F20\u6587\u4EF6"),
1469
- accept ? h("span", { class: "wf-upload-hint" }, `${FL.supportedFormats ?? "\u652F\u6301\u683C\u5F0F: "}${accept}`) : null,
1470
- maxSize ? h("span", { class: "wf-upload-hint" }, `${FL.maxSize ?? "\u6700\u5927 "}${formatSize(maxSize)}`) : null
1471
- ].filter(Boolean)));
1472
- const fileList = files.length > 0 ? h(
1473
- "ul",
1474
- { class: "wf-upload-list" },
1475
- files.map(
1476
- (f, i) => h(
1477
- "li",
1478
- { class: "wf-upload-item", key: f.name + f.size },
1479
- h("span", { class: "wf-upload-item-info" }, [
1480
- h("span", { class: "wf-upload-item-name" }, f.name),
1481
- h("span", { class: "wf-upload-item-size" }, formatSize(f.size))
1482
- ]),
1483
- h("button", {
1484
- class: "wf-upload-item-remove",
1485
- "aria-label": `${FL.remove ?? "\u5220\u9664"} ${f.name}`,
1486
- onClick: () => handleRemove(i)
1487
- }, "\u2715")
1488
- )
1489
- )
1490
- ) : null;
1491
- const parts = [inputEl, dropZone, fileList];
1492
- if (error) parts.push(h("div", { class: "wf-upload-err" }, error));
1493
- if (hint && !error) parts.push(h("div", { class: "wf-upload-hint" }, hint));
1494
- return h("div", { class: "wf-upload" }, parts);
1495
- };
1496
- };
1497
-
1498
- // src/client/popup.ts
1499
- function computeFixedPosRect(rect, placement = "bottom", gap = 6, center = true) {
1500
- switch (placement) {
1501
- case "bottom":
1502
- return {
1503
- top: rect.bottom + gap,
1504
- left: center ? rect.left + rect.width / 2 : rect.left
1505
- };
1506
- case "top":
1507
- return {
1508
- top: rect.top - gap,
1509
- left: center ? rect.left + rect.width / 2 : rect.left
1510
- };
1511
- case "left":
1512
- return {
1513
- top: center ? rect.top + rect.height / 2 : rect.top,
1514
- left: rect.left - gap
1515
- };
1516
- case "right":
1517
- return {
1518
- top: center ? rect.top + rect.height / 2 : rect.top,
1519
- left: rect.right + gap
1520
- };
1521
- }
1522
- }
1523
-
1524
- // src/components/Tooltip/Tooltip.ts
1525
- var Tooltip = (_props, ctx) => {
1526
- let show = false;
1527
- let wrapEl = null;
1528
- let latestPosition = "top";
1529
- let prevOpen = false;
1530
- const pos = ctx.ui.usePopupPosition({
1531
- el: () => wrapEl,
1532
- isOpen: () => show,
1533
- compute: (r) => computeFixedPosRect(r, latestPosition, 6, true)
1534
- });
1535
- return (props) => {
1536
- const { content, position = "top", children, disabled } = props;
1537
- latestPosition = position;
1538
- const showe = () => {
1539
- show = true;
1540
- ctx.ui.render();
1541
- };
1542
- const hide = () => {
1543
- show = false;
1544
- ctx.ui.render();
1545
- };
1546
- if (show && !prevOpen) pos.refresh();
1547
- prevOpen = show;
1548
- const p = pos;
1549
- const tip = !disabled ? h("div", {
1550
- class: `wf-tooltip wf-tooltip--${position}${show ? "" : " wf-tooltip--hidden"}`,
1551
- style: { top: p.top, left: p.left },
1552
- role: "tooltip"
1553
- }, [h("div", { class: "wf-tooltip-arrow" }), h("div", { class: "wf-tooltip-content" }, content)]) : null;
1554
- const portalContent = !disabled ? createPortal(tip, "tooltip") : null;
1555
- return h("div", {
1556
- class: "wf-tooltip-wrap",
1557
- ref: (el) => {
1558
- if (el) wrapEl = el;
1559
- },
1560
- onMouseEnter: showe,
1561
- onMouseLeave: hide,
1562
- onFocus: showe,
1563
- onBlur: hide
1564
- }, [children, portalContent].filter(Boolean));
1565
- };
1566
- };
1567
-
1568
- // src/components/Drawer/Drawer.ts
1569
- var Drawer = (_props, ctx) => {
1570
- let prevOpen;
1571
- let focusCleanup;
1572
- const rootRef = (el) => {
1573
- if (el) {
1574
- lockScroll();
1575
- const panelEl = el.querySelector(".wf-drawer") ?? el;
1576
- focusCleanup = trapFocus(panelEl);
1577
- } else {
1578
- unlockScroll();
1579
- focusCleanup?.();
1580
- }
1581
- };
1582
- return (props) => {
1583
- const { open, title, position = "right", onClose, children, footer } = props;
1584
- const DL = ctx?.i18n?.components?.Drawer ?? {};
1585
- if (prevOpen !== open) {
1586
- prevOpen = open;
1587
- }
1588
- if (!open) return null;
1589
- const overlay = h("div", {
1590
- class: "wf-drawer-overlay",
1591
- onClick: onClose
1592
- });
1593
- const closeBtn = h("button", {
1594
- class: "wf-drawer-close",
1595
- onClick: onClose,
1596
- type: "button",
1597
- "aria-label": "\u5173\u95ED"
1598
- }, "\u2715");
1599
- const titleEl = title ? h("div", { class: "wf-drawer-header" }, [title, closeBtn]) : null;
1600
- const bodyEl = h("div", { class: "wf-drawer-body" }, children);
1601
- const footerEl = footer ? h("div", { class: "wf-drawer-footer" }, footer) : null;
1602
- const panel = h("div", {
1603
- class: `wf-drawer-panel wf-drawer-panel--${position}`,
1604
- onClick: (e) => e.stopPropagation()
1605
- }, [titleEl, bodyEl, footerEl].filter(Boolean));
1606
- const root = h("div", {
1607
- ref: rootRef,
1608
- class: `wf-drawer wf-drawer--${position} wf-drawer--enter`,
1609
- role: "dialog",
1610
- "aria-modal": "true",
1611
- "aria-label": title ?? (DL.ariaLabel ?? "\u4FA7\u8FB9\u9762\u677F"),
1612
- tabIndex: -1,
1613
- onKeyDown: (e) => {
1614
- if (e.key === "Escape") onClose?.();
1615
- }
1616
- }, [overlay, panel]);
1617
- return createPortal(root, "drawer");
1618
- };
1619
- };
1620
-
1621
- // src/components/Popover/Popover.ts
1622
- var Popover = (_props, ctx) => {
1623
- let show = false;
1624
- let wrapEl = null;
1625
- let latestOpen = false;
1626
- let latestPosition = "bottom";
1627
- let prevOpen = false;
1628
- const pos = ctx.ui.usePopupPosition({
1629
- el: () => wrapEl,
1630
- isOpen: () => latestOpen,
1631
- compute: (r) => computeFixedPosRect(r, latestPosition, 6, true)
1632
- });
1633
- return (props) => {
1634
- const { content, trigger = "click", position = "bottom", open, onOpenChange, disabled, children } = props;
1635
- const isOpen = open !== void 0 ? open : show;
1636
- latestOpen = isOpen;
1637
- latestPosition = position;
1638
- const setOpen = (v) => {
1639
- if (open === void 0) {
1640
- show = v;
1641
- ctx.ui.render();
1642
- }
1643
- onOpenChange?.(v);
1644
- };
1645
- if (isOpen && !prevOpen) pos.refresh();
1646
- prevOpen = isOpen;
1647
- const onClick = trigger === "click" && !disabled ? () => setOpen(!isOpen) : void 0;
1648
- const hoverProps = {};
1649
- if (trigger === "hover" && !disabled) {
1650
- hoverProps.onMouseEnter = () => setOpen(true);
1651
- hoverProps.onMouseLeave = () => setOpen(false);
1652
- hoverProps.onFocus = () => setOpen(true);
1653
- hoverProps.onBlur = () => setOpen(false);
1654
- }
1655
- const p = pos;
1656
- const overlay = isOpen && trigger === "click" ? h("div", {
1657
- class: "wf-popover-overlay",
1658
- onMouseDown: (e) => {
1659
- e.stopPropagation();
1660
- setOpen(false);
1661
- }
1662
- }) : null;
1663
- const popover = isOpen ? h("div", {
1664
- class: `wf-popover wf-popover--${position} wf-popover--enter`,
1665
- style: { top: p.top, left: p.left },
1666
- role: "tooltip"
1667
- }, [
1668
- h("div", { class: "wf-popover-arrow" }),
1669
- h("div", { class: "wf-popover-content" }, content)
1670
- ]) : null;
1671
- const portalContent = isOpen ? createPortal([overlay, popover].filter(Boolean), "popover") : null;
1672
- return h("div", {
1673
- class: `wf-popover-wrap${isOpen ? " wf-popover-wrap--open" : ""}`,
1674
- ref: (el) => {
1675
- if (el) wrapEl = el;
1676
- },
1677
- ...hoverProps,
1678
- onClick
1679
- }, [children, portalContent].filter(Boolean));
1680
- };
1681
- };
1682
-
1683
- // src/components/Skeleton/Skeleton.ts
1684
- var Skeleton = (_init) => (props) => {
1685
- const { variant = "text", lines = 1, cols = 3, width, height, className } = props;
1686
- const style = {};
1687
- if (width !== void 0) style.width = typeof width === "number" ? `${width}px` : width;
1688
- if (height !== void 0) style.height = typeof height === "number" ? `${height}px` : height;
1689
- const cls = [
1690
- "wf-skeleton",
1691
- `wf-skeleton--${variant}`,
1692
- className
1693
- ].filter(Boolean).join(" ");
1694
- if (variant === "table") {
1695
- const rows = Array.from({ length: lines }, (_, r) => {
1696
- const cells = Array.from({ length: cols }, (_2, c) => {
1697
- const cellW = r === lines - 1 && c === cols - 1 ? "40%" : void 0;
1698
- return h("div", {
1699
- class: "wf-skeleton wf-skeleton--text",
1700
- style: cellW ? { width: cellW } : void 0
1701
- });
1702
- });
1703
- return h("div", { class: "wf-skeleton-row" }, cells);
1704
- });
1705
- return h("div", { class: "wf-skeleton-table" }, rows);
1706
- }
1707
- if (lines <= 1) {
1708
- return h("div", { class: cls, style: Object.keys(style).length ? style : void 0 });
1709
- }
1710
- const items = Array.from({ length: lines }, (_, i) => {
1711
- const itemCls = i === lines - 1 && lines > 1 ? `${cls} wf-skeleton--short` : cls;
1712
- return h("div", { class: itemCls, style: Object.keys(style).length ? style : void 0 });
1713
- });
1714
- return h(Fragment, null, items);
1715
- };
1716
-
1717
- // src/components/Img/Img.ts
1718
- var Img = (_init) => (props) => {
1719
- const { src, alt = "", fallback, loading, width, height, className, style } = props;
1720
- const imgProps = {
1721
- class: ["wf-image", className].filter(Boolean).join(" "),
1722
- src: src ?? fallback ?? "",
1723
- alt,
1724
- loading: loading ?? "lazy"
1725
- };
1726
- if (width !== void 0) imgProps.width = width;
1727
- if (height !== void 0) imgProps.height = height;
1728
- if (style) imgProps.style = style;
1729
- if (fallback) {
1730
- imgProps.onError = (e) => {
1731
- const el = e.currentTarget;
1732
- if (el.src !== fallback) el.src = fallback;
1733
- };
1734
- }
1735
- return h("img", imgProps);
1736
- };
1737
-
1738
- // src/components/InView/InView.ts
1739
- var InView = (_props, ctx) => {
1740
- let inView = false;
1741
- let entered = false;
1742
- let io;
1743
- const sentinelRef = (el) => {
1744
- if (el) {
1745
- io = new IntersectionObserver((entries) => {
1746
- if (entries[0]?.isIntersecting) {
1747
- inView = true;
1748
- ctx.ui.render();
1749
- }
1750
- }, { threshold: _props.threshold ?? 0, rootMargin: _props.rootMargin ?? "0px" });
1751
- io.observe(el);
1752
- } else {
1753
- io?.disconnect();
1754
- }
1755
- };
1756
- return (props) => {
1757
- if (inView) {
1758
- if (!entered) {
1759
- entered = true;
1760
- const once = props.once !== false;
1761
- if (once) io?.disconnect();
1762
- props.onEnter?.();
1763
- }
1764
- return h("div", { class: "wf-inview wf-inview--loaded" }, props.children);
1765
- }
1766
- const placeholderEl = props.placeholder !== void 0 ? props.placeholder : h("div", { class: "wf-inview-placeholder" });
1767
- return h("div", {
1768
- class: "wf-inview wf-inview--pending"
1769
- }, [
1770
- h("div", {
1771
- class: "wf-inview-pending",
1772
- style: { width: "1px", height: "1px", opacity: 0, pointerEvents: "none" },
1773
- ref: sentinelRef
1774
- }),
1775
- placeholderEl
1776
- ]);
1777
- };
1778
- };
1779
-
1780
- // src/components/DatePicker/calendar-utils.ts
1781
- var WEEKDAYS = ["\u65E5", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D"];
1782
- function getWeekdays() {
1783
- return WEEKDAYS;
1784
- }
1785
- function getDaysInMonth(year, month) {
1786
- return new Date(year, month + 1, 0).getDate();
1787
- }
1788
- function getFirstDayOfMonth(year, month) {
1789
- return new Date(year, month, 1).getDay();
1790
- }
1791
- function getCalendarGrid(year, month) {
1792
- const days = [];
1793
- const totalDays = getDaysInMonth(year, month);
1794
- const firstDay = getFirstDayOfMonth(year, month);
1795
- const prevMonth = month === 0 ? 11 : month - 1;
1796
- const prevYear = month === 0 ? year - 1 : year;
1797
- const prevMonthDays = getDaysInMonth(prevYear, prevMonth);
1798
- const today = /* @__PURE__ */ new Date();
1799
- let row = [];
1800
- for (let i = firstDay - 1; i >= 0; i--) {
1801
- const d = prevMonthDays - i;
1802
- row.push({
1803
- year: prevYear,
1804
- month: prevMonth,
1805
- day: d,
1806
- isOtherMonth: true,
1807
- isToday: prevYear === today.getFullYear() && prevMonth === today.getMonth() && d === today.getDate()
1808
- });
1809
- }
1810
- for (let d = 1; d <= totalDays; d++) {
1811
- row.push({
1812
- year,
1813
- month,
1814
- day: d,
1815
- isOtherMonth: false,
1816
- isToday: year === today.getFullYear() && month === today.getMonth() && d === today.getDate()
1817
- });
1818
- if (row.length === 7) {
1819
- days.push(row);
1820
- row = [];
1821
- }
1822
- }
1823
- const nextMonth = month === 11 ? 0 : month + 1;
1824
- const nextYear = month === 11 ? year + 1 : year;
1825
- let nextDay = 1;
1826
- while (days.length < 6) {
1827
- while (row.length < 7) {
1828
- row.push({
1829
- year: nextYear,
1830
- month: nextMonth,
1831
- day: nextDay++,
1832
- isOtherMonth: true,
1833
- isToday: nextYear === today.getFullYear() && nextMonth === today.getMonth() && nextDay - 1 === today.getDate()
1834
- });
1835
- }
1836
- days.push(row);
1837
- row = [];
1838
- }
1839
- return days;
1840
- }
1841
- function formatDate(year, month, day) {
1842
- return `${year}-${String(month + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
1843
- }
1844
- function formatTime(hour, minute) {
1845
- return `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
1846
- }
1847
- function formatDateTime(year, month, day, hour, minute) {
1848
- return `${formatDate(year, month, day)} ${formatTime(hour, minute)}`;
1849
- }
1850
- function hourOptions() {
1851
- return Array.from({ length: 24 }, (_, i) => i);
1852
- }
1853
- function minuteOptions() {
1854
- return Array.from({ length: 12 }, (_, i) => i * 5);
1855
- }
1856
-
1857
- // src/components/DatePicker/DatePicker.ts
1858
- var DatePicker = (_props, ctx) => {
1859
- let show = false;
1860
- let selectedValue = "";
1861
- const now = /* @__PURE__ */ new Date();
1862
- let viewYear = now.getFullYear();
1863
- let viewMonth = now.getMonth();
1864
- let hour = now.getHours();
1865
- let minute = Math.round(now.getMinutes() / 5) * 5;
1866
- let selYear = now.getFullYear();
1867
- let selMonth = now.getMonth();
1868
- let selDay = now.getDate();
1869
- let rangeStart = null;
1870
- let rangeEnd = null;
1871
- let inputEl = null;
1872
- let prevOpen = false;
1873
- const pos = ctx.ui.usePopupPosition({
1874
- el: () => inputEl,
1875
- isOpen: () => show,
1876
- compute: (r) => ({ top: r.bottom + 4, left: r.left, width: r.width })
1877
- });
1878
- return (props) => {
1879
- const L = ctx?.i18n?.components?.DatePicker ?? {};
1880
- const { mode = "date", value, onChange, placeholder = L.placeholder ?? "\u9009\u62E9\u65E5\u671F", disabled } = props;
1881
- const isOpen = show;
1882
- const setOpen = (v) => {
1883
- show = v;
1884
- ctx.ui.render();
1885
- };
1886
- if (show && !prevOpen) pos.refresh();
1887
- prevOpen = show;
1888
- const toggle = (e) => {
1889
- if (disabled) return;
1890
- setOpen(!show);
1891
- };
1892
- const selectDate = (day) => {
1893
- if (mode === "datetime") {
1894
- selYear = day.year;
1895
- selMonth = day.month;
1896
- selDay = day.day;
1897
- viewYear = day.year;
1898
- viewMonth = day.month;
1899
- ctx.ui.render();
1900
- } else if (mode === "range") {
1901
- if (!rangeStart || rangeStart && rangeEnd) {
1902
- rangeStart = formatDate(day.year, day.month, day.day);
1903
- rangeEnd = null;
1904
- ctx.ui.render();
1905
- } else {
1906
- rangeEnd = formatDate(day.year, day.month, day.day);
1907
- const ds = rangeStart < rangeEnd ? rangeStart : rangeEnd;
1908
- const de = rangeStart < rangeEnd ? rangeEnd : rangeStart;
1909
- selectedValue = `${ds} ~ ${de}`;
1910
- onChange?.(selectedValue);
1911
- setOpen(false);
1912
- }
1913
- } else {
1914
- selectedValue = formatDate(day.year, day.month, day.day);
1915
- onChange?.(selectedValue);
1916
- setOpen(false);
1917
- }
1918
- };
1919
- const prevMonth = () => {
1920
- if (viewMonth === 0) {
1921
- viewYear--;
1922
- viewMonth = 11;
1923
- } else viewMonth--;
1924
- ctx.ui.render();
1925
- };
1926
- const nextMonth = () => {
1927
- if (viewMonth === 11) {
1928
- viewYear++;
1929
- viewMonth = 0;
1930
- } else viewMonth++;
1931
- ctx.ui.render();
1932
- };
1933
- const confirmTime = () => {
1934
- selectedValue = formatTime(hour, minute);
1935
- onChange?.(selectedValue);
1936
- setOpen(false);
1937
- };
1938
- const confirmDateTime = () => {
1939
- selectedValue = formatDateTime(selYear, selMonth, selDay, hour, minute);
1940
- onChange?.(selectedValue);
1941
- setOpen(false);
1942
- };
1943
- const grid = getCalendarGrid(viewYear, viewMonth);
1944
- const weekdays = [L.w0, L.w1, L.w2, L.w3, L.w4, L.w5, L.w6].some((v) => v) ? [L.w0, L.w1, L.w2, L.w3, L.w4, L.w5, L.w6] : getWeekdays();
1945
- const headerBtn = (label, onClick) => h("button", { class: "wf-datepicker-header-btn", type: "button", onClick }, label);
1946
- const header = h("div", { class: "wf-datepicker-header" }, [
1947
- headerBtn("\u2039", prevMonth),
1948
- h("span", { class: "wf-datepicker-header-title" }, `${viewYear}\u5E74${viewMonth + 1}\u6708`),
1949
- headerBtn("\u203A", nextMonth)
1950
- ]);
1951
- const weekdayRow = h(
1952
- "div",
1953
- { class: "wf-datepicker-weekdays" },
1954
- weekdays.map((w) => h("span", { class: "wf-datepicker-weekday" }, w))
1955
- );
1956
- const gridRows = grid.map((row, ri) => h(
1957
- "div",
1958
- { class: "wf-datepicker-grid", key: `row-${ri}` },
1959
- row.map((cell, ci) => {
1960
- const classes = ["wf-datepicker-cell"];
1961
- if (cell.isOtherMonth) classes.push("wf-datepicker-cell--other-month");
1962
- if (cell.isToday) classes.push("wf-datepicker-cell--today");
1963
- const dateStr = formatDate(cell.year, cell.month, cell.day);
1964
- if (mode === "range") {
1965
- if (dateStr === rangeStart || dateStr === rangeEnd) classes.push("wf-datepicker-cell--range-edge");
1966
- else if (rangeStart && rangeEnd && dateStr > rangeStart && dateStr < rangeEnd) classes.push("wf-datepicker-cell--in-range");
1967
- } else if (mode === "datetime") {
1968
- if (selYear === cell.year && selMonth === cell.month && selDay === cell.day) classes.push("wf-datepicker-cell--selected");
1969
- } else {
1970
- if (dateStr === selectedValue) classes.push("wf-datepicker-cell--selected");
1971
- }
1972
- return h("button", {
1973
- class: classes.join(" "),
1974
- key: `${cell.year}-${cell.month}-${cell.day}`,
1975
- type: "button",
1976
- onClick: () => selectDate(cell)
1977
- }, String(cell.day));
1978
- })
1979
- ));
1980
- const calendarPanel = h("div", { class: "wf-datepicker-range-panel" }, [
1981
- header,
1982
- weekdayRow,
1983
- ...gridRows
1984
- ]);
1985
- const handleKeyDown = (e) => {
1986
- if (e.key === "Escape") setOpen(false);
1987
- };
1988
- const overlay = h("div", { class: "wf-datepicker-overlay", onMouseDown: () => setOpen(false) });
1989
- let panel = null;
1990
- if (isOpen) {
1991
- if (mode === "time") {
1992
- const hours = hourOptions();
1993
- const minutes = minuteOptions();
1994
- const timePanel = h("div", {
1995
- style: { top: pos.top, left: pos.left, width: pos.width },
1996
- class: "wf-time-picker",
1997
- role: "dialog",
1998
- onKeyDown: handleKeyDown,
1999
- onMouseDown: (e) => e.stopPropagation()
2000
- }, [
2001
- h("div", { class: "wf-time-body" }, [
2002
- h("div", { class: "wf-time-col" }, [
2003
- h("div", { class: "wf-time-col-label" }, L.hour ?? "\u65F6"),
2004
- h(
2005
- "div",
2006
- { class: "wf-time-opt-list" },
2007
- hours.map((hv) => h("button", {
2008
- class: `wf-time-opt${hv === hour ? " wf-time-opt--selected" : ""}`,
2009
- type: "button",
2010
- key: hv,
2011
- onClick: () => {
2012
- hour = hv;
2013
- ctx.ui.render();
2014
- }
2015
- }, String(hv).padStart(2, "0")))
2016
- )
2017
- ]),
2018
- h("div", { class: "wf-time-col" }, [
2019
- h("div", { class: "wf-time-col-label" }, L.minute ?? "\u5206"),
2020
- h(
2021
- "div",
2022
- { class: "wf-time-opt-list" },
2023
- minutes.map((mv) => h("button", {
2024
- class: `wf-time-opt${mv === minute ? " wf-time-opt--selected" : ""}`,
2025
- type: "button",
2026
- key: mv,
2027
- onClick: () => {
2028
- minute = mv;
2029
- ctx.ui.render();
2030
- }
2031
- }, String(mv).padStart(2, "0")))
2032
- )
2033
- ])
2034
- ]),
2035
- h("div", { class: "wf-time-footer" }, [
2036
- h("button", { class: "wf-datepicker-footer-btn", type: "button", onClick: () => setOpen(false) }, L.cancel ?? "\u53D6\u6D88"),
2037
- h("button", { class: "wf-datepicker-footer-btn", type: "button", onClick: confirmTime }, L.confirm ?? "\u786E\u5B9A")
2038
- ])
2039
- ]);
2040
- panel = [overlay, timePanel];
2041
- } else if (mode === "range") {
2042
- const nextM = viewMonth === 11 ? 0 : viewMonth + 1;
2043
- const nextY = viewMonth === 11 ? viewYear + 1 : viewYear;
2044
- const nextGrid = getCalendarGrid(nextY, nextM);
2045
- const rangeWrap = h("div", {
2046
- style: { top: pos.top, left: pos.left },
2047
- class: "wf-datepicker-range-wrap",
2048
- onMouseDown: (e) => e.stopPropagation()
2049
- }, [
2050
- h("div", { class: "wf-datepicker-range-panel" }, [
2051
- h("div", { class: "wf-datepicker-header" }, [
2052
- headerBtn("\u2039", prevMonth),
2053
- h("span", { class: "wf-datepicker-header-title" }, `${viewYear}\u5E74${viewMonth + 1}\u6708`),
2054
- h("span", { class: "wf-datepicker-header-title" })
2055
- ]),
2056
- weekdayRow,
2057
- ...gridRows
2058
- ]),
2059
- h("div", { class: "wf-datepicker-range-panel" }, [
2060
- h("div", { class: "wf-datepicker-header" }, [
2061
- h("span", { class: "wf-datepicker-header-title" }),
2062
- h("span", { class: "wf-datepicker-header-title" }, `${nextY}\u5E74${nextM + 1}\u6708`),
2063
- headerBtn("\u203A", nextMonth)
2064
- ]),
2065
- h("div", { class: "wf-datepicker-weekdays" }, weekdays.map((w) => h("span", { class: "wf-datepicker-weekday" }, w))),
2066
- ...nextGrid.map((row, ri) => h(
2067
- "div",
2068
- { class: "wf-datepicker-grid", key: `row-${ri}` },
2069
- row.map((cell) => {
2070
- const dateStr = formatDate(cell.year, cell.month, cell.day);
2071
- const cls = ["wf-datepicker-cell"];
2072
- if (cell.isOtherMonth) cls.push("wf-datepicker-cell--other-month");
2073
- if (cell.isToday) cls.push("wf-datepicker-cell--today");
2074
- if (dateStr === rangeStart || dateStr === rangeEnd) cls.push("wf-datepicker-cell--range-edge");
2075
- else if (rangeStart && rangeEnd && dateStr > rangeStart && dateStr < rangeEnd) cls.push("wf-datepicker-cell--in-range");
2076
- return h("button", {
2077
- class: cls.join(" "),
2078
- key: dateStr,
2079
- type: "button",
2080
- onClick: () => selectDate(cell)
2081
- }, String(cell.day));
2082
- })
2083
- ))
2084
- ])
2085
- ]);
2086
- panel = [overlay, rangeWrap];
2087
- } else {
2088
- const content = [calendarPanel];
2089
- if (mode === "datetime") {
2090
- content.push(h("div", { class: "wf-datetime-time" }, [
2091
- h("span", { class: "wf-datetime-time-label" }, (L.time ?? "\u65F6\u95F4") + "\uFF1A"),
2092
- h("div", { class: "wf-datetime-time-select" }, [
2093
- h("select", {
2094
- class: "wf-datetime-select",
2095
- value: hour,
2096
- onChange: (e) => {
2097
- hour = parseInt(e.target.value);
2098
- ctx.ui.render();
2099
- }
2100
- }, hourOptions().map((hv) => h("option", { value: hv, key: hv }, String(hv).padStart(2, "0")))),
2101
- h("span", { class: "wf-datetime-sep" }, ":"),
2102
- h("select", {
2103
- class: "wf-datetime-select",
2104
- value: minute,
2105
- onChange: (e) => {
2106
- minute = parseInt(e.target.value);
2107
- ctx.ui.render();
2108
- }
2109
- }, minuteOptions().map((mv) => h("option", { value: mv, key: mv }, String(mv).padStart(2, "0"))))
2110
- ])
2111
- ]));
2112
- content.push(h("div", { class: "wf-time-footer" }, [
2113
- h("button", { class: "wf-datepicker-footer-btn", type: "button", onClick: confirmDateTime }, L.confirm ?? "\u786E\u5B9A")
2114
- ]));
2115
- }
2116
- const dp = h("div", {
2117
- style: { top: pos.top, left: pos.left, width: pos.width },
2118
- class: "wf-datepicker-dropdown",
2119
- role: "dialog",
2120
- onKeyDown: handleKeyDown,
2121
- onMouseDown: (e) => e.stopPropagation()
2122
- }, content);
2123
- panel = [overlay, dp];
2124
- }
2125
- }
2126
- const portalContent = isOpen ? createPortal(panel, "dp-calendar") : null;
2127
- const displayValue = value ?? selectedValue ?? "";
2128
- return h("div", { class: `wf-datepicker${disabled ? " wf-datepicker--disabled" : ""}` }, [
2129
- h("input", {
2130
- class: "wf-datepicker-input",
2131
- type: "text",
2132
- placeholder,
2133
- value: displayValue || "",
2134
- ref: (el) => {
2135
- inputEl = el;
2136
- },
2137
- readonly: true,
2138
- disabled,
2139
- onClick: toggle
2140
- }),
2141
- portalContent
2142
- ].filter(Boolean));
2143
- };
2144
- };
2145
-
2146
- // src/components/Chart/chart-utils.ts
2147
- function scaleLinear(domain, range) {
2148
- const fn = ((v) => {
2149
- const t = (v - domain[0]) / (domain[1] - domain[0]);
2150
- return range[0] + t * (range[1] - range[0]);
2151
- });
2152
- fn.domain = domain;
2153
- fn.range = range;
2154
- fn.invert = (v) => {
2155
- const t = (v - range[0]) / (range[1] - range[0]);
2156
- return domain[0] + t * (domain[1] - domain[0]);
2157
- };
2158
- return fn;
2159
- }
2160
- function linePath(data, xScale, yScale) {
2161
- if (data.length === 0) return "";
2162
- return data.map((d, i) => {
2163
- const x = xScale(i);
2164
- const y = yScale(d.value);
2165
- return i === 0 ? `M${x},${y}` : `L${x},${y}`;
2166
- }).join(" ");
2167
- }
2168
- function areaPath(data, xScale, yScale, yBase) {
2169
- if (data.length === 0) return "";
2170
- const pts = data.map((d, i) => {
2171
- const x = xScale(i);
2172
- const y = yScale(d.value);
2173
- return `${x},${y}`;
2174
- });
2175
- const firstX = xScale(0);
2176
- const lastX = xScale(data.length - 1);
2177
- return `M${firstX},${yBase}L${pts.join("L")}L${lastX},${yBase}Z`;
2178
- }
2179
- function barRects(data, xScale, yScale, barWidth) {
2180
- const bw = barWidth ?? Math.max(4, (xScale.range[1] - xScale.range[0]) / data.length * 0.6);
2181
- return data.map((d, i) => ({
2182
- x: xScale(i) - bw / 2,
2183
- y: yScale(Math.max(0, d.value)),
2184
- width: bw,
2185
- height: Math.abs(yScale(d.value) - yScale(0)),
2186
- color: d.color ?? getDefaultColor(i),
2187
- label: d.label,
2188
- value: d.value
2189
- }));
2190
- }
2191
- function pieArcs(data, cx, cy, radius) {
2192
- const total = data.reduce((s, d) => s + Math.abs(d.value), 0);
2193
- if (total === 0) return [];
2194
- let startAngle = -Math.PI / 2;
2195
- return data.map((d, i) => {
2196
- const angle = Math.abs(d.value) / total * Math.PI * 2;
2197
- const endAngle = startAngle + angle;
2198
- const arc = createArc(cx, cy, radius, startAngle, endAngle);
2199
- const midAngle = startAngle + angle / 2;
2200
- startAngle = endAngle;
2201
- return {
2202
- d: arc,
2203
- color: d.color ?? getDefaultColor(i),
2204
- label: d.label,
2205
- value: d.value,
2206
- centroid: {
2207
- x: cx + Math.cos(midAngle) * radius * 0.6,
2208
- y: cy + Math.sin(midAngle) * radius * 0.6
2209
- }
2210
- };
2211
- });
2212
- }
2213
- function createArc(cx, cy, r, start, end) {
2214
- const x1 = cx + r * Math.cos(start);
2215
- const y1 = cy + r * Math.sin(start);
2216
- const x2 = cx + r * Math.cos(end);
2217
- const y2 = cy + r * Math.sin(end);
2218
- const large = end - start > Math.PI ? 1 : 0;
2219
- return `M${cx},${cy}L${x1},${y1}A${r},${r} 0 ${large} 1 ${x2},${y2}Z`;
2220
- }
2221
- var COLORS2 = ["#3b82f6", "#ef4444", "#22c55e", "#f59e0b", "#8b5cf6", "#ec4899", "#06b6d4", "#84cc16"];
2222
- function getDefaultColor(index) {
2223
- return COLORS2[index % COLORS2.length];
2224
- }
2225
- function getYTicks(yScale, tickCount = 5) {
2226
- const [d0, d1] = yScale.domain;
2227
- const step = (d1 - d0) / tickCount;
2228
- const ticks = [];
2229
- for (let i = 0; i <= tickCount; i++) {
2230
- const v = d0 + step * i;
2231
- ticks.push({ value: v, y: yScale(v), label: formatTick(v) });
2232
- }
2233
- return ticks;
2234
- }
2235
- function formatTick(v) {
2236
- if (Math.abs(v) >= 1e6) return (v / 1e6).toFixed(1) + "M";
2237
- if (Math.abs(v) >= 1e3) return (v / 1e3).toFixed(1) + "k";
2238
- return String(Math.round(v));
2239
- }
2240
-
2241
- // src/components/Chart/Chart.ts
2242
- var Chart = (_props, ctx) => {
2243
- let tooltip = null;
2244
- let tooltipEl = null;
2245
- let prevOpen = false;
2246
- const pos = ctx.ui.usePopupPosition({
2247
- el: () => tooltipEl,
2248
- isOpen: () => tooltip !== null,
2249
- compute: (r) => ({ top: r.top - 8, left: r.left + r.width / 2 })
2250
- });
2251
- return (props) => {
2252
- const { type = "line", data, options = {}, title, area, className } = props;
2253
- const W = options.width ?? 320;
2254
- const H = options.height ?? 200;
2255
- const pad = options.padding ?? 32;
2256
- const cw = W - pad * 2;
2257
- const ch = H - pad * 2;
2258
- const values = data.map((d) => d.value);
2259
- const minVal = Math.min(0, ...values);
2260
- const maxVal = Math.max(...values);
2261
- const valRange = maxVal - minVal || 1;
2262
- const renderLine = () => {
2263
- const n = Math.max(1, data.length - 1);
2264
- const xScale = scaleLinear([-0.5, n + 0.5], [0, cw]);
2265
- const yScale = scaleLinear([minVal, maxVal], [ch, 0]);
2266
- const ticks = getYTicks(yScale);
2267
- const lineD = linePath(data, xScale, yScale);
2268
- const areaD = area ? areaPath(data, xScale, yScale, yScale(0)) : null;
2269
- const dots = data.map((d, i) => {
2270
- const cx = xScale(i) + pad;
2271
- const cy = yScale(d.value) + pad;
2272
- return h("circle", {
2273
- key: `dot-${i}`,
2274
- cx,
2275
- cy,
2276
- r: 3,
2277
- fill: d.color ?? getDefaultColor(i),
2278
- stroke: "#fff",
2279
- "stroke-width": 1.5,
2280
- style: { cursor: "pointer" },
2281
- onMouseEnter: (e) => {
2282
- tooltipEl = e.target;
2283
- tooltip = { label: d.label, value: d.value };
2284
- ctx.ui.render();
2285
- },
2286
- onMouseLeave: () => {
2287
- tooltipEl = null;
2288
- tooltip = null;
2289
- ctx.ui.render();
2290
- }
2291
- });
2292
- });
2293
- return h("svg", { style: { width: "100%" }, height: H, viewBox: `0 0 ${W} ${H}` }, [
2294
- ...ticks.map((t, i) => h("g", { key: `tick-${i}` }, [
2295
- h("line", {
2296
- x1: pad,
2297
- y1: t.y + pad,
2298
- x2: W - pad,
2299
- y2: t.y + pad,
2300
- stroke: "#e5e7eb",
2301
- "stroke-width": 1
2302
- }),
2303
- h("text", {
2304
- x: pad - 6,
2305
- y: t.y + pad + 4,
2306
- "text-anchor": "end",
2307
- fill: "#6b7280",
2308
- "font-size": "11",
2309
- "font-family": "var(--wf-font-sans)"
2310
- }, t.label)
2311
- ])),
2312
- ...areaD ? [h("path", {
2313
- key: "area",
2314
- d: areaD,
2315
- fill: "#3b82f620",
2316
- stroke: "none",
2317
- transform: `translate(${pad},${pad})`
2318
- })] : [],
2319
- h("path", {
2320
- key: "line",
2321
- d: lineD,
2322
- fill: "none",
2323
- stroke: "#3b82f6",
2324
- "stroke-width": 2,
2325
- "stroke-linejoin": "round",
2326
- "stroke-linecap": "round",
2327
- transform: `translate(${pad},${pad})`
2328
- }),
2329
- ...data.map((d, i) => {
2330
- const x = xScale(i) + pad;
2331
- return h("text", {
2332
- key: `xlabel-${i}`,
2333
- x,
2334
- y: H - pad + 14,
2335
- "text-anchor": "middle",
2336
- fill: "#6b7280",
2337
- "font-size": "10",
2338
- "font-family": "var(--wf-font-sans)"
2339
- }, d.label);
2340
- }),
2341
- ...dots
2342
- ]);
2343
- };
2344
- const renderBar = () => {
2345
- const n = Math.max(1, data.length - 1);
2346
- const xScale = scaleLinear([-0.5, n + 0.5], [0, cw]);
2347
- const yScale = scaleLinear([minVal, maxVal], [ch, 0]);
2348
- const ticks = getYTicks(yScale);
2349
- const rects = barRects(data, xScale, yScale);
2350
- return h("svg", { style: { width: "100%" }, height: H, viewBox: `0 0 ${W} ${H}` }, [
2351
- ...ticks.map((t, i) => h("g", { key: `tick-${i}` }, [
2352
- h("line", {
2353
- x1: pad,
2354
- y1: t.y + pad,
2355
- x2: W - pad,
2356
- y2: t.y + pad,
2357
- stroke: "#e5e7eb",
2358
- "stroke-width": 1
2359
- }),
2360
- h("text", {
2361
- x: pad - 6,
2362
- y: t.y + pad + 4,
2363
- "text-anchor": "end",
2364
- fill: "#6b7280",
2365
- "font-size": "11",
2366
- "font-family": "var(--wf-font-sans)"
2367
- }, t.label)
2368
- ])),
2369
- ...rects.map((r, i) => h("rect", {
2370
- key: `bar-${i}`,
2371
- x: r.x + pad,
2372
- y: r.y + pad,
2373
- width: r.width,
2374
- height: r.height,
2375
- fill: r.color,
2376
- rx: 2,
2377
- onMouseEnter: (e) => {
2378
- tooltipEl = e.target;
2379
- tooltip = { label: r.label, value: r.value };
2380
- ctx.ui.render();
2381
- },
2382
- onMouseLeave: () => {
2383
- tooltipEl = null;
2384
- tooltip = null;
2385
- ctx.ui.render();
2386
- }
2387
- })),
2388
- ...data.map((d, i) => {
2389
- const x = xScale(i) + pad;
2390
- return h("text", {
2391
- key: `xlabel-${i}`,
2392
- x,
2393
- y: H - pad + 14,
2394
- "text-anchor": "middle",
2395
- fill: "#6b7280",
2396
- "font-size": "10",
2397
- "font-family": "var(--wf-font-sans)"
2398
- }, d.label);
2399
- })
2400
- ]);
2401
- };
2402
- const renderPie = () => {
2403
- const cx = W / 2;
2404
- const cy = H / 2;
2405
- const radius = Math.min(cw, ch) / 2 - 4;
2406
- const arcs = pieArcs(data, cx, cy, radius);
2407
- return h("svg", { style: { width: "100%" }, height: H, viewBox: `0 0 ${W} ${H}` }, [
2408
- ...arcs.map((a, i) => h("g", { key: `arc-${i}` }, [
2409
- h("path", {
2410
- d: a.d,
2411
- fill: a.color,
2412
- stroke: "#fff",
2413
- "stroke-width": 1.5,
2414
- onMouseEnter: (e) => {
2415
- tooltipEl = e.target;
2416
- tooltip = { label: a.label, value: a.value };
2417
- ctx.ui.render();
2418
- },
2419
- onMouseLeave: () => {
2420
- tooltipEl = null;
2421
- tooltip = null;
2422
- ctx.ui.render();
2423
- }
2424
- }),
2425
- ...a.value / data.reduce((s, d) => s + Math.abs(d.value), 0) > 0.05 ? [h("text", {
2426
- x: a.centroid.x,
2427
- y: a.centroid.y + 3,
2428
- "text-anchor": "middle",
2429
- fill: "#fff",
2430
- "font-size": "11",
2431
- "font-weight": "bold",
2432
- "font-family": "var(--wf-font-sans)"
2433
- }, `${Math.round(a.value / data.reduce((s, d) => s + Math.abs(d.value), 0) * 100)}%`)] : []
2434
- ]))
2435
- ]);
2436
- };
2437
- let chartContent;
2438
- if (type === "bar") chartContent = renderBar();
2439
- else if (type === "pie") chartContent = renderPie();
2440
- else chartContent = renderLine();
2441
- const legend = data.length > 1 ? h(
2442
- "div",
2443
- { class: "wf-chart-legend" },
2444
- data.map((d, i) => h("span", { class: "wf-chart-legend-item", key: `leg-${i}` }, [
2445
- h("span", { class: "wf-chart-legend-dot", style: { background: d.color ?? getDefaultColor(i) } }),
2446
- h("span", { class: "wf-chart-legend-label" }, d.label)
2447
- ]))
2448
- ) : null;
2449
- const isTipOpen = tooltip !== null;
2450
- if (isTipOpen && !prevOpen) pos.refresh();
2451
- prevOpen = isTipOpen;
2452
- const tip = tooltip ? h("div", {
2453
- class: "wf-chart-tooltip",
2454
- style: { left: pos.left, top: pos.top }
2455
- }, [
2456
- h("div", { class: "wf-chart-tooltip-label" }, tooltip.label),
2457
- h("div", { class: "wf-chart-tooltip-value" }, String(tooltip.value))
2458
- ]) : null;
2459
- return h("div", { class: `wf-chart${className ? " " + className : ""}` }, [
2460
- title ? h("div", { class: "wf-chart-title" }, title) : null,
2461
- chartContent,
2462
- legend,
2463
- tip
2464
- ].filter(Boolean));
2465
- };
2466
- };
2467
-
2468
- // src/components/Editor/tools/format.ts
2469
- function queryFormats() {
2470
- const f = {};
2471
- try {
2472
- f.bold = document.queryCommandState("bold");
2473
- f.italic = document.queryCommandState("italic");
2474
- f.underline = document.queryCommandState("underline");
2475
- const block = document.queryCommandValue("formatBlock");
2476
- f.h1 = block === "h1" || block === "H1";
2477
- f.h2 = block === "h2" || block === "H2";
2478
- f.h3 = block === "h3" || block === "H3";
2479
- f.blockquote = block === "blockquote" || block === "BLOCKQUOTE";
2480
- f.alignLeft = document.queryCommandState("justifyLeft");
2481
- f.alignCenter = document.queryCommandState("justifyCenter");
2482
- f.alignRight = document.queryCommandState("justifyRight");
2483
- } catch {
2484
- }
2485
- return f;
2486
- }
2487
- function exec(cmd, value) {
2488
- try {
2489
- document.execCommand(cmd, false, value);
2490
- } catch {
2491
- }
2492
- }
2493
- function execFormat(item) {
2494
- switch (item) {
2495
- case "bold":
2496
- exec("bold");
2497
- break;
2498
- case "italic":
2499
- exec("italic");
2500
- break;
2501
- case "underline":
2502
- exec("underline");
2503
- break;
2504
- case "h1":
2505
- exec("formatBlock", "<h1>");
2506
- break;
2507
- case "h2":
2508
- exec("formatBlock", "<h2>");
2509
- break;
2510
- case "h3":
2511
- exec("formatBlock", "<h3>");
2512
- break;
2513
- case "ul":
2514
- exec("insertUnorderedList");
2515
- break;
2516
- case "ol":
2517
- exec("insertOrderedList");
2518
- break;
2519
- case "blockquote":
2520
- exec("formatBlock", "<blockquote>");
2521
- break;
2522
- case "alignLeft":
2523
- exec("justifyLeft");
2524
- break;
2525
- case "alignCenter":
2526
- exec("justifyCenter");
2527
- break;
2528
- case "alignRight":
2529
- exec("justifyRight");
2530
- break;
2531
- case "hr":
2532
- exec("insertHorizontalRule");
2533
- break;
2534
- case "image":
2535
- break;
2536
- case "link":
2537
- break;
2538
- case "clear":
2539
- exec("removeFormat");
2540
- exec("formatBlock", "<div>");
2541
- break;
2542
- case "source":
2543
- break;
2544
- }
2545
- }
2546
-
2547
- // src/components/Editor/tools/toolbar.ts
2548
- var DEFAULT_TOOLBAR = [
2549
- "bold",
2550
- "italic",
2551
- "underline",
2552
- "h1",
2553
- "h2",
2554
- "h3",
2555
- "ul",
2556
- "ol",
2557
- "blockquote",
2558
- "alignLeft",
2559
- "alignCenter",
2560
- "alignRight",
2561
- "hr",
2562
- "image",
2563
- "table",
2564
- "link",
2565
- "clear",
2566
- "source"
2567
- ];
2568
- var TOOLBAR_LABELS = {
2569
- bold: "B",
2570
- italic: "I",
2571
- underline: "U",
2572
- h1: "H1",
2573
- h2: "H2",
2574
- h3: "H3",
2575
- ul: "\u25A1",
2576
- ol: "1.",
2577
- blockquote: "\u275D",
2578
- alignLeft: "\u21E4",
2579
- alignCenter: "\u21D4",
2580
- alignRight: "\u21E5",
2581
- hr: "\u2014",
2582
- image: "\u{1F5BC}",
2583
- table: "\u229E",
2584
- link: "\u{1F517}",
2585
- clear: "\u2715",
2586
- source: "</>"
2587
- };
2588
- var TOOLBAR_TITLES = {
2589
- bold: "\u52A0\u7C97 (Ctrl+B)",
2590
- italic: "\u659C\u4F53 (Ctrl+I)",
2591
- underline: "\u4E0B\u5212\u7EBF (Ctrl+U)",
2592
- h1: "\u6807\u9898 1",
2593
- h2: "\u6807\u9898 2",
2594
- h3: "\u6807\u9898 3",
2595
- ul: "\u65E0\u5E8F\u5217\u8868",
2596
- ol: "\u6709\u5E8F\u5217\u8868",
2597
- blockquote: "\u5F15\u7528",
2598
- alignLeft: "\u5DE6\u5BF9\u9F50",
2599
- alignCenter: "\u5C45\u4E2D",
2600
- alignRight: "\u53F3\u5BF9\u9F50",
2601
- hr: "\u5206\u5272\u7EBF",
2602
- image: "\u63D2\u5165\u56FE\u7247",
2603
- table: "\u63D2\u5165\u8868\u683C",
2604
- link: "\u63D2\u5165\u94FE\u63A5",
2605
- clear: "\u6E05\u9664\u683C\u5F0F",
2606
- source: "\u6E90\u7801"
2607
- };
2608
- var GRP_FORMAT = ["bold", "italic", "underline"];
2609
- var GRP_HEADING = ["h1", "h2", "h3"];
2610
- var GRP_LIST = ["ul", "ol"];
2611
- var GRP_BLOCK = ["blockquote", "alignLeft", "alignCenter", "alignRight", "hr"];
2612
- var GRP_INSERT = ["image", "table", "link", "clear"];
2613
- function needsSeparator(prev, item) {
2614
- return GRP_FORMAT.includes(prev) && GRP_HEADING.includes(item) || GRP_HEADING.includes(prev) && GRP_LIST.includes(item) || GRP_LIST.includes(prev) && GRP_BLOCK.includes(item) || GRP_BLOCK.includes(prev) && GRP_INSERT.includes(item) || ["link", "clear"].includes(prev) && item === "source";
2615
- }
2616
- function renderToolbar(items, active, isSource, onItem, customRender) {
2617
- const buttons = items.map((item) => {
2618
- if (customRender?.[item]) return customRender[item](item);
2619
- const isActive = item === "source" ? isSource : !!active[item];
2620
- const isLink = item === "link";
2621
- const cls = [
2622
- "wf-editor-tb-btn",
2623
- isActive && "wf-editor-tb-btn--active",
2624
- isLink && "wf-editor-tb-btn--link"
2625
- ].filter(Boolean).join(" ");
2626
- return h("button", {
2627
- key: item,
2628
- class: cls,
2629
- type: "button",
2630
- title: TOOLBAR_TITLES[item],
2631
- "aria-label": TOOLBAR_TITLES[item],
2632
- "data-item": item,
2633
- onClick: () => onItem(item)
2634
- }, TOOLBAR_LABELS[item]);
2635
- });
2636
- const withSeparators = [];
2637
- items.forEach((item, i) => {
2638
- if (i > 0 && needsSeparator(items[i - 1], item)) {
2639
- withSeparators.push(h("span", { class: "wf-editor-tb-sep", key: `sep-${i}` }));
2640
- }
2641
- withSeparators.push(buttons[i]);
2642
- });
2643
- return h("div", { class: "wf-editor-toolbar", role: "toolbar", "aria-label": "\u7F16\u8F91\u683C\u5F0F" }, withSeparators);
2644
- }
2645
-
2646
- // src/components/Editor/tools/table.ts
2647
- var MAX = 6;
2648
- function insertTable(rows, cols) {
2649
- const sel = window.getSelection();
2650
- if (!sel || !sel.rangeCount) return;
2651
- const range = sel.getRangeAt(0);
2652
- if (!range) return;
2653
- const table = document.createElement("table");
2654
- table.className = "wf-editor-table";
2655
- const tbody = document.createElement("tbody");
2656
- for (let ri = 0; ri < rows; ri++) {
2657
- const tr = document.createElement("tr");
2658
- for (let ci = 0; ci < cols; ci++) {
2659
- const td = document.createElement("td");
2660
- if (ri === 0) {
2661
- td.style.fontWeight = "var(--wf-font-weight-semibold,600)";
2662
- }
2663
- td.innerHTML = "&nbsp;";
2664
- tr.appendChild(td);
2665
- }
2666
- tbody.appendChild(tr);
2667
- }
2668
- table.appendChild(tbody);
2669
- const wrapper = document.createElement("div");
2670
- wrapper.appendChild(table);
2671
- range.deleteContents();
2672
- range.insertNode(wrapper);
2673
- range.setStartAfter(wrapper);
2674
- range.collapse(true);
2675
- sel.removeAllRanges();
2676
- sel.addRange(range);
2677
- }
2678
- function renderTableGrid(hoverRow, hoverCol, onSelect, onHover, onLeave) {
2679
- const grid = h("div", {
2680
- class: "wf-editor-table-grid",
2681
- onMouseLeave: onLeave
2682
- }, Array.from(
2683
- { length: MAX },
2684
- (_, ri) => h(
2685
- "div",
2686
- { class: "wf-editor-table-grid-row", key: `r${ri}` },
2687
- Array.from({ length: MAX }, (_2, ci) => {
2688
- const isHighlighted = ri <= hoverRow && ci <= hoverCol;
2689
- return h("div", {
2690
- class: `wf-editor-table-grid-cell${isHighlighted ? " wf-editor-table-grid-cell--active" : ""}`,
2691
- key: `${ri}-${ci}`,
2692
- onMouseEnter: () => onHover(ri, ci),
2693
- onClick: () => onSelect(ri + 1, ci + 1)
2694
- });
2695
- })
2696
- )
2697
- ));
2698
- const label = hoverRow >= 0 && hoverCol >= 0 ? `${hoverRow + 1} \xD7 ${hoverCol + 1} \u8868\u683C` : "\u9009\u62E9\u8868\u683C\u5927\u5C0F";
2699
- return h("div", {
2700
- class: "wf-editor-table-picker",
2701
- onMouseDown: (e) => e.stopPropagation()
2702
- }, [
2703
- grid,
2704
- h("div", { class: "wf-editor-table-picker-label" }, label)
2705
- ]);
2706
- }
2707
-
2708
- // src/components/Editor/Editor.ts
2709
- function shallowEqual(a, b) {
2710
- if (a === b) return true;
2711
- if (!a || !b) return false;
2712
- const keys = Object.keys(a);
2713
- if (keys.length !== Object.keys(b).length) return false;
2714
- for (const k of keys) {
2715
- if (a[k] !== b[k]) return false;
2716
- }
2717
- return true;
2718
- }
2719
- var Editor = (_props, ctx) => {
2720
- let activeFormats = null;
2721
- let showLinkInput = false;
2722
- let linkUrl = "";
2723
- let mode = "rich";
2724
- let showImageInput = false;
2725
- let imageUrl = "";
2726
- let imageUploading = false;
2727
- let showTableGrid = false;
2728
- let tableHoverRow = -1;
2729
- let tableHoverCol = -1;
2730
- let sourceText = "";
2731
- let editorEl = null;
2732
- let savedRange = null;
2733
- const saveSelection = () => {
2734
- const sel = window.getSelection();
2735
- if (sel && sel.rangeCount > 0) savedRange = sel.getRangeAt(0);
2736
- };
2737
- const restoreSelection = () => {
2738
- if (!editorEl || !savedRange) return;
2739
- editorEl.focus();
2740
- const sel = window.getSelection();
2741
- if (sel) {
2742
- sel.removeAllRanges();
2743
- sel.addRange(savedRange);
2744
- }
2745
- };
2746
- return (props) => {
2747
- const { value = "", onChange, onUpload, placeholder = "", disabled = false, minHeight = "200px" } = props;
2748
- const toolbarItems = props.toolbar ?? DEFAULT_TOOLBAR;
2749
- const isRichMode = mode === "rich";
2750
- const emitChange = (html) => {
2751
- onChange?.(html);
2752
- };
2753
- const handleToolbarItem = (item) => {
2754
- if (disabled) return;
2755
- if (item === "source") {
2756
- if (isRichMode) {
2757
- sourceText = editorEl?.innerHTML ?? value;
2758
- mode = "source";
2759
- ctx.ui.render();
2760
- } else {
2761
- mode = "rich";
2762
- activeFormats = {};
2763
- ctx.ui.render();
2764
- onChange?.(value);
2765
- }
2766
- return;
2767
- }
2768
- if (!isRichMode) return;
2769
- if (item === "image") {
2770
- showImageInput = true;
2771
- imageUrl = "";
2772
- ctx.ui.render();
2773
- return;
2774
- }
2775
- if (item === "link") {
2776
- saveSelection();
2777
- const sel = window.getSelection();
2778
- if (!sel || sel.isCollapsed) {
2779
- showLinkInput = true;
2780
- linkUrl = "";
2781
- ctx.ui.render();
2782
- return;
2783
- }
2784
- const existing = document.queryCommandState("createLink");
2785
- if (existing) {
2786
- exec("unlink");
2787
- activeFormats = queryFormats();
2788
- ctx.ui.render();
2789
- } else {
2790
- showLinkInput = true;
2791
- linkUrl = "";
2792
- ctx.ui.render();
2793
- }
2794
- return;
2795
- }
2796
- execFormat(item);
2797
- activeFormats = queryFormats();
2798
- ctx.ui.render();
2799
- if (editorEl && onChange) emitChange(editorEl.innerHTML);
2800
- };
2801
- const confirmLink = (url) => {
2802
- showLinkInput = false;
2803
- ctx.ui.render();
2804
- if (!url) return;
2805
- editorEl?.focus();
2806
- exec("createLink", url);
2807
- activeFormats = queryFormats();
2808
- if (editorEl && onChange) emitChange(editorEl.innerHTML);
2809
- };
2810
- const cancelLink = () => {
2811
- showLinkInput = false;
2812
- linkUrl = "";
2813
- ctx.ui.render();
2814
- };
2815
- const insertImageFn = (url) => {
2816
- if (!url) return;
2817
- exec("insertImage", url);
2818
- activeFormats = queryFormats();
2819
- if (editorEl && onChange) emitChange(editorEl.innerHTML);
2820
- };
2821
- const handleImageFile = async (files) => {
2822
- const file = files[0];
2823
- if (!file) return;
2824
- imageUploading = true;
2825
- ctx.ui.render();
2826
- try {
2827
- const url = await onUpload(file);
2828
- insertImageFn(url);
2829
- showImageInput = false;
2830
- imageUrl = "";
2831
- ctx.ui.render();
2832
- } catch {
2833
- } finally {
2834
- imageUploading = false;
2835
- ctx.ui.render();
2836
- }
2837
- };
2838
- const confirmImageUrl = (url) => {
2839
- showImageInput = false;
2840
- imageUrl = "";
2841
- ctx.ui.render();
2842
- editorEl?.focus();
2843
- insertImageFn(url);
2844
- };
2845
- const cancelImage = () => {
2846
- showImageInput = false;
2847
- imageUrl = "";
2848
- ctx.ui.render();
2849
- };
2850
- const handleTableSelect = (rows, cols) => {
2851
- showTableGrid = false;
2852
- tableHoverRow = -1;
2853
- tableHoverCol = -1;
2854
- console.log("[ED] table sel", "editorEl=", !!editorEl, "savedRange=", !!savedRange);
2855
- restoreSelection();
2856
- console.log("[ED] table after restore", "rc=", window.getSelection()?.rangeCount, "focused=", document.activeElement?.className?.includes("wf-editor-content"));
2857
- insertTable(rows, cols);
2858
- ctx.ui.render();
2859
- if (editorEl && onChange) emitChange(editorEl.innerHTML);
2860
- };
2861
- const handleTableHover = (row, col) => {
2862
- tableHoverRow = row;
2863
- tableHoverCol = col;
2864
- ctx.ui.render();
2865
- };
2866
- const handleTableLeave = () => {
2867
- tableHoverRow = -1;
2868
- tableHoverCol = -1;
2869
- ctx.ui.render();
2870
- };
2871
- const tableButton = h("button", {
2872
- key: "table",
2873
- class: "wf-editor-tb-btn",
2874
- type: "button",
2875
- title: "\u63D2\u5165\u8868\u683C",
2876
- "aria-label": "\u63D2\u5165\u8868\u683C",
2877
- "data-item": "table"
2878
- }, "\u229E");
2879
- const tableGrid = showTableGrid ? renderTableGrid(
2880
- tableHoverRow,
2881
- tableHoverCol,
2882
- handleTableSelect,
2883
- handleTableHover,
2884
- handleTableLeave
2885
- ) : null;
2886
- const tablePopover = h(Popover, {
2887
- key: "table",
2888
- open: isRichMode && !!showTableGrid,
2889
- onOpenChange: (v) => {
2890
- showTableGrid = v;
2891
- if (v) saveSelection();
2892
- ctx.ui.render();
2893
- },
2894
- content: tableGrid
2895
- }, tableButton);
2896
- const handleRichInput = (e) => {
2897
- if (disabled) return;
2898
- emitChange(e.currentTarget.innerHTML);
2899
- };
2900
- const handleSourceInput = (e) => {
2901
- const val = e.target.value;
2902
- onChange?.(val);
2903
- };
2904
- const handleKeyUp = (e) => {
2905
- if (disabled || !isRichMode) return;
2906
- saveSelection();
2907
- const isFormatShortcut = (e.ctrlKey || e.metaKey) && ["b", "i", "u"].includes(e.key.toLowerCase());
2908
- if (isFormatShortcut) {
2909
- activeFormats = queryFormats();
2910
- ctx.ui.render();
2911
- if (editorEl && onChange) emitChange(editorEl.innerHTML);
2912
- }
2913
- };
2914
- const handleMouseUp = () => {
2915
- if (!isRichMode) return;
2916
- saveSelection();
2917
- const newFormats = queryFormats();
2918
- if (activeFormats === null) {
2919
- activeFormats = newFormats;
2920
- return;
2921
- }
2922
- if (!shallowEqual(activeFormats, newFormats)) {
2923
- activeFormats = newFormats;
2924
- ctx.ui.render();
2925
- }
2926
- };
2927
- const handleMouseDown = () => {
2928
- saveSelection();
2929
- let needsRender = false;
2930
- if (showLinkInput) {
2931
- showLinkInput = false;
2932
- needsRender = true;
2933
- }
2934
- if (showImageInput) {
2935
- showImageInput = false;
2936
- needsRender = true;
2937
- }
2938
- if (needsRender) ctx.ui.render();
2939
- };
2940
- const linkModal = isRichMode && showLinkInput ? h(
2941
- Modal,
2942
- {
2943
- open: true,
2944
- title: "\u63D2\u5165\u94FE\u63A5",
2945
- onClose: cancelLink,
2946
- footer: [
2947
- h("button", { class: "wf-btn wf-btn--ghost wf-btn--sm", type: "button", onClick: cancelLink }, "\u53D6\u6D88"),
2948
- h("button", {
2949
- class: "wf-btn wf-btn--primary wf-btn--sm",
2950
- type: "button",
2951
- onClick: () => confirmLink(linkUrl)
2952
- }, "\u786E\u5B9A")
2953
- ]
2954
- },
2955
- h("input", {
2956
- type: "url",
2957
- class: "wf-editor-link-input",
2958
- placeholder: "https://...",
2959
- value: linkUrl,
2960
- "data-editor-link-input": true,
2961
- onInput: (e) => {
2962
- linkUrl = e.target.value;
2963
- ctx.ui.render();
2964
- },
2965
- onKeyDown: (e) => {
2966
- if (e.key === "Enter") confirmLink(e.target.value);
2967
- if (e.key === "Escape") cancelLink();
2968
- }
2969
- })
2970
- ) : null;
2971
- const imageBodyChildren = [];
2972
- if (onUpload) {
2973
- imageBodyChildren.push(h(FileUpload, {
2974
- accept: "image/*",
2975
- multiple: false,
2976
- disabled: imageUploading,
2977
- onChange: handleImageFile
2978
- }, h("div", { class: "wf-editor-img-zone" }, [
2979
- h("span", { class: "wf-editor-img-zone-icon" }, "\u{1F5BC}"),
2980
- h("span", { class: "wf-editor-img-zone-text" }, imageUploading ? "\u4E0A\u4F20\u4E2D..." : "\u70B9\u51FB\u6216\u62D6\u62FD\u4E0A\u4F20\u56FE\u7247")
2981
- ])));
2982
- imageBodyChildren.push(h("span", { class: "wf-editor-img-or" }, "\u6216"));
2983
- }
2984
- imageBodyChildren.push(h("input", {
2985
- type: "url",
2986
- class: "wf-editor-link-input",
2987
- placeholder: onUpload ? "\u7C98\u8D34\u56FE\u7247\u94FE\u63A5" : "https://...",
2988
- value: imageUrl,
2989
- "data-image-input": true,
2990
- disabled: imageUploading || void 0,
2991
- onInput: (e) => {
2992
- imageUrl = e.target.value;
2993
- ctx.ui.render();
2994
- },
2995
- onKeyDown: (e) => {
2996
- if (e.key === "Enter") confirmImageUrl(e.target.value);
2997
- if (e.key === "Escape") cancelImage();
2998
- }
2999
- }));
3000
- const imageModal = isRichMode && showImageInput ? h(
3001
- Modal,
3002
- {
3003
- open: true,
3004
- title: "\u63D2\u5165\u56FE\u7247",
3005
- onClose: cancelImage,
3006
- footer: [
3007
- h("button", { class: "wf-btn wf-btn--ghost wf-btn--sm", type: "button", disabled: imageUploading || void 0, onClick: cancelImage }, "\u53D6\u6D88"),
3008
- h("button", {
3009
- class: "wf-btn wf-btn--primary wf-btn--sm",
3010
- type: "button",
3011
- disabled: imageUploading || void 0,
3012
- onClick: () => confirmImageUrl(imageUrl)
3013
- }, onUpload ? "\u63D2\u5165" : "\u786E\u5B9A")
3014
- ]
3015
- },
3016
- h("div", { class: "wf-stack", style: "gap:8px" }, imageBodyChildren)
3017
- ) : null;
3018
- let editorBody = null;
3019
- if (isRichMode) {
3020
- const editorClass = [
3021
- "wf-editor-content",
3022
- disabled && "wf-editor-content--disabled",
3023
- placeholder && "wf-editor-content--has-placeholder"
3024
- ].filter(Boolean).join(" ");
3025
- editorBody = h("div", {
3026
- class: editorClass,
3027
- contentEditable: !disabled,
3028
- innerHTML: isRichMode ? value : sourceText,
3029
- "data-placeholder": placeholder || void 0,
3030
- style: { minHeight },
3031
- onInput: handleRichInput,
3032
- onKeyUp: handleKeyUp,
3033
- onMouseUp: handleMouseUp,
3034
- onMouseDown: handleMouseDown,
3035
- ref: (el) => {
3036
- if (el) editorEl = el;
3037
- }
3038
- });
3039
- } else {
3040
- editorBody = h("textarea", {
3041
- class: "wf-editor-source",
3042
- value,
3043
- disabled,
3044
- style: { minHeight },
3045
- onInput: handleSourceInput
3046
- });
3047
- }
3048
- const customRender = {
3049
- table: () => tablePopover
3050
- };
3051
- return h("div", {
3052
- class: `wf-editor${disabled ? " wf-editor--disabled" : ""}`
3053
- }, [
3054
- !disabled && toolbarItems.length > 0 ? renderToolbar(toolbarItems, activeFormats ?? {}, !isRichMode, handleToolbarItem, customRender) : null,
3055
- editorBody,
3056
- linkModal,
3057
- imageModal,
3058
- h("input", { type: "hidden", value, "aria-hidden": "true" })
3059
- ]);
3060
- };
3061
- };
3062
-
3063
- // src/components/ThemeSwitch/ThemeSwitch.ts
3064
- var DEFAULT_KEY = "wf_theme";
3065
- function readStored(key) {
3066
- try {
3067
- const v = localStorage.getItem(key);
3068
- return v === "light" || v === "dark" || v === "auto" ? v : null;
3069
- } catch {
3070
- return null;
3071
- }
3072
- }
3073
- function writeStored(key, mode) {
3074
- try {
3075
- localStorage.setItem(key, mode);
3076
- } catch {
3077
- }
3078
- }
3079
- function applyTheme(mode) {
3080
- if (typeof document === "undefined") return;
3081
- if (mode === "auto") document.documentElement.removeAttribute("data-theme");
3082
- else document.documentElement.setAttribute("data-theme", mode);
3083
- }
3084
- function getTheme() {
3085
- const stored = readStored(DEFAULT_KEY);
3086
- if (stored) return stored;
3087
- return "auto";
3088
- }
3089
- var ThemeSwitch = (initProps, ctx) => {
3090
- const storageKey = initProps.storageKey ?? DEFAULT_KEY;
3091
- let mode = initProps.mode ?? readStored(storageKey) ?? "auto";
3092
- applyTheme(mode);
3093
- return (props) => {
3094
- const SL = ctx?.i18n?.components?.ThemeSwitch ?? {};
3095
- const modes = [
3096
- { value: "auto", label: SL.auto ?? "\u81EA\u52A8" },
3097
- { value: "light", label: SL.light ?? "\u4EAE\u8272" },
3098
- { value: "dark", label: SL.dark ?? "\u6697\u8272" }
3099
- ];
3100
- const segments = modes.map(
3101
- (m) => h("button", {
3102
- type: "button",
3103
- class: `wf-theme-seg${mode === m.value ? " wf-theme-seg--active" : ""}`,
3104
- role: "radio",
3105
- "aria-checked": String(mode === m.value),
3106
- "aria-label": m.label,
3107
- onClick: () => {
3108
- if (mode === m.value) return;
3109
- mode = m.value;
3110
- applyTheme(mode);
3111
- writeStored(storageKey, mode);
3112
- props.onChange?.(mode);
3113
- ctx.ui.render();
3114
- }
3115
- }, m.label)
3116
- );
3117
- return h("div", {
3118
- class: "wf-theme-switch",
3119
- role: "radiogroup",
3120
- "aria-label": SL.label ?? "\u4E3B\u9898\u5207\u6362"
3121
- }, segments);
3122
- };
3123
- };
3124
-
3125
- // src/components/ToolCallCard/ToolCallCard.ts
3126
- var stateIcon = { running: "\u2699", ok: "\u2713", error: "\u2715" };
3127
- var ToolCallCard = (_init, _ctx) => (props) => {
3128
- const { call, progress, result, renderArgs } = props;
3129
- const state = result ? result.ok ? "ok" : "error" : "running";
3130
- const argsNode = renderArgs ? renderArgs(call.args) : h("code", { class: "wf-toolcall-args" }, JSON.stringify(call.args));
3131
- const progressNode = progress ? [
3132
- progress.message ? h("div", { class: "wf-toolcall-msg" }, `${progress.message} (${progress.step}/${progress.total})`) : null,
3133
- h("div", { class: "wf-toolcall-bar", role: "progressbar", "aria-valuenow": progress.step, "aria-valuemax": progress.total }, [
3134
- h("div", {
3135
- class: "wf-toolcall-bar-fill",
3136
- style: { width: `${Math.min(100, progress.step / Math.max(1, progress.total) * 100)}%` }
3137
- })
3138
- ])
3139
- ] : null;
3140
- const errorNode = result && !result.ok && result.error ? h("div", { class: "wf-toolcall-error" }, `${result.error.code}: ${result.error.message}`) : null;
3141
- return h("div", { class: `wf-toolcall wf-toolcall--${state}` }, [
3142
- h("div", { class: "wf-toolcall-header" }, [
3143
- h("span", { class: `wf-toolcall-icon wf-toolcall-icon--${state}` }, stateIcon[state]),
3144
- h("span", { class: "wf-toolcall-name" }, call.name)
3145
- ]),
3146
- h("div", { class: "wf-toolcall-body" }, [argsNode, progressNode, errorNode].filter(Boolean))
3147
- ]);
3148
- };
3149
-
3150
- // src/components/ApprovalCard/ApprovalCard.ts
3151
- var statusText = {
3152
- pending: "\u7B49\u5F85\u5BA1\u6279",
3153
- approved: "\u5DF2\u6279\u51C6",
3154
- rejected: "\u5DF2\u62D2\u7EDD",
3155
- timeout: "\u5BA1\u6279\u8D85\u65F6"
3156
- };
3157
- var ApprovalCard = (_init, ctx) => {
3158
- let note = "";
3159
- let showNote = false;
3160
- return (props) => {
3161
- const { request, status = "pending", onApprove, onReject, renderDetail } = props;
3162
- const detail = renderDetail ? renderDetail(request) : [
3163
- h("div", { class: "wf-approval-name" }, request.name),
3164
- h("code", { class: "wf-approval-args" }, JSON.stringify(request.args))
3165
- ];
3166
- const actions = status === "pending" ? h("div", { class: "wf-approval-actions" }, [
3167
- showNote ? h("div", { class: "wf-approval-note" }, [
3168
- h("input", {
3169
- class: "wf-approval-note-input",
3170
- placeholder: "\u5907\u6CE8\uFF08\u62D2\u7EDD\u539F\u56E0\uFF0C\u5C06\u8FDB\u5165 agent \u4E0A\u4E0B\u6587\uFF09\u2026",
3171
- value: note,
3172
- onInput: (e) => {
3173
- note = e.target.value;
3174
- }
3175
- })
3176
- ]) : null,
3177
- h("div", { class: "wf-approval-btns" }, [
3178
- h("button", {
3179
- class: "wf-btn wf-btn--primary wf-btn--sm",
3180
- type: "button",
3181
- onClick: () => onApprove?.()
3182
- }, "\u5141\u8BB8"),
3183
- h("button", {
3184
- class: "wf-btn wf-btn--danger wf-btn--sm",
3185
- type: "button",
3186
- onClick: () => {
3187
- if (!showNote) {
3188
- showNote = true;
3189
- ctx.ui.render();
3190
- return;
3191
- }
3192
- onReject?.(note);
3193
- }
3194
- }, showNote ? "\u786E\u8BA4\u62D2\u7EDD" : "\u62D2\u7EDD")
3195
- ])
3196
- ].filter(Boolean)) : h("div", { class: `wf-approval-status wf-approval-status--${status}` }, statusText[status]);
3197
- return h("div", { class: `wf-approval wf-approval--${status}` }, [
3198
- h("div", { class: "wf-approval-header" }, [
3199
- h("span", { class: "wf-approval-icon" }, status === "pending" ? "\u23F8" : status === "approved" ? "\u2713" : "\u2715"),
3200
- h("span", { class: "wf-approval-title" }, "\u5DE5\u5177\u5BA1\u6279")
3201
- ]),
3202
- h("div", { class: "wf-approval-detail" }, detail),
3203
- request.reason ? h("div", { class: "wf-approval-reason" }, request.reason) : null,
3204
- actions
3205
- ]);
3206
- };
3207
- };
3208
-
3209
- // src/components/AiChat/AiChat.ts
3210
- var defaultLabels = {
3211
- send: "\u53D1\u9001",
3212
- stop: "\u505C\u6B62",
3213
- retry: "\u91CD\u8BD5",
3214
- thinking: "\u{1F914} \u601D\u8003\u4E2D\u2026",
3215
- runningTool: (name) => name ? `\u2699\uFE0F \u6267\u884C\u5DE5\u5177 ${name}` : "\u2699\uFE0F \u6267\u884C\u5DE5\u5177\u2026",
3216
- tokens: (u) => `tokens: ${u.prompt_tokens}\u2192${u.completion_tokens}`,
3217
- error: (e) => `${e.code}: ${e.message}`,
3218
- placeholder: "\u8F93\u5165\u6D88\u606F\uFF0C\u56DE\u8F66\u53D1\u9001\u2026",
3219
- empty: "\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u5BF9\u8BDD\u3002"
3220
- };
3221
- var AiChat = (initProps, ctx) => {
3222
- let listEl;
3223
- let stickToBottom = true;
3224
- const unwatch = initProps.chat.__watch?.(() => ctx.ui.dirty());
3225
- const onScroll = () => {
3226
- if (!listEl) return;
3227
- stickToBottom = listEl.scrollHeight - listEl.scrollTop - listEl.clientHeight < 48;
3228
- };
3229
- const scrollToBottom = () => {
3230
- if (listEl) listEl.scrollTop = listEl.scrollHeight;
3231
- };
3232
- const listRef = (el) => {
3233
- if (el && !listEl) {
3234
- listEl = el;
3235
- el.addEventListener("scroll", onScroll);
3236
- queueMicrotask(scrollToBottom);
3237
- } else if (!el && listEl) {
3238
- listEl.removeEventListener("scroll", onScroll);
3239
- listEl = void 0;
3240
- unwatch?.();
3241
- }
3242
- };
3243
- return (props) => {
3244
- const { chat } = props;
3245
- const labels = { ...defaultLabels, ...props.labels };
3246
- if (stickToBottom) queueMicrotask(scrollToBottom);
3247
- const msgs = chat.messages ?? [];
3248
- const nodes = [];
3249
- if (msgs.length === 0) {
3250
- nodes.push(h("p", { class: "wf-aichat-empty" }, labels.empty));
3251
- }
3252
- for (const m of msgs) {
3253
- nodes.push(renderMessage(m, props, labels));
3254
- }
3255
- if (chat.step) {
3256
- nodes.push(
3257
- h(
3258
- "div",
3259
- { class: "wf-aichat-status" },
3260
- chat.step.type === "llm" ? labels.thinking : labels.runningTool(chat.step.name)
3261
- )
3262
- );
3263
- }
3264
- if (chat.usage) nodes.push(h("div", { class: "wf-aichat-usage" }, labels.tokens(chat.usage)));
3265
- if (chat.error) nodes.push(h("div", { class: "wf-aichat-error" }, labels.error(chat.error)));
3266
- return h("div", { class: "wf-aichat" }, [
3267
- h("div", {
3268
- class: "wf-aichat-list",
3269
- style: { maxHeight: props.maxHeight ?? "70vh" },
3270
- ref: listRef
3271
- }, nodes),
3272
- h("div", { class: "wf-aichat-inputbar" }, [
3273
- h("input", {
3274
- class: "wf-aichat-input",
3275
- value: chat.input ?? "",
3276
- placeholder: labels.placeholder,
3277
- onInput: (e) => {
3278
- chat.input = e.target.value;
3279
- },
3280
- onKeyDown: (e) => {
3281
- if (e.key === "Enter") chat.send();
3282
- }
3283
- }),
3284
- chat.streaming ? h("button", {
3285
- class: "wf-btn wf-btn--primary wf-btn--sm",
3286
- type: "button",
3287
- onClick: () => chat.stop()
3288
- }, labels.stop) : h("button", {
3289
- class: "wf-btn wf-btn--primary wf-btn--sm",
3290
- type: "button",
3291
- onClick: () => chat.send()
3292
- }, labels.send),
3293
- !chat.streaming && chat.error ? h("button", {
3294
- class: "wf-btn wf-btn--danger wf-btn--sm",
3295
- type: "button",
3296
- onClick: () => chat.retry()
3297
- }, labels.retry) : null
3298
- ])
3299
- ]);
3300
- };
3301
- };
3302
- function renderMessage(m, props, _labels) {
3303
- const nodes = [];
3304
- if (m.toolCalls?.length) {
3305
- const cards = m.toolCalls.map((tc, i) => h(ToolCallCard, {
3306
- key: `${m.id}-tool-${i}`,
3307
- call: tc.call,
3308
- progress: tc.progress,
3309
- result: tc.result,
3310
- renderArgs: props.renderToolArgs
3311
- }));
3312
- nodes.push(h("div", { class: "wf-aichat-tools" }, cards));
3313
- }
3314
- if (m.approval) {
3315
- const card = h(ApprovalCard, {
3316
- request: m.approval,
3317
- onApprove: () => props.chat.approve("approved"),
3318
- onReject: (note) => props.chat.approve("rejected", note ?? "\u7528\u6237\u62D2\u7EDD")
3319
- });
3320
- nodes.push(h("div", { class: "wf-aichat-approval" }, card));
3321
- }
3322
- nodes.push(h(
3323
- "div",
3324
- { class: `wf-aichat-bubble wf-aichat-bubble--${m.role}` },
3325
- props.renderMessage ? props.renderMessage(m) : m.content || "\u2026"
3326
- ));
3327
- return h("div", { key: m.id, class: `wf-aichat-msg wf-aichat-msg--${m.role}` }, nodes);
3328
- }
3329
- export {
3330
- Accordion,
3331
- AiChat,
3332
- Alert,
3333
- ApprovalCard,
3334
- Avatar,
3335
- Badge,
3336
- Breadcrumb,
3337
- Button,
3338
- Card,
3339
- Chart,
3340
- Checkbox,
3341
- Confirm,
3342
- DatePicker,
3343
- Divider,
3344
- Drawer,
3345
- Dropdown,
3346
- Editor,
3347
- EmptyState,
3348
- Field,
3349
- FileUpload,
3350
- Form,
3351
- Img,
3352
- InView,
3353
- Input,
3354
- Loading,
3355
- Modal,
3356
- PageHeader,
3357
- Pagination,
3358
- Popover,
3359
- ProgressBar,
3360
- RadioGroup,
3361
- SearchInput,
3362
- SegmentedControl,
3363
- Select,
3364
- Skeleton,
3365
- Slider,
3366
- StatCard,
3367
- Steps,
3368
- Switch,
3369
- Table,
3370
- Tabs,
3371
- Tag,
3372
- Textarea,
3373
- ThemeSwitch,
3374
- Toast,
3375
- ToolCallCard,
3376
- Tooltip,
3377
- applyTheme,
3378
- confirm,
3379
- getTheme,
3380
- toast
3381
- };
1
+ import{h as at}from"weifuwu/client";var Ot={"chevron-down":["M6 9l6 6 6-6"],"chevron-up":["M6 15l6-6 6 6"],"chevron-left":["M15 18l-6-6 6-6"],"chevron-right":["M9 18l6-6-6-6"],"arrow-left":["M19 12H5","M12 19l-7-7 7-7"],"arrow-up":["M12 19V5","M5 12l7-7 7 7"],"arrow-down":["M12 5v14","M19 12l-7 7-7-7"],sort:["M7 15l5 5 5-5","M7 9l5-5 5 5"],"sort-asc":["M12 19V5","M5 12l7-7 7 7"],"sort-desc":["M12 5v14","M19 12l-7 7-7-7"],check:["M20 6L9 17l-5-5"],close:["M18 6L6 18","M6 6l12 12"],alert:["M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z","M12 9v4","M12 17h.01"],info:["M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20z","M12 16v-4","M12 8h.01"],warning:["M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z","M12 9v4","M12 17h.01"],pause:["M6 4h4v16H6z","M14 4h4v16h-4z"],settings:["M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z","M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"],search:["M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16z","M21 21l-4.35-4.35"],send:["M22 2L11 13","M22 2l-7 20-4-9-9-4 20-7z"],stop:["M6 6h12v12H6z"],retry:["M1 4v6h6","M23 20v-6h-6","M20.49 9A9 9 0 0 0 5.64 5.64L1 10","M3.51 15a9 9 0 0 0 14.85 3.36L23 14"],upload:["M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4","M17 8l-5-5-5 5","M12 3v12"],trash:["M3 6h18","M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2","M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6h14","M10 11v6","M14 11v6"],edit:["M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7","M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"],plus:["M12 5v14","M5 12h14"]},S=(r,t)=>e=>{let{name:n,size:a,className:s}=e;return at("svg",{class:`wf-icon${s?" "+s:""}`,width:a??"1em",height:a??"1em",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":1.8,"stroke-linecap":"round","stroke-linejoin":"round","aria-hidden":"true",focusable:"false"},Ot[n].map(o=>at("path",{d:o})))};import{h as st}from"weifuwu/client";var Oe=(r,t)=>e=>{let{variant:n="primary",size:a="md",block:s,loading:o,disabled:l,type:i,onClick:c,children:p}=e,d=["wf-btn",`wf-btn--${n}`,`wf-btn--${a}`,s&&"wf-btn--block",o&&"wf-btn--loading"].filter(Boolean).join(" "),u=t?.i18n?.components?.Button??{};return st("button",{class:d,type:i??"button",disabled:l||o||void 0,"aria-busy":o||void 0,onClick:c},o?[st("span",{class:"wf-btn-spinner"}),u.loading??"\u52A0\u8F7D\u4E2D..."]:p)};import{h as be}from"weifuwu/client";var _t=r=>t=>{let{label:e,name:n,type:a="text",value:s,placeholder:o,required:l,disabled:i,error:c,hint:p,variant:d="default",onInput:u,onChange:f}=t,h=be("input",{class:`wf-input${d==="borderless"?" wf-input--borderless":""}`,name:n||void 0,type:a,value:s??"",placeholder:o,required:l||void 0,disabled:i||void 0,onInput:u,onChange:f});if(!e&&!c&&!p)return h;let m=[];if(e){let x=[e];l&&x.push(be("span",{class:"wf-input-req"},"*")),m.push(be("label",{class:"wf-input-label"},x))}return m.push(h),c&&m.push(be("div",{class:"wf-input-err"},c)),p&&!c&&m.push(be("div",{class:"wf-input-hint"},p)),be("div",{class:`wf-input-wrap${c?" wf-input--err":""}`},m)};import{h as pe}from"weifuwu/client";var Ht=(r,t)=>e=>{let{label:n,value:a,placeholder:s,required:o,disabled:l,error:i,hint:c,rows:p=3,maxLength:d,showCount:u,onInput:f}=e,h=pe("textarea",{class:"wf-textarea",value:a??"",placeholder:s,required:o||void 0,disabled:l||void 0,rows:p,maxLength:d,onInput:f}),m=[];if(n){let x=[n];o&&x.push(pe("span",{class:"wf-textarea-req"},"*")),m.push(pe("label",{class:"wf-textarea-label"},x))}if(m.push(h),u){let x=(a??"").length,b=d!=null&&x>d;m.push(pe("div",{class:`wf-textarea-count${b?" wf-textarea-count--over":""}`,"aria-live":"polite"},d!=null?`${x}/${d}`:String(x)))}return i&&m.push(pe("div",{class:"wf-textarea-err"},i)),c&&!i&&m.push(pe("div",{class:"wf-textarea-hint"},c)),pe("div",{class:`wf-textarea-wrap${i?" wf-textarea--err":""}`},m)};import{h as j}from"weifuwu/client";var Ft=(r,t)=>e=>{let{label:n,value:a,options:s,placeholder:o,required:l,disabled:i,error:c,onChange:p,children:d}=e,u=[];if(o&&u.push(j("option",{value:"",disabled:!0},o)),s)for(let m of s)u.push(j("option",{value:m.value,disabled:m.disabled},m.label));let f=j("select",{class:"wf-select",value:a??"",required:l||void 0,disabled:i||void 0,onChange:m=>p?.(m.target.value)},d??u),h=[];if(n){let m=[n];l&&m.push(j("span",{class:"wf-select-req"},"*")),h.push(j("label",{class:"wf-select-label"},m))}return h.push(f),c&&h.push(j("div",{class:"wf-select-err"},c)),j("div",{class:`wf-select-wrap${c?" wf-select--err":""}`},h)},Wt=(r,t)=>{let e=t.ui.$();return e.open=!1,e.keyword="",e.filteredOptions=[],n=>{let{label:a,value:s,options:o=[],placeholder:l,required:i,disabled:c,error:p,onChange:d,onSearch:u}=n,f=e.keyword?o.filter(y=>y.label.toLowerCase().includes(e.keyword.toLowerCase())):o,h=o.find(y=>y.value===s),m=async y=>{if(e.keyword=y,e.open=!0,u&&y){let k=await u(y);k&&(e.filteredOptions=k)}},x=y=>{y.disabled||(e.keyword="",e.open=!1,d?.(y.value))},b=j("div",{class:`wf-select-search-trigger${c?" wf-select-search--disabled":""}${p?" wf-select--err":""}`,onClick:c?void 0:()=>{e.open=!e.open}},[j("input",{class:"wf-select-search-input",type:"text",value:e.open?e.keyword:h?.label??"",placeholder:h?void 0:l??"",disabled:c,readOnly:!e.open||void 0,onInput:y=>m(y.target.value),onFocus:()=>{c||(e.open=!0)},onBlur:()=>{setTimeout(()=>{e.open=!1,e.keyword=""},150)}})]),w=[];if(a){let y=[a];i&&y.push(j("span",{class:"wf-select-req"},"*")),w.push(j("label",{class:"wf-select-label"},y))}let v=e.keyword&&u&&e.filteredOptions.length>0?e.filteredOptions:f,P=v.length>0?v.map(y=>j("div",{class:`wf-select-search-opt${y.value===s?" wf-select-search-opt--sel":""}${y.disabled?" wf-select-search-opt--dis":""}`,key:y.value,onMouseDown:k=>{k.preventDefault(),x(y)}},y.label)):e.keyword?[j("div",{class:"wf-select-search-empty"},"\u65E0\u5339\u914D")]:[],E=e.open?j("div",{class:"wf-select-search-menu"},P):null;return w.push(j("div",{class:"wf-select-search"},[b,E].filter(Boolean))),p&&w.push(j("div",{class:"wf-select-err"},p)),j("div",{class:`wf-select-wrap${p?" wf-select--err":""}`},w)}},qt=(r,t)=>{let e=Ft(r,t),n=Wt(r,t);return a=>a.searchable?n(a):e(a)};import{h as Pe}from"weifuwu/client";var zt=(r,t)=>e=>{let{label:n,checked:a,disabled:s,onChange:o}=e,l=Pe("input",{type:"checkbox",class:"wf-checkbox-input",checked:a||void 0,disabled:s||void 0,onChange:o?c=>o(c.target.checked):void 0}),i=Pe("span",{class:"wf-checkbox-visual"});return n?Pe("label",{class:"wf-checkbox"},[l,i,Pe("span",{class:"wf-checkbox-label"},n)]):Pe("label",{class:"wf-checkbox"},[l,i])};import{h as Te}from"weifuwu/client";var Vt=(r,t)=>e=>{let{label:n,checked:a,disabled:s,onChange:o}=e,l=Te("input",{type:"checkbox",class:"wf-switch-input",checked:a||void 0,disabled:s||void 0,role:"switch","aria-checked":String(!!a),onChange:o?p=>o(p.target.checked):void 0}),i=Te("span",{class:"wf-switch-track"}),c=t?.i18n?.components?.Switch??{};return n?Te("label",{class:"wf-switch"},[l,i,Te("span",{class:"wf-switch-label"},n)]):Te("label",{class:"wf-switch","aria-label":c.ariaLabel??"\u5207\u6362"},[l,i])};import{h as Me}from"weifuwu/client";var Nt=(r,t)=>e=>{let{name:n,value:a,options:s=[],inline:o,onChange:l}=e,i=s.map(c=>{let p=Me("input",{type:"radio",class:"wf-radio-input",name:n??"radio",value:c.value,checked:a===c.value||void 0,disabled:c.disabled||void 0,onChange:l?()=>l(c.value):void 0}),d=Me("span",{class:"wf-radio-visual"}),u=Me("span",{class:"wf-radio-label-text"},c.label);return Me("label",{class:"wf-radio",key:c.value},[p,d,u])});return Me("div",{class:`wf-radio-group${o?" wf-radio-group--inline":""}`},i)};import{h as J}from"weifuwu/client";function Kt(r,t,e,n){if(!e||!n)return r;let a=t.find(o=>o.key===e);if(!a||!a.sortable)return r;let s=[...r];return s.sort((o,l)=>{let i=o[e],c=l[e],p=a.sorter?a.sorter(i,c):String(i??"").localeCompare(String(c??""));return n==="desc"?-p:p}),s}var jt=(r,t)=>e=>{let{data:n=[],columns:a,onRowClick:s,sortKey:o,sortOrder:l,onSort:i,emptyText:c}=e,p=Kt(n,a,o,l),d=a.map(b=>{let w=b.key===o&&l,v=l==="asc",P=b.label,E=b.sortable?J(S,{name:w?v?"sort-asc":"sort-desc":"sort",className:`wf-table-sort-icon${w?" wf-table-sort-icon--active":""}`}):null,y=b.sortable&&i?()=>i(b.key,w&&v?"desc":"asc"):void 0;return J("th",{class:`wf-table-th${b.sortable?" wf-table-th--sortable":""}${w?" wf-table-th--sorted":""}`,scope:"col",tabindex:b.sortable?0:void 0,style:b.width?{width:b.width}:void 0,onClick:y,onKeyDown:y?k=>{(k.key==="Enter"||k.key===" ")&&(k.preventDefault(),y())}:void 0},[P,E].filter(Boolean))}),u=J("tr",{class:"wf-table-tr"},d),f=J("thead",{class:"wf-table-thead"},u),h;if(e.loading){let b=e.loadingRows??3;h=Array.from({length:b},(w,v)=>J("tr",{class:"wf-table-tr wf-table-tr--loading",key:`loading-${v}`},a.map((P,E)=>J("td",{class:"wf-table-td",key:`${v}-${E}`},J("span",{class:"wf-skeleton wf-skeleton--text"})))))}else if(p.length===0&&c){let b=a.length;h=[J("tr",{class:"wf-table-tr"},J("td",{class:"wf-table-td wf-table-empty",colspan:b,style:{textAlign:"center"}},c))]}else h=p.map((b,w)=>{let v=a.map(P=>{let E=b[P.key],y=P.render?P.render(E,b,w):String(E??"");return J("td",{class:"wf-table-td"},y)});return J("tr",{class:"wf-table-tr",onClick:s?()=>s(b,w):void 0,style:s?{cursor:"pointer"}:void 0},v)});let m=J("tbody",{class:"wf-table-tbody"},h),x=J("table",{class:"wf-table",style:e.minWidth?{minWidth:e.minWidth}:void 0},[f,m]);return J("div",{class:"wf-table-wrap"},x)};import{h as se,createPortal as Ut}from"weifuwu/client";import{lockScroll as Gt,unlockScroll as Yt}from"weifuwu/client";import{trapFocus as Xt}from"weifuwu/client";var ge=(r,t)=>{let e="closed",n,a,s=()=>{e="closed",t.ui.render()},o=l=>{if(l){Gt();let i=l.querySelector(".wf-modal")??l;n=Xt(i),a||(a=()=>{e==="exit"&&s()},l.addEventListener("animationend",a))}else Yt(),n?.(),l?.removeEventListener("animationend",a),a=void 0};return l=>{let{open:i,title:c,onClose:p,children:d,footer:u,width:f,closable:h=!0,maskClosable:m=!0}=l,x=t?.i18n?.components?.Modal??{};if(i?e="open":e==="open"&&(e="exit"),e==="closed")return null;let b=se("div",{class:"wf-modal-overlay",onClick:m?p:void 0}),w=h?se("button",{class:"wf-modal-close",onClick:p,type:"button","aria-label":x.closeAria??"\u5173\u95ED"},se(S,{name:"close"})):null,v=c?se("div",{class:"wf-modal-header"},[c,w].filter(Boolean)):null,P=se("div",{class:"wf-modal-body"},d),E=u?se("div",{class:"wf-modal-footer"},u):null,y=se("div",{class:"wf-modal-content",onClick:D=>D.stopPropagation(),style:f?{minWidth:f,maxWidth:f}:void 0},[v,P,E].filter(Boolean)),k=se("div",{ref:o,class:`wf-modal ${e==="exit"?"wf-modal--exit":"wf-modal--enter"}`,role:"dialog","aria-modal":"true","aria-label":c??x.ariaLabel??"\u5F39\u7A97",onKeyDown:D=>{D.key==="Escape"&&p?.()}},[b,y]);return Ut(k,"modal")}};import{h as _e}from"weifuwu/client";import{mountVNode as Zt,callRefCleanup as it}from"weifuwu/client";import{animateOut as Jt}from"weifuwu/client";function Qt(){return r=>(r.confirm=(t,e)=>eo(t,e??{},r),r)}function eo(r,t,e){return new Promise(n=>{let a=document.createElement("div");document.body.appendChild(a);let s=!1,o=_e(lt,{open:!0,title:t.title,message:r,confirmText:t.confirmText,cancelText:t.cancelText,variant:t.variant,width:t.width,maskClosable:t.maskClosable,onConfirm:()=>l(!0),onCancel:()=>l(!1)}),l=i=>{if(s)return;s=!0;let c=document.querySelector(".wf-modal");c?(c.classList.add("wf-modal--exit"),Jt(c,()=>{it(o),a.remove()})):(it(o),a.remove()),n(i)};Zt(a,o,e)})}var lt=(r,t)=>e=>{let{open:n=!1,title:a,message:s,confirmText:o,cancelText:l,variant:i="primary",width:c,maskClosable:p=!1,onConfirm:d,onCancel:u}=e,f=t?.i18n?.components?.Confirm??{},h=[_e(Oe,{variant:"secondary",size:"md",onClick:()=>u?.()},l??f.cancelText??"\u53D6\u6D88"),_e(Oe,{variant:i,size:"md",onClick:()=>d?.()},o??f.confirmText??"\u786E\u5B9A")];return _e(ge,{open:n,title:a,onClose:u,maskClosable:p,footer:h,width:c,closable:!1},s)};import{h as ne,createPortal as to}from"weifuwu/client";import{mountVNode as oo}from"weifuwu/client";import{animateOut as no}from"weifuwu/client";function ro(r){return{"top-right":"wf-toast--tr","top-left":"wf-toast--tl","bottom-right":"wf-toast--br","bottom-left":"wf-toast--bl","top-center":"wf-toast--tc"}[r]??"wf-toast--tr"}var ct=(r,t)=>e=>{let{toasts:n=[],onRemove:a,position:s="top-right",duration:o=0,max:l=0}=e,i=l>0&&n.length>l?n.slice(-l):n;if(i.length===0)return null;let c=i.map(p=>ne("div",{class:`wf-toast wf-toast--${p.type}`,key:p.id,"data-id":p.id,"data-duration":(p.duration??o)||void 0,onClick:a?()=>a(p.id):void 0},[ne("span",{class:"wf-toast-icon"},ne(S,{name:ao(p.type)})),ne("span",{class:"wf-toast-msg"},p.message),p.action?ne("button",{class:`wf-toast-action wf-toast-action--${p.type}`,type:"button",onClick:d=>{d.stopPropagation(),p.action.onClick()}},p.action.label):null].filter(Boolean)));return to(ne("div",{class:`wf-toast-container ${ro(s)}`,"data-max":l||void 0},c),"toast")};function ao(r){switch(r){case"success":return"check";case"error":return"close";case"warning":return"alert";case"info":return"info"}}function so(r){let t={position:r?.position??"top-right",duration:r?.duration??3e3,max:r?.max??3},e=null,n=null,a=0,s=(l,i)=>{let c=i.ui.$();return c.toasts=[],e={add:p=>{c.toasts=[...c.toasts,p]},remove:p=>{let d=document.querySelector(`.wf-toast[data-id="${p}"]`);if(d){d.classList.add("wf-toast-out");let u=getComputedStyle(d).animationName;if(u&&u!=="none"){no(d,()=>{c.toasts=c.toasts.filter(f=>f.id!==p)});return}}c.toasts=c.toasts.filter(u=>u.id!==p)}},()=>ne("div",{class:"wf-toast-host"},[ne(ct,{toasts:c.toasts,position:t.position,duration:t.duration,max:t.max,onRemove:p=>e?.remove(p)})])},o=()=>{if(e||!n)return;let l=document.createElement("div");document.body.appendChild(l),oo(l,ne(s,{}),n)};return l=>(n=l,l.toast=(i,c="info",p,d)=>{o();let u=String(++a);e?.add({id:u,type:c,message:i,duration:p,action:d});let f=p??t.duration;f>0&&setTimeout(()=>e?.remove(u),f)},l)}import{h as we}from"weifuwu/client";var io=(r,t)=>e=>{let{variant:n="info",closable:a,onClose:s,children:o}=e;if(!o)return null;let l=we("span",{class:"wf-alert-icon"},we(S,{name:lo(n)})),i=a?we("button",{class:"wf-alert-close",onClick:s,type:"button","aria-label":"\u5173\u95ED"},we(S,{name:"close"})):null,c=we("span",{class:"wf-alert-msg"},o);return we("div",{class:`wf-alert wf-alert--${n}`,role:"alert"},[l,c,i].filter(Boolean))};function lo(r){switch(r){case"success":return"check";case"error":return"close";case"warning":return"alert";case"info":return"info"}}import{h as Ne}from"weifuwu/client";var co=(r,t)=>e=>{let{text:n="\u52A0\u8F7D\u4E2D..."}=e;return Ne("div",{class:"wf-loading",role:"status","aria-live":"polite"},[Ne("div",{class:"wf-loading-spinner"}),Ne("span",{class:"wf-loading-text"},n)])};import{h as Se}from"weifuwu/client";var po=(r,t)=>e=>{let{icon:n="\u{1F4E6}",text:a="\u6682\u65E0\u6570\u636E",hint:s,children:o}=e,l=[Se("div",{class:"wf-empty-icon"},n),Se("div",{class:"wf-empty-text"},a)];return s&&l.push(Se("div",{class:"wf-empty-hint"},s)),o&&l.push(Se("div",{class:"wf-empty-action"},o)),Se("div",{class:"wf-empty",role:"status"},l)};import{h as He}from"weifuwu/client";var fo=(r,t)=>e=>{let{items:n=[],active:a,onChange:s}=e;if(n.length===0)return null;let o=a??n[0].key,l=d=>{let u=d.currentTarget,f=Array.from(u.querySelectorAll(".wf-tab")),h=f.indexOf(document.activeElement);if(h<0||!s)return;let m=h;if(d.key==="ArrowRight")m=(h+1)%f.length;else if(d.key==="ArrowLeft")m=(h-1+f.length)%f.length;else if(d.key==="Home")m=0;else if(d.key==="End")m=f.length-1;else return;d.preventDefault();let x=n[m];x&&x.key!==n[h].key&&(s(x.key),f[m].focus())},i=n.map(d=>He("button",{class:`wf-tab${d.key===o?" wf-tab--active":""}`,key:d.key,role:"tab",tabindex:d.key===o?0:-1,"aria-selected":d.key===o?"true":"false",onClick:d.key!==o&&s?()=>s(d.key):void 0},d.label)),c=n.find(d=>d.key===o),p=c?.content?He("div",{class:"wf-tab-content",role:"tabpanel"},c.content):null;return He("div",{class:"wf-tabs",role:"tablist",onKeyDown:l},[He("div",{class:"wf-tab-list"},i),p].filter(Boolean))};import{h as Ke,createPortal as uo}from"weifuwu/client";var mo=(r,t)=>{let e=null,n=l=>{e=l},a=!1,s=!1,o=t.ui.usePopupPosition({el:()=>e,isOpen:()=>a,compute:l=>({top:l.bottom+4,left:l.left})});return l=>{let{trigger:i,items:c=[],open:p,onOpenChange:d}=l;a=!!p,a&&!s&&o.refresh(),s=a;let u=c.map((m,x)=>Ke("button",{class:`wf-dropdown-item${m.variant==="danger"?" wf-dropdown-item--danger":""}`,key:m.value??x,disabled:m.disabled||void 0,role:"menuitem",onClick:m.onClick},m.label)),f=p?Ke("div",{class:"wf-dropdown-menu",role:"menu",style:{top:o.top,left:o.left},onKeyDown:m=>{m.key==="Escape"&&d?.(!1)}},u):null,h=p?uo(f,"dropdown"):null;return Ke("div",{class:`wf-dropdown${p?" wf-dropdown--open":""}`,ref:n,"aria-haspopup":"menu","aria-expanded":String(!!p)},[i,h].filter(Boolean))}};import{h as de}from"weifuwu/client";var ho=(r,t)=>e=>{let{total:n,page:a=1,pageSize:s=20,onChange:o}=e,l=t?.i18n?.components?.Pagination??{},i=Math.max(1,Math.ceil(n/s));if(i<=1)return null;let c=[];c.push(de("button",{class:`wf-page-btn${a<=1?" wf-page-btn--disabled":""}`,disabled:a<=1,"aria-label":l.prevAria??"\u4E0A\u4E00\u9875",onClick:a>1&&o?()=>o(a-1):void 0},de(S,{name:"chevron-left"})));let p=bo(a,i);for(let d of p)d==="..."?c.push(de("span",{class:"wf-page-ellipsis"},"...")):c.push(de("button",{class:`wf-page-btn${d===a?" wf-page-btn--active":""}`,"aria-current":d===a?"page":void 0,onClick:d!==a&&o?()=>o(d):void 0},String(d)));return c.push(de("button",{class:`wf-page-btn${a>=i?" wf-page-btn--disabled":""}`,disabled:a>=i,"aria-label":l.nextAria??"\u4E0B\u4E00\u9875",onClick:a<i&&o?()=>o(a+1):void 0},de(S,{name:"chevron-right"}))),de("nav",{class:"wf-pagination","aria-label":l.ariaLabel??"\u5206\u9875"},c)};function bo(r,t){if(t<=7)return Array.from({length:t},(s,o)=>o+1);let e=[1];r>3&&e.push("...");let n=Math.max(2,r-1),a=Math.min(t-1,r+1);for(let s=n;s<=a;s++)e.push(s);return r<t-2&&e.push("..."),e.push(t),e}import{h as go}from"weifuwu/client";var wo=(r,t)=>e=>{let{variant:n="default",padding:a="md",clickable:s,hover:o,active:l,onClick:i,children:c}=e,p=["wf-card",`wf-card--${n}`,`wf-card--pad-${a}`,s&&"wf-card--clickable",o&&"wf-card--hover",l&&"wf-card--active",(s||o)&&"wf-elevate"].filter(Boolean).join(" ");return go("div",{class:p,onClick:i,role:s?"button":void 0,tabindex:s?0:void 0,onKeyDown:s?d=>{(d.key==="Enter"||d.key===" ")&&(d.preventDefault(),i?.())}:void 0},c)};import{h as pt}from"weifuwu/client";var vo=(r,t)=>e=>{let{variant:n="default",dot:a,children:s}=e;return a?pt("span",{class:`wf-badge-dot wf-badge-dot--${n}`}):pt("span",{class:`wf-badge wf-badge--${n}`},s??"")};import{h as dt}from"weifuwu/client";var ft=["#4f6ef7","#22c55e","#f59e0b","#ef4444","#8b5cf6","#06b6d4","#ec4899"];function yo(r){let t=0;for(let e=0;e<r.length;e++)t=r.charCodeAt(e)+((t<<5)-t);return ft[Math.abs(t)%ft.length]}var xo=(r,t)=>e=>{let{name:n="",src:a,size:s="md",color:o}=e,l=n.trim()[0]?.toUpperCase()??"?";return a?dt("img",{class:`wf-avatar wf-avatar--${s}`,src:a,alt:n}):dt("div",{class:`wf-avatar wf-avatar--${s}`,style:{background:o??yo(n)}},l)};import{h as Fe}from"weifuwu/client";var Co=(r,t)=>e=>{let{closable:n,onClose:a,variant:s="default",children:o}=e,l=n?Fe("button",{class:"wf-tag-close",onClick:a,type:"button","aria-label":"\u79FB\u9664"},Fe(S,{name:"close"})):null;return Fe("span",{class:`wf-tag wf-tag--${s}`},[Fe("span",{class:"wf-tag-text"},o),l].filter(Boolean))};import{h as ie}from"weifuwu/client";var ko=(r,t)=>{let e=0,n;return a=>{let{label:s,value:o,trend:l,trendLabel:i,icon:c,onClick:p,animate:d}=a,u=typeof o=="number"?o:0;if(d&&typeof o=="number")if(typeof matchMedia<"u"&&matchMedia("(prefers-reduced-motion: reduce)").matches||e===u)e=u;else{let x=e,b=400,w=performance.now();n&&cancelAnimationFrame(n);let v=P=>{let E=Math.min(1,(P-w)/b),y=1-Math.pow(1-E,3);e=Math.round(x+(u-x)*y),E<1?(n=requestAnimationFrame(v),t.ui.render()):(n=void 0,t.ui.render())};n=requestAnimationFrame(v)}else e=u;let f=String(typeof o=="number"?e:o),h=[];return c&&h.push(ie("div",{class:"wf-stat-icon"},c)),h.push(ie("div",{class:"wf-stat-value wf-nums"},f)),h.push(ie("div",{class:"wf-stat-label"},s)),l&&h.push(ie("div",{class:`wf-stat-trend wf-stat-trend--${l}`},[ie("span",{class:"wf-stat-trend-arrow"},ie(S,{name:l==="up"?"arrow-up":"arrow-down"})),i?ie("span",{class:"wf-stat-trend-label"},i):null].filter(Boolean))),ie("div",{class:`wf-stat${p?" wf-stat--clickable":""}${p?" wf-elevate":""}`,onClick:p,role:p?"button":void 0,tabindex:p?0:void 0,onKeyDown:p?m=>{(m.key==="Enter"||m.key===" ")&&(m.preventDefault(),p())}:void 0},h)}};import{h as le}from"weifuwu/client";var Po=(r,t)=>e=>{let{items:n=[],active:a,current:s=0}=e,o=a??n[s]?.key,l=n.map((i,c)=>{let p=n.findIndex(w=>w.key===o),d=c<p,f=["wf-step",d&&"wf-step--done",c===p&&"wf-step--current"].filter(Boolean).join(" "),h=d?le("span",{class:"wf-step-num"},le(S,{name:"check"})):le("span",{class:"wf-step-num"},String(c+1)),m=le("span",{class:"wf-step-label"},i.label),x=i.description?le("span",{class:"wf-step-desc"},i.description):null,b=c<n.length-1?le("span",{class:`wf-step-connector${d?" wf-step-connector--done":""}`}):null;return le("div",{class:f,key:i.key},[h,m,x,b].filter(Boolean))});return le("div",{class:"wf-steps"},l)};import{h as To}from"weifuwu/client";async function Mo(r,t){let e={};for(let[n,a]of Object.entries(t)){let s=r[n]??"";for(let o of a){if(o.required&&!String(s).trim()){e[n]=o.message;break}if(o.pattern&&!o.pattern.test(String(s))){e[n]=o.message;break}if(o.minLength!=null&&String(s).length<o.minLength){e[n]=o.message;break}if(o.maxLength!=null&&String(s).length>o.maxLength){e[n]=o.message;break}if(o.validator){let l=await o.validator(s);if(l!==!0){e[n]=typeof l=="string"?l:o.message;break}}}}return e}var So=(r,t)=>e=>{let{validation:n,onSubmit:a,onError:s,children:o}=e;return To("form",{class:"wf-form",onSubmit:async i=>{i.preventDefault();let c=i.target,p=new FormData(c),d={};for(let[u,f]of p.entries())if(u in d){let h=d[u];d[u]=Array.isArray(h)?[...h,f]:[h,f]}else d[u]=f;if(n){let u=await Mo(d,n);if(Object.keys(u).length>0){s?.(u);return}s?.({})}await a?.(d)},noValidate:n?!0:void 0},o)};import{h as Ee}from"weifuwu/client";var Eo=(r,t)=>e=>{let{label:n,required:a,error:s,hint:o,children:l}=e,i=[];if(n){let c=[n];a&&c.push(Ee("span",{class:"wf-field-req"},"*")),i.push(Ee("label",{class:"wf-field-label"},c))}return i.push(l),s&&i.push(Ee("div",{class:"wf-field-err"},s)),o&&!s&&i.push(Ee("div",{class:"wf-field-hint"},o)),Ee("div",{class:`wf-field${s?" wf-field--err":""}`},i)};import{h as ve}from"weifuwu/client";var Lo=(r,t)=>e=>{let{label:n,value:a=0,min:s=0,max:o=100,step:l=1,onChange:i}=e,c=Number(a),p=ve("input",{type:"range",class:"wf-slider-input",value:c,min:s,max:o,step:l,onChange:i?u=>i(Number(u.target.value)):void 0}),d=ve("span",{class:"wf-slider-value"},String(c));return n?ve("div",{class:"wf-slider-wrap"},[ve("label",{class:"wf-slider-label"},n),ve("div",{class:"wf-slider"},[p,d])]):ve("div",{class:"wf-slider"},[p,d])};import{h as ye}from"weifuwu/client";var Io=(r,t)=>e=>{let{value:n="",placeholder:a="\u641C\u7D22...",onInput:s,onClear:o}=e,l=n&&o?ye("button",{class:"wf-search-clear",type:"button","aria-label":"\u6E05\u9664",onClick:o},ye(S,{name:"close"})):null,i=ye("span",{class:"wf-search-icon"},ye(S,{name:"search"}));return ye("div",{class:"wf-search"},[i,ye("input",{class:"wf-search-input",type:"search",value:n,placeholder:a,onInput:s}),l].filter(Boolean))};import{h as ut}from"weifuwu/client";var $o=(r,t)=>e=>{let{options:n,value:a,onChange:s,size:o="md",block:l,ariaLabel:i}=e,c=["wf-segmented",o==="sm"&&"wf-segmented--sm",l&&"wf-segmented--block"].filter(Boolean).join(" ");return ut("div",{class:c,role:"group","aria-label":i},n.map(p=>ut("button",{type:"button",class:`wf-segmented-option${p.value===a?" wf-segmented-option--active":""}`,"aria-pressed":p.value===a?"true":"false",disabled:p.disabled||void 0,onClick:p.disabled?void 0:()=>s?.(p.value)},p.label)))};import{h as Le}from"weifuwu/client";var Do=(r,t)=>e=>{let{value:n=0,max:a=100,label:s,showValue:o}=e,l=Math.min(100,Math.max(0,n/a*100)),i=t?.i18n?.components?.ProgressBar??{},c=Le("div",{class:"wf-progress",role:"progressbar","aria-valuenow":Math.round(n),"aria-valuemin":0,"aria-valuemax":Math.round(a),"aria-label":s??i.ariaLabel??"\u8FDB\u5EA6"},[Le("div",{class:"wf-progress-fill",style:{width:`${l}%`}})]);if(!s&&!o)return c;let p=[];return s&&p.push(Le("span",{class:"wf-progress-label"},s)),p.push(c),o&&p.push(Le("span",{class:"wf-progress-value"},`${Math.round(l)}%`)),Le("div",{class:"wf-progress-wrap"},p)};import{h as We}from"weifuwu/client";var Ao=(r,t)=>e=>{let{items:n=[],multiple:a}=e;if(n.length===0)return null;let s=n.map(o=>We("details",{class:"wf-accordion-item",key:o.key,open:!0},[We("summary",{class:"wf-accordion-summary","aria-expanded":"true"},o.title),o.content?We("div",{class:"wf-accordion-content"},o.content):null].filter(Boolean)));return We("div",{class:"wf-accordion"},s)};import{h as Ie}from"weifuwu/client";var Ro=(r,t)=>e=>{let{title:n,sub:a,display:s,children:o}=e;return Ie("div",{class:"wf-page-head"},[Ie("div",{class:"wf-page-head-left"},[Ie("h2",{class:`wf-page-title${s?" wf-page-title--display":""}`},n),a?Ie("p",{class:"wf-page-sub"},a):null].filter(Boolean)),o?Ie("div",{class:"wf-page-head-actions"},o):null].filter(Boolean))};import{h as $e}from"weifuwu/client";var Bo=(r,t)=>e=>{let{items:n}=e,a=n.flatMap((o,l)=>{let i=l===n.length-1,c=i?$e("span",{class:"wf-breadcrumb-current","aria-current":"page"},o.label):o.href?$e("a",{class:"wf-breadcrumb-link",href:o.href},o.label):$e("span",{class:"wf-breadcrumb-text"},o.label);return i?c:[c,$e("span",{class:"wf-breadcrumb-sep","aria-hidden":"true"},"/")]}),s=t?.i18n?.components?.Breadcrumb??{};return $e("nav",{class:"wf-breadcrumb","aria-label":s.ariaLabel??"\u9762\u5305\u5C51"},a)};import{h as je}from"weifuwu/client";var Oo=(r,t)=>e=>{let{vertical:n,children:a}=e;return n?je("div",{class:"wf-divider wf-divider--vertical",role:"separator"}):je("div",{class:a?"wf-divider wf-divider--with-text":"wf-divider",role:"separator"},a?je("span",{class:"wf-divider-text"},a):void 0)};import{h as U}from"weifuwu/client";function mt(r){return r<1024?`${r}B`:r<1024*1024?`${(r/1024).toFixed(1)}KB`:`${(r/(1024*1024)).toFixed(1)}MB`}var Ue=(r,t)=>{let e=t?.i18n?.components?.FileUpload??{},n=null,a=s=>{s&&(n=s)};return s=>{let{accept:o,multiple:l,maxSize:i,disabled:c,error:p,hint:d,value:u,onChange:f,children:h}=s,m=u??[],x=k=>{let D=k.target,A=Array.from(D.files??[]);i&&A.filter(q=>q.size>i).length>0||(f?.(A),D.value="")},b=k=>{if(!k||c)return;let D=q=>{if(q.preventDefault(),k.classList.remove("wf-upload-zone--drag"),c)return;let te=Array.from(q.dataTransfer?.files??[]);i&&te.filter(B=>B.size>i).length>0||f?.(te)},A=q=>{q.preventDefault(),k.classList.add("wf-upload-zone--drag")},L=()=>k.classList.remove("wf-upload-zone--drag");return k.addEventListener("drop",D),k.addEventListener("dragover",A),k.addEventListener("dragleave",L),()=>{k.removeEventListener("drop",D),k.removeEventListener("dragover",A),k.removeEventListener("dragleave",L)}},w=k=>{let D=m.filter((A,L)=>L!==k);f?.(D)},v=U("input",{type:"file",class:"wf-upload-input",accept:o||void 0,multiple:l||void 0,disabled:c||void 0,onChange:x,style:{display:"none"},ref:a}),P=U("div",{class:`wf-upload-zone${c?" wf-upload-zone--disabled":""}${p?" wf-upload-zone--err":""}`,onClick:c?void 0:()=>n?.click(),ref:b},h??U("div",{class:"wf-upload-placeholder"},[U("span",{class:"wf-upload-icon"},"\u{1F4C1}"),U("span",{class:"wf-upload-text"},e.placeholder??"\u70B9\u51FB\u6216\u62D6\u62FD\u4E0A\u4F20\u6587\u4EF6"),o?U("span",{class:"wf-upload-hint"},`${e.supportedFormats??"\u652F\u6301\u683C\u5F0F: "}${o}`):null,i?U("span",{class:"wf-upload-hint"},`${e.maxSize??"\u6700\u5927 "}${mt(i)}`):null].filter(Boolean))),E=m.length>0?U("ul",{class:"wf-upload-list"},m.map((k,D)=>U("li",{class:"wf-upload-item",key:k.name+k.size},U("span",{class:"wf-upload-item-info"},[U("span",{class:"wf-upload-item-name"},k.name),U("span",{class:"wf-upload-item-size"},mt(k.size))]),U("button",{class:"wf-upload-item-remove","aria-label":`${e.remove??"\u5220\u9664"} ${k.name}`,onClick:()=>w(D)},U(S,{name:"trash"}))))):null,y=[v,P,E];return p&&y.push(U("div",{class:"wf-upload-err"},p)),d&&!p&&y.push(U("div",{class:"wf-upload-hint"},d)),U("div",{class:"wf-upload"},y)}};import{h as qe,createPortal as _o}from"weifuwu/client";import{computeFixedPosRect as Ho}from"weifuwu/client";var Fo=(r,t)=>{let e=!1,n=null,a=i=>{i&&(n=i)},s="top",o=!1,l=t.ui.usePopupPosition({el:()=>n,isOpen:()=>e,compute:i=>Ho(i,s,6,!0)});return i=>{let{content:c,position:p="top",children:d,disabled:u}=i;s=p;let f=()=>{e=!0,t.ui.render()},h=()=>{e=!1,t.ui.render()};e&&!o&&l.refresh(),o=e;let m=l,x=u?null:qe("div",{class:`wf-tooltip wf-tooltip--${p}${e?"":" wf-tooltip--hidden"}`,style:{top:m.top,left:m.left},role:"tooltip"},[qe("div",{class:"wf-tooltip-arrow"}),qe("div",{class:"wf-tooltip-content"},c)]),b=u?null:_o(x,"tooltip");return qe("div",{class:"wf-tooltip-wrap",ref:a,onMouseEnter:f,onMouseLeave:h,onFocus:f,onBlur:h,onKeyDown:w=>{w.key==="Escape"&&h()}},[d,b].filter(Boolean))}};import{h as ce,createPortal as Wo}from"weifuwu/client";import{lockScroll as qo,unlockScroll as zo}from"weifuwu/client";import{trapFocus as Vo}from"weifuwu/client";var No=(r,t)=>{let e="closed",n,a,s=()=>{e="closed",t.ui.render()},o=l=>{if(l){qo();let i=l.querySelector(".wf-drawer")??l;n=Vo(i),a||(a=()=>{e==="exit"&&s()},l.addEventListener("animationend",a))}else zo(),n?.(),l?.removeEventListener("animationend",a),a=void 0};return l=>{let{open:i,title:c,position:p="right",onClose:d,children:u,footer:f}=l,h=t?.i18n?.components?.Drawer??{};if(i?e="open":e==="open"&&(e="exit"),e==="closed")return null;let m=ce("div",{class:"wf-drawer-overlay",onClick:d}),x=ce("button",{class:"wf-drawer-close",onClick:d,type:"button","aria-label":h.closeAria??"\u5173\u95ED"},ce(S,{name:"close"})),b=c?ce("div",{class:"wf-drawer-header"},[c,x]):null,w=ce("div",{class:"wf-drawer-body"},u),v=f?ce("div",{class:"wf-drawer-footer"},f):null,P=ce("div",{class:`wf-drawer-panel wf-drawer-panel--${p}`,onClick:y=>y.stopPropagation()},[b,w,v].filter(Boolean)),E=ce("div",{ref:o,class:`wf-drawer wf-drawer--${p} ${e==="exit"?"wf-drawer--exit":"wf-drawer--enter"}`,role:"dialog","aria-modal":"true","aria-label":c??h.ariaLabel??"\u4FA7\u8FB9\u9762\u677F",tabIndex:-1,onKeyDown:y=>{y.key==="Escape"&&d?.()}},[m,P]);return Wo(E,"drawer")}};import{h as De,createPortal as Ko}from"weifuwu/client";import{computeFixedPosRect as jo}from"weifuwu/client";var Ge=(r,t)=>{let e=!1,n=null,a=c=>{c&&(n=c)},s=!1,o="bottom",l=!1,i=t.ui.usePopupPosition({el:()=>n,isOpen:()=>s,compute:c=>jo(c,o,6,!0)});return c=>{let{content:p,trigger:d="click",position:u="bottom",open:f,onOpenChange:h,disabled:m,children:x}=c,b=f!==void 0?f:e;s=b,o=u;let w=A=>{f===void 0&&(e=A,t.ui.render()),h?.(A)};b&&!l&&i.refresh(),l=b;let v=d==="click"&&!m?()=>w(!b):void 0,P={};d==="hover"&&!m&&(P.onMouseEnter=()=>w(!0),P.onMouseLeave=()=>w(!1),P.onFocus=()=>w(!0),P.onBlur=()=>w(!1));let E=i,y=b&&d==="click"?De("div",{class:"wf-popover-overlay",onMouseDown:A=>{A.stopPropagation(),w(!1)}}):null,k=b?De("div",{class:`wf-popover wf-popover--${u} wf-popover--enter`,style:{top:E.top,left:E.left},role:"tooltip"},[De("div",{class:"wf-popover-arrow"}),De("div",{class:"wf-popover-content"},p)]):null,D=b?Ko([y,k].filter(Boolean),"popover"):null;return De("div",{class:`wf-popover-wrap${b?" wf-popover-wrap--open":""}`,ref:a,...P,onClick:v,onKeyDown:A=>{A.key==="Escape"&&w(!1)}},[x,D].filter(Boolean))}};import{h as xe,Fragment as Uo}from"weifuwu/client";var Go=r=>t=>{let{variant:e="text",lines:n=1,cols:a=3,width:s,height:o,className:l}=t,i={};s!==void 0&&(i.width=typeof s=="number"?`${s}px`:s),o!==void 0&&(i.height=typeof o=="number"?`${o}px`:o);let c=["wf-skeleton",`wf-skeleton--${e}`,l].filter(Boolean).join(" ");if(e==="table"){let d=Array.from({length:n},(u,f)=>{let h=Array.from({length:a},(m,x)=>{let b=f===n-1&&x===a-1?"40%":void 0;return xe("div",{class:"wf-skeleton wf-skeleton--text",style:b?{width:b}:void 0})});return xe("div",{class:"wf-skeleton-row"},h)});return xe("div",{class:"wf-skeleton-table"},d)}if(n<=1)return xe("div",{class:c,style:Object.keys(i).length?i:void 0});let p=Array.from({length:n},(d,u)=>{let f=u===n-1&&n>1?`${c} wf-skeleton--short`:c;return xe("div",{class:f,style:Object.keys(i).length?i:void 0})});return xe(Uo,null,p)};import{h as Yo}from"weifuwu/client";var Xo=r=>t=>{let{src:e,alt:n="",fallback:a,loading:s,width:o,height:l,className:i,style:c}=t,p={class:["wf-image",i].filter(Boolean).join(" "),src:e??a??"",alt:n,loading:s??"lazy"};return o!==void 0&&(p.width=o),l!==void 0&&(p.height=l),c&&(p.style=c),a&&(p.onError=d=>{let u=d.currentTarget;u.src!==a&&(u.src=a)}),Yo("img",p)};import{h as ze}from"weifuwu/client";var Zo=(r,t)=>{let e=!1,n=!1,a,s=o=>{o?(a=new IntersectionObserver(l=>{l[0]?.isIntersecting&&(e=!0,t.ui.render())},{threshold:r.threshold??0,rootMargin:r.rootMargin??"0px"}),a.observe(o)):a?.disconnect()};return o=>{if(e)return n||(n=!0,o.once!==!1&&a?.disconnect(),o.onEnter?.()),ze("div",{class:"wf-inview wf-inview--loaded"},o.children);let l=o.placeholder!==void 0?o.placeholder:ze("div",{class:"wf-inview-placeholder"});return ze("div",{class:"wf-inview wf-inview--pending"},[ze("div",{class:"wf-inview-pending",style:{width:"1px",height:"1px",opacity:0,pointerEvents:"none"},ref:s}),l])}};import{h as C,createPortal as en}from"weifuwu/client";var Jo=["\u65E5","\u4E00","\u4E8C","\u4E09","\u56DB","\u4E94","\u516D"];function bt(){return Jo}function ht(r,t){return new Date(r,t+1,0).getDate()}function Qo(r,t){return new Date(r,t,1).getDay()}function Ye(r,t){let e=[],n=ht(r,t),a=Qo(r,t),s=t===0?11:t-1,o=t===0?r-1:r,l=ht(o,s),i=new Date,c=[];for(let f=a-1;f>=0;f--){let h=l-f;c.push({year:o,month:s,day:h,isOtherMonth:!0,isToday:o===i.getFullYear()&&s===i.getMonth()&&h===i.getDate()})}for(let f=1;f<=n;f++)c.push({year:r,month:t,day:f,isOtherMonth:!1,isToday:r===i.getFullYear()&&t===i.getMonth()&&f===i.getDate()}),c.length===7&&(e.push(c),c=[]);let p=t===11?0:t+1,d=t===11?r+1:r,u=1;for(;e.length<6;){for(;c.length<7;)c.push({year:d,month:p,day:u++,isOtherMonth:!0,isToday:d===i.getFullYear()&&p===i.getMonth()&&u-1===i.getDate()});e.push(c),c=[]}return e}function fe(r,t,e){return`${r}-${String(t+1).padStart(2,"0")}-${String(e).padStart(2,"0")}`}function Xe(r,t){return`${String(r).padStart(2,"0")}:${String(t).padStart(2,"0")}`}function gt(r,t,e,n,a){return`${fe(r,t,e)} ${Xe(n,a)}`}function Ze(){return Array.from({length:24},(r,t)=>t)}function Je(){return Array.from({length:12},(r,t)=>t*5)}var tn=(r,t)=>{let e=!1,n="",a=new Date,s=a.getFullYear(),o=a.getMonth(),l=a.getHours(),i=Math.round(a.getMinutes()/5)*5,c=a.getFullYear(),p=a.getMonth(),d=a.getDate(),u=null,f=null,h=null,m=w=>{h=w},x=!1,b=t.ui.usePopupPosition({el:()=>h,isOpen:()=>e,compute:w=>({top:w.bottom+4,left:w.left,width:w.width})});return w=>{let v=t?.i18n?.components?.DatePicker??{},{mode:P="date",value:E,onChange:y,placeholder:k=v.placeholder??"\u9009\u62E9\u65E5\u671F",disabled:D}=w,A=e,L=T=>{e=T,t.ui.render()};e&&!x&&b.refresh(),x=e;let q=T=>{D||L(!e)},te=T=>{if(P==="datetime")c=T.year,p=T.month,d=T.day,s=T.year,o=T.month,t.ui.render();else if(P==="range")if(!u||u&&f)u=fe(T.year,T.month,T.day),f=null,t.ui.render();else{f=fe(T.year,T.month,T.day);let Y=u<f?u:f,M=u<f?f:u;n=`${Y} ~ ${M}`,y?.(n),L(!1)}else n=fe(T.year,T.month,T.day),y?.(n),L(!1)},V=()=>{o===0?(s--,o=11):o--,t.ui.render()},B=()=>{o===11?(s++,o=0):o++,t.ui.render()},Z=()=>{n=Xe(l,i),y?.(n),L(!1)},oe=()=>{n=gt(c,p,d,l,i),y?.(n),L(!1)},N=Ye(s,o),$=[v.w0,v.w1,v.w2,v.w3,v.w4,v.w5,v.w6].some(T=>T)?[v.w0,v.w1,v.w2,v.w3,v.w4,v.w5,v.w6]:bt(),O=(T,Y,M)=>C("button",{class:"wf-datepicker-header-btn",type:"button","aria-label":Y,onClick:M},C(S,{name:T})),R=C("div",{class:"wf-datepicker-header"},[O("chevron-left",v.prevMonth??"\u4E0A\u4E2A\u6708",V),C("span",{class:"wf-datepicker-header-title"},`${s}\u5E74${o+1}\u6708`),O("chevron-right",v.nextMonth??"\u4E0B\u4E2A\u6708",B)]),Q=C("div",{class:"wf-datepicker-weekdays"},$.map(T=>C("span",{class:"wf-datepicker-weekday"},T))),re=N.map((T,Y)=>C("div",{class:"wf-datepicker-grid",key:`row-${Y}`},T.map((M,F)=>{let _=["wf-datepicker-cell"];M.isOtherMonth&&_.push("wf-datepicker-cell--other-month"),M.isToday&&_.push("wf-datepicker-cell--today");let K=fe(M.year,M.month,M.day);return P==="range"?K===u||K===f?_.push("wf-datepicker-cell--range-edge"):u&&f&&K>u&&K<f&&_.push("wf-datepicker-cell--in-range"):P==="datetime"?c===M.year&&p===M.month&&d===M.day&&_.push("wf-datepicker-cell--selected"):K===n&&_.push("wf-datepicker-cell--selected"),C("button",{class:_.join(" "),key:`${M.year}-${M.month}-${M.day}`,type:"button",onClick:()=>te(M)},String(M.day))}))),Ce=C("div",{class:"wf-datepicker-range-panel"},[R,Q,...re]),me=T=>{if(T.key==="Escape"){L(!1);return}if(P==="time"||P==="datetime"||!["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"].includes(T.key))return;let Y=T.currentTarget,M=Array.from(Y.querySelectorAll(".wf-datepicker-cell")),F=M.indexOf(document.activeElement);if(F<0)return;T.preventDefault();let _=7,K=F;T.key==="ArrowLeft"?K--:T.key==="ArrowRight"?K++:T.key==="ArrowUp"?K-=_:T.key==="ArrowDown"&&(K+=_),K>=0&&K<M.length&&M[K].focus()},ke=C("div",{class:"wf-datepicker-overlay",onMouseDown:()=>L(!1)}),he=null;if(A)if(P==="time"){let T=Ze(),Y=Je(),M=C("div",{style:{top:b.top,left:b.left,width:b.width},class:"wf-time-picker",role:"dialog",onKeyDown:me,onMouseDown:F=>F.stopPropagation()},[C("div",{class:"wf-time-body"},[C("div",{class:"wf-time-col"},[C("div",{class:"wf-time-col-label"},v.hour??"\u65F6"),C("div",{class:"wf-time-opt-list"},T.map(F=>C("button",{class:`wf-time-opt${F===l?" wf-time-opt--selected":""}`,type:"button",key:F,onClick:()=>{l=F,t.ui.render()}},String(F).padStart(2,"0"))))]),C("div",{class:"wf-time-col"},[C("div",{class:"wf-time-col-label"},v.minute??"\u5206"),C("div",{class:"wf-time-opt-list"},Y.map(F=>C("button",{class:`wf-time-opt${F===i?" wf-time-opt--selected":""}`,type:"button",key:F,onClick:()=>{i=F,t.ui.render()}},String(F).padStart(2,"0"))))])]),C("div",{class:"wf-time-footer"},[C("button",{class:"wf-datepicker-footer-btn",type:"button",onClick:()=>L(!1)},v.cancel??"\u53D6\u6D88"),C("button",{class:"wf-datepicker-footer-btn",type:"button",onClick:Z},v.confirm??"\u786E\u5B9A")])]);he=[ke,M]}else if(P==="range"){let T=o===11?0:o+1,Y=o===11?s+1:s,M=Ye(Y,T),F=C("div",{style:{top:b.top,left:b.left},class:"wf-datepicker-range-wrap",onMouseDown:_=>_.stopPropagation()},[C("div",{class:"wf-datepicker-range-panel"},[C("div",{class:"wf-datepicker-header"},[O("chevron-left",v.prevMonth??"\u4E0A\u4E2A\u6708",V),C("span",{class:"wf-datepicker-header-title"},`${s}\u5E74${o+1}\u6708`),C("span",{class:"wf-datepicker-header-title"})]),Q,...re]),C("div",{class:"wf-datepicker-range-panel"},[C("div",{class:"wf-datepicker-header"},[C("span",{class:"wf-datepicker-header-title"}),C("span",{class:"wf-datepicker-header-title"},`${Y}\u5E74${T+1}\u6708`),O("chevron-right",v.nextMonth??"\u4E0B\u4E2A\u6708",B)]),C("div",{class:"wf-datepicker-weekdays"},$.map(_=>C("span",{class:"wf-datepicker-weekday"},_))),...M.map((_,K)=>C("div",{class:"wf-datepicker-grid",key:`row-${K}`},_.map(g=>{let z=fe(g.year,g.month,g.day),ae=["wf-datepicker-cell"];return g.isOtherMonth&&ae.push("wf-datepicker-cell--other-month"),g.isToday&&ae.push("wf-datepicker-cell--today"),z===u||z===f?ae.push("wf-datepicker-cell--range-edge"):u&&f&&z>u&&z<f&&ae.push("wf-datepicker-cell--in-range"),C("button",{class:ae.join(" "),key:z,type:"button",onClick:()=>te(g)},String(g.day))})))])]);he=[ke,F]}else{let T=[Ce];P==="datetime"&&(T.push(C("div",{class:"wf-datetime-time"},[C("span",{class:"wf-datetime-time-label"},(v.time??"\u65F6\u95F4")+"\uFF1A"),C("div",{class:"wf-datetime-time-select"},[C("select",{class:"wf-datetime-select",value:l,onChange:M=>{l=parseInt(M.target.value),t.ui.render()}},Ze().map(M=>C("option",{value:M,key:M},String(M).padStart(2,"0")))),C("span",{class:"wf-datetime-sep"},":"),C("select",{class:"wf-datetime-select",value:i,onChange:M=>{i=parseInt(M.target.value),t.ui.render()}},Je().map(M=>C("option",{value:M,key:M},String(M).padStart(2,"0"))))])])),T.push(C("div",{class:"wf-time-footer"},[C("button",{class:"wf-datepicker-footer-btn",type:"button",onClick:oe},v.confirm??"\u786E\u5B9A")])));let Y=C("div",{style:{top:b.top,left:b.left,width:b.width},class:"wf-datepicker-dropdown",role:"dialog",onKeyDown:me,onMouseDown:M=>M.stopPropagation()},T);he=[ke,Y]}let Ve=A?en(he,"dp-calendar"):null;return C("div",{class:`wf-datepicker${D?" wf-datepicker--disabled":""}`},[C("input",{class:"wf-datepicker-input",type:"text",placeholder:k,value:(E??n??"")||"",ref:m,readonly:!0,disabled:D,onClick:q}),Ve].filter(Boolean))}};import{h as I}from"weifuwu/client";function Ae(r,t){let e=(n=>{let a=(n-r[0])/(r[1]-r[0]);return t[0]+a*(t[1]-t[0])});return e.domain=r,e.range=t,e.invert=n=>{let a=(n-t[0])/(t[1]-t[0]);return r[0]+a*(r[1]-r[0])},e}function vt(r,t,e){return r.length===0?"":r.map((n,a)=>{let s=t(a),o=e(n.value);return a===0?`M${s},${o}`:`L${s},${o}`}).join(" ")}function yt(r,t,e,n){if(r.length===0)return"";let a=r.map((l,i)=>{let c=t(i),p=e(l.value);return`${c},${p}`}),s=t(0),o=t(r.length-1);return`M${s},${n}L${a.join("L")}L${o},${n}Z`}function xt(r,t,e,n){let a=n??Math.max(4,(t.range[1]-t.range[0])/r.length*.6);return r.map((s,o)=>({x:t(o)-a/2,y:e(Math.max(0,s.value)),width:a,height:Math.abs(e(s.value)-e(0)),color:s.color??Re(o),label:s.label,value:s.value}))}function Ct(r,t,e,n){let a=r.reduce((o,l)=>o+Math.abs(l.value),0);if(a===0)return[];let s=-Math.PI/2;return r.map((o,l)=>{let i=Math.abs(o.value)/a*Math.PI*2,c=s+i,p=on(t,e,n,s,c),d=s+i/2;return s=c,{d:p,color:o.color??Re(l),label:o.label,value:o.value,centroid:{x:t+Math.cos(d)*n*.6,y:e+Math.sin(d)*n*.6}}})}function on(r,t,e,n,a){let s=r+e*Math.cos(n),o=t+e*Math.sin(n),l=r+e*Math.cos(a),i=t+e*Math.sin(a),c=a-n>Math.PI?1:0;return`M${r},${t}L${s},${o}A${e},${e} 0 ${c} 1 ${l},${i}Z`}var wt=["#3b82f6","#ef4444","#22c55e","#f59e0b","#8b5cf6","#ec4899","#06b6d4","#84cc16"];function Re(r){return wt[r%wt.length]}function Qe(r,t=5){let[e,n]=r.domain,a=(n-e)/t,s=[];for(let o=0;o<=t;o++){let l=e+a*o;s.push({value:l,y:r(l),label:nn(l)})}return s}function nn(r){return Math.abs(r)>=1e6?(r/1e6).toFixed(1)+"M":Math.abs(r)>=1e3?(r/1e3).toFixed(1)+"k":String(Math.round(r))}var rn=(r,t)=>{let e=null,n=null,a=!1,s=t.ui.usePopupPosition({el:()=>n,isOpen:()=>e!==null,compute:o=>({top:o.top-8,left:o.left+o.width/2})});return o=>{let{type:l="line",data:i,options:c={},title:p,area:d,className:u}=o,f=c.width??320,h=c.height??200,m=c.padding??32,x=f-m*2,b=h-m*2,w=i.map(V=>V.value),v=Math.min(0,...w),P=Math.max(...w),E=P-v||1,y=()=>{let V=Math.max(1,i.length-1),B=Ae([-.5,V+.5],[0,x]),Z=Ae([v,P],[b,0]),oe=Qe(Z),N=vt(i,B,Z),$=d?yt(i,B,Z,Z(0)):null,O=i.map((R,Q)=>{let re=B(Q)+m,Ce=Z(R.value)+m;return I("circle",{key:`dot-${Q}`,cx:re,cy:Ce,r:3,fill:R.color??Re(Q),stroke:"#fff","stroke-width":1.5,style:{cursor:"pointer"},onMouseEnter:me=>{n=me.target,e={label:R.label,value:R.value},t.ui.render()},onMouseLeave:()=>{n=null,e=null,t.ui.render()}})});return I("svg",{style:{width:"100%"},height:h,viewBox:`0 0 ${f} ${h}`},[...oe.map((R,Q)=>I("g",{key:`tick-${Q}`},[I("line",{x1:m,y1:R.y+m,x2:f-m,y2:R.y+m,stroke:"#e5e7eb","stroke-width":1}),I("text",{x:m-6,y:R.y+m+4,"text-anchor":"end",fill:"#6b7280","font-size":"11","font-family":"var(--wf-font-sans)"},R.label)])),...$?[I("path",{key:"area",d:$,fill:"#3b82f620",stroke:"none",transform:`translate(${m},${m})`})]:[],I("path",{key:"line",d:N,fill:"none",stroke:"#3b82f6","stroke-width":2,"stroke-linejoin":"round","stroke-linecap":"round",transform:`translate(${m},${m})`}),...i.map((R,Q)=>{let re=B(Q)+m;return I("text",{key:`xlabel-${Q}`,x:re,y:h-m+14,"text-anchor":"middle",fill:"#6b7280","font-size":"10","font-family":"var(--wf-font-sans)"},R.label)}),...O])},k=()=>{let V=Math.max(1,i.length-1),B=Ae([-.5,V+.5],[0,x]),Z=Ae([v,P],[b,0]),oe=Qe(Z),N=xt(i,B,Z);return I("svg",{style:{width:"100%"},height:h,viewBox:`0 0 ${f} ${h}`},[...oe.map(($,O)=>I("g",{key:`tick-${O}`},[I("line",{x1:m,y1:$.y+m,x2:f-m,y2:$.y+m,stroke:"#e5e7eb","stroke-width":1}),I("text",{x:m-6,y:$.y+m+4,"text-anchor":"end",fill:"#6b7280","font-size":"11","font-family":"var(--wf-font-sans)"},$.label)])),...N.map(($,O)=>I("rect",{key:`bar-${O}`,x:$.x+m,y:$.y+m,width:$.width,height:$.height,fill:$.color,rx:2,onMouseEnter:R=>{n=R.target,e={label:$.label,value:$.value},t.ui.render()},onMouseLeave:()=>{n=null,e=null,t.ui.render()}})),...i.map(($,O)=>{let R=B(O)+m;return I("text",{key:`xlabel-${O}`,x:R,y:h-m+14,"text-anchor":"middle",fill:"#6b7280","font-size":"10","font-family":"var(--wf-font-sans)"},$.label)})])},D=()=>{let V=f/2,B=h/2,Z=Math.min(x,b)/2-4,oe=Ct(i,V,B,Z);return I("svg",{style:{width:"100%"},height:h,viewBox:`0 0 ${f} ${h}`},[...oe.map((N,$)=>I("g",{key:`arc-${$}`},[I("path",{d:N.d,fill:N.color,stroke:"#fff","stroke-width":1.5,onMouseEnter:O=>{n=O.target,e={label:N.label,value:N.value},t.ui.render()},onMouseLeave:()=>{n=null,e=null,t.ui.render()}}),...N.value/i.reduce((O,R)=>O+Math.abs(R.value),0)>.05?[I("text",{x:N.centroid.x,y:N.centroid.y+3,"text-anchor":"middle",fill:"#fff","font-size":"11","font-weight":"bold","font-family":"var(--wf-font-sans)"},`${Math.round(N.value/i.reduce((O,R)=>O+Math.abs(R.value),0)*100)}%`)]:[]]))])},A;l==="bar"?A=k():l==="pie"?A=D():A=y();let L=i.length>1?I("div",{class:"wf-chart-legend"},i.map((V,B)=>I("span",{class:"wf-chart-legend-item",key:`leg-${B}`},[I("span",{class:"wf-chart-legend-dot",style:{background:V.color??Re(B)}}),I("span",{class:"wf-chart-legend-label"},V.label)]))):null,q=e!==null;q&&!a&&s.refresh(),a=q;let te=e?I("div",{class:"wf-chart-tooltip",style:{left:s.left,top:s.top}},[I("div",{class:"wf-chart-tooltip-label"},e.label),I("div",{class:"wf-chart-tooltip-value"},String(e.value))]):null;return I("div",{class:`wf-chart${u?" "+u:""}`},[p?I("div",{class:"wf-chart-title"},p):null,A,L,te].filter(Boolean))}};import{h as H}from"weifuwu/client";function ue(){let r={};try{r.bold=document.queryCommandState("bold"),r.italic=document.queryCommandState("italic"),r.underline=document.queryCommandState("underline");let t=document.queryCommandValue("formatBlock");r.h1=t==="h1"||t==="H1",r.h2=t==="h2"||t==="H2",r.h3=t==="h3"||t==="H3",r.blockquote=t==="blockquote"||t==="BLOCKQUOTE",r.alignLeft=document.queryCommandState("justifyLeft"),r.alignCenter=document.queryCommandState("justifyCenter"),r.alignRight=document.queryCommandState("justifyRight")}catch{}return r}function W(r,t){try{document.execCommand(r,!1,t)}catch{}}function kt(r){switch(r){case"bold":W("bold");break;case"italic":W("italic");break;case"underline":W("underline");break;case"h1":W("formatBlock","<h1>");break;case"h2":W("formatBlock","<h2>");break;case"h3":W("formatBlock","<h3>");break;case"ul":W("insertUnorderedList");break;case"ol":W("insertOrderedList");break;case"blockquote":W("formatBlock","<blockquote>");break;case"alignLeft":W("justifyLeft");break;case"alignCenter":W("justifyCenter");break;case"alignRight":W("justifyRight");break;case"hr":W("insertHorizontalRule");break;case"image":break;case"link":break;case"clear":W("removeFormat"),W("formatBlock","<div>");break;case"source":break}}import{h as et}from"weifuwu/client";var Et=["bold","italic","underline","h1","h2","h3","ul","ol","blockquote","alignLeft","alignCenter","alignRight","hr","image","table","link","clear","source"],an={bold:"B",italic:"I",underline:"U",h1:"H1",h2:"H2",h3:"H3",ul:"\u25A1",ol:"1.",blockquote:"\u275D",alignLeft:"\u21E4",alignCenter:"\u21D4",alignRight:"\u21E5",hr:"\u2014",image:"\u{1F5BC}",table:"\u229E",link:"\u{1F517}",clear:"\u2715",source:"</>"},Pt={bold:"\u52A0\u7C97 (Ctrl+B)",italic:"\u659C\u4F53 (Ctrl+I)",underline:"\u4E0B\u5212\u7EBF (Ctrl+U)",h1:"\u6807\u9898 1",h2:"\u6807\u9898 2",h3:"\u6807\u9898 3",ul:"\u65E0\u5E8F\u5217\u8868",ol:"\u6709\u5E8F\u5217\u8868",blockquote:"\u5F15\u7528",alignLeft:"\u5DE6\u5BF9\u9F50",alignCenter:"\u5C45\u4E2D",alignRight:"\u53F3\u5BF9\u9F50",hr:"\u5206\u5272\u7EBF",image:"\u63D2\u5165\u56FE\u7247",table:"\u63D2\u5165\u8868\u683C",link:"\u63D2\u5165\u94FE\u63A5",clear:"\u6E05\u9664\u683C\u5F0F",source:"\u6E90\u7801"},sn=["bold","italic","underline"],Tt=["h1","h2","h3"],Mt=["ul","ol"],St=["blockquote","alignLeft","alignCenter","alignRight","hr"],ln=["image","table","link","clear"];function cn(r,t){return sn.includes(r)&&Tt.includes(t)||Tt.includes(r)&&Mt.includes(t)||Mt.includes(r)&&St.includes(t)||St.includes(r)&&ln.includes(t)||["link","clear"].includes(r)&&t==="source"}function Lt(r,t,e,n,a){let s=r.map(l=>{if(a?.[l])return a[l](l);let p=["wf-editor-tb-btn",(l==="source"?e:!!t[l])&&"wf-editor-tb-btn--active",l==="link"&&"wf-editor-tb-btn--link"].filter(Boolean).join(" ");return et("button",{key:l,class:p,type:"button",title:Pt[l],"aria-label":Pt[l],"data-item":l,onClick:()=>n(l)},an[l])}),o=[];return r.forEach((l,i)=>{i>0&&cn(r[i-1],l)&&o.push(et("span",{class:"wf-editor-tb-sep",key:`sep-${i}`})),o.push(s[i])}),et("div",{class:"wf-editor-toolbar",role:"toolbar","aria-label":"\u7F16\u8F91\u683C\u5F0F"},o)}import{h as Be}from"weifuwu/client";var It=6;function $t(r,t){let e=window.getSelection();if(!e||!e.rangeCount)return;let n=e.getRangeAt(0);if(!n)return;let a=document.createElement("table");a.className="wf-editor-table";let s=document.createElement("tbody");for(let l=0;l<r;l++){let i=document.createElement("tr");for(let c=0;c<t;c++){let p=document.createElement("td");l===0&&(p.style.fontWeight="var(--wf-font-weight-semibold,600)"),p.innerHTML="&nbsp;",i.appendChild(p)}s.appendChild(i)}a.appendChild(s);let o=document.createElement("div");o.appendChild(a),n.deleteContents(),n.insertNode(o),n.setStartAfter(o),n.collapse(!0),e.removeAllRanges(),e.addRange(n)}function Dt(r,t,e,n,a){let s=Be("div",{class:"wf-editor-table-grid",onMouseLeave:a},Array.from({length:It},(l,i)=>Be("div",{class:"wf-editor-table-grid-row",key:`r${i}`},Array.from({length:It},(c,p)=>{let d=i<=r&&p<=t;return Be("div",{class:`wf-editor-table-grid-cell${d?" wf-editor-table-grid-cell--active":""}`,key:`${i}-${p}`,onMouseEnter:()=>n(i,p),onClick:()=>e(i+1,p+1)})})))),o=r>=0&&t>=0?`${r+1} \xD7 ${t+1} \u8868\u683C`:"\u9009\u62E9\u8868\u683C\u5927\u5C0F";return Be("div",{class:"wf-editor-table-picker",onMouseDown:l=>l.stopPropagation()},[s,Be("div",{class:"wf-editor-table-picker-label"},o)])}function pn(r,t){if(r===t)return!0;if(!r||!t)return!1;let e=Object.keys(r);if(e.length!==Object.keys(t).length)return!1;for(let n of e)if(r[n]!==t[n])return!1;return!0}var dn=(r,t)=>{let e=null,n=!1,a="",s="rich",o=!1,l="",i=!1,c=!1,p=-1,d=-1,u="",f=null,h=w=>{w&&(f=w)},m=null,x=()=>{let w=window.getSelection();w&&w.rangeCount>0&&(m=w.getRangeAt(0))},b=()=>{if(!f||!m)return;f.focus();let w=window.getSelection();w&&(w.removeAllRanges(),w.addRange(m))};return w=>{let{value:v="",onChange:P,onUpload:E,placeholder:y="",disabled:k=!1,minHeight:D="200px"}=w,A=w.toolbar??Et,L=s==="rich",q=g=>{P?.(g)},te=g=>{if(!k){if(g==="source"){L?(u=f?.innerHTML??v,s="source",t.ui.render()):(s="rich",e={},t.ui.render(),P?.(v));return}if(L){if(g==="image"){o=!0,l="",t.ui.render();return}if(g==="link"){x();let z=window.getSelection();if(!z||z.isCollapsed){n=!0,a="",t.ui.render();return}document.queryCommandState("createLink")?(W("unlink"),e=ue(),t.ui.render()):(n=!0,a="",t.ui.render());return}kt(g),e=ue(),t.ui.render(),f&&P&&q(f.innerHTML)}}},V=g=>{n=!1,t.ui.render(),g&&(f?.focus(),W("createLink",g),e=ue(),f&&P&&q(f.innerHTML))},B=()=>{n=!1,a="",t.ui.render()},Z=g=>{g&&(W("insertImage",g),e=ue(),f&&P&&q(f.innerHTML))},oe=async g=>{let z=g[0];if(z){i=!0,t.ui.render();try{let ae=await E(z);Z(ae),o=!1,l="",t.ui.render()}catch{}finally{i=!1,t.ui.render()}}},N=g=>{o=!1,l="",t.ui.render(),f?.focus(),Z(g)},$=()=>{o=!1,l="",t.ui.render()},O=(g,z)=>{c=!1,p=-1,d=-1,console.log("[ED] table sel","editorEl=",!!f,"savedRange=",!!m),b(),console.log("[ED] table after restore","rc=",window.getSelection()?.rangeCount,"focused=",document.activeElement?.className?.includes("wf-editor-content")),$t(g,z),t.ui.render(),f&&P&&q(f.innerHTML)},R=(g,z)=>{p=g,d=z,t.ui.render()},Q=()=>{p=-1,d=-1,t.ui.render()},re=H("button",{key:"table",class:"wf-editor-tb-btn",type:"button",title:"\u63D2\u5165\u8868\u683C","aria-label":"\u63D2\u5165\u8868\u683C","data-item":"table"},"\u229E"),Ce=c?Dt(p,d,O,R,Q):null,me=H(Ge,{key:"table",open:L&&!!c,onOpenChange:g=>{c=g,g&&x(),t.ui.render()},content:Ce},re),ke=g=>{k||q(g.currentTarget.innerHTML)},he=g=>{let z=g.target.value;P?.(z)},Ve=g=>{if(k||!L)return;x(),(g.ctrlKey||g.metaKey)&&["b","i","u"].includes(g.key.toLowerCase())&&(e=ue(),t.ui.render(),f&&P&&q(f.innerHTML))},rt=()=>{if(!L)return;x();let g=ue();if(e===null){e=g;return}pn(e,g)||(e=g,t.ui.render())},T=()=>{x();let g=!1;n&&(n=!1,g=!0),o&&(o=!1,g=!0),g&&t.ui.render()},Y=L&&n?H(ge,{open:!0,title:"\u63D2\u5165\u94FE\u63A5",onClose:B,footer:[H("button",{class:"wf-btn wf-btn--ghost wf-btn--sm",type:"button",onClick:B},"\u53D6\u6D88"),H("button",{class:"wf-btn wf-btn--primary wf-btn--sm",type:"button",onClick:()=>V(a)},"\u786E\u5B9A")]},H("input",{type:"url",class:"wf-editor-link-input",placeholder:"https://...",value:a,"data-editor-link-input":!0,onInput:g=>{a=g.target.value,t.ui.render()},onKeyDown:g=>{g.key==="Enter"&&V(g.target.value),g.key==="Escape"&&B()}})):null,M=[];E&&(M.push(H(Ue,{accept:"image/*",multiple:!1,disabled:i,onChange:oe},H("div",{class:"wf-editor-img-zone"},[H("span",{class:"wf-editor-img-zone-icon"},"\u{1F5BC}"),H("span",{class:"wf-editor-img-zone-text"},i?"\u4E0A\u4F20\u4E2D...":"\u70B9\u51FB\u6216\u62D6\u62FD\u4E0A\u4F20\u56FE\u7247")]))),M.push(H("span",{class:"wf-editor-img-or"},"\u6216"))),M.push(H("input",{type:"url",class:"wf-editor-link-input",placeholder:E?"\u7C98\u8D34\u56FE\u7247\u94FE\u63A5":"https://...",value:l,"data-image-input":!0,disabled:i||void 0,onInput:g=>{l=g.target.value,t.ui.render()},onKeyDown:g=>{g.key==="Enter"&&N(g.target.value),g.key==="Escape"&&$()}}));let F=L&&o?H(ge,{open:!0,title:"\u63D2\u5165\u56FE\u7247",onClose:$,footer:[H("button",{class:"wf-btn wf-btn--ghost wf-btn--sm",type:"button",disabled:i||void 0,onClick:$},"\u53D6\u6D88"),H("button",{class:"wf-btn wf-btn--primary wf-btn--sm",type:"button",disabled:i||void 0,onClick:()=>N(l)},E?"\u63D2\u5165":"\u786E\u5B9A")]},H("div",{class:"wf-stack",style:"gap:8px"},M)):null,_=null;if(L){let g=["wf-editor-content",k&&"wf-editor-content--disabled",y&&"wf-editor-content--has-placeholder"].filter(Boolean).join(" ");_=H("div",{class:g,contentEditable:!k,innerHTML:L?v:u,"data-placeholder":y||void 0,style:{minHeight:D},onInput:ke,onKeyUp:Ve,onMouseUp:rt,onMouseDown:T,ref:h})}else _=H("textarea",{class:"wf-editor-source",value:v,disabled:k,style:{minHeight:D},onInput:he});let K={table:()=>me};return H("div",{class:`wf-editor${k?" wf-editor--disabled":""}`},[!k&&A.length>0?Lt(A,e??{},!L,te,K):null,_,Y,F,H("input",{type:"hidden",value:v,"aria-hidden":"true"})])}};import{h as At}from"weifuwu/client";var Rt="wf_theme";function Bt(r){try{let t=localStorage.getItem(r);return t==="light"||t==="dark"||t==="auto"?t:null}catch{return null}}function fn(r,t){try{localStorage.setItem(r,t)}catch{}}function tt(r){typeof document>"u"||(r==="auto"?document.documentElement.removeAttribute("data-theme"):document.documentElement.setAttribute("data-theme",r))}function un(){let r=Bt(Rt);return r||"auto"}var mn=(r,t)=>{let e=r.storageKey??Rt,n=r.mode??Bt(e)??"auto";return tt(n),a=>{let s=t?.i18n?.components?.ThemeSwitch??{},l=[{value:"auto",label:s.auto??"\u81EA\u52A8"},{value:"light",label:s.light??"\u4EAE\u8272"},{value:"dark",label:s.dark??"\u6697\u8272"}].map(i=>At("button",{type:"button",class:`wf-theme-seg${n===i.value?" wf-theme-seg--active":""}`,role:"radio","aria-checked":String(n===i.value),"aria-label":i.label,onClick:()=>{n!==i.value&&(n=i.value,tt(n),fn(e,n),a.onChange?.(n),t.ui.render())}},i.label));return At("div",{class:"wf-theme-switch",role:"radiogroup","aria-label":s.label??"\u4E3B\u9898\u5207\u6362"},l)}};import{h as ee}from"weifuwu/client";var hn={running:"settings",ok:"check",error:"close"},ot=(r,t)=>e=>{let{call:n,progress:a,result:s,renderArgs:o}=e,l=s?s.ok?"ok":"error":"running",i=o?o(n.args):ee("code",{class:"wf-toolcall-args"},JSON.stringify(n.args)),c=a?[a.message?ee("div",{class:"wf-toolcall-msg"},`${a.message} (${a.step}/${a.total})`):null,ee("div",{class:"wf-toolcall-bar",role:"progressbar","aria-valuenow":a.step,"aria-valuemax":a.total},[ee("div",{class:"wf-toolcall-bar-fill",style:{width:`${Math.min(100,a.step/Math.max(1,a.total)*100)}%`}})])]:null,p=s&&!s.ok&&s.error?ee("div",{class:"wf-toolcall-error"},`${s.error.code}: ${s.error.message}`):null;return ee("div",{class:`wf-toolcall wf-toolcall--${l}`},[ee("div",{class:"wf-toolcall-header"},[ee("span",{class:`wf-toolcall-icon wf-toolcall-icon--${l}`},hn[l]),ee("span",{class:"wf-toolcall-name"},n.name)]),ee("div",{class:"wf-toolcall-body"},[i,c,p].filter(Boolean))])};import{h as X}from"weifuwu/client";var bn={pending:"\u7B49\u5F85\u5BA1\u6279",approved:"\u5DF2\u6279\u51C6",rejected:"\u5DF2\u62D2\u7EDD",timeout:"\u5BA1\u6279\u8D85\u65F6"},nt=(r,t)=>{let e="",n=!1;return a=>{let{request:s,status:o="pending",onApprove:l,onReject:i,renderDetail:c}=a,p=c?c(s):[X("div",{class:"wf-approval-name"},s.name),X("code",{class:"wf-approval-args"},JSON.stringify(s.args))],d=o==="pending"?X("div",{class:"wf-approval-actions"},[n?X("div",{class:"wf-approval-note"},[X("input",{class:"wf-approval-note-input",placeholder:"\u5907\u6CE8\uFF08\u62D2\u7EDD\u539F\u56E0\uFF0C\u5C06\u8FDB\u5165 agent \u4E0A\u4E0B\u6587\uFF09\u2026",value:e,onInput:u=>{e=u.target.value}})]):null,X("div",{class:"wf-approval-btns"},[X("button",{class:"wf-btn wf-btn--primary wf-btn--sm",type:"button",onClick:()=>l?.()},"\u5141\u8BB8"),X("button",{class:"wf-btn wf-btn--danger wf-btn--sm",type:"button",onClick:()=>{if(!n){n=!0,t.ui.render();return}i?.(e)}},n?"\u786E\u8BA4\u62D2\u7EDD":"\u62D2\u7EDD")])].filter(Boolean)):X("div",{class:`wf-approval-status wf-approval-status--${o}`},bn[o]);return X("div",{class:`wf-approval wf-approval--${o}`},[X("div",{class:"wf-approval-header"},[X("span",{class:"wf-approval-icon"},X(S,{name:o==="pending"?"pause":o==="approved"?"check":"close"})),X("span",{class:"wf-approval-title"},"\u5DE5\u5177\u5BA1\u6279")]),X("div",{class:"wf-approval-detail"},p),s.reason?X("div",{class:"wf-approval-reason"},s.reason):null,d])}};import{h as G}from"weifuwu/client";var gn={send:"\u53D1\u9001",stop:"\u505C\u6B62",retry:"\u91CD\u8BD5",thinking:"\u{1F914} \u601D\u8003\u4E2D\u2026",runningTool:r=>r?`\u2699\uFE0F \u6267\u884C\u5DE5\u5177 ${r}`:"\u2699\uFE0F \u6267\u884C\u5DE5\u5177\u2026",tokens:r=>`tokens: ${r.prompt_tokens}\u2192${r.completion_tokens}`,error:r=>`${r.code}: ${r.message}`,placeholder:"\u8F93\u5165\u6D88\u606F\uFF0C\u56DE\u8F66\u53D1\u9001\u2026",empty:"\u8F93\u5165\u6D88\u606F\u5F00\u59CB\u5BF9\u8BDD\u3002"},wn=(r,t)=>{let e,n=!0,a=r.chat.__watch?.(()=>t.ui.dirty()),s=()=>{e&&(n=e.scrollHeight-e.scrollTop-e.clientHeight<48)},o=()=>{e&&(e.scrollTop=e.scrollHeight)},l=i=>{i&&!e?(e=i,i.addEventListener("scroll",s),queueMicrotask(o)):!i&&e&&(e.removeEventListener("scroll",s),e=void 0,a?.())};return i=>{let{chat:c}=i,p={...gn,...i.labels};n&&queueMicrotask(o);let d=c.messages??[],u=[];d.length===0&&u.push(G("p",{class:"wf-aichat-empty"},p.empty));for(let f of d)u.push(vn(f,i,p));return c.step&&u.push(G("div",{class:"wf-aichat-status"},c.step.type==="llm"?p.thinking:p.runningTool(c.step.name))),c.usage&&u.push(G("div",{class:"wf-aichat-usage"},p.tokens(c.usage))),c.error&&u.push(G("div",{class:"wf-aichat-error"},p.error(c.error))),G("div",{class:"wf-aichat"},[G("div",{class:"wf-aichat-list",style:{maxHeight:i.maxHeight??"70vh"},ref:l},u),G("div",{class:"wf-aichat-inputbar"},[G("input",{class:"wf-aichat-input",value:c.input??"",placeholder:p.placeholder,onInput:f=>{c.input=f.target.value},onKeyDown:f=>{f.key==="Enter"&&c.send()}}),c.streaming?G("button",{class:"wf-btn wf-btn--primary wf-btn--sm",type:"button",onClick:()=>c.stop()},p.stop):G("button",{class:"wf-btn wf-btn--primary wf-btn--sm",type:"button",onClick:()=>c.send()},p.send),!c.streaming&&c.error?G("button",{class:"wf-btn wf-btn--danger wf-btn--sm",type:"button",onClick:()=>c.retry()},p.retry):null])])}};function vn(r,t,e){let n=[];if(r.toolCalls?.length){let a=r.toolCalls.map((s,o)=>G(ot,{key:`${r.id}-tool-${o}`,call:s.call,progress:s.progress,result:s.result,renderArgs:t.renderToolArgs}));n.push(G("div",{class:"wf-aichat-tools"},a))}if(r.approval){let a=G(nt,{request:r.approval,onApprove:()=>t.chat.approve("approved"),onReject:s=>t.chat.approve("rejected",s??"\u7528\u6237\u62D2\u7EDD")});n.push(G("div",{class:"wf-aichat-approval"},a))}return n.push(G("div",{class:`wf-aichat-bubble wf-aichat-bubble--${r.role}`},t.renderMessage?t.renderMessage(r):r.content||"\u2026")),G("div",{key:r.id,class:`wf-aichat-msg wf-aichat-msg--${r.role}`},n)}export{Ao as Accordion,wn as AiChat,io as Alert,nt as ApprovalCard,xo as Avatar,vo as Badge,Bo as Breadcrumb,Oe as Button,wo as Card,rn as Chart,zt as Checkbox,lt as Confirm,tn as DatePicker,Oo as Divider,No as Drawer,mo as Dropdown,dn as Editor,po as EmptyState,Eo as Field,Ue as FileUpload,So as Form,S as Icon,Xo as Img,Zo as InView,_t as Input,co as Loading,ge as Modal,Ro as PageHeader,ho as Pagination,Ge as Popover,Do as ProgressBar,Nt as RadioGroup,Io as SearchInput,$o as SegmentedControl,qt as Select,Go as Skeleton,Lo as Slider,ko as StatCard,Po as Steps,Vt as Switch,jt as Table,fo as Tabs,Co as Tag,Ht as Textarea,mn as ThemeSwitch,ct as Toast,ot as ToolCallCard,Fo as Tooltip,tt as applyTheme,Qt as confirm,un as getTheme,so as toast};