fret_ui_kit/recipes/
surface.rs1use fret_core::{Color, Px};
2use fret_ui::Theme;
3
4use crate::style::PaddingRefinement;
5use crate::style::{ColorFallback, MetricFallback};
6use crate::{ChromeRefinement, ColorRef, MetricRef};
7
8#[derive(Debug, Clone, Copy)]
9pub struct SurfaceTokenKeys {
10 pub padding_x: Option<&'static str>,
11 pub padding_y: Option<&'static str>,
12 pub radius: Option<&'static str>,
13 pub border_width: Option<&'static str>,
14 pub bg: Option<&'static str>,
15 pub border: Option<&'static str>,
16}
17
18#[derive(Debug, Clone, Copy)]
19pub struct ResolvedSurfaceChrome {
20 pub padding_x: Px,
21 pub padding_y: Px,
22 pub radius: Px,
23 pub border_width: Px,
24 pub background: Color,
25 pub border_color: Color,
26}
27
28pub fn resolve_surface_chrome(
29 theme: &Theme,
30 style: &ChromeRefinement,
31 keys: SurfaceTokenKeys,
32) -> ResolvedSurfaceChrome {
33 let default_padding_x = MetricRef::Token {
34 key: "component.surface.padding_x",
35 fallback: MetricFallback::ThemePaddingSm,
36 };
37 let default_padding_y = MetricRef::Token {
38 key: "component.surface.padding_y",
39 fallback: MetricFallback::ThemePaddingSm,
40 };
41 let default_radius = MetricRef::Token {
42 key: "component.surface.radius",
43 fallback: MetricFallback::ThemeRadiusSm,
44 };
45 let default_bg = ColorRef::Token {
46 key: "component.surface.bg",
47 fallback: ColorFallback::ThemePanelBackground,
48 };
49 let default_border = ColorRef::Token {
50 key: "component.surface.border",
51 fallback: ColorFallback::ThemePanelBorder,
52 };
53
54 let padding_x = style
58 .padding
59 .as_ref()
60 .and_then(|p| p.left.as_ref().or(p.right.as_ref()))
61 .map(|m| m.resolve(theme))
62 .or_else(|| keys.padding_x.and_then(|k| theme.metric_by_key(k)))
63 .or_else(|| theme.metric_by_key("component.surface.padding_x"))
64 .unwrap_or_else(|| default_padding_x.resolve(theme));
65 let padding_y = style
66 .padding
67 .as_ref()
68 .and_then(|p| p.top.as_ref().or(p.bottom.as_ref()))
69 .map(|m| m.resolve(theme))
70 .or_else(|| keys.padding_y.and_then(|k| theme.metric_by_key(k)))
71 .or_else(|| theme.metric_by_key("component.surface.padding_y"))
72 .unwrap_or_else(|| default_padding_y.resolve(theme));
73 let radius = style
74 .radius
75 .as_ref()
76 .map(|m| m.resolve(theme))
77 .or_else(|| keys.radius.and_then(|k| theme.metric_by_key(k)))
78 .or_else(|| theme.metric_by_key("component.surface.radius"))
79 .unwrap_or_else(|| default_radius.resolve(theme));
80 let border_width = style
81 .border_width
82 .as_ref()
83 .map(|m| m.resolve(theme))
84 .or_else(|| keys.border_width.and_then(|k| theme.metric_by_key(k)))
85 .or_else(|| theme.metric_by_key("component.surface.border_width"))
86 .unwrap_or(Px(1.0));
87
88 let background = style
89 .background
90 .as_ref()
91 .map(|c| c.resolve(theme))
92 .or_else(|| keys.bg.and_then(|k| theme.color_by_key(k)))
93 .or_else(|| theme.color_by_key("component.surface.bg"))
94 .unwrap_or_else(|| default_bg.resolve(theme));
95 let border_color = style
96 .border_color
97 .as_ref()
98 .map(|c| c.resolve(theme))
99 .or_else(|| keys.border.and_then(|k| theme.color_by_key(k)))
100 .or_else(|| theme.color_by_key("component.surface.border"))
101 .unwrap_or_else(|| default_border.resolve(theme));
102
103 ResolvedSurfaceChrome {
104 padding_x: Px(padding_x.0.max(0.0)),
105 padding_y: Px(padding_y.0.max(0.0)),
106 radius: Px(radius.0.max(0.0)),
107 border_width: Px(border_width.0.max(0.0)),
108 background,
109 border_color,
110 }
111}
112
113pub fn surface_base_refinement() -> ChromeRefinement {
114 ChromeRefinement {
115 padding: Some(PaddingRefinement {
116 top: Some(MetricRef::Token {
117 key: "component.surface.padding_y",
118 fallback: MetricFallback::ThemePaddingSm,
119 }),
120 right: Some(MetricRef::Token {
121 key: "component.surface.padding_x",
122 fallback: MetricFallback::ThemePaddingSm,
123 }),
124 bottom: Some(MetricRef::Token {
125 key: "component.surface.padding_y",
126 fallback: MetricFallback::ThemePaddingSm,
127 }),
128 left: Some(MetricRef::Token {
129 key: "component.surface.padding_x",
130 fallback: MetricFallback::ThemePaddingSm,
131 }),
132 }),
133 radius: Some(MetricRef::Token {
134 key: "component.surface.radius",
135 fallback: MetricFallback::ThemeRadiusSm,
136 }),
137 border_width: Some(MetricRef::Token {
138 key: "component.surface.border_width",
139 fallback: MetricFallback::Px(Px(1.0)),
140 }),
141 background: Some(ColorRef::Token {
142 key: "component.surface.bg",
143 fallback: ColorFallback::ThemePanelBackground,
144 }),
145 border_color: Some(ColorRef::Token {
146 key: "component.surface.border",
147 fallback: ColorFallback::ThemePanelBorder,
148 }),
149 ..ChromeRefinement::default()
150 }
151}