modal.rs

  1use gpui::*;
  2use smallvec::SmallVec;
  3
  4use crate::{h_flex, IconButton, IconButtonShape, IconName, Label, LabelCommon, LabelSize};
  5
  6#[derive(IntoElement)]
  7pub struct ModalHeader {
  8    id: ElementId,
  9    children: SmallVec<[AnyElement; 2]>,
 10}
 11
 12impl ModalHeader {
 13    pub fn new(id: impl Into<ElementId>) -> Self {
 14        Self {
 15            id: id.into(),
 16            children: SmallVec::new(),
 17        }
 18    }
 19}
 20
 21impl ParentElement for ModalHeader {
 22    fn extend(&mut self, elements: impl Iterator<Item = AnyElement>) {
 23        self.children.extend(elements)
 24    }
 25}
 26
 27impl RenderOnce for ModalHeader {
 28    fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
 29        h_flex()
 30            .id(self.id)
 31            .w_full()
 32            .px_2()
 33            .py_1p5()
 34            .child(div().flex_1().children(self.children))
 35            .justify_between()
 36            .child(IconButton::new("dismiss", IconName::Close).shape(IconButtonShape::Square))
 37    }
 38}
 39
 40#[derive(IntoElement)]
 41pub struct ModalContent {
 42    children: SmallVec<[AnyElement; 2]>,
 43}
 44
 45impl ModalContent {
 46    pub fn new() -> Self {
 47        Self {
 48            children: SmallVec::new(),
 49        }
 50    }
 51}
 52
 53impl ParentElement for ModalContent {
 54    fn extend(&mut self, elements: impl Iterator<Item = AnyElement>) {
 55        self.children.extend(elements)
 56    }
 57}
 58
 59impl RenderOnce for ModalContent {
 60    fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
 61        h_flex().w_full().px_2().py_1p5().children(self.children)
 62    }
 63}
 64
 65#[derive(IntoElement)]
 66pub struct ModalRow {
 67    children: SmallVec<[AnyElement; 2]>,
 68}
 69
 70impl ModalRow {
 71    pub fn new() -> Self {
 72        Self {
 73            children: SmallVec::new(),
 74        }
 75    }
 76}
 77
 78impl ParentElement for ModalRow {
 79    fn extend(&mut self, elements: impl Iterator<Item = AnyElement>) {
 80        self.children.extend(elements)
 81    }
 82}
 83
 84impl RenderOnce for ModalRow {
 85    fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
 86        h_flex().w_full().px_2().py_1().children(self.children)
 87    }
 88}
 89
 90#[derive(IntoElement)]
 91pub struct SectionHeader {
 92    /// The label of the header.
 93    label: SharedString,
 94    /// A slot for content that appears after the label, usually on the other side of the header.
 95    /// This might be a button, a disclosure arrow, a face pile, etc.
 96    end_slot: Option<AnyElement>,
 97}
 98
 99impl SectionHeader {
100    pub fn new(label: impl Into<SharedString>) -> Self {
101        Self {
102            label: label.into(),
103            end_slot: None,
104        }
105    }
106
107    pub fn end_slot<E: IntoElement>(mut self, end_slot: impl Into<Option<E>>) -> Self {
108        self.end_slot = end_slot.into().map(IntoElement::into_any_element);
109        self
110    }
111}
112
113impl RenderOnce for SectionHeader {
114    fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
115        h_flex().id(self.label.clone()).w_full().child(
116            div()
117                .h_7()
118                .flex()
119                .items_center()
120                .justify_between()
121                .w_full()
122                .gap_1()
123                .child(
124                    div().flex_1().child(
125                        Label::new(self.label.clone())
126                            .size(LabelSize::Large)
127                            .into_element(),
128                    ),
129                )
130                .child(h_flex().children(self.end_slot)),
131        )
132    }
133}