Skip to main content

guise/
divider.rs

1//! `Divider` — a thin separating line, optionally with a centered label.
2
3use gpui::prelude::*;
4use gpui::{div, px, App, IntoElement, SharedString, Window};
5
6use crate::theme::theme;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum Orientation {
10    Horizontal,
11    Vertical,
12}
13
14/// A separator line. The Mantine `Divider`.
15#[derive(IntoElement)]
16pub struct Divider {
17    orientation: Orientation,
18    label: Option<SharedString>,
19}
20
21impl Divider {
22    pub fn new() -> Self {
23        Divider {
24            orientation: Orientation::Horizontal,
25            label: None,
26        }
27    }
28
29    pub fn vertical() -> Self {
30        Divider {
31            orientation: Orientation::Vertical,
32            label: None,
33        }
34    }
35
36    /// A label rendered centered on a horizontal divider.
37    pub fn label(mut self, label: impl Into<SharedString>) -> Self {
38        self.label = Some(label.into());
39        self
40    }
41}
42
43impl Default for Divider {
44    fn default() -> Self {
45        Divider::new()
46    }
47}
48
49impl RenderOnce for Divider {
50    fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
51        let t = theme(cx);
52        let line_color = t.border().hsla();
53
54        if self.orientation == Orientation::Vertical {
55            return div().w(px(1.0)).h_full().bg(line_color);
56        }
57
58        match self.label {
59            None => div().w_full().h(px(1.0)).bg(line_color),
60            Some(label) => div()
61                .flex()
62                .items_center()
63                .gap(px(t.spacing(crate::theme::Size::Sm)))
64                .w_full()
65                .child(div().flex_1().h(px(1.0)).bg(line_color))
66                .child(
67                    div()
68                        .text_size(px(t.font_size(crate::theme::Size::Sm)))
69                        .text_color(t.dimmed().hsla())
70                        .child(label),
71                )
72                .child(div().flex_1().h(px(1.0)).bg(line_color)),
73        }
74    }
75}