projectPanel.ts

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