1use gpui::{AnyElement, App, Window, div, prelude::*, px, relative};
8use theme::{TextStyle, Theme, Typeset};
9
10pub const LANGUAGE: &str = "chart";
11
12const LABEL_WIDTH: f32 = 72.0;
15const BAR_HEIGHT: f32 = 10.0;
16const BAR_RADIUS: f32 = 3.0;
17const ROW_GAP: f32 = 4.0;
18const PADDING: f32 = 12.0;
19
20pub fn render(code: &str, _: &mut Window, cx: &mut App) -> Option<AnyElement> {
21 let rows: Vec<(&str, f32)> = code
22 .lines()
23 .filter_map(|line| {
24 let (label, value) = line.split_once(':')?;
25 Some((label.trim(), value.trim().parse().ok()?))
26 })
27 .collect();
28 if rows.is_empty() {
31 return None;
32 }
33
34 let theme = Theme::of(cx);
35 let peak = rows.iter().map(|(_, value)| *value).fold(1.0, f32::max);
36 Some(
37 div()
38 .flex()
39 .flex_col()
40 .gap(px(ROW_GAP))
41 .p(px(PADDING))
42 .rounded(px(Theme::BASE_RADIUS))
43 .bg(theme.ink(0.02))
44 .children(rows.into_iter().map(|(label, value)| {
45 div()
46 .flex()
47 .flex_row()
48 .items_center()
49 .gap(px(Theme::SPACE))
50 .child(
51 div()
52 .flex_none()
53 .w(px(LABEL_WIDTH))
54 .text_style(TextStyle::Caption)
55 .text_color(theme.text_muted)
56 .child(label.to_string()),
57 )
58 .child(
59 div().flex_1().child(
60 div()
61 .h(px(BAR_HEIGHT))
62 .w(relative(value / peak))
63 .rounded(px(BAR_RADIUS))
64 .bg(theme.accent),
65 ),
66 )
67 }))
68 .into_any_element(),
69 )
70}