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