best-unit 1.2.17 → 1.2.19

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 (49) hide show
  1. package/dist/best-unit.cjs +1 -1
  2. package/dist/best-unit.js +1 -1
  3. package/package.json +4 -1
  4. package/BEST_UNIT_USAGE.md +0 -402
  5. package/index.html +0 -13
  6. package/src/api/axiosInstance.ts +0 -111
  7. package/src/api/index.ts +0 -136
  8. package/src/api/proxy.ts +0 -11
  9. package/src/components/business/recharge-sdk/components/offline-transfer-form/index.tsx +0 -158
  10. package/src/components/business/recharge-sdk/components/offline-transfer-form/theme.tsx +0 -238
  11. package/src/components/business/recharge-sdk/components/online-recharge-form/index.tsx +0 -199
  12. package/src/components/business/recharge-sdk/components/online-recharge-form/theme.tsx +0 -151
  13. package/src/components/business/recharge-sdk/components/recharge/index.tsx +0 -152
  14. package/src/components/business/recharge-sdk/components/recharge/theme.tsx +0 -64
  15. package/src/components/business/recharge-sdk/index.tsx +0 -37
  16. package/src/components/business/refresh-button/index.tsx +0 -99
  17. package/src/components/business/refresh-button/theme.tsx +0 -58
  18. package/src/components/business/statistical-balance/index.tsx +0 -190
  19. package/src/components/business/statistical-balance/theme.tsx +0 -110
  20. package/src/components/common/button/index.tsx +0 -17
  21. package/src/components/common/button/theme.tsx +0 -48
  22. package/src/components/common/hover-popover/index.tsx +0 -179
  23. package/src/components/common/hover-popover/theme.tsx +0 -39
  24. package/src/components/common/message/index.tsx +0 -321
  25. package/src/components/common/message/theme.tsx +0 -25
  26. package/src/components/common/modal/index.tsx +0 -99
  27. package/src/components/common/modal/theme.tsx +0 -91
  28. package/src/components/common/select/index.tsx +0 -229
  29. package/src/components/common/select/theme.tsx +0 -104
  30. package/src/components/common/upload/index.tsx +0 -140
  31. package/src/components/common/upload/theme.tsx +0 -89
  32. package/src/demo/App.tsx +0 -685
  33. package/src/demo/index.tsx +0 -4
  34. package/src/demo/testBalanceData.tsx +0 -79
  35. package/src/demo/theme-config-example.tsx +0 -1
  36. package/src/local/en.ts +0 -63
  37. package/src/local/index.ts +0 -36
  38. package/src/local/zh.ts +0 -62
  39. package/src/main.ts +0 -26
  40. package/src/types/global.d.ts +0 -146
  41. package/src/types/index.ts +0 -31
  42. package/src/types/preact-custom-element.d.ts +0 -1
  43. package/src/utils/business/index.ts +0 -132
  44. package/src/utils/common/index.ts +0 -8
  45. package/src/vite-env.d.ts +0 -8
  46. package/tsconfig.app.json +0 -33
  47. package/tsconfig.json +0 -15
  48. package/tsconfig.node.json +0 -24
  49. package/vite.config.ts +0 -24
@@ -1,229 +0,0 @@
1
- import type { FunctionalComponent, JSX } from "preact";
2
- import { useState, useRef, useEffect } from "preact/hooks";
3
- import { t } from "@/local";
4
- import { getSelectTheme } from "./theme";
5
- import { getInitParams } from "@/utils/business";
6
- import { Size } from "@/types";
7
- const size = getInitParams<Size>("size");
8
- interface Option {
9
- value: string;
10
- label: string;
11
- disabled?: boolean;
12
- }
13
-
14
- interface SelectProps {
15
- value?: string;
16
- onChange?: (value: string) => void;
17
- options: Option[];
18
- placeholder?: string;
19
- style?: any;
20
- error?: boolean;
21
- disabled?: boolean;
22
- dropdownStyle?: any;
23
- className?: string;
24
- dropdownClassName?: string;
25
- children?: JSX.Element;
26
- }
27
-
28
- export const Select: FunctionalComponent<SelectProps> = ({
29
- value,
30
- onChange,
31
- options,
32
- placeholder,
33
- style,
34
- error,
35
- disabled,
36
- dropdownStyle,
37
- className,
38
- dropdownClassName,
39
- children,
40
- }) => {
41
- const [open, setOpen] = useState(false);
42
- const ref = useRef<HTMLDivElement>(null);
43
- const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);
44
- const theme = getSelectTheme();
45
-
46
- useEffect(() => {
47
- if (!open) return;
48
- const handleClick = (e: MouseEvent) => {
49
- if (ref.current && !ref.current.contains(e.target as Node)) {
50
- setOpen(false);
51
- }
52
- };
53
- document.addEventListener("mousedown", handleClick);
54
- return () => document.removeEventListener("mousedown", handleClick);
55
- }, [open]);
56
-
57
- const selected = options.find((opt) => opt.value === value);
58
-
59
- // 获取触发器样式
60
- const getTriggerStyle = () => {
61
- if (error) return theme.triggerError;
62
- if (disabled) return theme.triggerDisabled;
63
- return theme.trigger;
64
- };
65
-
66
- return (
67
- <div
68
- ref={ref}
69
- className={className}
70
- style={{ position: "relative", ...style }}
71
- >
72
- <style>{`
73
- .custom-select-dropdown {
74
- scrollbar-width: thin;
75
- scrollbar-color: ${theme.scrollbarThumb} ${theme.scrollbarTrack};
76
- }
77
- .custom-select-dropdown::-webkit-scrollbar {
78
- width: ${size === Size.SMALL ? 6 : 8}px;
79
- }
80
- .custom-select-dropdown::-webkit-scrollbar-thumb {
81
- border-radius: 4px;
82
- background: ${theme.scrollbarThumb};
83
- }
84
- .custom-select-dropdown::-webkit-scrollbar-track {
85
- background: ${theme.scrollbarTrack};
86
- }
87
- `}</style>
88
- <div
89
- onClick={() => !disabled && setOpen((o) => !o)}
90
- style={{
91
- minHeight: size === Size.SMALL ? 32 : 40,
92
- borderRadius: 6,
93
- display: "flex",
94
- alignItems: "center",
95
- padding: size === Size.SMALL ? "0 10px" : "0 12px",
96
- fontSize: size === Size.SMALL ? 12 : 15,
97
- cursor: disabled ? "not-allowed" : "pointer",
98
- boxSizing: "border-box",
99
- transition: "border 0.2s",
100
- opacity: disabled ? 0.6 : 1,
101
- width: "100%",
102
- ...getTriggerStyle(),
103
- ...style,
104
- }}
105
- tabIndex={0}
106
- >
107
- <span style={{ flex: 1 }}>
108
- {selected ? (
109
- selected.label
110
- ) : (
111
- <span style={theme.placeholder}>{placeholder || "请选择"}</span>
112
- )}
113
- </span>
114
- <span style={{ marginLeft: 8, display: "flex", alignItems: "center" }}>
115
- <svg
116
- width={size === Size.SMALL ? 16 : 20}
117
- height={size === Size.SMALL ? 16 : 20}
118
- viewBox="0 0 20 20"
119
- fill="none"
120
- xmlns="http://www.w3.org/2000/svg"
121
- >
122
- <path
123
- d="M6 8L10 12L14 8"
124
- stroke="#bfbfbf"
125
- stroke-width="1.5"
126
- stroke-linecap="round"
127
- stroke-linejoin="round"
128
- />
129
- </svg>
130
- </span>
131
- </div>
132
- {open && !disabled && (
133
- <div
134
- className={`custom-select-dropdown${
135
- dropdownClassName ? " " + dropdownClassName : ""
136
- }`}
137
- style={{
138
- position: "absolute",
139
- left: 0,
140
- right: 0,
141
- top: size === Size.SMALL ? 32 : 44,
142
- zIndex: 10,
143
- borderRadius: 6,
144
- boxShadow: theme.boxShadow,
145
- maxHeight: size === Size.SMALL ? 160 : 220,
146
- overflowY: "auto",
147
- ...theme.dropdown,
148
- ...dropdownStyle,
149
- }}
150
- >
151
- {options.length === 0 && (
152
- <div
153
- style={{
154
- display: "flex",
155
- flexDirection: "column",
156
- alignItems: "center",
157
- justifyContent: "center",
158
- minHeight: size === Size.SMALL ? 80 : 120,
159
- width: "100%",
160
- userSelect: "none",
161
- }}
162
- >
163
- <svg
164
- width={size === Size.SMALL ? 48 : 64}
165
- height={size === Size.SMALL ? 32 : 41}
166
- viewBox="0 0 64 41"
167
- xmlns="http://www.w3.org/2000/svg"
168
- >
169
- <title>{t("暂无数据")}</title>
170
- <g transform="translate(0 1)" fill="none" fillRule="evenodd">
171
- <ellipse
172
- fill="#f5f5f5"
173
- cx="32"
174
- cy="33"
175
- rx="32"
176
- ry="7"
177
- ></ellipse>
178
- <g fillRule="nonzero" stroke="#d9d9d9">
179
- <path d="M55 12.76L44.854 1.258C44.367.474 43.656 0 42.907 0H21.093c-.749 0-1.46.474-1.947 1.257L9 12.761V22h46v-9.24z"></path>
180
- <path
181
- d="M41.613 15.931c0-1.605.994-2.93 2.227-2.931H55v18.137C55 33.26 53.68 35 52.05 35h-40.1C10.32 35 9 33.259 9 31.137V13h11.16c1.233 0 2.227 1.323 2.227 2.928v.022c0 1.605 1.005 2.901 2.237 2.901h14.752c1.232 0 2.237-1.308 2.237-2.913v-.007z"
182
- fill="#fafafa"
183
- ></path>
184
- </g>
185
- </g>
186
- </svg>
187
- <div
188
- style={{
189
- marginTop: 8,
190
- color: "#bfbfbf",
191
- fontSize: size === Size.SMALL ? 12 : 15,
192
- }}
193
- >
194
- {t("暂无数据")}
195
- </div>
196
- </div>
197
- )}
198
- {options.map((opt, idx) => (
199
- <div
200
- key={opt.value}
201
- onClick={() => {
202
- if (opt.disabled) return;
203
- setOpen(false);
204
- onChange?.(opt.value);
205
- }}
206
- onMouseEnter={() => setHoveredIndex(idx)}
207
- onMouseLeave={() => setHoveredIndex(null)}
208
- style={{
209
- padding: size === Size.SMALL ? "6px 10px" : "10px 16px",
210
- fontSize: size === Size.SMALL ? 12 : 15,
211
- cursor: opt.disabled ? "not-allowed" : "pointer",
212
- fontWeight: value === opt.value ? 600 : 400,
213
- opacity: opt.disabled ? 0.6 : 1,
214
- ...theme.option(
215
- value === opt.value,
216
- !!opt.disabled,
217
- hoveredIndex === idx
218
- ),
219
- }}
220
- >
221
- {opt.label}
222
- </div>
223
- ))}
224
- </div>
225
- )}
226
- {children}
227
- </div>
228
- );
229
- };
@@ -1,104 +0,0 @@
1
- import { Theme, type ThemeConfig } from "@/types";
2
- import { getInitParams } from "@/utils/business";
3
-
4
- export const selectThemes = {
5
- white: {
6
- trigger: {
7
- background: "#fff",
8
- color: "#222",
9
- border: "1px solid #d9d9d9",
10
- },
11
- triggerDisabled: {
12
- background: "#f5f5f5",
13
- color: "#bfbfbf",
14
- border: "1px solid #f0f0f0",
15
- },
16
- triggerError: {
17
- background: "#fff",
18
- color: "#222",
19
- border: "1px solid #ff4d4f",
20
- },
21
- dropdown: {
22
- background: "#fff",
23
- border: "1px solid #d9d9d9",
24
- color: "#222",
25
- },
26
- option: (active: boolean, optDisabled: boolean, hovered: boolean) => ({
27
- color: optDisabled ? "#bfbfbf" : active ? "#1890ff" : "#222",
28
- background: active
29
- ? "#e6f7ff"
30
- : hovered && !optDisabled
31
- ? "#f5f5f5"
32
- : optDisabled
33
- ? "#f5f5f5"
34
- : "#fff",
35
- }),
36
- placeholder: { color: "#bfbfbf" },
37
- scrollbarThumb: "#e5e5e5",
38
- scrollbarTrack: "#f5f5f5",
39
- boxShadow: "0 2px 8px rgba(0,0,0,0.08)",
40
- },
41
- dark: {
42
- trigger: {
43
- background: "#23262F",
44
- color: "#fff",
45
- border: "1px solid #374151",
46
- },
47
- triggerDisabled: {
48
- background: "#23262F",
49
- color: "#666",
50
- border: "1px solid #374151",
51
- },
52
- triggerError: {
53
- background: "#23262F",
54
- color: "#fff",
55
- border: "1px solid #ff4d4f",
56
- },
57
- dropdown: {
58
- background: "#23262F",
59
- border: "1px solid #374151",
60
- color: "#fff",
61
- },
62
- option: (active: boolean, optDisabled: boolean, hovered: boolean) => ({
63
- color: optDisabled ? "#666" : active ? "#00E8C6" : "#fff",
64
- background: active
65
- ? "#23262F"
66
- : hovered && !optDisabled
67
- ? "#333843"
68
- : optDisabled
69
- ? "#23262F"
70
- : "#23262F",
71
- }),
72
- placeholder: { color: "#666" },
73
- scrollbarThumb: "#444C5C",
74
- scrollbarTrack: "#23262F",
75
- boxShadow: "0 2px 8px rgba(0,0,0,0.32)",
76
- },
77
- };
78
-
79
- export function getSelectTheme() {
80
- const theme = getInitParams<Theme>("theme");
81
- const themeConfig = getInitParams<ThemeConfig>("themeConfig");
82
- const whiteTheme = theme === Theme.WHITE;
83
- const baseTheme = whiteTheme ? selectThemes.white : selectThemes.dark;
84
-
85
- // 如果初始化时传入了主题配置,则覆盖默认配置
86
- if (themeConfig) {
87
- const config = whiteTheme ? themeConfig.white : themeConfig.dark;
88
- if (config?.color) {
89
- return {
90
- ...baseTheme,
91
- option: (active: boolean, optDisabled: boolean, hovered: boolean) => ({
92
- ...baseTheme.option(active, optDisabled, hovered),
93
- color: optDisabled
94
- ? baseTheme.option(active, optDisabled, hovered).color
95
- : active
96
- ? config.color
97
- : baseTheme.option(active, optDisabled, hovered).color,
98
- }),
99
- };
100
- }
101
- }
102
-
103
- return baseTheme;
104
- }
@@ -1,140 +0,0 @@
1
- import type { FunctionalComponent } from "preact";
2
- import { useState, useRef } from "preact/hooks";
3
- import { uploadFile } from "@/api";
4
- import { t } from "@/local";
5
- import { getUploadTheme } from "./theme";
6
- import { getInitParams } from "@/utils/business";
7
- import { Size } from "@/types";
8
- const size = getInitParams<Size>("size");
9
- interface UploadProps {
10
- value?: string[];
11
- onChange?: (urls: string[]) => void;
12
- maxCount?: number;
13
- accept?: string;
14
- multiple?: boolean;
15
- disabled?: boolean;
16
- }
17
-
18
- export const Upload: FunctionalComponent<UploadProps> = ({
19
- value = [],
20
- onChange,
21
- maxCount = 10,
22
- accept = ".jpg,.jpeg,.png,.pdf",
23
- multiple = true,
24
- disabled = false,
25
- }) => {
26
- const fileInputRef = useRef<HTMLInputElement>(null);
27
- const [uploading, setUploading] = useState(false);
28
- const [progress, setProgress] = useState(0);
29
- const theme = getUploadTheme();
30
-
31
- const handleFileChange = async (e: any) => {
32
- const files: File[] = Array.from(e.target.files as FileList).slice(
33
- 0,
34
- maxCount
35
- );
36
- if (!files.length) return;
37
- setUploading(true);
38
- const urls: string[] = [];
39
- for (let i = 0; i < files.length; i++) {
40
- setProgress(0);
41
- const formData = new FormData();
42
- formData.append("file", files[i]);
43
- try {
44
- const url = await uploadFile(formData, (percent) =>
45
- setProgress(percent)
46
- );
47
- if (url) urls.push(url);
48
- } catch (err) {
49
- // 可扩展错误处理
50
- }
51
- }
52
- setUploading(false);
53
- setProgress(0);
54
- onChange?.([...value, ...urls]);
55
- if (fileInputRef.current) fileInputRef.current.value = "";
56
- };
57
-
58
- const handleRemove = (idx: number) => {
59
- const newArr = value.filter((_, i) => i !== idx);
60
- onChange?.(newArr);
61
- };
62
-
63
- return (
64
- <div>
65
- <div
66
- style={{
67
- ...theme.container,
68
- cursor: disabled ? "not-allowed" : theme.container.cursor,
69
- opacity: disabled ? 0.6 : 1,
70
- }}
71
- onClick={() => !disabled && fileInputRef.current?.click()}
72
- >
73
- <div
74
- style={{
75
- fontSize: size === Size.SMALL ? 32 : 48,
76
- marginBottom: size === Size.SMALL ? 8 : 12,
77
- }}
78
- >
79
- 📁
80
- </div>
81
- <div
82
- style={{
83
- color: "#222",
84
- fontSize: size === Size.SMALL ? 12 : 15,
85
- marginBottom: size === Size.SMALL ? 4 : 8,
86
- }}
87
- >
88
- {t("点击或拖拽文件到此处上传")}
89
- </div>
90
- <div style={{ color: "#999", fontSize: size === Size.SMALL ? 12 : 13 }}>
91
- {t("支持 JPG、PNG、PDF 格式,单个文件不超过 20MB,最多上传")}{" "}
92
- {maxCount} {t("个文件")}
93
- </div>
94
- <input
95
- ref={fileInputRef}
96
- type="file"
97
- multiple={multiple}
98
- accept={accept}
99
- style={{ display: "none" }}
100
- onChange={handleFileChange}
101
- disabled={disabled}
102
- />
103
- {uploading && (
104
- <div
105
- style={{
106
- marginTop: size === Size.SMALL ? 8 : 12,
107
- color: "#1677ff",
108
- }}
109
- >
110
- {t("正在上传...")} {progress}%
111
- </div>
112
- )}
113
- </div>
114
- {value && value.length > 0 && (
115
- <div style={{ marginTop: size === Size.SMALL ? 8 : 12 }}>
116
- {value.map((url, idx) => (
117
- <div key={url} style={theme.fileItem}>
118
- <div style={{ display: "flex", alignItems: "center", flex: 1 }}>
119
- <span style={{ fontWeight: 500, wordBreak: "break-all" }}>
120
- {url.split("/").pop()}
121
- </span>
122
- </div>
123
- <button
124
- type="button"
125
- onClick={(e) => {
126
- e.stopPropagation();
127
- handleRemove(idx);
128
- }}
129
- style={theme.removeBtn}
130
- disabled={disabled}
131
- >
132
- {t("移除")}
133
- </button>
134
- </div>
135
- ))}
136
- </div>
137
- )}
138
- </div>
139
- );
140
- };
@@ -1,89 +0,0 @@
1
- import { Size, Theme } from "@/types";
2
- import { getInitParams } from "@/utils/business";
3
- const size = getInitParams<Size>("size");
4
-
5
-
6
- export const uploadThemes = {
7
- white: {
8
- container: {
9
- border: "1px dashed #E5E6EB",
10
- borderRadius: 8,
11
- background: "#FCFCFD",
12
- padding: size === Size.SMALL ? 16 : 24,
13
- textAlign: "center",
14
- cursor: "pointer",
15
- minHeight: size === Size.SMALL ? 80 : 120,
16
- display: "flex",
17
- flexDirection: "column",
18
- alignItems: "center",
19
- justifyContent: "center",
20
- color: "#999",
21
- fontSize: size === Size.SMALL ? 12 : 15,
22
- },
23
- fileItem: {
24
- display: "flex",
25
- alignItems: "center",
26
- background: "#F7F8FA",
27
- borderRadius: 8,
28
- padding: size === Size.SMALL ? "8px 10px" : "12px 16px",
29
- marginBottom: 8,
30
- fontSize: size === Size.SMALL ? 12 : 15,
31
- color: "#222",
32
- justifyContent: "space-between",
33
- },
34
- removeBtn: {
35
- background: "#FF4D4F",
36
- color: "#fff",
37
- border: "none",
38
- borderRadius: 6,
39
- padding: size === Size.SMALL ? "6px 10px" : "4px 14px",
40
- fontSize: size === Size.SMALL ? 12 : 15,
41
- marginLeft: size === Size.SMALL ? 8 : 16,
42
- cursor: "pointer",
43
- },
44
- },
45
- dark: {
46
- container: {
47
- border: "1.5px dashed #444C5C",
48
- borderRadius: 8,
49
- background: "#181A20",
50
- padding: size === Size.SMALL ? 16 : 24,
51
- textAlign: "center",
52
- cursor: "pointer",
53
- minHeight: size === Size.SMALL ? 80 : 120,
54
- display: "flex",
55
- flexDirection: "column",
56
- alignItems: "center",
57
- justifyContent: "center",
58
- color: "#999",
59
- fontSize: size === Size.SMALL ? 12 : 15,
60
- },
61
- fileItem: {
62
- display: "flex",
63
- alignItems: "center",
64
- background: "#23262F",
65
- borderRadius: 8,
66
- padding: size === Size.SMALL ? "8px 10px" : "12px 16px",
67
- marginBottom: 8,
68
- fontSize: size === Size.SMALL ? 12 : 15,
69
- color: "#fff",
70
- justifyContent: "space-between",
71
- },
72
- removeBtn: {
73
- background: "#FF4D4F",
74
- color: "#fff",
75
- border: "none",
76
- borderRadius: 6,
77
- padding: size === Size.SMALL ? "6px 10px" : "4px 14px",
78
- fontSize: size === Size.SMALL ? 12 : 15,
79
- marginLeft: size === Size.SMALL ? 8 : 16,
80
- cursor: "pointer",
81
- },
82
- },
83
- };
84
-
85
- export function getUploadTheme() {
86
- const theme = getInitParams<Theme>("theme");
87
- const whiteTheme = theme === Theme.WHITE;
88
- return whiteTheme ? uploadThemes.white : uploadThemes.dark;
89
- }