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}