project_panel.ts

  1import { ColorScheme } from "../theme/color_scheme"
  2import { with_opacity } from "../theme/color"
  3import {
  4    Border,
  5    TextStyle,
  6    background,
  7    border,
  8    foreground,
  9    text,
 10} from "./components"
 11import { interactive, toggleable } from "../element"
 12import merge from "ts-deepmerge"
 13export default function project_panel(theme: ColorScheme): any {
 14    const { is_light } = theme
 15
 16    type EntryStateProps = {
 17        background?: string
 18        border?: Border
 19        text?: TextStyle
 20        icon_color?: string
 21    }
 22
 23    type EntryState = {
 24        default: EntryStateProps
 25        hovered?: EntryStateProps
 26        clicked?: EntryStateProps
 27    }
 28
 29    const entry = (unselected?: EntryState, selected?: EntryState) => {
 30        const git_status = {
 31            git: {
 32                modified: is_light
 33                    ? theme.ramps.yellow(0.6).hex()
 34                    : theme.ramps.yellow(0.5).hex(),
 35                inserted: is_light
 36                    ? theme.ramps.green(0.45).hex()
 37                    : theme.ramps.green(0.5).hex(),
 38                conflict: is_light
 39                    ? theme.ramps.red(0.6).hex()
 40                    : theme.ramps.red(0.5).hex(),
 41            },
 42        }
 43
 44        const base_properties = {
 45            height: 22,
 46            background: background(theme.middle),
 47            icon_color: foreground(theme.middle, "variant"),
 48            icon_size: 7,
 49            icon_spacing: 5,
 50            text: text(theme.middle, "sans", "variant", { size: "sm" }),
 51            status: {
 52                ...git_status,
 53            },
 54        }
 55
 56        const selected_style: EntryState | undefined = selected
 57            ? selected
 58            : unselected
 59
 60        const unselected_default_style = merge(
 61            base_properties,
 62            unselected?.default ?? {},
 63            {}
 64        )
 65        const unselected_hovered_style = merge(
 66            base_properties,
 67            { background: background(theme.middle, "hovered") },
 68            unselected?.hovered ?? {},
 69        )
 70        const unselected_clicked_style = merge(
 71            base_properties,
 72            { background: background(theme.middle, "pressed"), }
 73            ,
 74            unselected?.clicked ?? {},
 75        )
 76        const selected_default_style = merge(
 77            base_properties,
 78            {
 79                background: background(theme.lowest),
 80                text: text(theme.lowest, "sans", { size: "sm" }),
 81            },
 82            selected_style?.default ?? {},
 83
 84        )
 85        const selected_hovered_style = merge(
 86            base_properties,
 87            {
 88                background: background(theme.lowest, "hovered"),
 89                text: text(theme.lowest, "sans", { size: "sm" }),
 90
 91            },
 92            selected_style?.hovered ?? {},
 93
 94        )
 95        const selected_clicked_style = merge(
 96            base_properties,
 97            {
 98                background: background(theme.lowest, "pressed"),
 99                text: text(theme.lowest, "sans", { size: "sm" }),
100            },
101            selected_style?.clicked ?? {},
102
103        )
104
105        return toggleable({
106            state: {
107                inactive: interactive({
108                    state: {
109                        default: unselected_default_style,
110                        hovered: unselected_hovered_style,
111                        clicked: unselected_clicked_style,
112                    },
113                }),
114                active: interactive({
115                    state: {
116                        default: selected_default_style,
117                        hovered: selected_hovered_style,
118                        clicked: selected_clicked_style,
119                    },
120                }),
121            },
122        })
123    }
124
125    const default_entry = entry()
126
127    return {
128        open_project_button: interactive({
129            base: {
130                background: background(theme.middle),
131                border: border(theme.middle, "active"),
132                corner_radius: 4,
133                margin: {
134                    top: 16,
135                    left: 16,
136                    right: 16,
137                },
138                padding: {
139                    top: 3,
140                    bottom: 3,
141                    left: 7,
142                    right: 7,
143                },
144                ...text(theme.middle, "sans", "default", { size: "sm" }),
145            },
146            state: {
147                hovered: {
148                    ...text(theme.middle, "sans", "default", { size: "sm" }),
149                    background: background(theme.middle, "hovered"),
150                    border: border(theme.middle, "active"),
151                },
152                clicked: {
153                    ...text(theme.middle, "sans", "default", { size: "sm" }),
154                    background: background(theme.middle, "pressed"),
155                    border: border(theme.middle, "active"),
156                },
157            },
158        }),
159        background: background(theme.middle),
160        padding: { left: 6, right: 6, top: 0, bottom: 6 },
161        indent_width: 12,
162        entry: default_entry,
163        dragged_entry: {
164            ...default_entry.inactive.default,
165            text: text(theme.middle, "sans", "on", { size: "sm" }),
166            background: with_opacity(background(theme.middle, "on"), 0.9),
167            border: border(theme.middle),
168        },
169        ignored_entry: entry(
170            {
171                default: {
172                    text: text(theme.middle, "sans", "disabled"),
173                },
174            },
175            {
176                default: {
177                    icon_color: foreground(theme.middle, "variant"),
178                },
179            }
180        ),
181        cut_entry: entry(
182            {
183                default: {
184                    text: text(theme.middle, "sans", "disabled"),
185                },
186            },
187            {
188                default: {
189                    background: background(theme.middle, "active"),
190                    text: text(theme.middle, "sans", "disabled", {
191                        size: "sm",
192                    }),
193                },
194            }
195        ),
196        filename_editor: {
197            background: background(theme.middle, "on"),
198            text: text(theme.middle, "sans", "on", { size: "sm" }),
199            selection: theme.players[0],
200        },
201    }
202}