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 height = 32
 10
 11    const active_layer = theme.highest
 12    const layer = theme.middle
 13
 14    const tab = {
 15        height,
 16        text: text(layer, "sans", "variant", { size: "sm" }),
 17        background: background(layer),
 18        border: border(layer, {
 19            right: true,
 20            bottom: true,
 21            overlay: true,
 22        }),
 23        padding: {
 24            left: 8,
 25            right: 12,
 26        },
 27        spacing: 8,
 28
 29        // Tab type icons (e.g. Project Search)
 30        type_icon_width: 14,
 31
 32        // Close icons
 33        close_icon_width: 8,
 34        icon_close: foreground(layer, "variant"),
 35        icon_close_active: foreground(layer, "hovered"),
 36
 37        // Indicators
 38        icon_conflict: foreground(layer, "warning"),
 39        icon_dirty: foreground(layer, "accent"),
 40
 41        // When two tabs of the same name are open, a label appears next to them
 42        description: {
 43            margin: { left: 8 },
 44            ...text(layer, "sans", "disabled", { size: "2xs" }),
 45        },
 46    }
 47
 48    const active_pane_active_tab = {
 49        ...tab,
 50        background: background(active_layer),
 51        text: text(active_layer, "sans", "active", { size: "sm" }),
 52        border: {
 53            ...tab.border,
 54            bottom: false,
 55        },
 56    }
 57
 58    const inactive_pane_inactive_tab = {
 59        ...tab,
 60        background: background(layer),
 61        text: text(layer, "sans", "variant", { size: "sm" }),
 62    }
 63
 64    const inactive_pane_active_tab = {
 65        ...tab,
 66        background: background(active_layer),
 67        text: text(layer, "sans", "variant", { size: "sm" }),
 68        border: {
 69            ...tab.border,
 70            bottom: false,
 71        },
 72    }
 73
 74    const dragged_tab = {
 75        ...active_pane_active_tab,
 76        background: with_opacity(tab.background, 0.9),
 77        border: undefined as any,
 78        shadow: theme.popover_shadow,
 79    }
 80
 81    return {
 82        height,
 83        background: background(layer),
 84        active_pane: {
 85            active_tab: active_pane_active_tab,
 86            inactive_tab: tab,
 87        },
 88        inactive_pane: {
 89            active_tab: inactive_pane_active_tab,
 90            inactive_tab: inactive_pane_inactive_tab,
 91        },
 92        dragged_tab,
 93        pane_button: toggleable({
 94            base: interactive({
 95                base: {
 96                    color: foreground(layer, "variant"),
 97                    icon_width: 12,
 98                    button_width: active_pane_active_tab.height,
 99                },
100                state: {
101                    hovered: {
102                        color: foreground(layer, "hovered"),
103                    },
104                    clicked: {
105                        color: foreground(layer, "pressed"),
106                    },
107                },
108            }),
109            state: {
110                active: {
111                    default: {
112                        color: foreground(layer, "accent"),
113                    },
114                    hovered: {
115                        color: foreground(layer, "hovered"),
116                    },
117                    clicked: {
118                        color: foreground(layer, "pressed"),
119                    },
120                },
121            },
122        }),
123        pane_button_container: {
124            background: tab.background,
125            border: {
126                ...tab.border,
127                right: false,
128            },
129        },
130    }
131}