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