projectPanel.ts

  1import { ColorScheme } from "../theme/colorScheme"
  2import { withOpacity } from "../theme/color"
  3import { Border, TextStyle, background, border, foreground, text } from "./components"
  4import { interactive, toggleable } from "../element"
  5import merge from "ts-deepmerge"
  6export default function projectPanel(colorScheme: ColorScheme) {
  7    const { isLight } = colorScheme
  8
  9    let layer = colorScheme.middle
 10
 11    type EntryStateProps = {
 12        background?: string,
 13        border?: Border,
 14        text?: TextStyle,
 15        iconColor?: string,
 16    }
 17
 18    type EntryState = {
 19        default: EntryStateProps,
 20        hovered?: EntryStateProps,
 21        clicked?: EntryStateProps,
 22    }
 23
 24    const entry = (unselected?: EntryState, selected?: EntryState) => {
 25
 26        const git_status = {
 27            git: {
 28                modified: isLight
 29                    ? colorScheme.ramps.yellow(0.6).hex()
 30                    : colorScheme.ramps.yellow(0.5).hex(),
 31                inserted: isLight
 32                    ? colorScheme.ramps.green(0.45).hex()
 33                    : colorScheme.ramps.green(0.5).hex(),
 34                conflict: isLight
 35                    ? colorScheme.ramps.red(0.6).hex()
 36                    : colorScheme.ramps.red(0.5).hex(),
 37            },
 38        }
 39
 40        const base_properties = {
 41            height: 22,
 42            background: background(layer),
 43            iconColor: foreground(layer, "variant"),
 44            iconSize: 7,
 45            iconSpacing: 5,
 46            text: text(layer, "mono", "variant", { size: "sm" }),
 47            status: {
 48                ...git_status
 49            }
 50        }
 51
 52        const selectedStyle: EntryState | undefined = selected ? selected : unselected
 53
 54        const unselected_default_style = merge(base_properties, unselected?.default ?? {}, {})
 55        const unselected_hovered_style = merge(base_properties, unselected?.hovered ?? {}, { background: background(layer, "variant", "hovered") })
 56        const unselected_clicked_style = merge(base_properties, unselected?.clicked ?? {}, { background: background(layer, "variant", "pressed") })
 57        const selected_default_style = merge(base_properties, selectedStyle?.default ?? {}, { background: background(layer) })
 58        const selected_hovered_style = merge(base_properties, selectedStyle?.hovered ?? {}, { background: background(layer, "variant", "hovered") })
 59        const selected_clicked_style = merge(base_properties, selectedStyle?.clicked ?? {}, { background: background(layer, "variant", "pressed") })
 60
 61        return toggleable({
 62            state: {
 63                inactive: interactive({
 64                    state: {
 65                        default: unselected_default_style,
 66                        hovered: unselected_hovered_style,
 67                        clicked: unselected_clicked_style,
 68                    },
 69                }),
 70                active: interactive({
 71                    state: {
 72                        default: selected_default_style,
 73                        hovered: selected_hovered_style,
 74                        clicked: selected_clicked_style,
 75                    },
 76                }),
 77            }
 78        })
 79
 80    }
 81
 82    const defaultEntry = entry()
 83
 84    return {
 85        openProjectButton: interactive({
 86            base: {
 87                background: background(layer),
 88                border: border(layer, "active"),
 89                cornerRadius: 4,
 90                margin: {
 91                    top: 16,
 92                    left: 16,
 93                    right: 16,
 94                },
 95                padding: {
 96                    top: 3,
 97                    bottom: 3,
 98                    left: 7,
 99                    right: 7,
100                },
101                ...text(layer, "sans", "default", { size: "sm" }),
102            },
103            state: {
104                hovered: {
105                    ...text(layer, "sans", "default", { size: "sm" }),
106                    background: background(layer, "hovered"),
107                    border: border(layer, "active"),
108                },
109                clicked: {
110                    ...text(layer, "sans", "default", { size: "sm" }),
111                    background: background(layer, "pressed"),
112                    border: border(layer, "active"),
113                },
114            },
115        }),
116        background: background(layer),
117        padding: { left: 6, right: 6, top: 0, bottom: 6 },
118        indentWidth: 12,
119        entry: defaultEntry,
120        draggedEntry: {
121            ...defaultEntry.inactive.default,
122            text: text(layer, "mono", "on", { size: "sm" }),
123            background: withOpacity(background(layer, "on"), 0.9),
124            border: border(layer),
125        },
126        ignoredEntry: entry({
127            default: {
128                text: text(layer, "mono", "disabled"),
129            },
130        }, {
131            default: {
132                iconColor: foreground(layer, "variant"),
133            }
134        }),
135        cutEntry: entry({
136            default: {
137                text: text(layer, "mono", "disabled"),
138            },
139        }, {
140            default: {
141                background: background(layer, "active"),
142                text: text(layer, "mono", "disabled", { size: "sm" }),
143            }
144        }),
145        filenameEditor: {
146            background: background(layer, "on"),
147            text: text(layer, "mono", "on", { size: "sm" }),
148            selection: colorScheme.players[0],
149        },
150    }
151}