ui: Render keybinds for disabled actions with disabled color (#27693)

Finn Evers created

This PR ensures that keybinds for disabled actions in context menus are
also colored according th their disabled state.

### Default

| Current `main` | This PR | 
| --- | --- | 
| <img width="212" alt="main_default"
src="https://github.com/user-attachments/assets/c9f24f4b-dff1-4930-9a3c-07ce1fad516a"
/> | <img width="212" alt="pr_default"
src="https://github.com/user-attachments/assets/fd3db1b8-3a46-4b17-81e7-de66b35b4a79"
/> |

### Vim-Mode

| Current `main` | This PR | 
| --- | --- | 
| <img width="255" alt="main_vim"
src="https://github.com/user-attachments/assets/2845efd3-0109-4e00-af92-203a328d6282"
/> | <img width="255" alt="pr_vim"
src="https://github.com/user-attachments/assets/af073173-30c0-4a60-942f-0f124089c723"
/>|


Release Notes:

- Keybinds in contexts menus will now also be dimmed if the
corresponding action is currently disabled.

Change summary

crates/ui/src/components/context_menu.rs |  2 +-
crates/ui/src/components/keybinding.rs   | 18 +++++++++++++++---
2 files changed, 16 insertions(+), 4 deletions(-)

Detailed changes

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

@@ -752,7 +752,7 @@ impl ContextMenu {
                                         KeyBinding::for_action(&**action, window, cx)
                                     })
                                     .map(|binding| {
-                                        div().ml_4().child(binding).when(
+                                        div().ml_4().child(binding.disabled(*disabled)).when(
                                             *disabled && documentation_aside_callback.is_some(),
                                             |parent| parent.invisible(),
                                         )

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

@@ -20,6 +20,9 @@ pub struct KeyBinding {
 
     /// Determines whether the keybinding is meant for vim mode.
     vim_mode: bool,
+
+    /// Indicates whether the keybinding is currently disabled.
+    disabled: bool,
 }
 
 struct VimStyle(bool);
@@ -64,6 +67,7 @@ impl KeyBinding {
             platform_style: PlatformStyle::platform(),
             size: None,
             vim_mode: KeyBinding::is_vim_mode(cx),
+            disabled: false,
         }
     }
 
@@ -79,6 +83,13 @@ impl KeyBinding {
         self
     }
 
+    /// Sets whether this keybinding is currently disabled.
+    /// Disabled keybinds will be rendered in a dimmed state.
+    pub fn disabled(mut self, disabled: bool) -> Self {
+        self.disabled = disabled;
+        self
+    }
+
     pub fn vim_mode(mut self, enabled: bool) -> Self {
         self.vim_mode = enabled;
         self
@@ -98,6 +109,7 @@ impl KeyBinding {
 
 impl RenderOnce for KeyBinding {
     fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
+        let color = self.disabled.then_some(Color::Disabled);
         let use_text = self.vim_mode
             || matches!(
                 self.platform_style,
@@ -127,7 +139,7 @@ impl RenderOnce for KeyBinding {
                         el.child(
                             Key::new(
                                 keystroke_text(&keystroke, self.platform_style, self.vim_mode),
-                                None,
+                                color,
                             )
                             .size(self.size),
                         )
@@ -136,11 +148,11 @@ impl RenderOnce for KeyBinding {
                         el.children(render_modifiers(
                             &keystroke.modifiers,
                             self.platform_style,
-                            None,
+                            color,
                             self.size,
                             true,
                         ))
-                        .map(|el| el.child(self.render_key(&keystroke, None)))
+                        .map(|el| el.child(self.render_key(&keystroke, color)))
                     })
             }))
     }