tab_bar.ts

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