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 defaultEntry,
120 draggedEntry: entry({
121 default: {
122 text: text(layer, "mono", "on", { size: "sm" }),
123 background: withOpacity(background(layer, "on"), 0.9),
124 border: border(layer),
125 }
126 }),
127 ignoredEntry: entry({
128 default: {
129 text: text(layer, "mono", "disabled"),
130 },
131 }, {
132 default: {
133 iconColor: foreground(layer, "variant"),
134 }
135 }),
136 cutEntry: entry({
137 default: {
138 text: text(layer, "mono", "disabled"),
139 },
140 }, {
141 default: {
142 background: background(layer, "active"),
143 text: text(layer, "mono", "disabled", { size: "sm" }),
144 }
145 }),
146 filenameEditor: {
147 background: background(layer, "on"),
148 text: text(layer, "mono", "on", { size: "sm" }),
149 selection: colorScheme.players[0],
150 },
151 }
152}