cynx-ui 1.3.7 → 1.3.9
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/Divider.jsx +96 -0
- package/components/TabBar.jsx +308 -74
- package/index.js +2 -0
- package/package.json +1 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const SIZE_CONFIG = {
|
|
4
|
+
xs: { hMargin: '8px 0', vMargin: '0 4px', vHeight: '14px', fontSize: '.7rem', padding: '0 8px' },
|
|
5
|
+
sm: { hMargin: '12px 0', vMargin: '0 8px', vHeight: '18px', fontSize: '.75rem', padding: '0 10px' },
|
|
6
|
+
md: { hMargin: '16px 0', vMargin: '0 12px', vHeight: '24px', fontSize: '.82rem', padding: '0 12px' },
|
|
7
|
+
lg: { hMargin: '24px 0', vMargin: '0 16px', vHeight: '32px', fontSize: '.9rem', padding: '0 16px' },
|
|
8
|
+
xl: { hMargin: '32px 0', vMargin: '0 24px', vHeight: '48px', fontSize: '1rem', padding: '0 20px' },
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default function Divider({
|
|
12
|
+
children,
|
|
13
|
+
label,
|
|
14
|
+
orientation = 'horizontal',
|
|
15
|
+
align = 'center',
|
|
16
|
+
size = 'md',
|
|
17
|
+
color = 'var(--border-light, #ebebf0)',
|
|
18
|
+
thickness = 1,
|
|
19
|
+
variant = 'solid',
|
|
20
|
+
style = {},
|
|
21
|
+
className = '',
|
|
22
|
+
...props
|
|
23
|
+
}) {
|
|
24
|
+
const content = children || label;
|
|
25
|
+
const cfg = SIZE_CONFIG[size] || SIZE_CONFIG.md;
|
|
26
|
+
const thickStr = typeof thickness === 'number' ? `${thickness}px` : thickness;
|
|
27
|
+
const lineStyle = `${thickStr} ${variant} ${color}`;
|
|
28
|
+
|
|
29
|
+
if (orientation === 'vertical') {
|
|
30
|
+
return (
|
|
31
|
+
<div
|
|
32
|
+
className={`cynx-divider cynx-divider-vertical ${className}`}
|
|
33
|
+
style={{
|
|
34
|
+
display: 'inline-block',
|
|
35
|
+
width: 0,
|
|
36
|
+
height: style.height || cfg.vHeight,
|
|
37
|
+
margin: style.margin || cfg.vMargin,
|
|
38
|
+
borderLeft: lineStyle,
|
|
39
|
+
verticalAlign: 'middle',
|
|
40
|
+
alignSelf: 'center',
|
|
41
|
+
flexShrink: 0,
|
|
42
|
+
...style,
|
|
43
|
+
}}
|
|
44
|
+
{...props}
|
|
45
|
+
/>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Horizontal Divider
|
|
50
|
+
if (content) {
|
|
51
|
+
const leftFlex = align === 'left' ? '0 0 16px' : '1';
|
|
52
|
+
const rightFlex = align === 'right' ? '0 0 16px' : '1';
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<div
|
|
56
|
+
className={`cynx-divider cynx-divider-horizontal ${className}`}
|
|
57
|
+
style={{
|
|
58
|
+
display: 'flex',
|
|
59
|
+
alignItems: 'center',
|
|
60
|
+
width: '100%',
|
|
61
|
+
margin: style.margin || cfg.hMargin,
|
|
62
|
+
...style,
|
|
63
|
+
}}
|
|
64
|
+
{...props}
|
|
65
|
+
>
|
|
66
|
+
<div style={{ flex: leftFlex, borderBottom: lineStyle }} />
|
|
67
|
+
<span
|
|
68
|
+
style={{
|
|
69
|
+
padding: cfg.padding,
|
|
70
|
+
fontSize: cfg.fontSize,
|
|
71
|
+
color: 'var(--muted, #9b9daa)',
|
|
72
|
+
fontWeight: 500,
|
|
73
|
+
whiteSpace: 'nowrap',
|
|
74
|
+
lineHeight: 1,
|
|
75
|
+
}}
|
|
76
|
+
>
|
|
77
|
+
{content}
|
|
78
|
+
</span>
|
|
79
|
+
<div style={{ flex: rightFlex, borderBottom: lineStyle }} />
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<div
|
|
86
|
+
className={`cynx-divider cynx-divider-horizontal ${className}`}
|
|
87
|
+
style={{
|
|
88
|
+
width: '100%',
|
|
89
|
+
margin: style.margin || cfg.hMargin,
|
|
90
|
+
borderBottom: lineStyle,
|
|
91
|
+
...style,
|
|
92
|
+
}}
|
|
93
|
+
{...props}
|
|
94
|
+
/>
|
|
95
|
+
);
|
|
96
|
+
}
|
package/components/TabBar.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useRef, useEffect } from 'react';
|
|
1
|
+
import { useState, useRef, useEffect } from 'react';
|
|
2
2
|
|
|
3
3
|
const STYLES = `
|
|
4
4
|
@keyframes cx-tabSlide {
|
|
@@ -19,10 +19,64 @@ function ensureStyles() {
|
|
|
19
19
|
|
|
20
20
|
if (typeof document !== 'undefined') ensureStyles();
|
|
21
21
|
|
|
22
|
+
function ChevronIcon({ isOpen }) {
|
|
23
|
+
return (
|
|
24
|
+
<svg
|
|
25
|
+
width="12"
|
|
26
|
+
height="12"
|
|
27
|
+
viewBox="0 0 24 24"
|
|
28
|
+
fill="none"
|
|
29
|
+
stroke="currentColor"
|
|
30
|
+
strokeWidth="2.2"
|
|
31
|
+
strokeLinecap="round"
|
|
32
|
+
strokeLinejoin="round"
|
|
33
|
+
style={{
|
|
34
|
+
transition: 'transform 0.18s cubic-bezier(0.4, 0, 0.2, 1)',
|
|
35
|
+
transform: isOpen ? 'rotate(180deg)' : 'rotate(0deg)',
|
|
36
|
+
opacity: 0.75,
|
|
37
|
+
marginLeft: 2,
|
|
38
|
+
flexShrink: 0,
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
<polyline points="6 9 12 15 18 9" />
|
|
42
|
+
</svg>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function CheckIcon() {
|
|
47
|
+
return (
|
|
48
|
+
<svg
|
|
49
|
+
width="13"
|
|
50
|
+
height="13"
|
|
51
|
+
viewBox="0 0 24 24"
|
|
52
|
+
fill="none"
|
|
53
|
+
stroke="var(--accent, #3b82f6)"
|
|
54
|
+
strokeWidth="2.5"
|
|
55
|
+
strokeLinecap="round"
|
|
56
|
+
strokeLinejoin="round"
|
|
57
|
+
style={{ flexShrink: 0 }}
|
|
58
|
+
>
|
|
59
|
+
<polyline points="20 6 9 17 4 12" />
|
|
60
|
+
</svg>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
22
64
|
export default function TabBar({ tabs, active, onChange, capitalize = false, padding, variant = 'underline' }) {
|
|
23
65
|
const barRef = useRef(null);
|
|
24
66
|
const indRef = useRef(null);
|
|
25
67
|
const initDone = useRef(false);
|
|
68
|
+
const [openDropdownId, setOpenDropdownId] = useState(null);
|
|
69
|
+
|
|
70
|
+
// Click outside to close dropdowns
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
const handleClickOutside = (e) => {
|
|
73
|
+
if (barRef.current && !barRef.current.contains(e.target)) {
|
|
74
|
+
setOpenDropdownId(null);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
78
|
+
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
79
|
+
}, []);
|
|
26
80
|
|
|
27
81
|
// Underline indicator positioning
|
|
28
82
|
useEffect(() => {
|
|
@@ -31,7 +85,7 @@ export default function TabBar({ tabs, active, onChange, capitalize = false, pad
|
|
|
31
85
|
const ind = indRef.current;
|
|
32
86
|
if (!bar || !ind) return;
|
|
33
87
|
|
|
34
|
-
const activeBtn = bar.querySelector(`[data-tabid="${active}"]`);
|
|
88
|
+
const activeBtn = bar.querySelector(`[data-tabid="${active}"]`) || bar.querySelector(`[data-active="true"]`);
|
|
35
89
|
if (!activeBtn) return;
|
|
36
90
|
|
|
37
91
|
const barRect = bar.getBoundingClientRect();
|
|
@@ -53,49 +107,143 @@ export default function TabBar({ tabs, active, onChange, capitalize = false, pad
|
|
|
53
107
|
|
|
54
108
|
if (variant === 'pill') {
|
|
55
109
|
return (
|
|
56
|
-
<div
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
110
|
+
<div
|
|
111
|
+
ref={barRef}
|
|
112
|
+
style={{
|
|
113
|
+
display: 'inline-flex',
|
|
114
|
+
gap: 4,
|
|
115
|
+
background: 'var(--grey-1, #f5f5f8)',
|
|
116
|
+
borderRadius: 'var(--radxs, 6px)',
|
|
117
|
+
padding: '3px',
|
|
118
|
+
border: '1px solid var(--border-light, #ebebf0)',
|
|
119
|
+
position: 'relative',
|
|
120
|
+
alignItems: 'center',
|
|
121
|
+
flexWrap: 'wrap',
|
|
122
|
+
}}
|
|
123
|
+
>
|
|
63
124
|
{tabs.map(t => {
|
|
64
|
-
const
|
|
125
|
+
const hasItems = Array.isArray(t.items) && t.items.length > 0;
|
|
126
|
+
const activeSubItem = hasItems ? t.items.find(item => item.id === active) : null;
|
|
127
|
+
const isActive = active === t.id || !!activeSubItem;
|
|
128
|
+
const isOpen = openDropdownId === t.id;
|
|
129
|
+
|
|
130
|
+
const handleTabClick = () => {
|
|
131
|
+
if (hasItems) {
|
|
132
|
+
setOpenDropdownId(isOpen ? null : t.id);
|
|
133
|
+
} else {
|
|
134
|
+
setOpenDropdownId(null);
|
|
135
|
+
onChange(t.id);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
65
139
|
return (
|
|
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
|
-
|
|
140
|
+
<div key={t.id} style={{ position: 'relative' }}>
|
|
141
|
+
<button
|
|
142
|
+
type="button"
|
|
143
|
+
data-tabid={t.id}
|
|
144
|
+
data-active={isActive}
|
|
145
|
+
onClick={handleTabClick}
|
|
146
|
+
style={{
|
|
147
|
+
display: 'flex', alignItems: 'center', gap: 5,
|
|
148
|
+
height: 26,
|
|
149
|
+
padding: padding || '0 10px',
|
|
150
|
+
border: 'none',
|
|
151
|
+
borderRadius: 'var(--radxs, 6px)',
|
|
152
|
+
background: isActive ? 'var(--surface,#fff)' : isOpen ? 'var(--grey-2, #e5e7eb)' : 'transparent',
|
|
153
|
+
boxShadow: isActive ? 'var(--shadow, 0 1px 3px rgba(0,0,0,.08))' : 'none',
|
|
154
|
+
fontSize: '.75rem', fontWeight: isActive ? 600 : 500,
|
|
155
|
+
color: isActive ? 'var(--primary-text, #0f111c)' : 'var(--muted, #9b9daa)',
|
|
156
|
+
cursor: 'pointer',
|
|
157
|
+
transition: 'all .18s ease',
|
|
158
|
+
fontFamily: 'inherit',
|
|
159
|
+
whiteSpace: 'nowrap',
|
|
160
|
+
textTransform: capitalize ? 'capitalize' : 'none',
|
|
161
|
+
}}
|
|
162
|
+
>
|
|
163
|
+
{t.icon}{t.label}
|
|
164
|
+
{activeSubItem && (
|
|
165
|
+
<span style={{
|
|
166
|
+
fontSize: '.68rem',
|
|
167
|
+
fontWeight: 600,
|
|
168
|
+
color: 'var(--accent, #3b82f6)',
|
|
169
|
+
background: 'var(--accent-bg, rgba(59,130,246,0.12))',
|
|
170
|
+
padding: '1px 6px',
|
|
171
|
+
borderRadius: 4,
|
|
172
|
+
marginLeft: 2,
|
|
173
|
+
}}>
|
|
174
|
+
{activeSubItem.label}
|
|
175
|
+
</span>
|
|
176
|
+
)}
|
|
177
|
+
{hasItems && <ChevronIcon isOpen={isOpen} />}
|
|
178
|
+
{t.count != null && t.count > 0 && (
|
|
179
|
+
<span style={{
|
|
180
|
+
background: isActive ? 'var(--accent-bg)' : 'var(--grey-2, #d7d8e0)',
|
|
181
|
+
color: isActive ? 'var(--accent)' : 'var(--muted)',
|
|
182
|
+
borderRadius: 10,
|
|
183
|
+
padding: '1px 6px',
|
|
184
|
+
fontSize: '.68rem',
|
|
185
|
+
fontWeight: 600,
|
|
186
|
+
}}>{t.count}</span>
|
|
187
|
+
)}
|
|
188
|
+
</button>
|
|
189
|
+
|
|
190
|
+
{/* Dropdown Menu for Pill Tab */}
|
|
191
|
+
{isOpen && hasItems && (
|
|
192
|
+
<div style={{
|
|
193
|
+
position: 'absolute',
|
|
194
|
+
top: 'calc(100% + 4px)',
|
|
195
|
+
left: 0,
|
|
196
|
+
zIndex: 9999,
|
|
197
|
+
minWidth: 185,
|
|
198
|
+
background: 'var(--surface, #fff)',
|
|
199
|
+
border: '1px solid var(--border-light, #ebebf0)',
|
|
200
|
+
borderRadius: 'var(--radxs, 6px)',
|
|
201
|
+
boxShadow: '0 8px 24px rgba(0,0,0,0.12)',
|
|
202
|
+
padding: '4px',
|
|
203
|
+
display: 'flex',
|
|
204
|
+
flexDirection: 'column',
|
|
205
|
+
gap: 2,
|
|
206
|
+
}}>
|
|
207
|
+
{t.items.map(subItem => {
|
|
208
|
+
const isSubSelected = active === subItem.id;
|
|
209
|
+
return (
|
|
210
|
+
<button
|
|
211
|
+
key={subItem.id}
|
|
212
|
+
type="button"
|
|
213
|
+
onClick={() => {
|
|
214
|
+
onChange(subItem.id);
|
|
215
|
+
setOpenDropdownId(null);
|
|
216
|
+
}}
|
|
217
|
+
style={{
|
|
218
|
+
display: 'flex',
|
|
219
|
+
alignItems: 'center',
|
|
220
|
+
justifyContent: 'space-between',
|
|
221
|
+
padding: '6px 10px',
|
|
222
|
+
fontSize: '.75rem',
|
|
223
|
+
fontWeight: isSubSelected ? 600 : 400,
|
|
224
|
+
color: isSubSelected ? 'var(--accent, #3b82f6)' : 'var(--primary-text, #0f111c)',
|
|
225
|
+
background: isSubSelected ? 'var(--accent-bg, rgba(59,130,246,0.08))' : 'transparent',
|
|
226
|
+
borderRadius: 4,
|
|
227
|
+
border: 'none',
|
|
228
|
+
cursor: 'pointer',
|
|
229
|
+
textAlign: 'left',
|
|
230
|
+
transition: 'background .15s',
|
|
231
|
+
}}
|
|
232
|
+
onMouseEnter={(e) => {
|
|
233
|
+
if (!isSubSelected) e.currentTarget.style.background = 'var(--grey-1, #f5f5f8)';
|
|
234
|
+
}}
|
|
235
|
+
onMouseLeave={(e) => {
|
|
236
|
+
if (!isSubSelected) e.currentTarget.style.background = 'transparent';
|
|
237
|
+
}}
|
|
238
|
+
>
|
|
239
|
+
<span>{subItem.label}</span>
|
|
240
|
+
{isSubSelected && <CheckIcon />}
|
|
241
|
+
</button>
|
|
242
|
+
);
|
|
243
|
+
})}
|
|
244
|
+
</div>
|
|
97
245
|
)}
|
|
98
|
-
</
|
|
246
|
+
</div>
|
|
99
247
|
);
|
|
100
248
|
})}
|
|
101
249
|
</div>
|
|
@@ -106,7 +254,7 @@ export default function TabBar({ tabs, active, onChange, capitalize = false, pad
|
|
|
106
254
|
const defaultPadding = padding || '10px 16px';
|
|
107
255
|
|
|
108
256
|
return (
|
|
109
|
-
<div ref={barRef} style={{ display:'flex', position:'relative' }}>
|
|
257
|
+
<div ref={barRef} style={{ display:'flex', position:'relative', alignItems: 'center' }}>
|
|
110
258
|
<div ref={indRef} style={{
|
|
111
259
|
position:'absolute', bottom:'-1px', left:0,
|
|
112
260
|
height:2, width:0,
|
|
@@ -117,39 +265,125 @@ export default function TabBar({ tabs, active, onChange, capitalize = false, pad
|
|
|
117
265
|
}} />
|
|
118
266
|
|
|
119
267
|
{tabs.map(t => {
|
|
120
|
-
const
|
|
268
|
+
const hasItems = Array.isArray(t.items) && t.items.length > 0;
|
|
269
|
+
const activeSubItem = hasItems ? t.items.find(item => item.id === active) : null;
|
|
270
|
+
const isActive = active === t.id || !!activeSubItem;
|
|
271
|
+
const isOpen = openDropdownId === t.id;
|
|
272
|
+
|
|
273
|
+
const handleTabClick = () => {
|
|
274
|
+
if (hasItems) {
|
|
275
|
+
setOpenDropdownId(isOpen ? null : t.id);
|
|
276
|
+
} else {
|
|
277
|
+
setOpenDropdownId(null);
|
|
278
|
+
onChange(t.id);
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
|
|
121
282
|
return (
|
|
122
|
-
<
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
283
|
+
<div key={t.id} style={{ position: 'relative' }}>
|
|
284
|
+
<button
|
|
285
|
+
type="button"
|
|
286
|
+
data-tabid={t.id}
|
|
287
|
+
data-active={isActive}
|
|
288
|
+
onClick={handleTabClick}
|
|
289
|
+
style={{
|
|
290
|
+
display:'flex', alignItems:'center', gap:6,
|
|
291
|
+
padding: defaultPadding,
|
|
292
|
+
border:'none', background:'none',
|
|
293
|
+
fontSize:'.82rem', fontWeight:500,
|
|
294
|
+
color: isActive ? 'var(--accent)' : 'var(--muted)',
|
|
295
|
+
cursor:'pointer',
|
|
296
|
+
transition:'color .18s',
|
|
297
|
+
marginBottom:'-1px',
|
|
298
|
+
position:'relative', zIndex:1,
|
|
299
|
+
fontFamily:'inherit',
|
|
300
|
+
whiteSpace:'nowrap',
|
|
301
|
+
textTransform: capitalize ? 'capitalize' : 'none',
|
|
302
|
+
}}
|
|
303
|
+
>
|
|
304
|
+
{t.icon}{t.label}
|
|
305
|
+
{activeSubItem && (
|
|
306
|
+
<span style={{
|
|
307
|
+
fontSize: '.68rem',
|
|
308
|
+
fontWeight: 600,
|
|
309
|
+
color: 'var(--accent, #3b82f6)',
|
|
310
|
+
background: 'var(--accent-bg, rgba(59,130,246,0.12))',
|
|
311
|
+
padding: '1px 6px',
|
|
312
|
+
borderRadius: 4,
|
|
313
|
+
}}>
|
|
314
|
+
{activeSubItem.label}
|
|
315
|
+
</span>
|
|
316
|
+
)}
|
|
317
|
+
{hasItems && <ChevronIcon isOpen={isOpen} />}
|
|
318
|
+
{t.count != null && t.count > 0 && (
|
|
319
|
+
<span style={{
|
|
320
|
+
background: isActive ? 'var(--accent-bg)' : 'var(--grey-1)',
|
|
321
|
+
color: isActive ? 'var(--accent)' : 'var(--muted)',
|
|
322
|
+
borderRadius: 10,
|
|
323
|
+
padding: '1px 6px',
|
|
324
|
+
fontSize: '.68rem',
|
|
325
|
+
transition: 'background .18s, color .18s',
|
|
326
|
+
}}>{t.count}</span>
|
|
327
|
+
)}
|
|
328
|
+
</button>
|
|
329
|
+
|
|
330
|
+
{/* Dropdown Menu for Underline Tab */}
|
|
331
|
+
{isOpen && hasItems && (
|
|
332
|
+
<div style={{
|
|
333
|
+
position: 'absolute',
|
|
334
|
+
top: 'calc(100% + 2px)',
|
|
335
|
+
left: 0,
|
|
336
|
+
zIndex: 9999,
|
|
337
|
+
minWidth: 190,
|
|
338
|
+
background: 'var(--surface, #fff)',
|
|
339
|
+
border: '1px solid var(--border-light, #ebebf0)',
|
|
340
|
+
borderRadius: 'var(--radxs, 6px)',
|
|
341
|
+
boxShadow: '0 6px 20px rgba(0,0,0,0.12)',
|
|
342
|
+
padding: '4px',
|
|
343
|
+
display: 'flex',
|
|
344
|
+
flexDirection: 'column',
|
|
345
|
+
gap: 2,
|
|
346
|
+
}}>
|
|
347
|
+
{t.items.map(subItem => {
|
|
348
|
+
const isSubSelected = active === subItem.id;
|
|
349
|
+
return (
|
|
350
|
+
<button
|
|
351
|
+
key={subItem.id}
|
|
352
|
+
type="button"
|
|
353
|
+
onClick={() => {
|
|
354
|
+
onChange(subItem.id);
|
|
355
|
+
setOpenDropdownId(null);
|
|
356
|
+
}}
|
|
357
|
+
style={{
|
|
358
|
+
display: 'flex',
|
|
359
|
+
alignItems: 'center',
|
|
360
|
+
justify: 'space-between',
|
|
361
|
+
padding: '6px 10px',
|
|
362
|
+
fontSize: '.78rem',
|
|
363
|
+
fontWeight: isSubSelected ? 600 : 400,
|
|
364
|
+
color: isSubSelected ? 'var(--accent, #3b82f6)' : 'var(--primary-text, #0f111c)',
|
|
365
|
+
background: isSubSelected ? 'var(--accent-bg, rgba(59,130,246,0.08))' : 'transparent',
|
|
366
|
+
borderRadius: 4,
|
|
367
|
+
border: 'none',
|
|
368
|
+
cursor: 'pointer',
|
|
369
|
+
textAlign: 'left',
|
|
370
|
+
transition: 'background .15s',
|
|
371
|
+
}}
|
|
372
|
+
onMouseEnter={(e) => {
|
|
373
|
+
if (!isSubSelected) e.currentTarget.style.background = 'var(--grey-1, #f5f5f8)';
|
|
374
|
+
}}
|
|
375
|
+
onMouseLeave={(e) => {
|
|
376
|
+
if (!isSubSelected) e.currentTarget.style.background = 'transparent';
|
|
377
|
+
}}
|
|
378
|
+
>
|
|
379
|
+
<span>{subItem.label}</span>
|
|
380
|
+
{isSubSelected && <CheckIcon />}
|
|
381
|
+
</button>
|
|
382
|
+
);
|
|
383
|
+
})}
|
|
384
|
+
</div>
|
|
151
385
|
)}
|
|
152
|
-
</
|
|
386
|
+
</div>
|
|
153
387
|
);
|
|
154
388
|
})}
|
|
155
389
|
</div>
|
package/index.js
CHANGED
|
@@ -38,9 +38,11 @@ import { XTable as _XTable, XThead as _XThead, XTbody as _XTbody, XTr as _XTr, X
|
|
|
38
38
|
import { PageShell as _PageShell, TableCard as _TableCard, TableCardFilters as _TableCardFilters, TableCardBody as _TableCardBody, TableCardFooter as _TableCardFooter, CardHdr as _CardHdr, StatCard as _StatCard, StatCardSkeleton as _StatCardSkeleton } from './components/Card.jsx';
|
|
39
39
|
|
|
40
40
|
import { default as _FilePicker } from './components/FilePicker.jsx';
|
|
41
|
+
import { default as _Divider } from './components/Divider.jsx';
|
|
41
42
|
|
|
42
43
|
export const Button = _Button;
|
|
43
44
|
export const FilePicker = _FilePicker;
|
|
45
|
+
export const Divider = _Divider;
|
|
44
46
|
export const Input = _Input;
|
|
45
47
|
export const Toggle = _Toggle;
|
|
46
48
|
export const Spinner = _Spinner || _SpinnerNamed;
|