tabs.jsx
2.21 KB
1
2
3
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
// Top-bar tab strip — IDE-style, multi-tab open/close/switch.
const TabStrip = ({ tabs, activeTabId, onSelect, onClose }) => {
return (
<div style={{
display: "flex", alignItems: "stretch", height: 30,
background: "var(--bg-tab-strip)",
borderBottom: "1px solid var(--border)",
paddingLeft: 8, gap: 0,
overflow: "hidden",
}}>
{tabs.map((t) => {
const active = t.id === activeTabId;
return <Tab key={t.id} tab={t} active={active} onSelect={onSelect} onClose={onClose} />;
})}
</div>
);
};
const Tab = ({ tab, active, onSelect, onClose }) => {
const [hover, setHover] = React.useState(false);
return (
<div
onClick={() => onSelect(tab.id)}
onMouseEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}
style={{
position: "relative",
display: "flex", alignItems: "center", gap: 6,
height: "100%", padding: "0 12px",
background: active ? "var(--bg-tab-active)" : hover ? "rgba(255,255,255,0.5)" : "transparent",
borderTop: active ? "2px solid var(--accent)" : "2px solid transparent",
borderLeft: "1px solid var(--border)",
borderRight: "1px solid var(--border)",
marginRight: -1,
cursor: "pointer", fontSize: 12,
color: active ? "var(--text)" : "var(--text-muted)",
fontWeight: active ? 500 : 400,
whiteSpace: "nowrap",
}}
>
<span>{tab.label}</span>
{tab.closable !== false ? (
<span
onClick={(e) => { e.stopPropagation(); onClose(tab.id); }}
style={{
display: "inline-flex", alignItems: "center", justifyContent: "center",
width: 14, height: 14, color: "var(--text-faint)",
borderRadius: 2,
}}
onMouseEnter={(e) => {
e.currentTarget.style.background = "var(--danger)";
e.currentTarget.style.color = "#fff";
}}
onMouseLeave={(e) => {
e.currentTarget.style.background = "transparent";
e.currentTarget.style.color = "var(--text-faint)";
}}
>
<Ic.close size={10} />
</span>
) : null}
</div>
);
};
window.TabStrip = TabStrip;