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