1use 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#[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 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}