best-unit 0.0.41 → 0.0.43
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/best-unit.cjs +26 -11
- package/dist/best-unit.js +1306 -1143
- package/package.json +1 -1
- package/src/components/business/recharge-sdk/components/OfflineTransferForm.tsx +11 -15
- package/src/components/business/recharge-sdk/components/OnlineRechargeForm.tsx +17 -50
- package/src/components/common/Select.tsx +195 -21
- package/src/local/en.ts +1 -0
- package/src/local/zh.ts +1 -0
package/package.json
CHANGED
|
@@ -4,6 +4,7 @@ import { createOfflineRecharge } from "../../../../api";
|
|
|
4
4
|
import { message } from "../../../common/Message";
|
|
5
5
|
import { t } from "../../../../local";
|
|
6
6
|
import { Theme } from "../../../../types";
|
|
7
|
+
import { Select } from "../../../common/Select";
|
|
7
8
|
|
|
8
9
|
interface OfflineTransferFormProps {
|
|
9
10
|
formState: {
|
|
@@ -281,28 +282,23 @@ export const OfflineTransferForm: FunctionalComponent<
|
|
|
281
282
|
<div style={theme.label}>
|
|
282
283
|
<span style={{ color: "#F53F3F" }}>*</span> {t("第三方支付平台")}
|
|
283
284
|
</div>
|
|
284
|
-
<
|
|
285
|
-
style={{
|
|
286
|
-
...theme.select,
|
|
287
|
-
...(formState.platformError ? theme.selectError : {}),
|
|
288
|
-
}}
|
|
285
|
+
<Select
|
|
289
286
|
value={formState.platform}
|
|
290
|
-
|
|
291
|
-
const value = (e.target as HTMLSelectElement).value;
|
|
287
|
+
onChange={(value) => {
|
|
292
288
|
setFormState((state: any) => ({
|
|
293
289
|
...state,
|
|
294
290
|
platform: value,
|
|
295
291
|
platformError: value ? "" : state.platformError,
|
|
296
292
|
}));
|
|
297
293
|
}}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
)
|
|
305
|
-
|
|
294
|
+
options={[
|
|
295
|
+
...channelDict?.map((item: any) => ({
|
|
296
|
+
value: item.value,
|
|
297
|
+
label: item.label,
|
|
298
|
+
})),
|
|
299
|
+
]}
|
|
300
|
+
placeholder={t("请选择支付平台")}
|
|
301
|
+
/>
|
|
306
302
|
{formState.platformError && (
|
|
307
303
|
<div style={theme.error}>{formState.platformError}</div>
|
|
308
304
|
)}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { FunctionalComponent } from "preact";
|
|
2
2
|
import { t } from "../../../../local";
|
|
3
3
|
import { Theme } from "../../../../types";
|
|
4
|
+
import { Select } from "../../../common/Select";
|
|
4
5
|
|
|
5
6
|
interface OnlineRechargeFormProps {
|
|
6
7
|
formState: {
|
|
@@ -54,16 +55,6 @@ export const OnlineRechargeForm: FunctionalComponent<
|
|
|
54
55
|
inputError: {
|
|
55
56
|
border: "1px solid #ff4d4f",
|
|
56
57
|
},
|
|
57
|
-
select: {
|
|
58
|
-
width: "100%",
|
|
59
|
-
padding: "10px 12px",
|
|
60
|
-
borderRadius: 6,
|
|
61
|
-
border: "1px solid #E5E6EB",
|
|
62
|
-
background: "#fff",
|
|
63
|
-
color: "#222",
|
|
64
|
-
fontSize: 15,
|
|
65
|
-
outline: "none",
|
|
66
|
-
},
|
|
67
58
|
selectError: {
|
|
68
59
|
border: "1px solid #ff4d4f",
|
|
69
60
|
},
|
|
@@ -116,16 +107,6 @@ export const OnlineRechargeForm: FunctionalComponent<
|
|
|
116
107
|
inputError: {
|
|
117
108
|
border: "1px solid #ff4d4f",
|
|
118
109
|
},
|
|
119
|
-
select: {
|
|
120
|
-
width: "100%",
|
|
121
|
-
padding: "10px 12px",
|
|
122
|
-
borderRadius: 6,
|
|
123
|
-
border: "1px solid #23262F",
|
|
124
|
-
background: "#23262F",
|
|
125
|
-
color: "#fff",
|
|
126
|
-
fontSize: 15,
|
|
127
|
-
outline: "none",
|
|
128
|
-
},
|
|
129
110
|
selectError: {
|
|
130
111
|
border: "1px solid #ff4d4f",
|
|
131
112
|
},
|
|
@@ -233,27 +214,20 @@ export const OnlineRechargeForm: FunctionalComponent<
|
|
|
233
214
|
<div style={theme.label}>
|
|
234
215
|
<span style={{ color: "#F53F3F" }}>*</span> {t("充值币种")}
|
|
235
216
|
</div>
|
|
236
|
-
<
|
|
237
|
-
style={{
|
|
238
|
-
...theme.select,
|
|
239
|
-
// 币种没有错误校验
|
|
240
|
-
}}
|
|
217
|
+
<Select
|
|
241
218
|
value={formState.currency}
|
|
242
|
-
|
|
243
|
-
const value = (e.target as HTMLSelectElement).value;
|
|
219
|
+
onChange={(value) => {
|
|
244
220
|
setFormState((state: any) => ({
|
|
245
221
|
...state,
|
|
246
222
|
currency: value,
|
|
247
223
|
}));
|
|
248
224
|
}}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
{
|
|
254
|
-
|
|
255
|
-
))}
|
|
256
|
-
</select>
|
|
225
|
+
options={currencyDict?.map((item: any) => ({
|
|
226
|
+
value: item.value,
|
|
227
|
+
label: item.label,
|
|
228
|
+
}))}
|
|
229
|
+
placeholder={t("请选择充值币种")}
|
|
230
|
+
/>
|
|
257
231
|
</div>
|
|
258
232
|
<div style={{ marginBottom: 18 }}>
|
|
259
233
|
<div style={theme.label}>
|
|
@@ -284,28 +258,21 @@ export const OnlineRechargeForm: FunctionalComponent<
|
|
|
284
258
|
<div style={theme.label}>
|
|
285
259
|
<span style={{ color: "#F53F3F" }}>*</span> {t("支付平台")}
|
|
286
260
|
</div>
|
|
287
|
-
<
|
|
288
|
-
style={{
|
|
289
|
-
...theme.select,
|
|
290
|
-
...(formState.rechargeChannelError ? theme.selectError : {}),
|
|
291
|
-
}}
|
|
261
|
+
<Select
|
|
292
262
|
value={formState.rechargeChannel}
|
|
293
|
-
|
|
294
|
-
const value = (e.target as HTMLSelectElement).value;
|
|
263
|
+
onChange={(value) => {
|
|
295
264
|
setFormState((state: any) => ({
|
|
296
265
|
...state,
|
|
297
266
|
rechargeChannel: value,
|
|
298
267
|
rechargeChannelError: value ? "" : state.rechargeChannelError,
|
|
299
268
|
}));
|
|
300
269
|
}}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
{
|
|
306
|
-
|
|
307
|
-
))}
|
|
308
|
-
</select>
|
|
270
|
+
options={channelDict?.map((item: any) => ({
|
|
271
|
+
value: item.value,
|
|
272
|
+
label: item.label,
|
|
273
|
+
}))}
|
|
274
|
+
placeholder={t("请选择支付平台")}
|
|
275
|
+
></Select>
|
|
309
276
|
{formState.rechargeChannelError && (
|
|
310
277
|
<div style={theme.error}>{formState.rechargeChannelError}</div>
|
|
311
278
|
)}
|
|
@@ -1,18 +1,26 @@
|
|
|
1
|
-
import type { FunctionalComponent } from "preact";
|
|
1
|
+
import type { FunctionalComponent, JSX } from "preact";
|
|
2
2
|
import { useState, useRef, useEffect } from "preact/hooks";
|
|
3
|
+
import { Theme } from "../../types";
|
|
4
|
+
import { t } from "../../local";
|
|
3
5
|
|
|
4
6
|
interface Option {
|
|
5
7
|
value: string;
|
|
6
8
|
label: string;
|
|
9
|
+
disabled?: boolean;
|
|
7
10
|
}
|
|
8
11
|
|
|
9
12
|
interface SelectProps {
|
|
10
|
-
value
|
|
11
|
-
onChange
|
|
13
|
+
value?: string;
|
|
14
|
+
onChange?: (value: string) => void;
|
|
12
15
|
options: Option[];
|
|
13
16
|
placeholder?: string;
|
|
14
17
|
style?: any;
|
|
15
18
|
error?: boolean;
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
dropdownStyle?: any;
|
|
21
|
+
className?: string;
|
|
22
|
+
dropdownClassName?: string;
|
|
23
|
+
children?: JSX.Element;
|
|
16
24
|
}
|
|
17
25
|
|
|
18
26
|
export const Select: FunctionalComponent<SelectProps> = ({
|
|
@@ -22,11 +30,80 @@ export const Select: FunctionalComponent<SelectProps> = ({
|
|
|
22
30
|
placeholder,
|
|
23
31
|
style,
|
|
24
32
|
error,
|
|
33
|
+
disabled,
|
|
34
|
+
dropdownStyle,
|
|
35
|
+
className,
|
|
36
|
+
dropdownClassName,
|
|
37
|
+
children,
|
|
25
38
|
}) => {
|
|
26
39
|
const [open, setOpen] = useState(false);
|
|
27
40
|
const ref = useRef<HTMLDivElement>(null);
|
|
41
|
+
const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);
|
|
42
|
+
|
|
43
|
+
// 主题切换
|
|
44
|
+
const fundUnitParams = JSON.parse(
|
|
45
|
+
sessionStorage.getItem("fund_unit_params") || "{}"
|
|
46
|
+
);
|
|
47
|
+
const whiteTheme = fundUnitParams.theme === Theme.WHITE;
|
|
48
|
+
// hover灰色 #f5f5f5,选中蓝色 #e6f7ff
|
|
49
|
+
const selectTheme = whiteTheme
|
|
50
|
+
? {
|
|
51
|
+
trigger: {
|
|
52
|
+
background: disabled ? "#f5f5f5" : "#fff",
|
|
53
|
+
color: disabled ? "#bfbfbf" : value ? "#222" : "#bfbfbf",
|
|
54
|
+
border: error
|
|
55
|
+
? "1px solid #ff4d4f"
|
|
56
|
+
: disabled
|
|
57
|
+
? "1px solid #f0f0f0"
|
|
58
|
+
: "1px solid #d9d9d9",
|
|
59
|
+
},
|
|
60
|
+
dropdown: {
|
|
61
|
+
background: "#fff",
|
|
62
|
+
border: "1px solid #d9d9d9",
|
|
63
|
+
color: "#222",
|
|
64
|
+
},
|
|
65
|
+
option: (active: boolean, optDisabled: boolean, hovered: boolean) => ({
|
|
66
|
+
color: optDisabled ? "#bfbfbf" : active ? "#1890ff" : "#222",
|
|
67
|
+
background: active
|
|
68
|
+
? "#e6f7ff"
|
|
69
|
+
: hovered && !optDisabled
|
|
70
|
+
? "#f5f5f5"
|
|
71
|
+
: optDisabled
|
|
72
|
+
? "#f5f5f5"
|
|
73
|
+
: "#fff",
|
|
74
|
+
}),
|
|
75
|
+
placeholder: { color: "#bfbfbf" },
|
|
76
|
+
}
|
|
77
|
+
: {
|
|
78
|
+
trigger: {
|
|
79
|
+
background: disabled ? "#23262F" : "#23262F",
|
|
80
|
+
color: disabled ? "#666" : value ? "#fff" : "#666",
|
|
81
|
+
border: error
|
|
82
|
+
? "1px solid #ff4d4f"
|
|
83
|
+
: disabled
|
|
84
|
+
? "1px solid #23262F"
|
|
85
|
+
: "1px solid #23262F",
|
|
86
|
+
},
|
|
87
|
+
dropdown: {
|
|
88
|
+
background: "#23262F",
|
|
89
|
+
border: "1px solid #23262F",
|
|
90
|
+
color: "#fff",
|
|
91
|
+
},
|
|
92
|
+
option: (active: boolean, optDisabled: boolean, hovered: boolean) => ({
|
|
93
|
+
color: optDisabled ? "#666" : active ? "#00E8C6" : "#fff",
|
|
94
|
+
background: active
|
|
95
|
+
? "#23262F"
|
|
96
|
+
: hovered && !optDisabled
|
|
97
|
+
? "#333843"
|
|
98
|
+
: optDisabled
|
|
99
|
+
? "#23262F"
|
|
100
|
+
: "#23262F",
|
|
101
|
+
}),
|
|
102
|
+
placeholder: { color: "#666" },
|
|
103
|
+
};
|
|
28
104
|
|
|
29
105
|
useEffect(() => {
|
|
106
|
+
if (!open) return;
|
|
30
107
|
const handleClick = (e: MouseEvent) => {
|
|
31
108
|
if (ref.current && !ref.current.contains(e.target as Node)) {
|
|
32
109
|
setOpen(false);
|
|
@@ -34,64 +111,160 @@ export const Select: FunctionalComponent<SelectProps> = ({
|
|
|
34
111
|
};
|
|
35
112
|
document.addEventListener("mousedown", handleClick);
|
|
36
113
|
return () => document.removeEventListener("mousedown", handleClick);
|
|
37
|
-
}, []);
|
|
114
|
+
}, [open]);
|
|
38
115
|
|
|
39
116
|
const selected = options.find((opt) => opt.value === value);
|
|
40
117
|
|
|
41
118
|
return (
|
|
42
|
-
<div
|
|
119
|
+
<div
|
|
120
|
+
ref={ref}
|
|
121
|
+
className={className}
|
|
122
|
+
style={{ position: "relative", ...style }}
|
|
123
|
+
>
|
|
124
|
+
<style>{`
|
|
125
|
+
.custom-select-dropdown {
|
|
126
|
+
scrollbar-width: thin;
|
|
127
|
+
scrollbar-color: #bfbfbf #f5f5f5;
|
|
128
|
+
}
|
|
129
|
+
.custom-select-dropdown::-webkit-scrollbar {
|
|
130
|
+
width: 8px;
|
|
131
|
+
}
|
|
132
|
+
.custom-select-dropdown::-webkit-scrollbar-thumb {
|
|
133
|
+
border-radius: 4px;
|
|
134
|
+
background: ${whiteTheme ? "#e5e5e5" : "#444C5C"};
|
|
135
|
+
}
|
|
136
|
+
.custom-select-dropdown::-webkit-scrollbar-track {
|
|
137
|
+
background: ${whiteTheme ? "#f5f5f5" : "#23262F"};
|
|
138
|
+
}
|
|
139
|
+
`}</style>
|
|
43
140
|
<div
|
|
44
|
-
onClick={() => setOpen((o) => !o)}
|
|
141
|
+
onClick={() => !disabled && setOpen((o) => !o)}
|
|
45
142
|
style={{
|
|
46
143
|
minHeight: 40,
|
|
47
|
-
border: error ? "1px solid #ff4d4f" : "1px solid #d9d9d9",
|
|
48
144
|
borderRadius: 6,
|
|
49
|
-
background: "#fff",
|
|
50
145
|
display: "flex",
|
|
51
146
|
alignItems: "center",
|
|
52
147
|
padding: "0 12px",
|
|
53
148
|
fontSize: 15,
|
|
54
|
-
|
|
55
|
-
cursor: "pointer",
|
|
149
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
56
150
|
boxSizing: "border-box",
|
|
57
151
|
transition: "border 0.2s",
|
|
152
|
+
opacity: disabled ? 0.6 : 1,
|
|
153
|
+
width: "100%",
|
|
154
|
+
...selectTheme.trigger,
|
|
58
155
|
...style,
|
|
59
156
|
}}
|
|
157
|
+
tabIndex={0}
|
|
60
158
|
>
|
|
61
159
|
<span style={{ flex: 1 }}>
|
|
62
|
-
{selected ?
|
|
160
|
+
{selected ? (
|
|
161
|
+
selected.label
|
|
162
|
+
) : (
|
|
163
|
+
<span style={selectTheme.placeholder}>
|
|
164
|
+
{placeholder || "请选择"}
|
|
165
|
+
</span>
|
|
166
|
+
)}
|
|
167
|
+
</span>
|
|
168
|
+
<span style={{ marginLeft: 8, display: "flex", alignItems: "center" }}>
|
|
169
|
+
<svg
|
|
170
|
+
width="20"
|
|
171
|
+
height="20"
|
|
172
|
+
viewBox="0 0 20 20"
|
|
173
|
+
fill="none"
|
|
174
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
175
|
+
>
|
|
176
|
+
<path
|
|
177
|
+
d="M6 8L10 12L14 8"
|
|
178
|
+
stroke="#bfbfbf"
|
|
179
|
+
stroke-width="1.5"
|
|
180
|
+
stroke-linecap="round"
|
|
181
|
+
stroke-linejoin="round"
|
|
182
|
+
/>
|
|
183
|
+
</svg>
|
|
63
184
|
</span>
|
|
64
|
-
<span style={{ marginLeft: 8, fontSize: 12, color: "#bfbfbf" }}>▼</span>
|
|
65
185
|
</div>
|
|
66
|
-
{open && (
|
|
186
|
+
{open && !disabled && (
|
|
67
187
|
<div
|
|
188
|
+
className={`custom-select-dropdown${
|
|
189
|
+
dropdownClassName ? " " + dropdownClassName : ""
|
|
190
|
+
}`}
|
|
68
191
|
style={{
|
|
69
192
|
position: "absolute",
|
|
70
193
|
left: 0,
|
|
71
194
|
right: 0,
|
|
72
195
|
top: 44,
|
|
73
196
|
zIndex: 10,
|
|
74
|
-
background: "#fff",
|
|
75
|
-
border: "1px solid #d9d9d9",
|
|
76
197
|
borderRadius: 6,
|
|
77
|
-
boxShadow:
|
|
198
|
+
boxShadow: whiteTheme
|
|
199
|
+
? "0 2px 8px rgba(0,0,0,0.08)"
|
|
200
|
+
: "0 2px 8px rgba(0,0,0,0.32)",
|
|
78
201
|
maxHeight: 220,
|
|
79
202
|
overflowY: "auto",
|
|
203
|
+
...selectTheme.dropdown,
|
|
204
|
+
...dropdownStyle,
|
|
80
205
|
}}
|
|
81
206
|
>
|
|
82
|
-
{options.
|
|
207
|
+
{options.length === 0 && (
|
|
208
|
+
<div
|
|
209
|
+
style={{
|
|
210
|
+
display: "flex",
|
|
211
|
+
flexDirection: "column",
|
|
212
|
+
alignItems: "center",
|
|
213
|
+
justifyContent: "center",
|
|
214
|
+
minHeight: 120,
|
|
215
|
+
width: "100%",
|
|
216
|
+
userSelect: "none",
|
|
217
|
+
}}
|
|
218
|
+
>
|
|
219
|
+
<svg
|
|
220
|
+
width="64"
|
|
221
|
+
height="41"
|
|
222
|
+
viewBox="0 0 64 41"
|
|
223
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
224
|
+
>
|
|
225
|
+
<title>{t("暂无数据")}</title>
|
|
226
|
+
<g transform="translate(0 1)" fill="none" fillRule="evenodd">
|
|
227
|
+
<ellipse
|
|
228
|
+
fill="#f5f5f5"
|
|
229
|
+
cx="32"
|
|
230
|
+
cy="33"
|
|
231
|
+
rx="32"
|
|
232
|
+
ry="7"
|
|
233
|
+
></ellipse>
|
|
234
|
+
<g fillRule="nonzero" stroke="#d9d9d9">
|
|
235
|
+
<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>
|
|
236
|
+
<path
|
|
237
|
+
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"
|
|
238
|
+
fill="#fafafa"
|
|
239
|
+
></path>
|
|
240
|
+
</g>
|
|
241
|
+
</g>
|
|
242
|
+
</svg>
|
|
243
|
+
<div style={{ marginTop: 8, color: "#bfbfbf", fontSize: 15 }}>
|
|
244
|
+
{t("暂无数据")}
|
|
245
|
+
</div>
|
|
246
|
+
</div>
|
|
247
|
+
)}
|
|
248
|
+
{options.map((opt, idx) => (
|
|
83
249
|
<div
|
|
84
250
|
key={opt.value}
|
|
85
251
|
onClick={() => {
|
|
252
|
+
if (opt.disabled) return;
|
|
86
253
|
setOpen(false);
|
|
87
|
-
onChange(opt.value);
|
|
254
|
+
onChange?.(opt.value);
|
|
88
255
|
}}
|
|
256
|
+
onMouseEnter={() => setHoveredIndex(idx)}
|
|
257
|
+
onMouseLeave={() => setHoveredIndex(null)}
|
|
89
258
|
style={{
|
|
90
259
|
padding: "10px 16px",
|
|
91
|
-
cursor: "pointer",
|
|
92
|
-
color: "#222",
|
|
93
|
-
background: value === opt.value ? "#f5f5f5" : "#fff",
|
|
260
|
+
cursor: opt.disabled ? "not-allowed" : "pointer",
|
|
94
261
|
fontWeight: value === opt.value ? 600 : 400,
|
|
262
|
+
opacity: opt.disabled ? 0.6 : 1,
|
|
263
|
+
...selectTheme.option(
|
|
264
|
+
value === opt.value,
|
|
265
|
+
!!opt.disabled,
|
|
266
|
+
hoveredIndex === idx
|
|
267
|
+
),
|
|
95
268
|
}}
|
|
96
269
|
>
|
|
97
270
|
{opt.label}
|
|
@@ -99,6 +272,7 @@ export const Select: FunctionalComponent<SelectProps> = ({
|
|
|
99
272
|
))}
|
|
100
273
|
</div>
|
|
101
274
|
)}
|
|
275
|
+
{children}
|
|
102
276
|
</div>
|
|
103
277
|
);
|
|
104
278
|
};
|
package/src/local/en.ts
CHANGED