Allow the context menu to take an `icon_color` (#23600)

Danilo Leal created

Doing this to enable customization in the Assistant 2 context picker.

Release Notes:

- N/A

Change summary

crates/ui/src/components/context_menu.rs | 42 +++++++++++++++++++------
1 file changed, 31 insertions(+), 11 deletions(-)

Detailed changes

crates/ui/src/components/context_menu.rs 🔗

@@ -41,8 +41,9 @@ pub struct ContextMenuEntry {
     toggle: Option<(IconPosition, bool)>,
     label: SharedString,
     icon: Option<IconName>,
-    icon_size: IconSize,
     icon_position: IconPosition,
+    icon_size: IconSize,
+    icon_color: Option<Color>,
     handler: Rc<dyn Fn(Option<&FocusHandle>, &mut WindowContext)>,
     action: Option<Box<dyn Action>>,
     disabled: bool,
@@ -54,8 +55,9 @@ impl ContextMenuEntry {
             toggle: None,
             label: label.into(),
             icon: None,
-            icon_size: IconSize::Small,
             icon_position: IconPosition::Start,
+            icon_size: IconSize::Small,
+            icon_color: None,
             handler: Rc::new(|_, _| {}),
             action: None,
             disabled: false,
@@ -77,6 +79,11 @@ impl ContextMenuEntry {
         self
     }
 
+    pub fn icon_color(mut self, icon_color: Color) -> Self {
+        self.icon_color = Some(icon_color);
+        self
+    }
+
     pub fn toggle(mut self, toggle_position: IconPosition, toggled: bool) -> Self {
         self.toggle = Some((toggle_position, toggled));
         self
@@ -188,8 +195,9 @@ impl ContextMenu {
             label: label.into(),
             handler: Rc::new(move |_, cx| handler(cx)),
             icon: None,
-            icon_size: IconSize::Small,
             icon_position: IconPosition::End,
+            icon_size: IconSize::Small,
+            icon_color: None,
             action,
             disabled: false,
         }));
@@ -209,8 +217,9 @@ impl ContextMenu {
             label: label.into(),
             handler: Rc::new(move |_, cx| handler(cx)),
             icon: None,
-            icon_size: IconSize::Small,
             icon_position: position,
+            icon_size: IconSize::Small,
+            icon_color: None,
             action,
             disabled: false,
         }));
@@ -262,6 +271,7 @@ impl ContextMenu {
             icon: None,
             icon_position: IconPosition::End,
             icon_size: IconSize::Small,
+            icon_color: None,
             disabled: false,
         }));
         self
@@ -286,6 +296,7 @@ impl ContextMenu {
             icon: None,
             icon_size: IconSize::Small,
             icon_position: IconPosition::End,
+            icon_color: None,
             disabled: true,
         }));
         self
@@ -301,6 +312,7 @@ impl ContextMenu {
             icon: Some(IconName::ArrowUpRight),
             icon_size: IconSize::XSmall,
             icon_position: IconPosition::End,
+            icon_color: None,
             disabled: false,
         }));
         self
@@ -508,39 +520,47 @@ impl Render for ContextMenu {
                                     label,
                                     handler,
                                     icon,
-                                    icon_size,
                                     icon_position,
+                                    icon_size,
+                                    icon_color,
                                     action,
                                     disabled,
                                 }) => {
                                     let handler = handler.clone();
                                     let menu = cx.view().downgrade();
-                                    let color = if *disabled {
+                                    let icon_color = if *disabled {
+                                        Color::Muted
+                                    } else {
+                                        icon_color.unwrap_or(Color::Default)
+                                    };
+                                    let label_color = if *disabled {
                                         Color::Muted
                                     } else {
                                         Color::Default
                                     };
                                     let label_element = if let Some(icon_name) = icon {
                                         h_flex()
-                                            .gap_1()
+                                            .gap_2()
                                             .when(*icon_position == IconPosition::Start, |flex| {
                                                 flex.child(
                                                     Icon::new(*icon_name)
                                                         .size(*icon_size)
-                                                        .color(color),
+                                                        .color(icon_color),
                                                 )
                                             })
-                                            .child(Label::new(label.clone()).color(color))
+                                            .child(Label::new(label.clone()).color(label_color))
                                             .when(*icon_position == IconPosition::End, |flex| {
                                                 flex.child(
                                                     Icon::new(*icon_name)
                                                         .size(*icon_size)
-                                                        .color(color),
+                                                        .color(icon_color),
                                                 )
                                             })
                                             .into_any_element()
                                     } else {
-                                        Label::new(label.clone()).color(color).into_any_element()
+                                        Label::new(label.clone())
+                                            .color(label_color)
+                                            .into_any_element()
                                     };
 
                                     ListItem::new(ix)