Make selectors stylable via theme

Max Brunsfeld and Nate Butler created

* input editor container style
* "no matches" message style

Co-Authored-By: Nate Butler <nate@zed.dev>

Change summary

zed/assets/themes/_base.toml | 10 +++++-----
zed/src/chat_panel.rs        |  2 +-
zed/src/file_finder.rs       | 14 +++++++++++---
zed/src/theme.rs             | 13 +++++++------
zed/src/theme_selector.rs    |  8 ++++++--
5 files changed, 30 insertions(+), 17 deletions(-)

Detailed changes

zed/assets/themes/_base.toml 🔗

@@ -88,15 +88,12 @@ corner_radius = 6
 border = { color = "#000000", width = 1 }
 background = "$surface.0"
 
-[chat_panel.input_editor_container]
+[chat_panel.input_editor]
 background = "$surface.1"
 corner_radius = 6
 padding = 6
-
-[chat_panel.input_editor]
 text = "$text.1.color"
 placeholder_text = "$text.2.color"
-background = "$surface.1"
 selection = "$selection.host"
 
 [chat_panel.sign_in_prompt]
@@ -109,7 +106,6 @@ color = "$text.1.color"
 
 [selector]
 background = "$surface.0"
-text = "$text.0"
 padding = 8
 margin.top = 12
 corner_radius = 6
@@ -117,6 +113,10 @@ shadow = { offset = [0, 2], blur = 16, color = "$shadow.0" }
 input_editor = "$chat_panel.input_editor"
 border = { width = 1, color = "$border.0" }
 
+[selector.empty]
+text = "$text.0"
+padding = { left = 16, right = 16, top = 4, bottom = 4 }
+
 [selector.item]
 text = "$text.1"
 highlight_text = { extends = "$text.base", color = "$syntax.keyword.color", weight = "$syntax.keyword.weight" }

zed/src/chat_panel.rs 🔗

@@ -258,7 +258,7 @@ impl ChatPanel {
     fn render_input_box(&self) -> ElementBox {
         let theme = &self.settings.borrow().theme;
         Container::new(ChildView::new(self.input_editor.id()).boxed())
-            .with_style(&theme.chat_panel.input_editor_container)
+            .with_style(&theme.chat_panel.input_editor.container)
             .boxed()
     }
 

zed/src/file_finder.rs 🔗

@@ -86,7 +86,11 @@ impl View for FileFinder {
             ConstrainedBox::new(
                 Container::new(
                     Flex::new(Axis::Vertical)
-                        .with_child(ChildView::new(self.query_editor.id()).boxed())
+                        .with_child(
+                            Container::new(ChildView::new(self.query_editor.id()).boxed())
+                                .with_style(&settings.theme.selector.input_editor.container)
+                                .boxed(),
+                        )
                         .with_child(Flexible::new(1.0, self.render_matches()).boxed())
                         .boxed(),
                 )
@@ -117,9 +121,13 @@ impl FileFinder {
         if self.matches.is_empty() {
             let settings = self.settings.borrow();
             return Container::new(
-                Label::new("No matches".into(), settings.theme.selector.label.clone()).boxed(),
+                Label::new(
+                    "No matches".into(),
+                    settings.theme.selector.empty.label.clone(),
+                )
+                .boxed(),
             )
-            .with_margin_top(6.0)
+            .with_style(&settings.theme.selector.empty.container)
             .named("empty matches");
         }
 

zed/src/theme.rs 🔗

@@ -75,7 +75,6 @@ pub struct ChatPanel {
     pub container: ContainerStyle,
     pub message: ChatMessage,
     pub channel_select: ChannelSelect,
-    pub input_editor_container: ContainerStyle,
     pub input_editor: InputEditorStyle,
     pub sign_in_prompt: TextStyle,
     pub hovered_sign_in_prompt: TextStyle,
@@ -114,9 +113,7 @@ pub struct ChannelName {
 pub struct Selector {
     #[serde(flatten)]
     pub container: ContainerStyle,
-    #[serde(flatten)]
-    pub label: LabelStyle,
-
+    pub empty: ContainedLabel,
     pub input_editor: InputEditorStyle,
     pub item: ContainedLabel,
     pub active_item: ContainedLabel,
@@ -154,9 +151,10 @@ pub struct EditorStyle {
 
 #[derive(Clone, Deserialize)]
 pub struct InputEditorStyle {
+    #[serde(flatten)]
+    pub container: ContainerStyle,
     pub text: HighlightStyle,
     pub placeholder_text: HighlightStyle,
-    pub background: Color,
     pub selection: SelectionStyle,
 }
 
@@ -212,7 +210,10 @@ impl InputEditorStyle {
         EditorStyle {
             text: self.text.clone(),
             placeholder_text: self.placeholder_text.clone(),
-            background: self.background,
+            background: self
+                .container
+                .background_color
+                .unwrap_or(Color::transparent_black()),
             selection: self.selection,
             ..Default::default()
         }

zed/src/theme_selector.rs 🔗

@@ -208,9 +208,13 @@ impl ThemeSelector {
         if self.matches.is_empty() {
             let settings = self.settings.borrow();
             return Container::new(
-                Label::new("No matches".into(), settings.theme.selector.label.clone()).boxed(),
+                Label::new(
+                    "No matches".into(),
+                    settings.theme.selector.empty.label.clone(),
+                )
+                .boxed(),
             )
-            .with_margin_top(6.0)
+            .with_style(&settings.theme.selector.empty.container)
             .named("empty matches");
         }