tab_bar.ts

  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}