egui_components/
heading.rs1use egui::{FontId, Response, RichText, Ui, Widget};
20use egui_components_theme::Theme;
21
22#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
25pub enum HeadingLevel {
26 H1,
27 #[default]
28 H2,
29 H3,
30 H4,
31}
32
33impl HeadingLevel {
34 fn font_size(&self) -> f32 {
36 match self {
37 HeadingLevel::H1 => 30.0,
38 HeadingLevel::H2 => 24.0,
39 HeadingLevel::H3 => 19.0,
40 HeadingLevel::H4 => 16.0,
41 }
42 }
43}
44
45pub struct Heading {
47 text: String,
48 level: HeadingLevel,
49 description: Option<String>,
50}
51
52impl Heading {
53 pub fn new(text: impl Into<String>) -> Self {
54 Self {
55 text: text.into(),
56 level: HeadingLevel::default(),
57 description: None,
58 }
59 }
60
61 pub fn level(mut self, level: HeadingLevel) -> Self {
62 self.level = level;
63 self
64 }
65
66 pub fn h1(self) -> Self {
67 self.level(HeadingLevel::H1)
68 }
69 pub fn h2(self) -> Self {
70 self.level(HeadingLevel::H2)
71 }
72 pub fn h3(self) -> Self {
73 self.level(HeadingLevel::H3)
74 }
75 pub fn h4(self) -> Self {
76 self.level(HeadingLevel::H4)
77 }
78
79 pub fn description(mut self, text: impl Into<String>) -> Self {
81 self.description = Some(text.into());
82 self
83 }
84}
85
86impl Widget for Heading {
87 fn ui(self, ui: &mut Ui) -> Response {
88 let theme = Theme::get(ui.ctx());
89 let c = theme.colors;
90 ui.vertical(|ui| {
91 ui.add(egui::Label::new(
92 RichText::new(self.text)
93 .color(c.foreground)
94 .font(FontId::proportional(self.level.font_size()))
95 .strong(),
96 ));
97 if let Some(desc) = self.description {
98 ui.add_space(2.0);
99 ui.add(egui::Label::new(
100 RichText::new(desc)
101 .color(c.muted_foreground)
102 .font(FontId::proportional(theme.metrics.font_size_sm)),
103 ));
104 }
105 })
106 .response
107 }
108}