Skip to main content

fret_ui_kit/style/
refs.rs

1use fret_core::{Color, Px};
2use fret_ui::ThemeNamedColorKey;
3
4use super::ThemeTokenRead;
5use super::{ColorFallback, MetricFallback, Radius, Space};
6
7#[derive(Debug, Clone)]
8pub enum MetricRef {
9    Px(Px),
10    Token {
11        key: &'static str,
12        fallback: MetricFallback,
13    },
14}
15
16impl MetricRef {
17    pub fn space(space: Space) -> Self {
18        MetricRef::Token {
19            key: space.token_key(),
20            fallback: space.fallback_metric(),
21        }
22    }
23
24    pub fn radius(radius: Radius) -> Self {
25        match radius {
26            Radius::Sm => MetricRef::Token {
27                key: "component.radius.sm",
28                fallback: MetricFallback::ThemeRadiusSm,
29            },
30            Radius::Md => MetricRef::Token {
31                key: "component.radius.md",
32                fallback: MetricFallback::ThemeRadiusMd,
33            },
34            Radius::Lg => MetricRef::Token {
35                key: "component.radius.lg",
36                fallback: MetricFallback::ThemeRadiusLg,
37            },
38            Radius::Full => MetricRef::Token {
39                key: "component.radius.full",
40                fallback: MetricFallback::Px(Px(999.0)),
41            },
42        }
43    }
44
45    pub fn resolve<T: ThemeTokenRead + ?Sized>(&self, theme: &T) -> Px {
46        match self {
47            Self::Px(px) => *px,
48            Self::Token { key, fallback } => theme
49                .metric_by_key(key)
50                .unwrap_or_else(|| fallback.resolve(theme)),
51        }
52    }
53}
54
55impl From<Px> for MetricRef {
56    fn from(value: Px) -> Self {
57        Self::Px(value)
58    }
59}
60
61impl From<Space> for MetricRef {
62    fn from(value: Space) -> Self {
63        Self::space(value)
64    }
65}
66
67impl From<Radius> for MetricRef {
68    fn from(value: Radius) -> Self {
69        Self::radius(value)
70    }
71}
72
73#[derive(Debug, Clone)]
74pub enum SignedMetricRef {
75    Pos(MetricRef),
76    Neg(MetricRef),
77}
78
79impl SignedMetricRef {
80    pub fn pos(metric: MetricRef) -> Self {
81        Self::Pos(metric)
82    }
83
84    pub fn neg(metric: MetricRef) -> Self {
85        Self::Neg(metric)
86    }
87
88    pub fn resolve<T: ThemeTokenRead + ?Sized>(&self, theme: &T) -> Px {
89        match self {
90            Self::Pos(m) => m.resolve(theme),
91            Self::Neg(m) => {
92                let px = m.resolve(theme);
93                Px(-px.0)
94            }
95        }
96    }
97}
98
99impl From<MetricRef> for SignedMetricRef {
100    fn from(value: MetricRef) -> Self {
101        Self::Pos(value)
102    }
103}
104
105#[derive(Debug, Clone)]
106pub enum ColorRef {
107    Color(Color),
108    Named(ThemeNamedColorKey),
109    Token {
110        key: &'static str,
111        fallback: ColorFallback,
112    },
113}
114
115impl ColorRef {
116    pub fn resolve<T: ThemeTokenRead + ?Sized>(&self, theme: &T) -> Color {
117        match self {
118            Self::Color(c) => *c,
119            Self::Named(key) => theme.named_color(*key),
120            Self::Token { key, fallback } => theme
121                .color_by_key(key)
122                .unwrap_or_else(|| fallback.resolve(theme)),
123        }
124    }
125}