cynx-ui 1.2.6 → 1.2.7
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/components/ActionsMenu.jsx +149 -149
- package/components/ActivityCard.jsx +184 -184
- package/components/Badge.jsx +129 -105
- package/components/Button.jsx +126 -43
- package/components/Card.jsx +62 -62
- package/components/CircularProgress.jsx +163 -163
- package/components/Dropzone.jsx +29 -29
- package/components/HoverCard.jsx +81 -81
- package/components/Input.jsx +181 -121
- package/components/LineProgress.jsx +109 -109
- package/components/Modal.jsx +124 -8
- package/components/Pagination.jsx +41 -41
- package/components/PulseDot.jsx +76 -58
- package/components/Select.jsx +175 -91
- package/components/Skeleton.jsx +31 -47
- package/components/Spinner.jsx +36 -36
- package/components/StatBarCard.jsx +25 -25
- package/components/StatsCard.jsx +114 -40
- package/components/Tabs.jsx +16 -16
- package/components/Toast.jsx +57 -57
- package/components/Toggle.jsx +56 -56
- package/components/UptimeBar.jsx +200 -200
- package/components/XTable.jsx +22 -22
- package/index.js +94 -94
- package/package.json +18 -18
package/components/Dropzone.jsx
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import { useState, useRef } from 'react';
|
|
2
|
-
|
|
3
|
-
export function Dropzone({ onFile, accept, hint, file }) {
|
|
4
|
-
const [over, setOver] = useState(false);
|
|
5
|
-
const inputRef = useRef(null);
|
|
6
|
-
return (
|
|
7
|
-
<div className={`dropzone${over ? ' over' : ''}`}
|
|
8
|
-
onDragOver={e => { e.preventDefault(); setOver(true); }}
|
|
9
|
-
onDragLeave={() => setOver(false)}
|
|
10
|
-
onDrop={e => { e.preventDefault(); setOver(false); const f = e.dataTransfer.files[0]; if (f) onFile(f); }}
|
|
11
|
-
onClick={() => inputRef.current?.click()}>
|
|
12
|
-
<input ref={inputRef} type="file" accept={accept}
|
|
13
|
-
onChange={e => e.target.files[0] && onFile(e.target.files[0])} style={{ display: 'none' }} />
|
|
14
|
-
<div className="dropzone-icon">
|
|
15
|
-
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="var(--grey-3)" strokeWidth="1.5" strokeLinecap="round">
|
|
16
|
-
<path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/>
|
|
17
|
-
</svg>
|
|
18
|
-
</div>
|
|
19
|
-
{file ? (
|
|
20
|
-
<div className="dropzone-file">{file.name}</div>
|
|
21
|
-
) : (
|
|
22
|
-
<>
|
|
23
|
-
<div className="dropzone-text"><b>Click to select</b> or drag & drop</div>
|
|
24
|
-
{hint && <div className="dropzone-hint">{hint}</div>}
|
|
25
|
-
</>
|
|
26
|
-
)}
|
|
27
|
-
</div>
|
|
28
|
-
);
|
|
29
|
-
}
|
|
1
|
+
import { useState, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
export function Dropzone({ onFile, accept, hint, file }) {
|
|
4
|
+
const [over, setOver] = useState(false);
|
|
5
|
+
const inputRef = useRef(null);
|
|
6
|
+
return (
|
|
7
|
+
<div className={`dropzone${over ? ' over' : ''}`}
|
|
8
|
+
onDragOver={e => { e.preventDefault(); setOver(true); }}
|
|
9
|
+
onDragLeave={() => setOver(false)}
|
|
10
|
+
onDrop={e => { e.preventDefault(); setOver(false); const f = e.dataTransfer.files[0]; if (f) onFile(f); }}
|
|
11
|
+
onClick={() => inputRef.current?.click()}>
|
|
12
|
+
<input ref={inputRef} type="file" accept={accept}
|
|
13
|
+
onChange={e => e.target.files[0] && onFile(e.target.files[0])} style={{ display: 'none' }} />
|
|
14
|
+
<div className="dropzone-icon">
|
|
15
|
+
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="var(--grey-3)" strokeWidth="1.5" strokeLinecap="round">
|
|
16
|
+
<path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/>
|
|
17
|
+
</svg>
|
|
18
|
+
</div>
|
|
19
|
+
{file ? (
|
|
20
|
+
<div className="dropzone-file">{file.name}</div>
|
|
21
|
+
) : (
|
|
22
|
+
<>
|
|
23
|
+
<div className="dropzone-text"><b>Click to select</b> or drag & drop</div>
|
|
24
|
+
{hint && <div className="dropzone-hint">{hint}</div>}
|
|
25
|
+
</>
|
|
26
|
+
)}
|
|
27
|
+
</div>
|
|
28
|
+
);
|
|
29
|
+
}
|
package/components/HoverCard.jsx
CHANGED
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
import { useState, useRef, useEffect } from 'react';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* HoverCard — reusable tooltip/popover on hover
|
|
5
|
-
*
|
|
6
|
-
* Props:
|
|
7
|
-
* trigger — React node as hover target
|
|
8
|
-
* children — popup content
|
|
9
|
-
* position — 'top' | 'bottom' (default: 'top')
|
|
10
|
-
* width — min-width (default: 180)
|
|
11
|
-
* style — extra popup styles
|
|
12
|
-
* triggerStyle — extra trigger wrapper styles
|
|
13
|
-
*/
|
|
14
|
-
export default function HoverCard({ trigger, children, position = 'top', width = 180, style, triggerStyle }) {
|
|
15
|
-
const [open, setOpen] = useState(false);
|
|
16
|
-
const [pos, setPos] = useState({ x: 0, y: 0 });
|
|
17
|
-
const wrapRef = useRef(null);
|
|
18
|
-
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
if (open && wrapRef.current) {
|
|
21
|
-
const r = wrapRef.current.getBoundingClientRect();
|
|
22
|
-
setPos({ x: r.left + r.width / 2, y: position === 'top' ? r.top : r.bottom });
|
|
23
|
-
}
|
|
24
|
-
}, [open, position]);
|
|
25
|
-
|
|
26
|
-
useEffect(() => {
|
|
27
|
-
if (!open) return;
|
|
28
|
-
const close = (e) => {
|
|
29
|
-
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
30
|
-
};
|
|
31
|
-
document.addEventListener('mousedown', close);
|
|
32
|
-
return () => document.removeEventListener('mousedown', close);
|
|
33
|
-
}, [open]);
|
|
34
|
-
|
|
35
|
-
return (
|
|
36
|
-
<div
|
|
37
|
-
ref={wrapRef}
|
|
38
|
-
onMouseEnter={() => setOpen(true)}
|
|
39
|
-
onMouseLeave={() => setOpen(false)}
|
|
40
|
-
style={{ display: 'inline-block', position: 'relative', ...triggerStyle }}
|
|
41
|
-
>
|
|
42
|
-
{trigger}
|
|
43
|
-
{open && (
|
|
44
|
-
<div style={{
|
|
45
|
-
position: 'fixed',
|
|
46
|
-
left: pos.x,
|
|
47
|
-
top: position === 'top' ? 'auto' : pos.y + 6,
|
|
48
|
-
bottom: position === 'top' ? window.innerHeight - pos.y + 6 : 'auto',
|
|
49
|
-
transform: 'translateX(-50%)',
|
|
50
|
-
zIndex: 9999,
|
|
51
|
-
minWidth: width,
|
|
52
|
-
background: '#fff',
|
|
53
|
-
border: '1px solid var(--border)',
|
|
54
|
-
borderRadius: 'var(--rads, 8px)',
|
|
55
|
-
padding: '10px 14px',
|
|
56
|
-
boxShadow: '0 4px 12px rgba(0,0,0,.12)',
|
|
57
|
-
pointerEvents: 'none',
|
|
58
|
-
animation: 'hoverCardIn .15s ease',
|
|
59
|
-
...style,
|
|
60
|
-
}}>
|
|
61
|
-
{children}
|
|
62
|
-
<div style={{
|
|
63
|
-
position: 'absolute', left: '50%',
|
|
64
|
-
[position === 'top' ? 'bottom' : 'top']: -5,
|
|
65
|
-
transform: 'translateX(-50%) rotate(45deg)',
|
|
66
|
-
width: 8, height: 8, background: '#fff',
|
|
67
|
-
borderRight: '1px solid var(--border)',
|
|
68
|
-
borderBottom: position === 'top' ? 'none' : '1px solid var(--border)',
|
|
69
|
-
borderTop: position === 'top' ? '1px solid var(--border)' : 'none',
|
|
70
|
-
}} />
|
|
71
|
-
</div>
|
|
72
|
-
)}
|
|
73
|
-
<style>{`
|
|
74
|
-
@keyframes hoverCardIn {
|
|
75
|
-
from { opacity: 0; transform: translateX(-50%) translateY(4px); }
|
|
76
|
-
to { opacity: 1; transform: translateX(-50%) translateY(0); }
|
|
77
|
-
}
|
|
78
|
-
`}</style>
|
|
79
|
-
</div>
|
|
80
|
-
);
|
|
81
|
-
}
|
|
1
|
+
import { useState, useRef, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* HoverCard — reusable tooltip/popover on hover
|
|
5
|
+
*
|
|
6
|
+
* Props:
|
|
7
|
+
* trigger — React node as hover target
|
|
8
|
+
* children — popup content
|
|
9
|
+
* position — 'top' | 'bottom' (default: 'top')
|
|
10
|
+
* width — min-width (default: 180)
|
|
11
|
+
* style — extra popup styles
|
|
12
|
+
* triggerStyle — extra trigger wrapper styles
|
|
13
|
+
*/
|
|
14
|
+
export default function HoverCard({ trigger, children, position = 'top', width = 180, style, triggerStyle }) {
|
|
15
|
+
const [open, setOpen] = useState(false);
|
|
16
|
+
const [pos, setPos] = useState({ x: 0, y: 0 });
|
|
17
|
+
const wrapRef = useRef(null);
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (open && wrapRef.current) {
|
|
21
|
+
const r = wrapRef.current.getBoundingClientRect();
|
|
22
|
+
setPos({ x: r.left + r.width / 2, y: position === 'top' ? r.top : r.bottom });
|
|
23
|
+
}
|
|
24
|
+
}, [open, position]);
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (!open) return;
|
|
28
|
+
const close = (e) => {
|
|
29
|
+
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
30
|
+
};
|
|
31
|
+
document.addEventListener('mousedown', close);
|
|
32
|
+
return () => document.removeEventListener('mousedown', close);
|
|
33
|
+
}, [open]);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div
|
|
37
|
+
ref={wrapRef}
|
|
38
|
+
onMouseEnter={() => setOpen(true)}
|
|
39
|
+
onMouseLeave={() => setOpen(false)}
|
|
40
|
+
style={{ display: 'inline-block', position: 'relative', ...triggerStyle }}
|
|
41
|
+
>
|
|
42
|
+
{trigger}
|
|
43
|
+
{open && (
|
|
44
|
+
<div style={{
|
|
45
|
+
position: 'fixed',
|
|
46
|
+
left: pos.x,
|
|
47
|
+
top: position === 'top' ? 'auto' : pos.y + 6,
|
|
48
|
+
bottom: position === 'top' ? window.innerHeight - pos.y + 6 : 'auto',
|
|
49
|
+
transform: 'translateX(-50%)',
|
|
50
|
+
zIndex: 9999,
|
|
51
|
+
minWidth: width,
|
|
52
|
+
background: '#fff',
|
|
53
|
+
border: '1px solid var(--border)',
|
|
54
|
+
borderRadius: 'var(--rads, 8px)',
|
|
55
|
+
padding: '10px 14px',
|
|
56
|
+
boxShadow: '0 4px 12px rgba(0,0,0,.12)',
|
|
57
|
+
pointerEvents: 'none',
|
|
58
|
+
animation: 'hoverCardIn .15s ease',
|
|
59
|
+
...style,
|
|
60
|
+
}}>
|
|
61
|
+
{children}
|
|
62
|
+
<div style={{
|
|
63
|
+
position: 'absolute', left: '50%',
|
|
64
|
+
[position === 'top' ? 'bottom' : 'top']: -5,
|
|
65
|
+
transform: 'translateX(-50%) rotate(45deg)',
|
|
66
|
+
width: 8, height: 8, background: '#fff',
|
|
67
|
+
borderRight: '1px solid var(--border)',
|
|
68
|
+
borderBottom: position === 'top' ? 'none' : '1px solid var(--border)',
|
|
69
|
+
borderTop: position === 'top' ? '1px solid var(--border)' : 'none',
|
|
70
|
+
}} />
|
|
71
|
+
</div>
|
|
72
|
+
)}
|
|
73
|
+
<style>{`
|
|
74
|
+
@keyframes hoverCardIn {
|
|
75
|
+
from { opacity: 0; transform: translateX(-50%) translateY(4px); }
|
|
76
|
+
to { opacity: 1; transform: translateX(-50%) translateY(0); }
|
|
77
|
+
}
|
|
78
|
+
`}</style>
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
}
|
package/components/Input.jsx
CHANGED
|
@@ -1,121 +1,181 @@
|
|
|
1
|
-
import { useRef } from 'react';
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
const SIZES = {
|
|
4
|
+
xs: { height: 30, fontSize: 11, paddingH: 8 },
|
|
5
|
+
sm: { height: 32, fontSize: 12, paddingH: 9 },
|
|
6
|
+
md: { height: 34, fontSize: 13, paddingH: 11 },
|
|
7
|
+
lg: { height: 40, fontSize: 14, paddingH: 14 },
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default function Input({
|
|
11
|
+
label,
|
|
12
|
+
required = false,
|
|
13
|
+
hint,
|
|
14
|
+
error,
|
|
15
|
+
size = 'md',
|
|
16
|
+
icon,
|
|
17
|
+
iconRight,
|
|
18
|
+
clearable = false,
|
|
19
|
+
suffix,
|
|
20
|
+
onClear,
|
|
21
|
+
className = '',
|
|
22
|
+
style = {},
|
|
23
|
+
value,
|
|
24
|
+
...props
|
|
25
|
+
}) {
|
|
26
|
+
const inputRef = useRef(null);
|
|
27
|
+
const s = SIZES[size] || SIZES.md;
|
|
28
|
+
|
|
29
|
+
function handleClear() {
|
|
30
|
+
if (props.onChange) props.onChange({ target: { value: '' } });
|
|
31
|
+
if (onClear) onClear();
|
|
32
|
+
inputRef.current?.focus();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const hasIconLeft = !!icon;
|
|
36
|
+
const hasIconRight = !!iconRight;
|
|
37
|
+
const showClear = clearable && !!value && !props.disabled;
|
|
38
|
+
const hasSuffix = !!suffix;
|
|
39
|
+
const showRightSlot = showClear || hasSuffix;
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div style={{
|
|
43
|
+
display: 'flex',
|
|
44
|
+
flexDirection: 'column',
|
|
45
|
+
gap: 5,
|
|
46
|
+
}}>
|
|
47
|
+
{label && (
|
|
48
|
+
<label style={{
|
|
49
|
+
fontSize: size === 'xs' ? 9 : 11,
|
|
50
|
+
fontWeight: 600,
|
|
51
|
+
color: 'var(--t2,#797b8d)',
|
|
52
|
+
textTransform: 'uppercase',
|
|
53
|
+
letterSpacing: '.08em',
|
|
54
|
+
}}>
|
|
55
|
+
{label}
|
|
56
|
+
{required && <span style={{ color: 'var(--danger,#f64747)', marginLeft: 2 }}>*</span>}
|
|
57
|
+
</label>
|
|
58
|
+
)}
|
|
59
|
+
|
|
60
|
+
<div style={{
|
|
61
|
+
position: 'relative',
|
|
62
|
+
display: 'flex',
|
|
63
|
+
alignItems: 'center',
|
|
64
|
+
}}>
|
|
65
|
+
{hasIconLeft && (
|
|
66
|
+
<span style={{
|
|
67
|
+
position: 'absolute',
|
|
68
|
+
left: 10,
|
|
69
|
+
top: '50%',
|
|
70
|
+
transform: 'translateY(-50%)',
|
|
71
|
+
color: 'var(--t3,#9b9daa)',
|
|
72
|
+
pointerEvents: 'none',
|
|
73
|
+
lineHeight: 0,
|
|
74
|
+
display: 'flex',
|
|
75
|
+
alignItems: 'center',
|
|
76
|
+
}}>
|
|
77
|
+
{icon}
|
|
78
|
+
</span>
|
|
79
|
+
)}
|
|
80
|
+
|
|
81
|
+
{hasIconRight && (
|
|
82
|
+
<span style={{
|
|
83
|
+
position: 'absolute',
|
|
84
|
+
right: 10,
|
|
85
|
+
top: '50%',
|
|
86
|
+
transform: 'translateY(-50%)',
|
|
87
|
+
color: 'var(--t3,#9b9daa)',
|
|
88
|
+
pointerEvents: 'none',
|
|
89
|
+
display: 'flex',
|
|
90
|
+
alignItems: 'center',
|
|
91
|
+
}}>
|
|
92
|
+
{iconRight}
|
|
93
|
+
</span>
|
|
94
|
+
)}
|
|
95
|
+
|
|
96
|
+
<input
|
|
97
|
+
ref={inputRef}
|
|
98
|
+
className={className}
|
|
99
|
+
style={{
|
|
100
|
+
display: 'block',
|
|
101
|
+
width: '100%',
|
|
102
|
+
background: 'var(--input-bg,#fff)',
|
|
103
|
+
border: `1px solid ${error ? 'var(--danger,#f64747)' : 'var(--bd,#d7d8e0)'}`,
|
|
104
|
+
borderRadius: 'var(--rads,8px)',
|
|
105
|
+
color: 'var(--t1,#1a1a2e)',
|
|
106
|
+
fontFamily: 'var(--f,var(--sans,inherit))',
|
|
107
|
+
fontSize: s.fontSize,
|
|
108
|
+
height: s.height,
|
|
109
|
+
padding: `0 ${s.paddingH}px`,
|
|
110
|
+
paddingLeft: hasIconLeft ? 34 : s.paddingH,
|
|
111
|
+
paddingRight: (hasIconRight || showRightSlot) ? 34 : s.paddingH,
|
|
112
|
+
outline: 'none',
|
|
113
|
+
transition: 'border-color .14s, box-shadow .14s',
|
|
114
|
+
boxShadow: error
|
|
115
|
+
? '0 0 0 3px rgba(246,71,71,.12), var(--shadow,0 1px 3px rgba(20,22,41,.1))'
|
|
116
|
+
: 'var(--shadow,0 1px 3px rgba(20,22,41,.1))',
|
|
117
|
+
opacity: props.disabled ? 0.5 : 1,
|
|
118
|
+
cursor: props.disabled ? 'not-allowed' : undefined,
|
|
119
|
+
background: props.disabled ? 'var(--grey-1,#f5f5f8)' : undefined,
|
|
120
|
+
...style,
|
|
121
|
+
}}
|
|
122
|
+
value={value}
|
|
123
|
+
{...props}
|
|
124
|
+
/>
|
|
125
|
+
|
|
126
|
+
{showClear && (
|
|
127
|
+
<button
|
|
128
|
+
type="button"
|
|
129
|
+
tabIndex={-1}
|
|
130
|
+
onClick={handleClear}
|
|
131
|
+
style={{
|
|
132
|
+
position: 'absolute',
|
|
133
|
+
right: 8,
|
|
134
|
+
top: '50%',
|
|
135
|
+
transform: 'translateY(-50%)',
|
|
136
|
+
display: 'flex',
|
|
137
|
+
alignItems: 'center',
|
|
138
|
+
justifyContent: 'center',
|
|
139
|
+
width: 18,
|
|
140
|
+
height: 18,
|
|
141
|
+
borderRadius: '50%',
|
|
142
|
+
background: 'transparent',
|
|
143
|
+
border: 'none',
|
|
144
|
+
cursor: 'pointer',
|
|
145
|
+
color: 'var(--t3,#9b9daa)',
|
|
146
|
+
padding: 0,
|
|
147
|
+
lineHeight: 0,
|
|
148
|
+
}}
|
|
149
|
+
>
|
|
150
|
+
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round">
|
|
151
|
+
<line x1="1" y1="1" x2="9" y2="9" />
|
|
152
|
+
<line x1="9" y1="1" x2="1" y2="9" />
|
|
153
|
+
</svg>
|
|
154
|
+
</button>
|
|
155
|
+
)}
|
|
156
|
+
|
|
157
|
+
{hasSuffix && !showClear && (
|
|
158
|
+
<span style={{
|
|
159
|
+
position: 'absolute',
|
|
160
|
+
right: 8,
|
|
161
|
+
top: '50%',
|
|
162
|
+
transform: 'translateY(-50%)',
|
|
163
|
+
display: 'flex',
|
|
164
|
+
alignItems: 'center',
|
|
165
|
+
gap: 4,
|
|
166
|
+
pointerEvents: 'none',
|
|
167
|
+
}}>
|
|
168
|
+
{suffix}
|
|
169
|
+
</span>
|
|
170
|
+
)}
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
{hint && !error && (
|
|
174
|
+
<span style={{ fontSize: 11, color: 'var(--t3,#9b9daa)' }}>{hint}</span>
|
|
175
|
+
)}
|
|
176
|
+
{error && (
|
|
177
|
+
<span style={{ fontSize: 11, color: 'var(--danger,#f64747)' }}>{error}</span>
|
|
178
|
+
)}
|
|
179
|
+
</div>
|
|
180
|
+
);
|
|
181
|
+
}
|