1import { color, fontWeights, NumberToken } from "../tokens";
2import { withOpacity } from "../utils/color";
3import Theme, { buildPlayer, Syntax } from "./theme";
4
5// Dark: 0 == Darkest, 3 == Lightest
6const dark = {
7 0: color("#002b36"),
8 1: color("#073642"),
9 2: color("#586e75"),
10 3: color("#657b83"),
11};
12// Light: 0 == Lightest, 3 == Darkest
13const light = {
14 0: color("#fdf6e3"),
15 1: color("#eee8d5"),
16 2: color("#93a1a1"),
17 3: color("#839496"),
18};
19
20const colors = {
21 "red": color("#dc322f"),
22 "orange": color("#cb4b16"),
23 "yellow": color("#b58900"),
24 "green": color("#859900"),
25 "cyan": color("#2aa198"),
26 "blue": color("#268bd2"),
27 "violet": color("#6c71c4"),
28 "magenta": color("#d33682"),
29};
30
31export function solarized(darkTheme: boolean): Theme {
32 let fg = darkTheme ? light : dark;
33 let bg = darkTheme ? dark : light;
34 let name = darkTheme ? "solarized-dark" : "solarized-light";
35
36 const backgroundColor = {
37 100: {
38 base: bg[1],
39 hovered: bg[3],
40 active: bg[3],
41 focused: bg[3],
42 },
43 300: {
44 base: bg[1],
45 hovered: bg[3],
46 active: bg[3],
47 focused: bg[3],
48 },
49 500: {
50 base: bg[0],
51 hovered: bg[1],
52 active: bg[1],
53 focused: bg[1],
54 },
55 on300: {
56 base: bg[0],
57 hovered: bg[1],
58 active: bg[1],
59 focused: bg[1],
60 },
61 on500: {
62 base: bg[1],
63 hovered: bg[3],
64 active: bg[3],
65 focused: bg[3],
66 },
67 ok: {
68 base: colors.green,
69 hovered: colors.green,
70 active: colors.green,
71 focused: colors.green,
72 },
73 error: {
74 base: colors.red,
75 hovered: colors.red,
76 active: colors.red,
77 focused: colors.red,
78 },
79 warning: {
80 base: colors.yellow,
81 hovered: colors.yellow,
82 active: colors.yellow,
83 focused: colors.yellow,
84 },
85 info: {
86 base: colors.blue,
87 hovered: colors.blue,
88 active: colors.blue,
89 focused: colors.blue,
90 },
91 };
92
93 const borderColor = {
94 primary: bg[0],
95 secondary: bg[1],
96 muted: bg[3],
97 focused: bg[3],
98 active: bg[3],
99 ok: colors.green,
100 error: colors.red,
101 warning: colors.yellow,
102 info: colors.blue,
103 };
104
105 const textColor = {
106 primary: fg[1],
107 secondary: fg[2],
108 muted: fg[2],
109 placeholder: fg[3],
110 active: fg[0],
111 //TODO: (design) define feature and it's correct value
112 feature: colors.blue,
113 ok: colors.green,
114 error: colors.red,
115 warning: colors.yellow,
116 info: colors.blue,
117 };
118
119 const player = {
120 1: buildPlayer(colors.blue),
121 2: buildPlayer(colors.green),
122 3: buildPlayer(colors.magenta),
123 4: buildPlayer(colors.orange),
124 5: buildPlayer(colors.violet),
125 6: buildPlayer(colors.cyan),
126 7: buildPlayer(colors.red),
127 8: buildPlayer(colors.yellow),
128 };
129
130 const editor = {
131 background: backgroundColor[500].base,
132 indent_guide: borderColor.muted,
133 indent_guide_active: borderColor.secondary,
134 line: {
135 active: withOpacity(fg[0], 0.07),
136 highlighted: withOpacity(fg[0], 0.12),
137 inserted: backgroundColor.ok.active,
138 deleted: backgroundColor.error.active,
139 modified: backgroundColor.info.active,
140 },
141 highlight: {
142 selection: player[1].selectionColor,
143 occurrence: withOpacity(bg[0], 0.12),
144 activeOccurrence: withOpacity(bg[0], 0.16), // TODO: This is not correctly hooked up to occurences on the rust side
145 matchingBracket: backgroundColor[500].active,
146 match: withOpacity(colors.violet, 0.5),
147 activeMatch: withOpacity(colors.violet, 0.7),
148 related: backgroundColor[500].focused,
149 },
150 gutter: {
151 primary: textColor.placeholder,
152 active: textColor.active,
153 },
154 };
155
156 const syntax: Syntax = {
157 primary: {
158 color: fg[0],
159 weight: fontWeights.normal,
160 },
161 comment: {
162 color: fg[2],
163 weight: fontWeights.normal,
164 },
165 punctuation: {
166 color: fg[2],
167 weight: fontWeights.normal,
168 },
169 constant: {
170 color: fg[3],
171 weight: fontWeights.normal,
172 },
173 keyword: {
174 color: colors.blue,
175 weight: fontWeights.normal,
176 },
177 function: {
178 color: colors.yellow,
179 weight: fontWeights.normal,
180 },
181 type: {
182 color: colors.cyan,
183 weight: fontWeights.normal,
184 },
185 variant: {
186 color: colors.blue,
187 weight: fontWeights.normal,
188 },
189 property: {
190 color: colors.blue,
191 weight: fontWeights.normal,
192 },
193 enum: {
194 color: colors.orange,
195 weight: fontWeights.normal,
196 },
197 operator: {
198 color: colors.orange,
199 weight: fontWeights.normal,
200 },
201 string: {
202 color: colors.orange,
203 weight: fontWeights.normal,
204 },
205 number: {
206 color: colors.green,
207 weight: fontWeights.normal,
208 },
209 boolean: {
210 color: colors.green,
211 weight: fontWeights.normal,
212 },
213 predictive: {
214 color: textColor.muted,
215 weight: fontWeights.normal,
216 },
217 title: {
218 color: colors.yellow,
219 weight: fontWeights.bold,
220 },
221 emphasis: {
222 color: textColor.feature,
223 weight: fontWeights.normal,
224 },
225 "emphasis.strong": {
226 color: textColor.feature,
227 weight: fontWeights.bold,
228 },
229 linkUri: {
230 color: colors.green,
231 weight: fontWeights.normal,
232 underline: true,
233 },
234 linkText: {
235 color: colors.orange,
236 weight: fontWeights.normal,
237 italic: true,
238 },
239 };
240
241 const shadowAlpha: NumberToken = {
242 value: 0.32,
243 type: "number",
244 };
245
246 return {
247 name,
248 backgroundColor,
249 borderColor,
250 textColor,
251 iconColor: textColor,
252 editor,
253 syntax,
254 player,
255 shadowAlpha,
256 };
257}