Settings
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).
Import
use gpui_component::setting::{Settings, SettingPage, SettingGroup, SettingItem, SettingField};Usage
Build a settings
Here we have components that can be used to build a settings page.
- Settings - The main settings component that holds multiple setting pages.
- SettingPage - A page of related setting groups.
- SettingGroup - A group of related setting items based on GroupBox style.
- SettingItem - A single setting item with title, description, and field.
- SettingField - Provide different field types like Input, Dropdown, Switch, etc.
The layout of the settings is like this:
Settings
SettingPage
SettingGroup
SettingItem
Title
Description (optional)
SettingFieldBasic Settings
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);
},
)
)
)
)
])With Multiple Pages
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![...])),
])Group Variants
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![...])Setting Page
Basic Page
SettingPage::new("General")
.group(SettingGroup::new().title("Options").items(vec![...]))Multiple Groups
SettingPage::new("General")
.groups(vec![
SettingGroup::new().title("Appearance").items(vec![...]),
SettingGroup::new().title("Font").items(vec![...]),
SettingGroup::new().title("Other").items(vec![...]),
])Icon
SettingPage::new("General")
.icon(IconName::Settings)
.groups(vec![...])Default Open
SettingPage::new("General")
.default_open(true)
.groups(vec![...])resettable
Enable reset functionality for a page:
SettingPage::new("General")
.resettable(true)
.groups(vec![...])Setting Group
Basic Group
SettingGroup::new()
.title("Appearance")
.items(vec![
SettingItem::new(...),
SettingItem::new(...),
])Single Item
SettingGroup::new()
.title("Font")
.item(SettingItem::new(...))Without Title
SettingGroup::new()
.items(vec![...])Setting Item
Basic Item
SettingItem::new("Title", SettingField::switch(...))
.description("Description text")Custom Item with a render closure
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()
})Vertical Layout
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.")With Markdown Description
use gpui_component::text::markdown;
SettingItem::new(
"Documentation",
SettingField::element(...)
)
.description(markdown("Rust doc for the `gpui-component` crate."))Setting Fields
The SettingField enum provides different field types for various input needs.
Switch
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)
)Checkbox
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)
)Input
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.")Dropdown
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())
)NumberInput
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)
)Custom Field by Render Closure
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");
})
})
)Custom Field Element
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(),
})
)API Reference
Sizing
Implements Sizable trait:
xsmall()- Extra small sizesmall()- Small sizemedium()- Medium size (default)large()- Large sizewith_size(Size)- Set specific size
Examples
Complete Settings Example
use 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."),
])
),
])