1use aetna_core::prelude::*;
11
12fn main() -> std::io::Result<()> {
13 let viewport = Rect::new(0.0, 0.0, 1180.0, 876.0);
14 let out_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("out");
15
16 let name = "polish_calibration";
17 let theme = Theme::aetna_dark();
18 let mut root = polish_calibration();
19 let bundle = render_bundle_themed(&mut root, viewport, &theme);
20 let written = write_bundle(&bundle, &out_dir, name)?;
21 for p in &written {
22 println!("wrote {}", p.display());
23 }
24 if !bundle.lint.findings.is_empty() {
25 eprintln!(
26 "\nlint findings for {name} ({}):",
27 bundle.lint.findings.len()
28 );
29 eprint!("{}", bundle.lint.text());
30 }
31
32 Ok(())
33}
34
35fn polish_calibration() -> El {
36 row([sidebar(), main_panel()])
37 .key("metric:root")
38 .gap(0.0)
39 .fill_size()
40 .align(Align::Stretch)
41 .fill(tokens::BACKGROUND)
42}
43
44fn sidebar() -> El {
45 column([
46 column([h2("Aetna"), text("calibration").muted()])
47 .key("metric:sidebar.brand")
48 .gap(tokens::SPACE_1)
49 .height(Size::Hug),
50 spacer().height(Size::Fixed(tokens::SPACE_4)),
51 nav_item("01", "Overview", true),
52 nav_item("02", "Commands", false),
53 nav_item("03", "Tables", false),
54 nav_item("04", "Forms", false),
55 spacer(),
56 badge("dark theme").muted(),
57 ])
58 .gap(tokens::SPACE_2)
59 .padding(tokens::SPACE_5)
60 .key("metric:sidebar")
61 .width(Size::Fixed(220.0))
62 .height(Size::Fill(1.0))
63 .fill(tokens::CARD)
64 .stroke(tokens::BORDER)
65}
66
67fn nav_item(icon: &'static str, label: &'static str, selected: bool) -> El {
68 let mut item = row([
69 icon_cell(icon),
70 text(label)
71 .font_weight(FontWeight::Medium)
72 .ellipsis()
73 .width(Size::Fill(1.0)),
74 ])
75 .key(if selected {
76 "metric:sidebar.nav.row".to_string()
77 } else {
78 format!("nav-{label}")
79 })
80 .metrics_role(MetricsRole::ListItem)
81 .gap(tokens::SPACE_3)
82 .padding(Sides::xy(tokens::SPACE_2, 0.0))
83 .height(Size::Fixed(40.0))
84 .align(Align::Center)
85 .focusable();
86
87 if selected {
88 item = item.current();
89 }
90
91 item
92}
93
94fn main_panel() -> El {
95 column([
96 toolbar(),
97 column([
98 row([
99 kpi_card("Latency", "42 ms", "-18%", true),
100 kpi_card("Runs", "1,284", "+12%", true),
101 kpi_card("Errors", "7", "+2", false),
102 ])
103 .gap(tokens::SPACE_4),
104 row([table_card(), command_card()])
105 .gap(tokens::SPACE_4)
106 .height(Size::Fill(1.0))
107 .align(Align::Stretch),
108 ])
109 .gap(tokens::SPACE_4)
110 .height(Size::Fill(1.0))
111 .align(Align::Stretch),
112 ])
113 .padding(tokens::SPACE_7)
114 .gap(tokens::SPACE_2)
115 .width(Size::Fill(1.0))
116 .height(Size::Fill(1.0))
117}
118
119fn toolbar() -> El {
120 row([
121 column([
122 h1("Polish calibration").key("metric:page.title"),
123 text("A representative app surface for default tuning.")
124 .muted()
125 .key("metric:page.subtitle"),
126 ])
127 .gap(tokens::SPACE_2)
128 .height(Size::Hug),
129 spacer(),
130 button_with_icon("search", "Preview")
131 .secondary()
132 .key("metric:action.secondary"),
133 button_with_icon("upload", "Publish")
134 .primary()
135 .key("metric:action.primary"),
136 ])
137 .key("metric:header")
138 .gap(tokens::SPACE_4)
139 .height(Size::Hug)
140 .align(Align::Start)
141}
142
143fn kpi_card(label: &'static str, value: &'static str, delta: &'static str, positive: bool) -> El {
144 let delta_badge = if positive {
145 badge(delta).success()
146 } else {
147 badge(delta).destructive()
148 };
149 let delta_badge = if label == "Latency" {
150 delta_badge.key("metric:kpi.badge")
151 } else {
152 delta_badge
153 };
154 let value_text = h2(value).display();
155 let value_text = if label == "Latency" {
156 value_text.key("metric:kpi.value")
157 } else {
158 value_text
159 };
160 card([
161 card_header([card_title(label)]),
162 card_content([
163 row([value_text, spacer(), delta_badge]).align(Align::Center),
164 text(if positive {
165 "Moving in the expected direction"
166 } else {
167 "Needs visual attention"
168 })
169 .muted(),
170 ])
171 .gap(tokens::SPACE_6),
172 ])
173 .key(if label == "Latency" {
174 "metric:kpi.card"
175 } else {
176 label
177 })
178 .width(Size::Fill(1.0))
179}
180
181fn table_card() -> El {
182 card([
183 card_header([card_title("Reference rows")]),
184 card_content([table([
185 table_header([table_row([
186 table_head("Status").width(Size::Fixed(86.0)),
187 table_head("Surface").width(Size::Fill(1.0)),
188 table_head("Owner").width(Size::Fixed(110.0)),
189 table_head("State").width(Size::Fixed(86.0)),
190 ])
191 .key("metric:table.header")]),
192 divider(),
193 table_body([
194 data_row("OK", "Settings card", "core", "selected", true, "success"),
195 data_row(
196 "WARN",
197 "Command palette density",
198 "widgets",
199 "needs work",
200 false,
201 "warning",
202 ),
203 data_row(
204 "ERR",
205 "Disabled and invalid states",
206 "style",
207 "missing",
208 false,
209 "destructive",
210 ),
211 data_row(
212 "INFO",
213 "Token resolution",
214 "theme",
215 "planned",
216 false,
217 "info",
218 ),
219 data_row(
220 "OK",
221 "Popover elevation",
222 "shader",
223 "queued",
224 false,
225 "success",
226 ),
227 ])
228 .gap(tokens::SPACE_1)
229 .width(Size::Fill(1.0)),
230 ])]),
231 ])
232 .key("metric:table.card")
233 .width(Size::Fill(1.2))
234 .height(Size::Fill(1.0))
235}
236
237fn data_row(
238 status: &'static str,
239 title: &'static str,
240 owner: &'static str,
241 state: &'static str,
242 selected: bool,
243 tone: &'static str,
244) -> El {
245 let status_badge = match tone {
246 "success" => badge(status).success(),
247 "warning" => badge(status).warning(),
248 "destructive" => badge(status).destructive(),
249 _ => badge(status).info(),
250 };
251 let status_badge = if selected {
252 status_badge.key("metric:table.badge")
253 } else {
254 status_badge
255 };
256
257 let mut row = table_row([
258 table_cell(status_badge).width(Size::Fixed(70.0)),
259 column([
260 text(title)
261 .font_weight(FontWeight::Medium)
262 .ellipsis()
263 .width(Size::Fill(1.0)),
264 text("Default styling probe.")
265 .caption()
266 .ellipsis()
267 .width(Size::Fill(1.0)),
268 ])
269 .gap(2.0)
270 .width(Size::Fill(1.0)),
271 table_cell(text(owner).muted()).width(Size::Fixed(110.0)),
272 table_cell(text(state).label().small()).width(Size::Fixed(86.0)),
273 ])
274 .key(if selected {
275 "metric:table.row".to_string()
276 } else {
277 format!("row-{title}")
278 })
279 .focusable();
280
281 if selected {
282 row = row.selected();
283 }
284
285 row
286}
287
288fn command_card() -> El {
289 card([
290 card_header([card_title("Command surface")]),
291 card_content([
292 text_input(
293 "Search commands...",
294 &Selection::default(),
295 "command-search",
296 )
297 .key("metric:command.input")
298 .width(Size::Fill(1.0)),
299 popover_panel([
300 command_row("git-branch", "New branch", "Ctrl+B").key("metric:command.row"),
301 command_row("git-commit", "Commit staged files", "Ctrl+Enter")
302 .key("command-row-commit"),
303 command_row("refresh-cw", "Refresh repository", "Ctrl+R")
304 .key("command-row-refresh"),
305 command_row("alert-circle", "Force push", "Danger").key("command-row-force"),
306 ])
307 .width(Size::Fill(1.0)),
308 scroll([form_probe()]).key("form-probe-scroll"),
309 ])
310 .height(Size::Fill(1.0)),
311 ])
312 .key("metric:command.card")
313 .width(Size::Fill(0.8))
314 .height(Size::Fill(1.0))
315}
316
317fn form_probe() -> El {
318 form([
319 form_item([
320 form_label("Valid input"),
321 form_control(
322 text_input(
323 "Valid input",
324 &Selection::caret("valid-input", 11),
325 "valid-input",
326 )
327 .key("metric:form.input"),
328 ),
329 form_description("Default field spacing and helper text."),
330 ]),
331 form_item([
332 form_label("Invalid input"),
333 form_control(
334 text_input(
335 "Invalid input",
336 &Selection::caret("invalid-input", 13),
337 "invalid-input",
338 )
339 .invalid(),
340 ),
341 form_message("This field needs attention."),
342 ]),
343 row([
344 button("Disabled").secondary().disabled(),
345 button("Loading").primary().loading(),
346 spacer(),
347 ]),
348 ])
349 .padding(tokens::SPACE_3)
350 .fill(tokens::MUTED)
351 .stroke(tokens::BORDER)
352 .radius(tokens::RADIUS_MD)
353}
354
355fn icon_cell(label: &'static str) -> El {
356 El::new(Kind::Custom("icon_cell"))
357 .style_profile(StyleProfile::Surface)
358 .text(label)
359 .text_align(TextAlign::Center)
360 .caption()
361 .font_weight(FontWeight::Semibold)
362 .fill(tokens::MUTED)
363 .stroke(tokens::BORDER)
364 .radius(tokens::RADIUS_SM)
365 .width(Size::Fixed(26.0))
366 .height(Size::Fixed(26.0))
367}