docs/docs/components/settings.md
Since: v0.5.0
The Settings component provides a UI for managing application settings. It includes grouped setting items and pages. We can search by title and description to filter the settings to display only relevant settings (Like this macOS, iOS Settings).
use gpui_component::setting::{Settings, SettingPage, SettingGroup, SettingItem, SettingField};
Here we have components that can be used to build a settings page.
The layout of the settings is like this:
Settings
SettingPage
SettingGroup
SettingItem
Title
Description (optional)
SettingField
use gpui_component::setting::{Settings, SettingPage, SettingGroup, SettingItem, SettingField};
Settings::new("my-settings")
.pages(vec![
SettingPage::new("General")
.group(
SettingGroup::new()
.title("Basic Options")
.item(
SettingItem::new(
"Enable Feature",
SettingField::switch(
|cx: &App| true,
|val: bool, cx: &mut App| {
println!("Feature enabled: {}", val);
},
)
)
)
)
])
:::info
When you want default expland a page, you can use default_open(true) on the SettingPage.
:::
Settings::new("app-settings")
.pages(vec![
SettingPage::new("General")
.default_open(true)
.group(SettingGroup::new().title("Appearance").items(vec![...])),
SettingPage::new("Software Update")
.group(SettingGroup::new().title("Updates").items(vec![...])),
SettingPage::new("About")
.group(SettingGroup::new().items(vec![...])),
])
use gpui_component::group_box::GroupBoxVariant;
Settings::new("my-settings")
.with_group_variant(GroupBoxVariant::Outline)
.pages(vec![...])
Settings::new("my-settings")
.with_group_variant(GroupBoxVariant::Fill)
.pages(vec![...])
SettingPage::new("General")
.group(SettingGroup::new().title("Options").items(vec![...]))
SettingPage::new("General")
.groups(vec![
SettingGroup::new().title("Appearance").items(vec![...]),
SettingGroup::new().title("Font").items(vec![...]),
SettingGroup::new().title("Other").items(vec![...]),
])
SettingPage::new("General")
.icon(IconName::Settings)
.groups(vec![...])
SettingPage::new("General")
.default_open(true)
.groups(vec![...])
Enable reset functionality for a page:
SettingPage::new("General")
.resettable(true)
.groups(vec![...])
SettingGroup::new()
.title("Appearance")
.items(vec![
SettingItem::new(...),
SettingItem::new(...),
])
SettingGroup::new()
.title("Font")
.item(SettingItem::new(...))
SettingGroup::new()
.items(vec![...])
SettingItem::new("Title", SettingField::switch(...))
.description("Description text")
You can create a fully custom setting item using SettingItem::render:
SettingItem::render(|options, _, _| {
h_flex()
.w_full()
.justify_between()
.child("Custom content")
.child(
Button::new("action")
.label("Action")
.with_size(options.size)
)
.into_any_element()
})
By default, setting items use horizontal layout. Use layout(Axis::Vertical) for vertical layout:
SettingItem::new(
"CLI Path",
SettingField::input(...)
)
.layout(Axis::Vertical)
.description("This item uses vertical layout.")
use gpui_component::text::markdown;
SettingItem::new(
"Documentation",
SettingField::element(...)
)
.description(markdown("Rust doc for the `gpui-component` crate."))
The SettingField enum provides different field types for various input needs.
The switch field represents a boolean on/off state.
SettingItem::new(
"Dark Mode",
SettingField::switch(
|cx: &App| cx.theme().mode.is_dark(),
|val: bool, cx: &mut App| {
// Handle value change
},
)
.default_value(false)
)
Like the switch, but uses a checkbox UI.
SettingItem::new(
"Auto Switch Theme",
SettingField::checkbox(
|cx: &App| AppSettings::global(cx).auto_switch_theme,
|val: bool, cx: &mut App| {
AppSettings::global_mut(cx).auto_switch_theme = val;
},
)
.default_value(false)
)
Display a single line text input.
SettingItem::new(
"CLI Path",
SettingField::input(
|cx: &App| AppSettings::global(cx).cli_path.clone(),
|val: SharedString, cx: &mut App| {
AppSettings::global_mut(cx).cli_path = val;
},
)
.default_value("/usr/local/bin/bash".into())
)
.layout(Axis::Vertical)
.description("Path to the CLI executable.")
A dropdown with a list of options.
SettingItem::new(
"Font Family",
SettingField::dropdown(
vec![
("Arial".into(), "Arial".into()),
("Helvetica".into(), "Helvetica".into()),
("Times New Roman".into(), "Times New Roman".into()),
],
|cx: &App| AppSettings::global(cx).font_family.clone(),
|val: SharedString, cx: &mut App| {
AppSettings::global_mut(cx).font_family = val;
},
)
.default_value("Arial".into())
)
use gpui_component::setting::NumberFieldOptions;
SettingItem::new(
"Font Size",
SettingField::number_input(
NumberFieldOptions {
min: 8.0,
max: 72.0,
..Default::default()
},
|cx: &App| AppSettings::global(cx).font_size,
|val: f64, cx: &mut App| {
AppSettings::global_mut(cx).font_size = val;
},
)
.default_value(14.0)
)
The SettingField::render method allows you to create a custom field using a closure that returns an element.
SettingItem::new(
"GitHub Repository",
SettingField::render(|options, _window, _cx| {
Button::new("open-url")
.outline()
.label("Repository...")
.with_size(options.size)
.on_click(|_, _window, cx| {
cx.open_url("https://github.com/example/repo");
})
})
)
You may have a complex field that you want to reuse, you may want split the element into a separate struct to do the complex logic.
In this case, the SettingFieldElement trait can help you to create a custom field element.
use gpui_component::setting::{SettingFieldElement, RenderOptions};
struct OpenURLSettingField {
label: SharedString,
url: SharedString,
}
impl SettingFieldElement for OpenURLSettingField {
type Element = Button;
fn render_field(&self, options: &RenderOptions, _: &mut Window, _: &mut App) -> Self::Element {
let url = self.url.clone();
Button::new("open-url")
.outline()
.label(self.label.clone())
.with_size(options.size)
.on_click(move |_, _window, cx| {
cx.open_url(url.as_str());
})
}
}
Then use it in the setting item:
SettingItem::new(
"GitHub Repository",
SettingField::element(OpenURLSettingField {
label: "Repository...".into(),
url: "https://github.com/longbridge/gpui-component".into(),
})
)
Implements Sizable trait:
xsmall() - Extra small sizesmall() - Small sizemedium() - Medium size (default)large() - Large sizewith_size(Size) - Set specific sizeuse gpui::{App, SharedString};
use gpui_component::{
Settings, SettingPage, SettingGroup, SettingItem, SettingField,
setting::NumberFieldOptions,
group_box::GroupBoxVariant,
Size,
};
Settings::new("app-settings")
.with_size(Size::Medium)
.with_group_variant(GroupBoxVariant::Outline)
.pages(vec![
SettingPage::new("General")
.resettable(true)
.default_open(true)
.groups(vec![
SettingGroup::new()
.title("Appearance")
.items(vec![
SettingItem::new(
"Dark Mode",
SettingField::switch(
|cx: &App| cx.theme().mode.is_dark(),
|val: bool, cx: &mut App| {
// Handle theme change
},
)
)
.description("Switch between light and dark themes."),
]),
SettingGroup::new()
.title("Font")
.items(vec![
SettingItem::new(
"Font Family",
SettingField::dropdown(
vec![
("Arial".into(), "Arial".into()),
("Helvetica".into(), "Helvetica".into()),
],
|cx: &App| "Arial".into(),
|val: SharedString, cx: &mut App| {
// Handle font change
},
)
),
SettingItem::new(
"Font Size",
SettingField::number_input(
NumberFieldOptions {
min: 8.0,
max: 72.0,
..Default::default()
},
|cx: &App| 14.0,
|val: f64, cx: &mut App| {
// Handle size change
},
)
),
]),
]),
SettingPage::new("Software Update")
.resettable(true)
.group(
SettingGroup::new()
.title("Updates")
.items(vec![
SettingItem::new(
"Auto Update",
SettingField::switch(
|cx: &App| true,
|val: bool, cx: &mut App| {
// Handle auto update
},
)
)
.description("Automatically download and install updates."),
])
),
])