1import { with_opacity } from "../theme/color"
2import { text, border, background, foreground } from "./components"
3import { interactive, toggleable } from "../element"
4import { useTheme } from "../common"
5
6export default function tab_bar(): any {
7 const theme = useTheme()
8
9 const { is_light } = theme
10
11 const height = 32
12
13 const active_layer = theme.highest
14 const layer = theme.middle
15
16 const tab = {
17 height,
18 text: text(layer, "sans", "variant", { size: "sm" }),
19 background: background(layer),
20 border: border(layer, {
21 right: true,
22 bottom: true,
23 overlay: true,
24 }),
25 padding: {
26 left: 8,
27 right: 12,
28 },
29 spacing: 8,
30
31 // Tab type icons (e.g. Project Search)
32 type_icon_width: 14,
33
34 // Close icons
35 close_icon_width: 14,
36 icon_close: foreground(layer, "variant"),
37 icon_close_active: foreground(layer, "hovered"),
38
39 // Indicators
40 icon_conflict: foreground(layer, "warning"),
41 icon_dirty: foreground(layer, "accent"),
42
43 git: {
44 modified: is_light
45 ? theme.ramps.yellow(0.6).hex()
46 : theme.ramps.yellow(0.5).hex(),
47 inserted: is_light
48 ? theme.ramps.green(0.45).hex()
49 : theme.ramps.green(0.5).hex(),
50 conflict: is_light
51 ? theme.ramps.red(0.6).hex()
52 : theme.ramps.red(0.5).hex(),
53 },
54
55 // When two tabs of the same name are open, a label appears next to them
56 description: {
57 margin: { left: 8 },
58 ...text(layer, "sans", "disabled", { size: "2xs" }),
59 },
60 }
61
62 const active_pane_active_tab = {
63 ...tab,
64 background: background(active_layer),
65 text: text(active_layer, "sans", "active", { size: "sm" }),
66 border: {
67 ...tab.border,
68 bottom: false,
69 },
70 }
71
72 const inactive_pane_inactive_tab = {
73 ...tab,
74 background: background(layer),
75 text: text(layer, "sans", "variant", { size: "sm" }),
76 }
77
78 const inactive_pane_active_tab = {
79 ...tab,
80 background: background(active_layer),
81 text: text(layer, "sans", "variant", { size: "sm" }),
82 border: {
83 ...tab.border,
84 bottom: false,
85 },
86 }
87 const nav_button = interactive({
88 base: {
89 color: foreground(theme.highest, "on"),
90 icon_width: 12,
91
92 button_width: active_pane_active_tab.height,
93 border: border(theme.lowest, "on", {
94 bottom: true,
95 overlay: true,
96 }),
97 },
98 state: {
99 hovered: {
100 color: foreground(theme.highest, "on", "hovered"),
101 background: background(theme.highest, "on", "hovered"),
102 },
103 disabled: {
104 color: foreground(theme.highest, "on", "disabled"),
105 },
106 },
107 })
108
109 const dragged_tab = {
110 ...active_pane_active_tab,
111 background: with_opacity(tab.background, 0.9),
112 border: undefined as any,
113 shadow: theme.popover_shadow,
114 }
115
116 return {
117 height,
118 background: background(layer),
119 active_pane: {
120 active_tab: active_pane_active_tab,
121 inactive_tab: tab,
122 },
123 inactive_pane: {
124 active_tab: inactive_pane_active_tab,
125 inactive_tab: inactive_pane_inactive_tab,
126 },
127 dragged_tab,
128 pane_button: toggleable({
129 base: interactive({
130 base: {
131 color: foreground(layer, "variant"),
132 icon_width: 12,
133 button_width: active_pane_active_tab.height,
134 },
135 state: {
136 hovered: {
137 color: foreground(layer, "hovered"),
138 },
139 clicked: {
140 color: foreground(layer, "pressed"),
141 },
142 },
143 }),
144 state: {
145 active: {
146 default: {
147 color: foreground(layer, "accent"),
148 },
149 hovered: {
150 color: foreground(layer, "hovered"),
151 },
152 clicked: {
153 color: foreground(layer, "pressed"),
154 },
155 },
156 },
157 }),
158 pane_button_container: {
159 background: tab.background,
160 border: {
161 ...tab.border,
162 right: false,
163 },
164 },
165 nav_button: nav_button,
166 }
167}