1use fret_core::{Color, Px};
2
3fn alpha_mul(mut c: Color, mul: f32) -> Color {
4 c.a = (c.a * mul).clamp(0.0, 1.0);
5 c
6}
7
8use super::ThemeTokenRead;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum Space {
16 N0,
17 N0p5,
18 N1,
19 N1p5,
20 N2,
21 N2p5,
22 N3,
23 N3p5,
24 N4,
25 N5,
26 N6,
27 N8,
28 N10,
29 N11,
30 N12,
31}
32
33impl Space {
34 pub fn token_key(self) -> &'static str {
35 match self {
36 Self::N0 => "component.space.0",
37 Self::N0p5 => "component.space.0p5",
38 Self::N1 => "component.space.1",
39 Self::N1p5 => "component.space.1p5",
40 Self::N2 => "component.space.2",
41 Self::N2p5 => "component.space.2p5",
42 Self::N3 => "component.space.3",
43 Self::N3p5 => "component.space.3p5",
44 Self::N4 => "component.space.4",
45 Self::N5 => "component.space.5",
46 Self::N6 => "component.space.6",
47 Self::N8 => "component.space.8",
48 Self::N10 => "component.space.10",
49 Self::N11 => "component.space.11",
50 Self::N12 => "component.space.12",
51 }
52 }
53
54 pub(super) fn fallback_metric(self) -> MetricFallback {
55 match self {
56 Self::N0 => MetricFallback::Px(Px(0.0)),
57 Self::N0p5 => MetricFallback::ThemePaddingSmMulDiv { mul: 1, div: 4 },
58 Self::N1 => MetricFallback::ThemePaddingSmMulDiv { mul: 1, div: 2 },
59 Self::N1p5 => MetricFallback::ThemePaddingSmMulDiv { mul: 3, div: 4 },
60 Self::N2 => MetricFallback::ThemePaddingSm,
61 Self::N2p5 => MetricFallback::ThemePaddingMd,
64 Self::N3 => MetricFallback::ThemePaddingSmMulDiv { mul: 3, div: 2 },
65 Self::N3p5 => MetricFallback::ThemePaddingSmMulDiv { mul: 7, div: 4 },
66 Self::N4 => MetricFallback::ThemePaddingSmMulDiv { mul: 2, div: 1 },
67 Self::N5 => MetricFallback::ThemePaddingSmMulDiv { mul: 5, div: 2 },
68 Self::N6 => MetricFallback::ThemePaddingSmMulDiv { mul: 3, div: 1 },
69 Self::N8 => MetricFallback::ThemePaddingSmMulDiv { mul: 4, div: 1 },
70 Self::N10 => MetricFallback::ThemePaddingSmMulDiv { mul: 5, div: 1 },
71 Self::N11 => MetricFallback::ThemePaddingSmMulDiv { mul: 11, div: 2 },
72 Self::N12 => MetricFallback::ThemePaddingSmMulDiv { mul: 6, div: 1 },
73 }
74 }
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq)]
79pub enum Radius {
80 Sm,
81 Md,
82 Lg,
83 Full,
84}
85
86#[derive(Debug, Clone)]
87pub enum MetricFallback {
88 Px(Px),
89 ThemeRadiusSm,
90 ThemeRadiusMd,
91 ThemeRadiusLg,
92 ThemePaddingSm,
93 ThemePaddingMd,
94 ThemePaddingSmMulDiv { mul: u32, div: u32 },
95}
96
97impl MetricFallback {
98 pub(super) fn resolve<T: ThemeTokenRead + ?Sized>(&self, theme: &T) -> Px {
99 match *self {
100 Self::Px(px) => px,
101 Self::ThemeRadiusSm => theme.metric_token("metric.radius.sm"),
102 Self::ThemeRadiusMd => theme.metric_token("metric.radius.md"),
103 Self::ThemeRadiusLg => theme.metric_token("metric.radius.lg"),
104 Self::ThemePaddingSm => theme.metric_token("metric.padding.sm"),
105 Self::ThemePaddingMd => theme.metric_token("metric.padding.md"),
106 Self::ThemePaddingSmMulDiv { mul, div } => {
107 if div == 0 {
108 return Px(0.0);
109 }
110 let base = theme.metric_token("metric.padding.sm");
111 Px(base.0 * (mul as f32) / (div as f32))
112 }
113 }
114 }
115}
116
117#[derive(Debug, Clone)]
118pub enum ColorFallback {
119 Color(Color),
120 ThemeSurfaceBackground,
121 ThemePanelBackground,
122 ThemePanelBorder,
123 ThemeTextPrimary,
124 ThemeTextMuted,
125 ThemeTextDisabled,
126 ThemeAccent,
127 ThemeHoverBackground,
128 ThemeSelectionBackground,
129 ThemeFocusRing,
130 ThemeTokenAlphaMul { key: &'static str, mul: f32 },
131}
132
133impl ColorFallback {
134 pub(super) fn resolve<T: ThemeTokenRead + ?Sized>(&self, theme: &T) -> Color {
135 match *self {
136 Self::Color(c) => c,
137 Self::ThemeSurfaceBackground => theme.color_token("background"),
138 Self::ThemePanelBackground => theme.color_token("card"),
139 Self::ThemePanelBorder => theme.color_token("border"),
140 Self::ThemeTextPrimary => theme.color_token("foreground"),
141 Self::ThemeTextMuted => theme.color_token("muted-foreground"),
142 Self::ThemeTextDisabled => alpha_mul(theme.color_token("muted-foreground"), 0.5),
143 Self::ThemeAccent => theme.color_token("primary"),
144 Self::ThemeHoverBackground => theme.color_token("accent"),
145 Self::ThemeSelectionBackground => theme.color_token("selection.background"),
146 Self::ThemeFocusRing => theme.color_token("ring"),
147 Self::ThemeTokenAlphaMul { key, mul } => alpha_mul(theme.color_token(key), mul),
148 }
149 }
150}