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