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