Skip to main content

guise/
title.rs

1//! `Title` — headings `h1..h6` by `order`.
2
3use gpui::prelude::*;
4use gpui::{div, px, App, FontWeight, IntoElement, SharedString, Window};
5
6use crate::theme::{theme, Color};
7
8/// A heading. The Mantine `Title`; `order` 1..=6 selects the heading level.
9#[derive(IntoElement)]
10pub struct Title {
11    content: SharedString,
12    order: u8,
13    color: Option<Color>,
14}
15
16impl Title {
17    pub fn new(content: impl Into<SharedString>) -> Self {
18        Title {
19            content: content.into(),
20            order: 1,
21            color: None,
22        }
23    }
24
25    /// Heading level 1..=6 (clamped). 1 is the largest.
26    pub fn order(mut self, order: u8) -> Self {
27        self.order = order.clamp(1, 6);
28        self
29    }
30
31    pub fn color(mut self, color: Color) -> Self {
32        self.color = Some(color);
33        self
34    }
35
36    fn font_size(&self) -> f32 {
37        match self.order {
38            1 => 34.0,
39            2 => 26.0,
40            3 => 22.0,
41            4 => 18.0,
42            5 => 16.0,
43            _ => 14.0,
44        }
45    }
46}
47
48impl RenderOnce for Title {
49    fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
50        let t = theme(cx);
51        let color = self.color.unwrap_or_else(|| t.text());
52        let size = self.font_size();
53        div()
54            .text_size(px(size))
55            .font_weight(FontWeight::BOLD)
56            .line_height(px(size * 1.3))
57            .text_color(color.hsla())
58            .child(self.content)
59    }
60}