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