Components / controls
SettingsList builder
Settings sections filtered by one caller-owned query.
A builder is RenderOnce. Construct and mount it in one expression.
use gpui_kit::controls::settings_row::SettingsList;
Reviewed in settings settings-page.
Construct
new(ident: impl Into<Ident>) -> Self
Options
Chain onto the value.
query(query: impl Into<SharedString>) -> Self
section(section: impl Into<EffectScoped<SettingsSection>>) -> Self
sections<S: Into<EffectScoped<SettingsSection>>>(sections: impl IntoIterator<Item = S>) -> Self
Example · settings
fn settings(window: &mut Window, cx: &mut App) -> AnyElement {
if !cx.has_global::<SceneSettingsInputs>() {
let inputs = [("name", "Fixture assistant"), ("model", "Local model")]
.into_iter()
.map(|(id, value)| {
cx.new(|cx| {
TextInput::new(format!("scene.settings.fields.{id}.input"), window, cx)
.text(value)
.control_size(ControlSize::Sm)
})
})
.collect();
cx.set_global(SceneSettingsInputs(inputs));
}
let fields = cx.global::<SceneSettingsInputs>().0.clone();
let theme = cx.theme().clone();
let general = || {
SettingsSection::new("scene.settings.general", "General")
.description("How this workspace behaves")
.row(
SettingsRow::new("scene.settings.general.autosave", "Save automatically")
.description("Write changes as they happen")
.control(
Switch::new("scene.settings.general.autosave.switch")
.named("Save automatically")
.on(true)
.on_change(|_, _, _| {}),
),
)
.row(
SettingsRow::new("scene.settings.general.runtime", "Native runtime")
.description("Runs work on this machine instead of a host")
.badge("Requires restart")
.search_terms(["engine", "local executor"])
.control(
Switch::new("scene.settings.general.runtime.switch")
.named("Native runtime")
.on(false)
.on_change(|_, _, _| {}),
),
)
.row(
SettingsRow::new("scene.settings.general.telemetry", "Usage reporting")
.description("Nobody on this machine can change this")
.value("Off")
.managed("your administrator"),
)
};
let sync = || {
SettingsSection::new("scene.settings.sync", "Synchronisation")
.description("What travels between machines")
.dimmed_by("This workspace is local, so nothing synchronises.")
.row(
SettingsRow::new("scene.settings.sync.settings", "Sync settings")
.description("Keyboard, theme, and editor preferences")
.value("Off")
.control(
Switch::new("scene.settings.sync.settings.switch")
.named("Sync settings")
.on(false)
.on_change(|_, _, _| {}),
),
)
.row(
SettingsRow::new("scene.settings.sync.history", "Sync history")
.description("Runs and transcripts from the last 30 days")
.value("Off")
.control(
Switch::new("scene.settings.sync.history.switch")
.named("Sync history")
.on(false)
.on_change(|_, _, _| {}),
),
)
};
stack(&theme)
.w_full()
.child(
row(&theme)
.w_full()
.items_start()
// The filtered list opens with its own count, so the
// unfiltered one is given a line saying what it is. Without
// it the two pages start at different heights and nothing in
// the picture says why one column sits lower than the other.
.child(
div()
.flex_1()
.min_w_0()
.column()
.gap_token(&theme, Space::Md)
.child(caption(&theme, "no query, so every section"))
.child(SettingsList::new("scene.settings.all").section(general())),
)
.child(
div().flex_1().min_w_0().child(
SettingsList::new("scene.settings.filtered")
.query("sync")
.section(general())
.section(sync()),
),
),
)
.child(
SettingsSection::new("scene.settings.fields", "Aligned fields and custom blocks")
.description("120px labels; flexible fields; annotations at the reading end")
.label_width(px(120.0))
.row(
SettingsRow::new("scene.settings.fields.name", "Name")
.control(fields[0].clone())
.description("Visible in the workspace"),
)
.child(
crate::display::card::ListRow::new()
.id("scene.settings.fields.device")
.child(crate::foundation::text(
&theme,
TypeScale::Body,
"Fixture device · connected",
)),
)
.row(
SettingsRow::new("scene.settings.fields.model", "Model")
.control(fields[1].clone())
.description("Chosen by the caller"),
),
)
.into_any_element()
}