@guiwzh/small-design 0.1.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.
package/dist/index.mjs ADDED
@@ -0,0 +1,1143 @@
1
+ // src/components/Button/button.tsx
2
+ import classNames from "classnames";
3
+ import { jsx } from "react/jsx-runtime";
4
+ var Button = (props) => {
5
+ const { className, disabled = false, size, btnType = "default", href, children, ...restProps } = props;
6
+ const classes = classNames("btn", className, {
7
+ [`btn-${btnType}`]: btnType,
8
+ [`btn-${size}`]: size,
9
+ "disabled": disabled
10
+ });
11
+ if (btnType === "link" && href) {
12
+ return /* @__PURE__ */ jsx("a", { className: classes, href, ...restProps, children });
13
+ } else {
14
+ return /* @__PURE__ */ jsx("button", { className: classes, disabled, ...restProps, children });
15
+ }
16
+ };
17
+ Button.displayName = "Button";
18
+ var button_default = Button;
19
+
20
+ // src/components/Menu/menu.tsx
21
+ import React, { useState, createContext, Children } from "react";
22
+ import classNames2 from "classnames";
23
+ import { jsx as jsx2 } from "react/jsx-runtime";
24
+ var MenuContext = createContext({ index: "0" });
25
+ var Menu = (props) => {
26
+ const { className, mode = "horizontal", style, children, defaultIndex = "0", onSelect, defaultOpenSubMenus = [] } = props;
27
+ const [currentActive, setActive] = useState(defaultIndex);
28
+ const handleClick = (index, e) => {
29
+ setActive(index);
30
+ if (onSelect) {
31
+ onSelect(index, e);
32
+ }
33
+ };
34
+ const passedContext = {
35
+ index: currentActive,
36
+ onSelect: handleClick,
37
+ mode,
38
+ defaultOpenSubMenus
39
+ };
40
+ const renderChildren = () => {
41
+ return Children.map(children, (child, index) => {
42
+ var _a;
43
+ const childElement = child;
44
+ if (typeof child !== "object" || child === null) {
45
+ console.error("Warning: Menu has a child which is not a MenuItem component");
46
+ return null;
47
+ }
48
+ const displayName = (_a = childElement.type) == null ? void 0 : _a.displayName;
49
+ if (displayName === "MenuItem" || displayName === "SubMenu") {
50
+ return React.cloneElement(childElement, {
51
+ index: index.toString()
52
+ });
53
+ } else {
54
+ console.error("Warning: Menu has a child which is not a MenuItem component");
55
+ }
56
+ });
57
+ };
58
+ const classes = classNames2("viking-menu", className, {
59
+ "menu-vertical": mode === "vertical",
60
+ "menu-horizontal": mode !== "vertical"
61
+ });
62
+ return /* @__PURE__ */ jsx2("ul", { className: classes, style, role: "menubar", children: /* @__PURE__ */ jsx2(MenuContext.Provider, { value: passedContext, children: renderChildren() }) });
63
+ };
64
+ var menu_default = Menu;
65
+
66
+ // src/components/Menu/subMenu.tsx
67
+ import React2, { useContext, useState as useState2, useRef } from "react";
68
+ import classNames4 from "classnames";
69
+
70
+ // src/components/Icon/icon.tsx
71
+ import classNames3 from "classnames";
72
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
73
+ import { jsx as jsx3 } from "react/jsx-runtime";
74
+ var Icon = (props) => {
75
+ const { className, theme, ...restProps } = props;
76
+ const classes = classNames3("viking-icon", className, {
77
+ [`icon-${theme}`]: theme
78
+ });
79
+ return /* @__PURE__ */ jsx3(FontAwesomeIcon, { className: classes, ...restProps });
80
+ };
81
+ var icon_default = Icon;
82
+
83
+ // src/components/Transition/transition.tsx
84
+ import { CSSTransition } from "react-transition-group";
85
+ import { jsx as jsx4 } from "react/jsx-runtime";
86
+ var Transition = (props) => {
87
+ const {
88
+ children,
89
+ classNames: classNames9,
90
+ animation,
91
+ wrapper,
92
+ unmountOnExit = true,
93
+ //该属性可以根据in属性的true和false实现子节点的挂载与卸载,从而无需自行添加display:none与block的转换
94
+ appear = true,
95
+ ...restProps
96
+ } = props;
97
+ return /* @__PURE__ */ jsx4(
98
+ CSSTransition,
99
+ {
100
+ classNames: classNames9 ? classNames9 : animation,
101
+ unmountOnExit,
102
+ appear,
103
+ ...restProps,
104
+ children: wrapper ? /* @__PURE__ */ jsx4("div", { children }) : children
105
+ }
106
+ );
107
+ };
108
+ var transition_default = Transition;
109
+
110
+ // src/components/Menu/subMenu.tsx
111
+ import { jsx as jsx5, jsxs } from "react/jsx-runtime";
112
+ var SubMenu = ({ index, title, children, className }) => {
113
+ const context = useContext(MenuContext);
114
+ const openedSubMenus = context.defaultOpenSubMenus;
115
+ const isOpend = index && context.mode === "vertical" ? openedSubMenus.includes(index) : false;
116
+ const [menuOpen, setOpen] = useState2(isOpend);
117
+ const classes = classNames4("menu-item submenu-item", className, {
118
+ "is-active": context.index === index,
119
+ "is-opened": menuOpen,
120
+ "is-vertical": context.mode === "vertical"
121
+ });
122
+ const handleClick = (e) => {
123
+ e.preventDefault();
124
+ setOpen(!menuOpen);
125
+ };
126
+ const timer = useRef();
127
+ const handleMouse = (e, toggle) => {
128
+ clearTimeout(timer.current);
129
+ e.preventDefault();
130
+ timer.current = setTimeout(() => {
131
+ setOpen(toggle);
132
+ }, 300);
133
+ };
134
+ const clickEvents = context.mode === "vertical" ? {
135
+ onClick: handleClick
136
+ } : {};
137
+ const hoverEvents = context.mode !== "vertical" ? {
138
+ onMouseEnter: (e) => {
139
+ handleMouse(e, true);
140
+ },
141
+ onMouseLeave: (e) => {
142
+ handleMouse(e, false);
143
+ }
144
+ } : {};
145
+ const renderChildren = () => {
146
+ const childrenComponent = React2.Children.map(children, (child, i) => {
147
+ const childElement = child;
148
+ if (childElement.type.displayName === "MenuItem" || childElement.type.displayName === "SubMenu") {
149
+ return React2.cloneElement(childElement, {
150
+ index: `${index}-${i}`
151
+ });
152
+ } else {
153
+ console.error("Warning: SubMenu has a child which is not a MenuItem component");
154
+ }
155
+ });
156
+ return /* @__PURE__ */ jsx5(
157
+ transition_default,
158
+ {
159
+ in: menuOpen,
160
+ timeout: 300,
161
+ animation: "zoom-in-top",
162
+ children: /* @__PURE__ */ jsx5("ul", { className: "viking-submenu", children: childrenComponent })
163
+ }
164
+ );
165
+ };
166
+ return /* @__PURE__ */ jsxs("li", { className: classes, ...hoverEvents, children: [
167
+ /* @__PURE__ */ jsxs("div", { className: "submenu-title", ...clickEvents, children: [
168
+ title,
169
+ /* @__PURE__ */ jsx5(icon_default, { icon: "angle-down", className: "arrow-icon" })
170
+ ] }),
171
+ renderChildren()
172
+ ] }, index);
173
+ };
174
+ SubMenu.displayName = "SubMenu";
175
+ var subMenu_default = SubMenu;
176
+
177
+ // src/components/Menu/menuItem.tsx
178
+ import { useContext as useContext2 } from "react";
179
+ import classNames5 from "classnames";
180
+ import { jsx as jsx6 } from "react/jsx-runtime";
181
+ var MenuItem = (props) => {
182
+ const { index, disabled, className, style, children } = props;
183
+ const context = useContext2(MenuContext);
184
+ const classes = classNames5("menu-item", className, {
185
+ "is-disabled": disabled,
186
+ "is-active": context.index === index
187
+ });
188
+ const handleClick = (e) => {
189
+ if (context.onSelect && !disabled && index) {
190
+ context.onSelect(index, e);
191
+ }
192
+ };
193
+ const handleKeyDown = (e) => {
194
+ if (e.key === "Enter" || e.key === " ") {
195
+ e.preventDefault();
196
+ if (context.onSelect && !disabled && index) {
197
+ context.onSelect(index, e);
198
+ }
199
+ }
200
+ };
201
+ return /* @__PURE__ */ jsx6(
202
+ "li",
203
+ {
204
+ className: classes,
205
+ style,
206
+ onClick: handleClick,
207
+ onKeyDown: handleKeyDown,
208
+ role: "menuitem",
209
+ tabIndex: disabled ? -1 : 0,
210
+ "aria-disabled": disabled,
211
+ children
212
+ }
213
+ );
214
+ };
215
+ MenuItem.displayName = "MenuItem";
216
+ var menuItem_default = MenuItem;
217
+
218
+ // src/components/Menu/index.tsx
219
+ var TransMenu = menu_default;
220
+ TransMenu.Item = menuItem_default;
221
+ TransMenu.SubMenu = subMenu_default;
222
+ var Menu_default = TransMenu;
223
+
224
+ // src/components/AutoComplete/autoComplete.tsx
225
+ import { useState as useState4, useEffect as useEffect3, useRef as useRef2 } from "react";
226
+
227
+ // src/components/Input/input.tsx
228
+ import { forwardRef } from "react";
229
+ import classNames6 from "classnames";
230
+ import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
231
+ var Input = forwardRef((props, ref) => {
232
+ const {
233
+ disabled,
234
+ size,
235
+ icon,
236
+ prepend,
237
+ append,
238
+ style,
239
+ ...restProps
240
+ } = props;
241
+ const cnames = classNames6("viking-input-wrapper", {
242
+ [`input-size-${size}`]: size,
243
+ "is-disabled": disabled,
244
+ "input-group": prepend || append,
245
+ "input-group-append": !!append,
246
+ "input-group-prepend": !!prepend
247
+ });
248
+ const fixControlledValue = (value) => {
249
+ if (typeof value === "undefined" || value === null) {
250
+ return "";
251
+ }
252
+ return value;
253
+ };
254
+ if ("value" in props) {
255
+ delete restProps.defaultValue;
256
+ restProps.value = fixControlledValue(props.value);
257
+ }
258
+ return /* @__PURE__ */ jsxs2("div", { className: cnames, style, children: [
259
+ prepend && /* @__PURE__ */ jsx7("div", { className: "viking-input-group-prepend", children: prepend }),
260
+ icon && /* @__PURE__ */ jsx7("div", { className: "icon-wrapper", children: /* @__PURE__ */ jsx7(icon_default, { icon, title: `title-${icon}` }) }),
261
+ /* @__PURE__ */ jsx7(
262
+ "input",
263
+ {
264
+ ref,
265
+ className: "viking-input-inner",
266
+ disabled,
267
+ ...restProps
268
+ }
269
+ ),
270
+ append && /* @__PURE__ */ jsx7("div", { className: "viking-input-group-append", children: append })
271
+ ] });
272
+ });
273
+ var input_default = Input;
274
+
275
+ // src/hooks/useDebounce.tsx
276
+ import { useState as useState3, useEffect } from "react";
277
+ function useDebounce(value, delay = 300) {
278
+ const [debouncedValue, setDebouncedValue] = useState3(value);
279
+ useEffect(() => {
280
+ const handler = setTimeout(() => {
281
+ setDebouncedValue(value);
282
+ }, delay);
283
+ return () => {
284
+ clearTimeout(handler);
285
+ };
286
+ }, [value, delay]);
287
+ return debouncedValue;
288
+ }
289
+ var useDebounce_default = useDebounce;
290
+
291
+ // src/components/AutoComplete/autoComplete.tsx
292
+ import classNames7 from "classnames";
293
+
294
+ // src/hooks/useClickOutside.tsx
295
+ import { useEffect as useEffect2 } from "react";
296
+ function useClickOutside(ref, handler) {
297
+ useEffect2(() => {
298
+ const listener = (event) => {
299
+ if (!ref.current || ref.current.contains(event.target)) {
300
+ return;
301
+ }
302
+ handler(event);
303
+ };
304
+ document.addEventListener("click", listener);
305
+ return () => {
306
+ document.removeEventListener("click", listener);
307
+ };
308
+ }, [ref, handler]);
309
+ }
310
+ var useClickOutside_default = useClickOutside;
311
+
312
+ // src/components/AutoComplete/autoComplete.tsx
313
+ import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
314
+ var AutoComplete = (props) => {
315
+ const { value, fetchSuggestions, onSelect, onChange, onEnterDown, onError, renderOption, style, debounceTime = 300, expireTime = 36e5, ...restprops } = props;
316
+ const [inputValue, setInputValue] = useState4(value || "");
317
+ const [suggestions, setSuggestions] = useState4([]);
318
+ const [loading, setloading] = useState4(false);
319
+ const [highlightIndex, sethighlightIndex] = useState4(-1);
320
+ const [isFocus, setisFocus] = useState4(true);
321
+ const componentRef = useRef2(null);
322
+ const triggerSearch = useRef2(false);
323
+ const fetchId = useRef2(0);
324
+ const intialInputvalue = useRef2(value || "");
325
+ const debouncedValue = useDebounce_default(inputValue, debounceTime);
326
+ useClickOutside_default(componentRef, () => {
327
+ setisFocus(false);
328
+ });
329
+ useEffect3(() => {
330
+ function getData() {
331
+ async function fetchData() {
332
+ fetchId.current++;
333
+ if (debouncedValue) {
334
+ const Id = fetchId.current;
335
+ setloading(true);
336
+ setSuggestions([]);
337
+ try {
338
+ const results = await fetchSuggestions(debouncedValue);
339
+ if (Id === fetchId.current && results) {
340
+ setloading(false);
341
+ setSuggestions(results);
342
+ const item = {
343
+ value: results,
344
+ // 实际数据
345
+ expiry: Date.now() + expireTime
346
+ // 当前时间加上1小时的过期时间 (单位毫秒)
347
+ };
348
+ localStorage.setItem(debouncedValue, JSON.stringify(item));
349
+ }
350
+ } catch (e) {
351
+ onError == null ? void 0 : onError(e);
352
+ setloading(false);
353
+ setSuggestions([]);
354
+ }
355
+ } else {
356
+ setloading(false);
357
+ setSuggestions([]);
358
+ }
359
+ }
360
+ if (triggerSearch.current) {
361
+ if (localStorage.getItem(debouncedValue)) {
362
+ const item = JSON.parse(localStorage.getItem(debouncedValue));
363
+ if (item.expiry > (/* @__PURE__ */ new Date()).getTime()) {
364
+ fetchId.current++;
365
+ setloading(false);
366
+ setSuggestions(item.value);
367
+ } else {
368
+ localStorage.removeItem(debouncedValue);
369
+ fetchData();
370
+ }
371
+ } else {
372
+ fetchData();
373
+ }
374
+ sethighlightIndex(-1);
375
+ }
376
+ }
377
+ getData();
378
+ }, [debouncedValue, fetchSuggestions, expireTime, onError]);
379
+ const handleChange = (e) => {
380
+ const value2 = e.target.value.trim();
381
+ setInputValue(value2);
382
+ onChange == null ? void 0 : onChange(value2);
383
+ intialInputvalue.current = value2;
384
+ triggerSearch.current = true;
385
+ };
386
+ const handleSelect = (item) => {
387
+ setInputValue(item.value);
388
+ intialInputvalue.current = item.value;
389
+ setSuggestions([]);
390
+ onSelect == null ? void 0 : onSelect(item);
391
+ triggerSearch.current = false;
392
+ };
393
+ const handleUpDown = (item) => {
394
+ setInputValue(item.value);
395
+ triggerSearch.current = false;
396
+ };
397
+ const handleArrowDown = () => {
398
+ if (highlightIndex + 1 > suggestions.length - 1) {
399
+ sethighlightIndex(-1);
400
+ setInputValue(intialInputvalue.current);
401
+ triggerSearch.current = false;
402
+ } else {
403
+ sethighlightIndex(highlightIndex + 1);
404
+ if (suggestions[highlightIndex + 1]) handleUpDown(suggestions[highlightIndex + 1]);
405
+ }
406
+ };
407
+ const handleArrowUp = () => {
408
+ if (highlightIndex - 1 === -1) {
409
+ sethighlightIndex(highlightIndex - 1);
410
+ setInputValue(intialInputvalue.current);
411
+ triggerSearch.current = false;
412
+ } else if (highlightIndex - 1 < -1) {
413
+ sethighlightIndex(suggestions.length - 1);
414
+ if (suggestions[suggestions.length - 1]) handleUpDown(suggestions[suggestions.length - 1]);
415
+ } else {
416
+ sethighlightIndex(highlightIndex - 1);
417
+ handleUpDown(suggestions[highlightIndex - 1]);
418
+ }
419
+ };
420
+ const handleKeyDown = (e) => {
421
+ switch (e.key) {
422
+ case "Enter":
423
+ if (suggestions[highlightIndex]) {
424
+ handleSelect(suggestions[highlightIndex]);
425
+ onEnterDown == null ? void 0 : onEnterDown(suggestions[highlightIndex]);
426
+ } else {
427
+ onEnterDown == null ? void 0 : onEnterDown({ value: intialInputvalue.current });
428
+ }
429
+ break;
430
+ case "ArrowDown":
431
+ handleArrowDown();
432
+ break;
433
+ case "ArrowUp":
434
+ handleArrowUp();
435
+ break;
436
+ case "Escape":
437
+ setisFocus(false);
438
+ break;
439
+ default:
440
+ break;
441
+ }
442
+ };
443
+ const handleClick = (e) => {
444
+ setisFocus(true);
445
+ };
446
+ const generateDropdown = () => {
447
+ return /* @__PURE__ */ jsx8("ul", { className: "viking-suggestion-list", role: "listbox", id: "suggestion-listbox", children: suggestions.map(
448
+ (item, index) => {
449
+ const cnames = classNames7("suggestion-item", {
450
+ "item-highlighted": index === highlightIndex
451
+ });
452
+ return /* @__PURE__ */ jsx8(
453
+ "li",
454
+ {
455
+ onClick: () => handleSelect(item),
456
+ className: cnames,
457
+ role: "option",
458
+ id: `suggestion-item-${index}`,
459
+ "aria-selected": index === highlightIndex,
460
+ children: renderOption ? renderOption(item) : item.value
461
+ },
462
+ index
463
+ );
464
+ }
465
+ ) });
466
+ };
467
+ const showSuggestions = isFocus && suggestions.length > 0;
468
+ return /* @__PURE__ */ jsxs3("div", { className: "viking-auto-complete", style, ref: componentRef, children: [
469
+ /* @__PURE__ */ jsx8(
470
+ input_default,
471
+ {
472
+ value: inputValue,
473
+ onChange: handleChange,
474
+ ...restprops,
475
+ onKeyDown: handleKeyDown,
476
+ onClick: handleClick,
477
+ "aria-expanded": showSuggestions,
478
+ "aria-autocomplete": "list",
479
+ "aria-controls": showSuggestions ? "suggestion-listbox" : void 0,
480
+ "aria-activedescendant": highlightIndex >= 0 ? `suggestion-item-${highlightIndex}` : void 0,
481
+ role: "combobox"
482
+ }
483
+ ),
484
+ isFocus && loading && /* @__PURE__ */ jsxs3("ul", { children: [
485
+ /* @__PURE__ */ jsx8(icon_default, { icon: "spinner", spin: true }),
486
+ "loading..."
487
+ ] }),
488
+ showSuggestions && generateDropdown()
489
+ ] });
490
+ };
491
+ var autoComplete_default = AutoComplete;
492
+
493
+ // src/components/Upload/upload.tsx
494
+ import { useRef as useRef4, useState as useState6 } from "react";
495
+ import axios from "axios";
496
+
497
+ // src/components/Progress/progress.tsx
498
+ import { jsx as jsx9 } from "react/jsx-runtime";
499
+ var Progress = (props) => {
500
+ const {
501
+ percent,
502
+ strokeHeight = 15,
503
+ showText = true,
504
+ style,
505
+ theme = "primary"
506
+ } = props;
507
+ return /* @__PURE__ */ jsx9("div", { className: "viking-progress-bar", style, children: /* @__PURE__ */ jsx9("div", { className: "viking-progress-bar-outer", style: { height: `${strokeHeight}px` }, children: /* @__PURE__ */ jsx9(
508
+ "div",
509
+ {
510
+ className: `viking-progress-bar-inner color-${theme}`,
511
+ style: { width: `${percent}%` },
512
+ children: showText && /* @__PURE__ */ jsx9("span", { className: "inner-text", children: `${percent}%` })
513
+ }
514
+ ) }) });
515
+ };
516
+ var progress_default = Progress;
517
+
518
+ // src/components/Upload/uploadList.tsx
519
+ import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
520
+ var UploadList = (props) => {
521
+ const {
522
+ fileList,
523
+ onRemove,
524
+ style
525
+ } = props;
526
+ return /* @__PURE__ */ jsx10("ul", { className: "viking-upload-list", style, children: fileList.map((item) => {
527
+ return /* @__PURE__ */ jsxs4("li", { className: "viking-upload-list-item", children: [
528
+ /* @__PURE__ */ jsxs4("span", { className: `file-name file-name-${item.status}`, children: [
529
+ /* @__PURE__ */ jsx10(icon_default, { icon: "file-alt", theme: "secondary" }),
530
+ item.name
531
+ ] }),
532
+ /* @__PURE__ */ jsxs4("span", { className: "file-status", children: [
533
+ (item.status === "uploading" || item.status === "ready") && /* @__PURE__ */ jsx10(icon_default, { icon: "spinner", spin: true, theme: "primary" }),
534
+ item.status === "success" && /* @__PURE__ */ jsx10(icon_default, { icon: "check-circle", theme: "success" }),
535
+ item.status === "error" && /* @__PURE__ */ jsx10(icon_default, { icon: "times-circle", theme: "danger" })
536
+ ] }),
537
+ /* @__PURE__ */ jsx10("span", { className: "file-actions", children: /* @__PURE__ */ jsx10(icon_default, { icon: "times", onClick: () => {
538
+ onRemove(item);
539
+ } }) }),
540
+ item.status === "uploading" && /* @__PURE__ */ jsx10(
541
+ progress_default,
542
+ {
543
+ percent: item.percent || 0
544
+ }
545
+ )
546
+ ] }, item.uid);
547
+ }) });
548
+ };
549
+ var uploadList_default = UploadList;
550
+
551
+ // src/components/Upload/dragger.tsx
552
+ import { useState as useState5, useRef as useRef3 } from "react";
553
+ import classNames8 from "classnames";
554
+ import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
555
+ var Dragger = (props) => {
556
+ const { onFile, children, style } = props;
557
+ const [dragOver, setDragOver] = useState5(false);
558
+ const fileInput = useRef3(null);
559
+ const klass = classNames8("viking-uploader-dragger", {
560
+ "is-dragover": dragOver
561
+ });
562
+ const handleDrop = (e) => {
563
+ e.preventDefault();
564
+ setDragOver(false);
565
+ onFile(e.dataTransfer.files);
566
+ };
567
+ const handleDrag = (e, over) => {
568
+ e.preventDefault();
569
+ setDragOver(over);
570
+ };
571
+ const handleKeyDown = (e) => {
572
+ var _a;
573
+ if (e.key === "Enter" || e.key === " ") {
574
+ e.preventDefault();
575
+ (_a = fileInput.current) == null ? void 0 : _a.click();
576
+ }
577
+ };
578
+ return /* @__PURE__ */ jsxs5(
579
+ "div",
580
+ {
581
+ className: klass,
582
+ onDragOver: (e) => {
583
+ handleDrag(e, true);
584
+ },
585
+ onDragLeave: (e) => {
586
+ handleDrag(e, false);
587
+ },
588
+ onDrop: handleDrop,
589
+ style,
590
+ role: "button",
591
+ tabIndex: 0,
592
+ onKeyDown: handleKeyDown,
593
+ "aria-label": "\u62D6\u62FD\u4E0A\u4F20\u533A\u57DF",
594
+ children: [
595
+ /* @__PURE__ */ jsx11(
596
+ "input",
597
+ {
598
+ type: "file",
599
+ ref: fileInput,
600
+ style: { display: "none" },
601
+ onChange: (e) => {
602
+ if (e.target.files) {
603
+ onFile(e.target.files);
604
+ e.target.value = "";
605
+ }
606
+ }
607
+ }
608
+ ),
609
+ children
610
+ ]
611
+ }
612
+ );
613
+ };
614
+ var dragger_default = Dragger;
615
+
616
+ // src/components/Upload/upload.tsx
617
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
618
+ var Upload = (props) => {
619
+ const {
620
+ action,
621
+ beforeUpload,
622
+ onprogress,
623
+ onSuccess,
624
+ onError,
625
+ onChange,
626
+ onRemove,
627
+ onExceed,
628
+ name = "file",
629
+ headers,
630
+ data,
631
+ withCredentials,
632
+ accept,
633
+ multiple,
634
+ children,
635
+ drag,
636
+ maxsize,
637
+ maxnum,
638
+ styleButton,
639
+ styleDrag,
640
+ styleUploadList,
641
+ failednums = 0,
642
+ limit = Infinity
643
+ } = props;
644
+ const fileInput = useRef4(null);
645
+ const abortRecord = useRef4({});
646
+ const FileRecord = useRef4(/* @__PURE__ */ new Set());
647
+ const [fileList, setFileList] = useState6([]);
648
+ const handleClick = () => {
649
+ var _a;
650
+ (_a = fileInput.current) == null ? void 0 : _a.click();
651
+ };
652
+ const uploadFiles = (files) => {
653
+ if (maxnum && files.length > maxnum) {
654
+ onExceed == null ? void 0 : onExceed(`\u6587\u4EF6\u6570\u91CF\u4E0D\u80FD\u8D85\u8FC7${maxnum}`);
655
+ return;
656
+ }
657
+ let concurrency = 0;
658
+ const queue = [];
659
+ function AskTask(task) {
660
+ return new Promise(() => {
661
+ const executeRequest = () => {
662
+ concurrency++;
663
+ task[0]().then(() => {
664
+ concurrency--;
665
+ nextTask();
666
+ });
667
+ };
668
+ if (concurrency < limit) {
669
+ executeRequest();
670
+ } else {
671
+ queue.push([executeRequest, task[1]]);
672
+ }
673
+ });
674
+ }
675
+ function nextTask() {
676
+ if (concurrency < limit && queue.length > 0) {
677
+ while (queue.length > 0) {
678
+ const [task, fileName] = queue.shift();
679
+ if (FileRecord.current.has(fileName)) {
680
+ task();
681
+ break;
682
+ }
683
+ }
684
+ }
685
+ }
686
+ let uidCounter = 0;
687
+ function dealFile(file) {
688
+ let _file = {
689
+ uid: `upload-file-${Date.now()}-${uidCounter++}`,
690
+ size: file.size,
691
+ name: file.name,
692
+ percent: 0,
693
+ status: "ready",
694
+ raw: file
695
+ };
696
+ setFileList((prevList) => {
697
+ let isSame = false;
698
+ for (let i = 0; i < prevList.length; i++) {
699
+ if (prevList[i].name === _file.name) {
700
+ prevList[i] = _file;
701
+ isSame = true;
702
+ }
703
+ }
704
+ if (isSame) return prevList;
705
+ return [_file, ...prevList];
706
+ });
707
+ const formData = new FormData();
708
+ formData.append(name || "file", file);
709
+ data && Object.keys(data).forEach((key) => formData.append(key, data[key]));
710
+ const controller = new AbortController();
711
+ abortRecord.current = { ...abortRecord.current, [_file.uid]: controller };
712
+ return [_file, formData, controller];
713
+ }
714
+ const post = (_file, formData, controller, try_nums) => {
715
+ return new Promise((resolve) => {
716
+ axios.post(action, formData, {
717
+ headers: {
718
+ ...headers,
719
+ "Content-Type": "multipart/form-data"
720
+ },
721
+ withCredentials,
722
+ signal: controller.signal,
723
+ onUploadProgress: (e) => {
724
+ let percentage = Math.floor(e.loaded * 100 / e.total || 0);
725
+ if (percentage < 100) {
726
+ updateFileList(_file, {
727
+ percent: percentage,
728
+ status: "uploading"
729
+ });
730
+ _file.status = "uploading";
731
+ _file.percent = percentage;
732
+ onprogress == null ? void 0 : onprogress(percentage, _file);
733
+ }
734
+ }
735
+ }).then((res) => {
736
+ updateFileList(_file, { status: "success", response: res.data });
737
+ _file.status = "success";
738
+ _file.response = res.data;
739
+ onSuccess == null ? void 0 : onSuccess(res.data, _file);
740
+ onChange == null ? void 0 : onChange(_file);
741
+ resolve("success");
742
+ }).catch((err) => {
743
+ if (axios.isCancel(err)) {
744
+ resolve("cancel");
745
+ } else {
746
+ if (try_nums < failednums) {
747
+ const [_file_new, formData2, controller2] = dealFile(_file.raw);
748
+ AskTask([
749
+ () => post(_file_new, formData2, controller2, try_nums + 1),
750
+ _file.name
751
+ ]);
752
+ }
753
+ updateFileList(_file, { status: "error", error: err });
754
+ _file.status = "error";
755
+ _file.error = err;
756
+ onError == null ? void 0 : onError(err, _file);
757
+ onChange == null ? void 0 : onChange(_file);
758
+ resolve("failed");
759
+ }
760
+ });
761
+ });
762
+ };
763
+ let postFiles = Array.from(files);
764
+ postFiles.forEach((file) => {
765
+ if (maxsize && file.size > maxsize * 1024 * 1024) {
766
+ onExceed == null ? void 0 : onExceed(`\u6587\u4EF6\u5927\u5C0F\u4E0D\u80FD\u8D85\u8FC7${maxsize}Mb`);
767
+ return;
768
+ }
769
+ FileRecord.current.add(file.name);
770
+ if (!beforeUpload) {
771
+ const [_file, formData, source] = dealFile(file);
772
+ AskTask([() => post(_file, formData, source, 0), file.name]);
773
+ } else {
774
+ const result = beforeUpload(file);
775
+ if (result && result instanceof Promise) {
776
+ result.then((processedFile) => {
777
+ const [_file, formData, source] = dealFile(file);
778
+ AskTask([() => post(_file, formData, source, 0), file.name]);
779
+ });
780
+ } else if (result) {
781
+ const [_file, formData, source] = dealFile(file);
782
+ AskTask([() => post(_file, formData, source, 0), file.name]);
783
+ }
784
+ }
785
+ });
786
+ };
787
+ const updateFileList = (updateFile, uploadobj) => {
788
+ setFileList((prevList) => {
789
+ return prevList.map(
790
+ (file) => file.uid === updateFile.uid ? { ...file, ...uploadobj } : file
791
+ );
792
+ });
793
+ };
794
+ const handleFileChange = (e) => {
795
+ const files = e.target.files;
796
+ if (files) {
797
+ uploadFiles(files);
798
+ if (fileInput.current) {
799
+ fileInput.current.value = "";
800
+ }
801
+ }
802
+ };
803
+ const handleRemove = (file) => {
804
+ var _a;
805
+ setFileList((prevList) => {
806
+ return prevList.filter((item) => item.uid !== file.uid);
807
+ });
808
+ (_a = abortRecord.current[file.uid]) == null ? void 0 : _a.abort();
809
+ delete abortRecord.current[file.uid];
810
+ FileRecord.current.delete(file.name);
811
+ onRemove == null ? void 0 : onRemove(file);
812
+ };
813
+ return /* @__PURE__ */ jsxs6("div", { className: "viking-upload-component", children: [
814
+ drag ? /* @__PURE__ */ jsx12(
815
+ dragger_default,
816
+ {
817
+ style: styleDrag,
818
+ onFile: (files) => {
819
+ uploadFiles(files);
820
+ },
821
+ children
822
+ }
823
+ ) : /* @__PURE__ */ jsx12(button_default, { btnType: "default", onClick: handleClick, style: styleButton, children }),
824
+ /* @__PURE__ */ jsx12(
825
+ "input",
826
+ {
827
+ type: "file",
828
+ className: "viking-file-input",
829
+ style: { display: "none" },
830
+ ref: fileInput,
831
+ onChange: handleFileChange,
832
+ accept,
833
+ multiple
834
+ }
835
+ ),
836
+ /* @__PURE__ */ jsx12(
837
+ uploadList_default,
838
+ {
839
+ style: styleUploadList,
840
+ fileList,
841
+ onRemove: handleRemove
842
+ }
843
+ )
844
+ ] });
845
+ };
846
+ var upload_default = Upload;
847
+
848
+ // src/components/Signature/signature.tsx
849
+ import { useState as useState7, useRef as useRef5, useEffect as useEffect4 } from "react";
850
+ import { Fragment, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
851
+ var Signature = ({
852
+ width = 400,
853
+ height = 200,
854
+ style,
855
+ onSave
856
+ }) => {
857
+ const [isDrawing, setIsDrawing] = useState7(false);
858
+ const [strokeStyle, setStrokeStyle] = useState7("pen");
859
+ const [points, setPoints] = useState7({
860
+ x: 0,
861
+ y: 0
862
+ });
863
+ const canvas = useRef5(null);
864
+ const ctx = useRef5();
865
+ useEffect4(() => {
866
+ var _a;
867
+ ctx.current = (_a = canvas.current) == null ? void 0 : _a.getContext("2d");
868
+ }, []);
869
+ useEffect4(() => {
870
+ if (!ctx.current) return;
871
+ if (strokeStyle === "pen") {
872
+ ctx.current.lineWidth = 2;
873
+ ctx.current.lineCap = "round";
874
+ } else if (strokeStyle === "brush") {
875
+ ctx.current.lineWidth = 5;
876
+ ctx.current.lineCap = "round";
877
+ }
878
+ }, [strokeStyle]);
879
+ const startDrawing = (e) => {
880
+ var _a, _b;
881
+ setIsDrawing(true);
882
+ (_a = ctx.current) == null ? void 0 : _a.beginPath();
883
+ const { offsetX, offsetY } = getEventPosition(e);
884
+ setPoints({ x: offsetX, y: offsetY });
885
+ (_b = ctx.current) == null ? void 0 : _b.moveTo(offsetX, offsetY);
886
+ };
887
+ const draw = (e) => {
888
+ var _a, _b;
889
+ if (!isDrawing) return;
890
+ const { offsetX, offsetY } = getEventPosition(e);
891
+ (_a = ctx.current) == null ? void 0 : _a.quadraticCurveTo(
892
+ points["x"],
893
+ points["y"],
894
+ (points["x"] + offsetX) / 2,
895
+ (points["y"] + offsetY) / 2
896
+ );
897
+ (_b = ctx.current) == null ? void 0 : _b.stroke();
898
+ setPoints({ x: offsetX, y: offsetY });
899
+ };
900
+ const stopDrawing = (e) => {
901
+ setIsDrawing(false);
902
+ };
903
+ const getEventPosition = (e) => {
904
+ var _a, _b;
905
+ const offsetX = (_a = e.nativeEvent.offsetX) != null ? _a : e.touches[0].clientX - canvas.current.offsetLeft;
906
+ const offsetY = (_b = e.nativeEvent.offsetY) != null ? _b : e.touches[0].clientY - canvas.current.offsetTop;
907
+ return { offsetX, offsetY };
908
+ };
909
+ const handleStrokeStyle = (e) => {
910
+ setStrokeStyle(e.target.value);
911
+ };
912
+ const handleSave = () => {
913
+ var _a;
914
+ const dataURL = (_a = canvas.current) == null ? void 0 : _a.toDataURL();
915
+ onSave == null ? void 0 : onSave(dataURL);
916
+ };
917
+ return /* @__PURE__ */ jsxs7(Fragment, { children: [
918
+ /* @__PURE__ */ jsx13(
919
+ "canvas",
920
+ {
921
+ ref: canvas,
922
+ onMouseDown: startDrawing,
923
+ onMouseUp: stopDrawing,
924
+ onMouseMove: draw,
925
+ onMouseOut: stopDrawing,
926
+ onTouchStart: startDrawing,
927
+ onTouchEnd: stopDrawing,
928
+ onTouchMove: draw,
929
+ onTouchCancel: stopDrawing,
930
+ style: { border: "1px solid black", ...style },
931
+ width,
932
+ height,
933
+ className: "viking-signature",
934
+ "aria-label": "\u7B7E\u540D\u753B\u5E03",
935
+ role: "img"
936
+ }
937
+ ),
938
+ /* @__PURE__ */ jsxs7("div", { className: "controls", style: { width }, children: [
939
+ /* @__PURE__ */ jsx13("label", { htmlFor: "stroke-style-select", children: "\u7B14\u89E6\u6837\u5F0F" }),
940
+ /* @__PURE__ */ jsxs7("select", { id: "stroke-style-select", onChange: handleStrokeStyle, children: [
941
+ /* @__PURE__ */ jsx13("option", { value: "pen", children: "\u94A2\u7B14" }),
942
+ /* @__PURE__ */ jsx13("option", { value: "brush", children: "\u6BDB\u7B14" })
943
+ ] }),
944
+ /* @__PURE__ */ jsx13(
945
+ "button",
946
+ {
947
+ type: "button",
948
+ onClick: () => ctx.current.clearRect(
949
+ 0,
950
+ 0,
951
+ canvas.current.width,
952
+ canvas.current.height
953
+ ),
954
+ children: "\u6E05\u7A7A"
955
+ }
956
+ ),
957
+ /* @__PURE__ */ jsx13("button", { type: "button", onClick: handleSave, children: "\u4FDD\u5B58" })
958
+ ] })
959
+ ] });
960
+ };
961
+ var signature_default = Signature;
962
+
963
+ // src/components/VirtualList/virtualList.tsx
964
+ import { useState as useState8, Children as Children2, cloneElement } from "react";
965
+ import { jsx as jsx14 } from "react/jsx-runtime";
966
+ var VirtualList = ({
967
+ containerHeight,
968
+ itemHeight,
969
+ itemCount,
970
+ children
971
+ }) => {
972
+ if (Children2.count(children) > 1) {
973
+ throw new Error("VirtualList only accept one child");
974
+ }
975
+ const contentHeight = itemHeight * itemCount;
976
+ const [scrollTop, setScrollTop] = useState8(0);
977
+ let startIdx = Math.floor(scrollTop / itemHeight);
978
+ let endIdx = Math.floor((scrollTop + containerHeight) / itemHeight);
979
+ const paddingCount = 2;
980
+ startIdx = Math.max(startIdx - paddingCount, 0);
981
+ endIdx = Math.min(endIdx + paddingCount, itemCount - 1);
982
+ const top = itemHeight * startIdx;
983
+ const items = [];
984
+ for (let i = startIdx; i <= endIdx; i++) {
985
+ items.push(
986
+ cloneElement(children, {
987
+ index: i,
988
+ style: { height: itemHeight }
989
+ })
990
+ );
991
+ }
992
+ return /* @__PURE__ */ jsx14(
993
+ "div",
994
+ {
995
+ style: { height: containerHeight, overflow: "auto" },
996
+ onScroll: (e) => {
997
+ setScrollTop(e.target.scrollTop);
998
+ },
999
+ children: /* @__PURE__ */ jsx14("div", { style: { height: contentHeight }, children: /* @__PURE__ */ jsx14("div", { style: { transform: `translate3d(0px, ${top}px, 0` }, children: items }) })
1000
+ }
1001
+ );
1002
+ };
1003
+ var virtualList_default = VirtualList;
1004
+
1005
+ // src/components/LazyLoad/lazyLoad.tsx
1006
+ import {
1007
+ useEffect as useEffect5,
1008
+ useRef as useRef6,
1009
+ useState as useState9
1010
+ } from "react";
1011
+ import { jsx as jsx15 } from "react/jsx-runtime";
1012
+ var Lazyload = (props) => {
1013
+ const {
1014
+ className = "",
1015
+ style,
1016
+ offset = 0,
1017
+ width,
1018
+ onContentVisible,
1019
+ placeholder,
1020
+ height,
1021
+ children
1022
+ } = props;
1023
+ const containerRef = useRef6(null);
1024
+ const [visible, setVisible] = useState9(false);
1025
+ const elementObserver = useRef6();
1026
+ useEffect5(() => {
1027
+ function lazyLoadHandler(entries) {
1028
+ var _a;
1029
+ const [entry] = entries;
1030
+ const { isIntersecting } = entry;
1031
+ if (isIntersecting) {
1032
+ setVisible(true);
1033
+ onContentVisible == null ? void 0 : onContentVisible();
1034
+ const node2 = containerRef.current;
1035
+ if (node2 && node2 instanceof HTMLElement) {
1036
+ (_a = elementObserver.current) == null ? void 0 : _a.unobserve(node2);
1037
+ }
1038
+ }
1039
+ }
1040
+ const options = {
1041
+ rootMargin: typeof offset === "number" ? `${offset}px` : offset || "0px",
1042
+ threshold: 0
1043
+ };
1044
+ elementObserver.current = new IntersectionObserver(
1045
+ lazyLoadHandler,
1046
+ options
1047
+ );
1048
+ const node = containerRef.current;
1049
+ if (node instanceof HTMLElement) {
1050
+ elementObserver.current.observe(node);
1051
+ }
1052
+ return () => {
1053
+ var _a;
1054
+ if (node && node instanceof HTMLElement) {
1055
+ (_a = elementObserver.current) == null ? void 0 : _a.unobserve(node);
1056
+ }
1057
+ };
1058
+ }, [offset, onContentVisible]);
1059
+ const styles = { height, width, ...style };
1060
+ return /* @__PURE__ */ jsx15("div", { ref: containerRef, className, style: styles, children: visible ? children : placeholder });
1061
+ };
1062
+ var lazyLoad_default = Lazyload;
1063
+
1064
+ // src/components/Keepalive/Keepalive.tsx
1065
+ import { createContext as createContext2, useContext as useContext3, useEffect as useEffect6, useRef as useRef7, useState as useState10 } from "react";
1066
+ import { useOutlet, useLocation, matchPath } from "react-router-dom";
1067
+ import { Fragment as Fragment2, jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
1068
+ var KeepAliveContext = createContext2({
1069
+ keepPaths: [],
1070
+ keepElements: {},
1071
+ dropByPath() {
1072
+ }
1073
+ });
1074
+ var isKeepPath = (keepPaths, path) => {
1075
+ for (let i = 0; i < keepPaths.length; i++) {
1076
+ let item = keepPaths[i];
1077
+ if (item === path) return true;
1078
+ if (item instanceof RegExp && item.test(path)) return true;
1079
+ if (typeof item === "string" && item.toLowerCase() === path) return true;
1080
+ }
1081
+ return false;
1082
+ };
1083
+ function useKeepOutlet() {
1084
+ const location = useLocation();
1085
+ const element = useOutlet();
1086
+ const { keepElements, keepPaths } = useContext3(KeepAliveContext);
1087
+ const isKeep = isKeepPath(keepPaths, location.pathname);
1088
+ const keepElementsRef = useRef7(keepElements);
1089
+ keepElementsRef.current = keepElements;
1090
+ useEffect6(() => {
1091
+ if (isKeep && element) {
1092
+ keepElementsRef.current[location.pathname] = element;
1093
+ }
1094
+ });
1095
+ return /* @__PURE__ */ jsxs8(Fragment2, { children: [
1096
+ Object.entries(keepElements).map(([pathname, el]) => /* @__PURE__ */ jsx16(
1097
+ "div",
1098
+ {
1099
+ style: {
1100
+ height: "100%",
1101
+ width: "100%",
1102
+ position: "relative",
1103
+ overflow: "hidden auto"
1104
+ },
1105
+ className: "keep-alive-page",
1106
+ hidden: !matchPath(location.pathname, pathname),
1107
+ children: el
1108
+ },
1109
+ pathname
1110
+ )),
1111
+ !isKeep && element
1112
+ ] });
1113
+ }
1114
+ var KeepAliveLayout = (props) => {
1115
+ const { keepPaths, children } = props;
1116
+ const [keepElements] = useState10({});
1117
+ const dropByPath = (path) => {
1118
+ delete keepElements[path];
1119
+ };
1120
+ return /* @__PURE__ */ jsx16(KeepAliveContext.Provider, { value: { keepPaths, keepElements, dropByPath }, children });
1121
+ };
1122
+ var Keepalive_default = KeepAliveLayout;
1123
+ export {
1124
+ autoComplete_default as AutoComplete,
1125
+ button_default as Button,
1126
+ icon_default as Icon,
1127
+ input_default as Input,
1128
+ KeepAliveContext,
1129
+ Keepalive_default as KeepAliveLayout,
1130
+ lazyLoad_default as LazyLoad,
1131
+ Menu_default as Menu,
1132
+ menuItem_default as MenuItem,
1133
+ progress_default as Progress,
1134
+ signature_default as Signature,
1135
+ subMenu_default as SubMenu,
1136
+ transition_default as Transition,
1137
+ upload_default as Upload,
1138
+ virtualList_default as VirtualList,
1139
+ useClickOutside_default as useClickOutside,
1140
+ useDebounce_default as useDebounce,
1141
+ useKeepOutlet
1142
+ };
1143
+ //# sourceMappingURL=index.mjs.map