1import { ColorScheme } from "../theme/colorScheme"
2import { withOpacity } from "../theme/color"
3import { toggleable } from "../element"
4import {
5 background,
6 border,
7 borderColor,
8 foreground,
9 svg,
10 text,
11} from "./components"
12import statusBar from "./statusBar"
13import tabBar from "./tabBar"
14import { interactive } from "../element"
15import merge from "ts-deepmerge"
16export default function workspace(colorScheme: ColorScheme) {
17 const layer = colorScheme.lowest
18 const isLight = colorScheme.isLight
19 const itemSpacing = 8
20 const titlebarButton = toggleable({
21 base:
22 interactive({
23 base: {
24 cornerRadius: 6,
25 padding: {
26 top: 1,
27 bottom: 1,
28 left: 8,
29 right: 8,
30 },
31 ...text(layer, "sans", "variant", { size: "xs" }),
32 background: background(layer, "variant"),
33 border: border(layer),
34 },
35 state: {
36 hovered: {
37 ...text(layer, "sans", "variant", "hovered", {
38 size: "xs",
39 }),
40 background: background(layer, "variant", "hovered"),
41 border: border(layer, "variant", "hovered"),
42 },
43 clicked: {
44 ...text(layer, "sans", "variant", "pressed", {
45 size: "xs",
46 }),
47 background: background(layer, "variant", "pressed"),
48 border: border(layer, "variant", "pressed"),
49 },
50 },
51 }),
52 state: {
53 active: {
54 default: {
55 ...text(layer, "sans", "variant", "active", { size: "xs" }),
56 background: background(layer, "variant", "active"),
57 border: border(layer, "variant", "active"),
58 },
59 }
60 }
61 }
62 )
63 const avatarWidth = 18
64 const avatarOuterWidth = avatarWidth + 4
65 const followerAvatarWidth = 14
66 const followerAvatarOuterWidth = followerAvatarWidth + 4
67
68 return {
69 background: background(colorScheme.lowest),
70 blankPane: {
71 logoContainer: {
72 width: 256,
73 height: 256,
74 },
75 logo: svg(
76 withOpacity("#000000", colorScheme.isLight ? 0.6 : 0.8),
77 "icons/logo_96.svg",
78 256,
79 256
80 ),
81
82 logoShadow: svg(
83 withOpacity(
84 colorScheme.isLight
85 ? "#FFFFFF"
86 : colorScheme.lowest.base.default.background,
87 colorScheme.isLight ? 1 : 0.6
88 ),
89 "icons/logo_96.svg",
90 256,
91 256
92 ),
93 keyboardHints: {
94 margin: {
95 top: 96,
96 },
97 cornerRadius: 4,
98 },
99 keyboardHint: interactive({
100 base: {
101 ...text(layer, "sans", "variant", { size: "sm" }),
102 padding: {
103 top: 3,
104 left: 8,
105 right: 8,
106 bottom: 3,
107 },
108 cornerRadius: 8,
109 },
110 state: {
111 hovered: {
112 ...text(layer, "sans", "active", { size: "sm" }),
113 },
114 },
115 }),
116
117 keyboardHintWidth: 320,
118 },
119 joiningProjectAvatar: {
120 cornerRadius: 40,
121 width: 80,
122 },
123 joiningProjectMessage: {
124 padding: 12,
125 ...text(layer, "sans", { size: "lg" }),
126 },
127 externalLocationMessage: {
128 background: background(colorScheme.middle, "accent"),
129 border: border(colorScheme.middle, "accent"),
130 cornerRadius: 6,
131 padding: 12,
132 margin: { bottom: 8, right: 8 },
133 ...text(colorScheme.middle, "sans", "accent", { size: "xs" }),
134 },
135 leaderBorderOpacity: 0.7,
136 leaderBorderWidth: 2.0,
137 tabBar: tabBar(colorScheme),
138 modal: {
139 margin: {
140 bottom: 52,
141 top: 52,
142 },
143 cursor: "Arrow",
144 },
145 zoomedBackground: {
146 cursor: "Arrow",
147 background: isLight
148 ? withOpacity(background(colorScheme.lowest), 0.8)
149 : withOpacity(background(colorScheme.highest), 0.6),
150 },
151 zoomedPaneForeground: {
152 margin: 16,
153 shadow: colorScheme.modalShadow,
154 border: border(colorScheme.lowest, { overlay: true }),
155 },
156 zoomedPanelForeground: {
157 margin: 16,
158 border: border(colorScheme.lowest, { overlay: true }),
159 },
160 dock: {
161 left: {
162 border: border(layer, { right: true }),
163 },
164 bottom: {
165 border: border(layer, { top: true }),
166 },
167 right: {
168 border: border(layer, { left: true }),
169 },
170 },
171 paneDivider: {
172 color: borderColor(layer),
173 width: 1,
174 },
175 statusBar: statusBar(colorScheme),
176 titlebar: {
177 itemSpacing,
178 facePileSpacing: 2,
179 height: 33, // 32px + 1px border. It's important the content area of the titlebar is evenly sized to vertically center avatar images.
180 background: background(layer),
181 border: border(layer, { bottom: true }),
182 padding: {
183 left: 80,
184 right: itemSpacing,
185 },
186
187 // Project
188 title: text(layer, "sans", "variant"),
189 highlight_color: text(layer, "sans", "active").color,
190
191 // Collaborators
192 leaderAvatar: {
193 width: avatarWidth,
194 outerWidth: avatarOuterWidth,
195 cornerRadius: avatarWidth / 2,
196 outerCornerRadius: avatarOuterWidth / 2,
197 },
198 followerAvatar: {
199 width: followerAvatarWidth,
200 outerWidth: followerAvatarOuterWidth,
201 cornerRadius: followerAvatarWidth / 2,
202 outerCornerRadius: followerAvatarOuterWidth / 2,
203 },
204 inactiveAvatarGrayscale: true,
205 followerAvatarOverlap: 8,
206 leaderSelection: {
207 margin: {
208 top: 4,
209 bottom: 4,
210 },
211 padding: {
212 left: 2,
213 right: 2,
214 top: 2,
215 bottom: 2,
216 },
217 cornerRadius: 6,
218 },
219 avatarRibbon: {
220 height: 3,
221 width: 12,
222 // TODO: Chore: Make avatarRibbon colors driven by the theme rather than being hard coded.
223 },
224
225 // Sign in buttom
226 // FlatButton, Variant
227 signInPrompt: merge(titlebarButton, {
228 inactive: {
229 default: {
230 margin: {
231 left: itemSpacing,
232 },
233 },
234 },
235 }),
236
237 // Offline Indicator
238 offlineIcon: {
239 color: foreground(layer, "variant"),
240 width: 16,
241 margin: {
242 left: itemSpacing,
243 },
244 padding: {
245 right: 4,
246 },
247 },
248
249 // Notice that the collaboration server is out of date
250 outdatedWarning: {
251 ...text(layer, "sans", "warning", { size: "xs" }),
252 background: withOpacity(background(layer, "warning"), 0.3),
253 border: border(layer, "warning"),
254 margin: {
255 left: itemSpacing,
256 },
257 padding: {
258 left: 8,
259 right: 8,
260 },
261 cornerRadius: 6,
262 },
263 callControl: interactive({
264 base: {
265 cornerRadius: 6,
266 color: foreground(layer, "variant"),
267 iconWidth: 12,
268 buttonWidth: 20,
269 },
270 state: {
271 hovered: {
272 background: background(layer, "variant", "hovered"),
273 color: foreground(layer, "variant", "hovered"),
274 },
275 },
276 }),
277 toggleContactsButton: toggleable({
278 base:
279 interactive({
280 base: {
281 margin: { left: itemSpacing },
282 cornerRadius: 6,
283 color: foreground(layer, "variant"),
284 iconWidth: 14,
285 buttonWidth: 20,
286 },
287 state: {
288 clicked: {
289 background: background(layer, "variant", "pressed"),
290 color: foreground(layer, "variant", "pressed"),
291 },
292 hovered: {
293 background: background(layer, "variant", "hovered"),
294 color: foreground(layer, "variant", "hovered"),
295 },
296 },
297 }), state:
298 {
299 active: {
300 default: {
301 background: background(layer, "variant", "active"),
302 color: foreground(layer, "variant", "active"),
303 },
304 }
305 }
306 }
307 ),
308 userMenuButton: merge(titlebarButton, {
309 inactive: {
310 default: {
311 buttonWidth: 20,
312 iconWidth: 12,
313 },
314 },
315 active: {
316 // posiewic: these properties are not currently set on main
317 default: {
318 iconWidth: 12,
319 button_width: 20,
320 },
321 },
322 }),
323
324 toggleContactsBadge: {
325 cornerRadius: 3,
326 padding: 2,
327 margin: { top: 3, left: 3 },
328 border: border(layer),
329 background: foreground(layer, "accent"),
330 },
331 shareButton: {
332 ...titlebarButton,
333 },
334 },
335
336 toolbar: {
337 height: 34,
338 background: background(colorScheme.highest),
339 border: border(colorScheme.highest, { bottom: true }),
340 itemSpacing: 8,
341 navButton: interactive({
342 base: {
343 color: foreground(colorScheme.highest, "on"),
344 iconWidth: 12,
345 buttonWidth: 24,
346 cornerRadius: 6,
347 },
348 state: {
349 hovered: {
350 color: foreground(colorScheme.highest, "on", "hovered"),
351 background: background(
352 colorScheme.highest,
353 "on",
354 "hovered"
355 ),
356 },
357 disabled: {
358 color: foreground(
359 colorScheme.highest,
360 "on",
361 "disabled"
362 ),
363 },
364 },
365 }),
366 padding: { left: 8, right: 8, top: 4, bottom: 4 },
367 },
368 breadcrumbHeight: 24,
369 breadcrumbs: interactive({
370 base: {
371 ...text(colorScheme.highest, "sans", "variant"),
372 cornerRadius: 6,
373 padding: {
374 left: 6,
375 right: 6,
376 },
377 },
378 state: {
379 hovered: {
380 color: foreground(colorScheme.highest, "on", "hovered"),
381 background: background(
382 colorScheme.highest,
383 "on",
384 "hovered"
385 ),
386 },
387 },
388 }),
389 disconnectedOverlay: {
390 ...text(layer, "sans"),
391 background: withOpacity(background(layer), 0.8),
392 },
393 notification: {
394 margin: { top: 10 },
395 background: background(colorScheme.middle),
396 cornerRadius: 6,
397 padding: 12,
398 border: border(colorScheme.middle),
399 shadow: colorScheme.popoverShadow,
400 },
401 notifications: {
402 width: 400,
403 margin: { right: 10, bottom: 10 },
404 },
405 dropTargetOverlayColor: withOpacity(foreground(layer, "variant"), 0.5),
406 }
407}