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