theme_selector: Mark the active theme with a check icon (#58404)

While browsing themes in theme selector, the currently active theme will
always be marked with a check icon so you can always have a reference of
where you started from.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Here's a preview: 
<img width="950" height="806" alt="Screenshot 2026-06-03 at 13 09 46"
src="https://github.com/user-attachments/assets/2081d9ec-b56d-4542-be58-e59e3569bc7a"
/>
<img width="958" height="818" alt="Screenshot 2026-06-03 at 13 09 52"
src="https://github.com/user-attachments/assets/134d933f-c9de-4b2c-80f5-ed5be4fb2844"
/>


Release Notes:

- Improved the theme and icon selectors to display a check next to the
active theme

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
This commit is contained in:
Matei Opreaanddino authored and GitHub committed 2026-06-03 13:56:42 +00:00
1 parent d178767443
commit 5282cffff6
2 files changed
+33 -4

No files matched your search

@@ -299,6 +299,7 @@ impl PickerDelegate for IconThemeSelectorDelegate {
_cx: &mut Context<Picker<Self>>,
) -> Option<Self::ListItem> {
let theme_match = &self.matches.get(ix)?;
let is_original_theme = theme_match.string.as_str() == self.original_theme.0.as_ref();
Some(
ListItem::new(ix)
@@ -308,7 +309,10 @@ impl PickerDelegate for IconThemeSelectorDelegate {
.child(HighlightedLabel::new(
theme_match.string.clone(),
theme_match.positions.clone(),
)),
))
.when(is_original_theme, |this| {
this.end_slot(Icon::new(IconName::Check).color(Color::Muted))
}),
)
}
+28 -3
View File
@@ -134,6 +134,14 @@ struct ThemeSelectorDelegate {
original_theme_settings: ThemeSettings,
/// The current system appearance.
original_system_appearance: Appearance,
/// The id of the original theme in the list of themes.
/// Using `Option<usize>` instead of `usize` because it's possible that the
/// original theme is not present in the list of themes when it is first
/// built, depending on the provided `themes_filter`. For example, when a
/// theme is installed, the `themes_filter` is set to the new theme names
/// and, if we used `unwrap_or(0)` as a fallback, the first theme in the
/// list would be shown as "active".
original_theme_id: Option<usize>,
/// The currently selected new theme.
new_theme: Arc<Theme>,
selection_completed: bool,
@@ -174,10 +182,15 @@ impl ThemeSelectorDelegate {
.then(a.name.cmp(&b.name))
});
let original_theme_id = themes
.iter()
.position(|meta| meta.name == original_theme.name);
let matches: Vec<StringMatch> = themes
.iter()
.map(|meta| StringMatch {
candidate_id: 0,
.enumerate()
.map(|(id, meta)| StringMatch {
candidate_id: id,
score: 0.0,
positions: Default::default(),
string: meta.name.to_string(),
@@ -196,6 +209,7 @@ impl ThemeSelectorDelegate {
matches,
original_theme_settings,
original_system_appearance,
original_theme_id,
new_theme: original_theme, // Start with the original theme.
selected_index,
selection_completed: false,
@@ -204,6 +218,13 @@ impl ThemeSelectorDelegate {
}
}
fn is_original_theme(&self, index: usize) -> bool {
self.matches
.get(index)
.zip(self.original_theme_id)
.is_some_and(|(mat, original_theme_id)| mat.candidate_id == original_theme_id)
}
fn show_selected_theme(
&mut self,
cx: &mut Context<Picker<ThemeSelectorDelegate>>,
@@ -487,6 +508,7 @@ impl PickerDelegate for ThemeSelectorDelegate {
_cx: &mut Context<Picker<Self>>,
) -> Option<Self::ListItem> {
let theme_match = &self.matches.get(ix)?;
let is_original_theme = self.is_original_theme(ix);
Some(
ListItem::new(ix)
@@ -496,7 +518,10 @@ impl PickerDelegate for ThemeSelectorDelegate {
.child(HighlightedLabel::new(
theme_match.string.clone(),
theme_match.positions.clone(),
)),
))
.when(is_original_theme, |this| {
this.end_slot(Icon::new(IconName::Check).color(Color::Muted))
}),
)
}