1#[derive(Debug)]
7pub struct RecipeState {
8 pub state: &'static str,
9 pub slots: &'static [(&'static str, &'static str)],
10}
11
12#[derive(Debug)]
13pub struct Recipe {
14 pub name: &'static str,
15 pub states: &'static [RecipeState],
16}
17
18impl Recipe {
19 pub fn state(&self, name: &str) -> Option<&RecipeState> {
20 self.states.iter().find(|state| state.state == name)
21 }
22}
23
24const fn state(state: &'static str, slots: &'static [(&'static str, &'static str)]) -> RecipeState {
25 RecipeState { state, slots }
26}
27
28const FOCUS: RecipeState = state("focus", &[("ring", "focus.indicator")]);
30
31pub const RECIPES: &[Recipe] = &[
32 Recipe {
33 name: "button.standard",
34 states: &[
36 state(
37 "rest",
38 &[
39 ("background", "surface.canvas"),
40 ("foreground", "text.primary"),
41 ("border", "separator"),
42 ],
43 ),
44 state(
45 "hover",
46 &[
47 ("background", "button.standard.hover"),
48 ("foreground", "text.primary"),
49 ("border", "separator"),
50 ],
51 ),
52 state(
53 "pressed",
54 &[
55 ("background", "button.standard.pressed"),
56 ("foreground", "text.primary"),
57 ("border", "separator"),
58 ],
59 ),
60 FOCUS,
61 state(
62 "disabled",
63 &[
64 ("background", "disabled.surface"),
65 ("foreground", "disabled.foreground"),
66 ("border", "transparent"),
67 ],
68 ),
69 ],
70 },
71 Recipe {
72 name: "button.prominent",
73 states: &[
74 state(
75 "rest",
76 &[("background", "accent"), ("foreground", "on_accent")],
77 ),
78 state(
79 "hover",
80 &[
81 ("background", "button.prominent.hover"),
82 ("foreground", "on_accent"),
83 ],
84 ),
85 state(
86 "pressed",
87 &[
88 ("background", "button.prominent.pressed"),
89 ("foreground", "on_accent"),
90 ],
91 ),
92 FOCUS,
93 state(
94 "disabled",
95 &[
96 ("background", "disabled.surface"),
97 ("foreground", "disabled.foreground"),
98 ],
99 ),
100 ],
101 },
102 Recipe {
103 name: "button.plain",
104 states: &[
105 state(
106 "rest",
107 &[("background", "transparent"), ("foreground", "accent.text")],
108 ),
109 state(
110 "hover",
111 &[
112 ("background", "hover.overlay"),
113 ("foreground", "accent.text"),
114 ],
115 ),
116 state(
117 "pressed",
118 &[
119 ("background", "pressed.overlay"),
120 ("foreground", "accent.text"),
121 ],
122 ),
123 FOCUS,
124 state(
125 "disabled",
126 &[
127 ("background", "transparent"),
128 ("foreground", "disabled.foreground"),
129 ],
130 ),
131 ],
132 },
133 Recipe {
134 name: "button.destructive",
135 states: &[
136 state(
137 "rest",
138 &[
139 ("background", "status.error.surface"),
140 ("foreground", "on_error"),
141 ],
142 ),
143 state(
144 "hover",
145 &[
146 ("background", "button.destructive.hover"),
147 ("foreground", "on_error"),
148 ],
149 ),
150 state(
151 "pressed",
152 &[
153 ("background", "button.destructive.pressed"),
154 ("foreground", "on_error"),
155 ],
156 ),
157 FOCUS,
158 state(
159 "disabled",
160 &[
161 ("background", "disabled.surface"),
162 ("foreground", "disabled.foreground"),
163 ],
164 ),
165 ],
166 },
167 Recipe {
168 name: "icon_button",
169 states: &[
170 state(
171 "rest",
172 &[
173 ("background", "transparent"),
174 ("foreground", "icon.secondary"),
175 ],
176 ),
177 state(
178 "hover",
179 &[("background", "transparent"), ("foreground", "accent")],
180 ),
181 state(
182 "pressed",
183 &[("background", "transparent"), ("foreground", "accent.text")],
184 ),
185 state(
186 "selected",
187 &[("background", "transparent"), ("foreground", "accent.text")],
188 ),
189 FOCUS,
190 state(
191 "disabled",
192 &[
193 ("background", "transparent"),
194 ("foreground", "disabled.foreground"),
195 ],
196 ),
197 ],
198 },
199 Recipe {
200 name: "field",
201 states: &[
202 state(
203 "rest",
204 &[
205 ("background", "surface.raised"),
206 ("foreground", "text.primary"),
207 ("placeholder", "text.placeholder"),
208 ("border", "control.border"),
209 ],
210 ),
211 state(
212 "focus",
213 &[
214 ("background", "surface.raised"),
215 ("foreground", "text.primary"),
216 ("border", "accent"),
217 ("ring", "focus.indicator"),
218 ],
219 ),
220 state(
221 "error",
222 &[
223 ("background", "surface.raised"),
224 ("foreground", "text.primary"),
225 ("border", "status.error"),
226 ],
227 ),
228 state(
229 "disabled",
230 &[
231 ("background", "disabled.surface"),
232 ("foreground", "disabled.foreground"),
233 ("border", "transparent"),
234 ],
235 ),
236 ],
237 },
238 Recipe {
239 name: "switch",
240 states: &[
242 state(
243 "off",
244 &[
245 ("track", "transparent"),
246 ("border", "control.border"),
247 ("thumb", "control.border"),
248 ],
249 ),
250 state(
251 "off.hover",
252 &[
253 ("track", "transparent"),
254 ("border", "text.secondary"),
255 ("thumb", "text.secondary"),
256 ],
257 ),
258 state(
259 "on",
260 &[
261 ("track", "accent"),
262 ("border", "transparent"),
263 ("thumb", "on_accent"),
264 ],
265 ),
266 state(
267 "on.hover",
268 &[
269 ("track", "button.prominent.hover"),
270 ("border", "transparent"),
271 ("thumb", "on_accent"),
272 ],
273 ),
274 FOCUS,
275 state(
276 "disabled",
277 &[
278 ("track", "transparent"),
279 ("border", "disabled.foreground"),
280 ("thumb", "disabled.foreground"),
281 ],
282 ),
283 ],
284 },
285 Recipe {
286 name: "slider",
287 states: &[
289 state(
290 "rest",
291 &[
292 ("fill", "accent"),
293 ("track", "control.track"),
294 ("thumb", "control.thumb"),
295 ("thumb_border", "control.border"),
296 ("thumb_center", "accent"),
297 ],
298 ),
299 state(
300 "hover",
301 &[
302 ("fill", "accent"),
303 ("track", "control.track"),
304 ("thumb", "control.thumb"),
305 ("thumb_border", "control.border"),
306 ("thumb_center", "button.prominent.hover"),
307 ],
308 ),
309 state(
310 "active",
311 &[
312 ("fill", "accent"),
313 ("track", "control.track"),
314 ("thumb", "control.thumb"),
315 ("thumb_border", "control.border"),
316 ("thumb_center", "button.prominent.pressed"),
317 ],
318 ),
319 FOCUS,
320 state(
321 "disabled",
322 &[
323 ("fill", "disabled.foreground"),
324 ("track", "disabled.surface"),
325 ("thumb", "disabled.surface"),
326 ("thumb_border", "disabled.foreground"),
327 ("thumb_center", "disabled.foreground"),
328 ],
329 ),
330 ],
331 },
332 Recipe {
333 name: "media_scrubber",
334 states: &[
336 state(
337 "rest",
338 &[
339 ("fill", "media.played"),
340 ("track", "media.track"),
341 ("thumb", "control.thumb"),
342 ("thumb_border", "control.border"),
343 ("shadow", "scrim"),
344 ],
345 ),
346 FOCUS,
347 state(
348 "disabled",
349 &[
350 ("fill", "disabled.foreground"),
351 ("track", "media.track"),
352 ("thumb", "disabled.surface"),
353 ("thumb_border", "disabled.foreground"),
354 ("shadow", "transparent"),
355 ],
356 ),
357 ],
358 },
359 Recipe {
360 name: "segmented",
361 states: &[
362 state(
363 "rest",
364 &[
365 ("track", "surface.panel"),
366 ("background", "transparent"),
367 ("foreground", "text.secondary"),
368 ("border", "control.border"),
369 ],
370 ),
371 state(
372 "hover",
373 &[
374 ("background", "hover.overlay"),
375 ("foreground", "text.primary"),
376 ],
377 ),
378 state(
379 "selected",
380 &[
381 ("background", "surface.canvas"),
382 ("foreground", "text.primary"),
383 ("border", "separator"),
384 ],
385 ),
386 FOCUS,
387 state(
388 "disabled",
389 &[
390 ("background", "transparent"),
391 ("foreground", "disabled.foreground"),
392 ],
393 ),
394 ],
395 },
396 Recipe {
397 name: "chip",
398 states: &[
401 state(
402 "rest",
403 &[
404 ("background", "transparent"),
405 ("foreground", "text.secondary"),
406 ("border", "control.border"),
407 ],
408 ),
409 state(
410 "hover",
411 &[
412 ("background", "hover.overlay"),
413 ("foreground", "text.primary"),
414 ],
415 ),
416 state(
417 "selected",
418 &[
419 ("background", "text.primary"),
420 ("foreground", "surface.canvas"),
421 ("border", "transparent"),
422 ],
423 ),
424 FOCUS,
425 state(
426 "disabled",
427 &[
428 ("background", "transparent"),
429 ("foreground", "disabled.foreground"),
430 ],
431 ),
432 ],
433 },
434 Recipe {
435 name: "nav_item",
436 states: &[
439 state(
440 "rest",
441 &[
442 ("background", "transparent"),
443 ("foreground", "text.secondary"),
444 ],
445 ),
446 state(
447 "hover",
448 &[
449 ("background", "hover.overlay"),
450 ("foreground", "text.primary"),
451 ],
452 ),
453 state(
454 "selected",
455 &[("background", "accent"), ("foreground", "on_accent")],
456 ),
457 state(
458 "selected.hover",
459 &[
460 ("background", "button.prominent.hover"),
461 ("foreground", "on_accent"),
462 ],
463 ),
464 FOCUS,
465 ],
466 },
467 Recipe {
468 name: "row",
469 states: &[
470 state(
471 "rest",
472 &[
473 ("background", "transparent"),
474 ("foreground", "text.primary"),
475 ],
476 ),
477 state(
478 "hover",
479 &[
480 ("background", "hover.overlay"),
481 ("foreground", "text.primary"),
482 ],
483 ),
484 state(
485 "pressed",
486 &[
487 ("background", "pressed.overlay"),
488 ("foreground", "text.primary"),
489 ],
490 ),
491 FOCUS,
492 ],
493 },
494 Recipe {
495 name: "tab",
496 states: &[
497 state(
498 "rest",
499 &[
500 ("background", "transparent"),
501 ("foreground", "text.secondary"),
502 ],
503 ),
504 state(
505 "hover",
506 &[
507 ("background", "transparent"),
508 ("foreground", "text.primary"),
509 ],
510 ),
511 state(
512 "selected",
513 &[
514 ("background", "transparent"),
515 ("foreground", "accent.text"),
516 ("indicator", "accent"),
517 ],
518 ),
519 state(
522 "selected.vertical",
523 &[("background", "accent"), ("foreground", "on_accent")],
524 ),
525 FOCUS,
526 ],
527 },
528 Recipe {
529 name: "menu",
530 states: &[
532 state(
533 "popup",
534 &[
535 ("background", "surface.raised"),
536 ("border", "separator"),
537 ("shadow", "scrim"),
538 ],
539 ),
540 state(
541 "rest",
542 &[
543 ("background", "transparent"),
544 ("foreground", "text.primary"),
545 ],
546 ),
547 state(
548 "hover",
549 &[
550 ("background", "hover.overlay"),
551 ("foreground", "text.primary"),
552 ],
553 ),
554 state(
555 "selected",
556 &[
557 ("background", "transparent"),
558 ("foreground", "text.primary"),
559 ("check", "accent.text"),
560 ],
561 ),
562 FOCUS,
563 ],
564 },
565 Recipe {
566 name: "dialog",
567 states: &[state(
568 "open",
569 &[
570 ("background", "surface.raised"),
571 ("foreground", "text.primary"),
572 ("border", "separator"),
573 ("scrim", "scrim"),
574 ],
575 )],
576 },
577 Recipe {
578 name: "window.chrome",
579 states: &[
580 state(
581 "active",
582 &[
583 ("background", "surface.raised"),
584 ("foreground", "text.primary"),
585 ("border", "separator"),
586 ],
587 ),
588 state(
589 "inactive",
590 &[
591 ("background", "surface.raised"),
592 ("foreground", "text.secondary"),
593 ("border", "separator"),
594 ],
595 ),
596 ],
597 },
598];