1use gpui::AnyElement;
  2use smallvec::SmallVec;
  3
  4use crate::{ListHeader, prelude::*};
  5
  6use super::Checkbox;
  7
  8/// A group of settings.
  9#[derive(IntoElement, RegisterComponent)]
 10pub struct SettingsGroup {
 11    header: SharedString,
 12    children: SmallVec<[AnyElement; 2]>,
 13}
 14
 15impl SettingsGroup {
 16    pub fn new(header: impl Into<SharedString>) -> Self {
 17        Self {
 18            header: header.into(),
 19            children: SmallVec::new(),
 20        }
 21    }
 22}
 23
 24impl ParentElement for SettingsGroup {
 25    fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
 26        self.children.extend(elements)
 27    }
 28}
 29
 30impl RenderOnce for SettingsGroup {
 31    fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
 32        v_flex()
 33            .p_1()
 34            .gap_2()
 35            .child(ListHeader::new(self.header))
 36            .children(self.children)
 37    }
 38}
 39
 40impl Component for SettingsGroup {
 41    fn scope() -> ComponentScope {
 42        ComponentScope::Layout
 43    }
 44
 45    fn name() -> &'static str {
 46        "SettingsGroup"
 47    }
 48
 49    fn description() -> Option<&'static str> {
 50        Some("A group of settings with a header, used to organize related settings.")
 51    }
 52
 53    fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
 54        Some(
 55            v_flex()
 56                .gap_6()
 57                .children(vec![
 58                    example_group_with_title(
 59                        "Basic Usage",
 60                        vec![
 61                            single_example(
 62                                "Empty Group",
 63                                SettingsGroup::new("General Settings").into_any_element(),
 64                            ),
 65                            single_example(
 66                                "With Children",
 67                                SettingsGroup::new("Appearance")
 68                                    .child(
 69                                        Checkbox::new("dark_mode", ToggleState::Unselected)
 70                                            .label("Dark Mode"),
 71                                    )
 72                                    .child(
 73                                        Checkbox::new("high_contrast", ToggleState::Unselected)
 74                                            .label("High Contrast"),
 75                                    )
 76                                    .into_any_element(),
 77                            ),
 78                        ],
 79                    ),
 80                    example_group_with_title(
 81                        "Multiple Groups",
 82                        vec![single_example(
 83                            "Two Groups",
 84                            v_flex()
 85                                .gap_4()
 86                                .child(
 87                                    SettingsGroup::new("General").child(
 88                                        Checkbox::new("auto_update", ToggleState::Selected)
 89                                            .label("Auto Update"),
 90                                    ),
 91                                )
 92                                .child(
 93                                    SettingsGroup::new("Editor")
 94                                        .child(
 95                                            Checkbox::new("line_numbers", ToggleState::Selected)
 96                                                .label("Show Line Numbers"),
 97                                        )
 98                                        .child(
 99                                            Checkbox::new("word_wrap", ToggleState::Unselected)
100                                                .label("Word Wrap"),
101                                        ),
102                                )
103                                .into_any_element(),
104                        )],
105                    ),
106                ])
107                .into_any_element(),
108        )
109    }
110}