Add additional keybinding icons (#3861)

Nate Butler created

Note: There is still some consistency work to do between all the
keybinding icons. I'll tackle this at a later time.

- Adds `return`, `space`, `tab`, `escape`, `pgup` and `pgdn`
- Simplifies keybinding rendering (due to theme changes)
- Standardizes icon naming convention to use `_` everywhere.

Release Notes:

- Zed 2: Added additional keybinding icons

Change summary

assets/icons/at_sign.svg               |  2 
assets/icons/bell_off.svg              |  0 
assets/icons/bell_ring.svg             |  0 
assets/icons/delete.svg                |  5 -
assets/icons/escape.svg                |  1 
assets/icons/magic_wand.svg            |  0 
assets/icons/mail_open.svg             |  0 
assets/icons/mic_mute.svg              |  0 
assets/icons/page_down.svg             |  2 
assets/icons/page_up.svg               |  2 
assets/icons/return.svg                |  4 -
assets/icons/select_all.svg            |  0 
assets/icons/space.svg                 |  1 
assets/icons/speaker_loud.svg          |  0 
assets/icons/speaker_off.svg           |  0 
assets/icons/tab.svg                   |  1 
crates/ui/src/components/icon.rs       | 80 +++++++++++++++------------
crates/ui/src/components/keybinding.rs | 19 ++++-
18 files changed, 69 insertions(+), 48 deletions(-)

Detailed changes

assets/icons/at-sign.svg → assets/icons/at_sign.svg 🔗

@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-at-sign"><circle cx="12" cy="12" r="4"/><path d="M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-4 8"/></svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-at-sign"><circle cx="12" cy="12" r="4"/><path d="M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-4 8"/></svg>

assets/icons/delete.svg 🔗

@@ -1,4 +1 @@
-<svg width="15" height="11" viewBox="0 0 15 11" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M0.272727 11V0.818182H9.77841L14.8395 5.90909L9.77841 11H0.272727ZM4.03125 8.89205L3.3054 8.15625L8.54545 2.92614L9.27131 3.66193L4.03125 8.89205ZM8.54545 8.89205L3.3054 3.66193L4.03125 2.92614L9.27131 8.15625L8.54545 8.89205ZM1.34659 9.90625H9.34091L13.3182 5.90909L9.34091 1.91193H1.34659V9.90625Z" fill="black"/>
-</svg>
-
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-delete"><path d="M20 5H9l-7 7 7 7h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2Z"/><line x1="18" x2="12" y1="9" y2="15"/><line x1="12" x2="18" y1="9" y2="15"/></svg>

assets/icons/escape.svg 🔗

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-up-left-from-circle"><path d="M2 8V2h6"/><path d="m2 2 10 10"/><path d="M12 2A10 10 0 1 1 2 12"/></svg>

assets/icons/page_down.svg 🔗

@@ -0,0 +1,6 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M9.19131 16V8.53964H10.6313L13.2953 14.3455C13.2553 13.8719 13.2153 13.4016 13.1753 12.9347C13.1353 12.4677 13.1153 11.9975 13.1153 11.5238V8.53964H14.3993V16H12.9593L10.2953 10.1941C10.3353 10.6678 10.3753 11.1381 10.4153 11.605C10.4553 12.0719 10.4753 12.5422 10.4753 13.0159V16H9.19131Z" fill="black"/>

assets/icons/page_up.svg 🔗

@@ -0,0 +1,13 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_1650_1657)">

assets/icons/return.svg 🔗

@@ -1,3 +1 @@
-<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path fill-rule="evenodd" clip-rule="evenodd" d="M8.375 1.63C8.375 1.28482 8.65482 1.005 9 1.005H12.375C13.8247 1.005 15 2.18025 15 3.63V7.625C15 9.07474 13.8247 10.25 12.375 10.25H3.13388L6.07194 13.1881C6.31602 13.4321 6.31602 13.8279 6.07194 14.0719C5.82786 14.316 5.43214 14.316 5.18806 14.0719L1.18306 10.0669C0.938981 9.82286 0.938981 9.42714 1.18306 9.18306L5.18306 5.18306C5.42714 4.93898 5.82286 4.93898 6.06694 5.18306C6.31102 5.42714 6.31102 5.82286 6.06694 6.06694L3.13388 9H12.375C13.1344 9 13.75 8.38439 13.75 7.625V3.63C13.75 2.87061 13.1344 2.255 12.375 2.255H9C8.65482 2.255 8.375 1.97518 8.375 1.63Z" fill="black"/>
-</svg>
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-corner-down-left"><polyline points="9 10 4 15 9 20"/><path d="M20 4v7a4 4 0 0 1-4 4H4"/></svg>

assets/icons/space.svg 🔗

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-space"><path d="M22 17v1c0 .5-.5 1-1 1H3c-.5 0-1-.5-1-1v-1"/></svg>

assets/icons/tab.svg 🔗

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-right-to-line"><path d="M17 12H3"/><path d="m11 18 6-6-6-6"/><path d="M21 5v14"/></svg>

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

@@ -24,10 +24,10 @@ impl IconSize {
 #[derive(Debug, PartialEq, Copy, Clone, EnumIter)]
 pub enum Icon {
     Ai,
-    ArrowLeft,
-    ArrowUp,
     ArrowDown,
+    ArrowLeft,
     ArrowRight,
+    ArrowUp,
     ArrowUpRight,
     AtSign,
     AudioOff,
@@ -39,25 +39,28 @@ pub enum Icon {
     Bolt,
     CaseSensitive,
     Check,
-    Copy,
     ChevronDown,
     ChevronLeft,
     ChevronRight,
     ChevronUp,
     Close,
     Collab,
+    Command,
+    Control,
     Copilot,
-    CopilotInit,
-    CopilotError,
     CopilotDisabled,
+    CopilotError,
+    CopilotInit,
+    Copy,
     Dash,
     Delete,
     Disconnected,
     Ellipsis,
     Envelope,
-    ExternalLink,
+    Escape,
     ExclamationTriangle,
     Exit,
+    ExternalLink,
     File,
     FileDoc,
     FileGeneric,
@@ -78,30 +81,32 @@ pub enum Icon {
     MagnifyingGlass,
     MailOpen,
     Maximize,
-    Minimize,
     Menu,
     MessageBubbles,
     Mic,
     MicMute,
+    Minimize,
+    Option,
+    PageDown,
+    PageUp,
     Plus,
     Public,
     Quote,
     Replace,
     ReplaceAll,
     ReplaceNext,
+    Return,
     Screen,
     SelectAll,
-    Split,
+    Shift,
     Snip,
+    Space,
+    Split,
+    Tab,
     Terminal,
+    Update,
     WholeWord,
     XCircle,
-    Command,
-    Control,
-    Shift,
-    Option,
-    Return,
-    Update,
     ZedXCopilot,
 }
 
@@ -109,40 +114,43 @@ impl Icon {
     pub fn path(self) -> &'static str {
         match self {
             Icon::Ai => "icons/ai.svg",
+            Icon::ArrowDown => "icons/arrow_down.svg",
             Icon::ArrowLeft => "icons/arrow_left.svg",
             Icon::ArrowRight => "icons/arrow_right.svg",
             Icon::ArrowUp => "icons/arrow_up.svg",
-            Icon::ArrowDown => "icons/arrow_down.svg",
             Icon::ArrowUpRight => "icons/arrow_up_right.svg",
-            Icon::AtSign => "icons/at-sign.svg",
-            Icon::AudioOff => "icons/speaker-off.svg",
+            Icon::AtSign => "icons/at_sign.svg",
+            Icon::AudioOff => "icons/speaker_off.svg",
             Icon::AudioOn => "icons/speaker-loud.svg",
             Icon::Backspace => "icons/backspace.svg",
             Icon::Bell => "icons/bell.svg",
-            Icon::BellOff => "icons/bell-off.svg",
-            Icon::BellRing => "icons/bell-ring.svg",
+            Icon::BellOff => "icons/bell_off.svg",
+            Icon::BellRing => "icons/bell_ring.svg",
             Icon::Bolt => "icons/bolt.svg",
             Icon::CaseSensitive => "icons/case_insensitive.svg",
             Icon::Check => "icons/check.svg",
-            Icon::Copy => "icons/copy.svg",
             Icon::ChevronDown => "icons/chevron_down.svg",
             Icon::ChevronLeft => "icons/chevron_left.svg",
             Icon::ChevronRight => "icons/chevron_right.svg",
             Icon::ChevronUp => "icons/chevron_up.svg",
             Icon::Close => "icons/x.svg",
             Icon::Collab => "icons/user_group_16.svg",
+            Icon::Command => "icons/command.svg",
+            Icon::Control => "icons/control.svg",
             Icon::Copilot => "icons/copilot.svg",
-            Icon::CopilotInit => "icons/copilot_init.svg",
-            Icon::CopilotError => "icons/copilot_error.svg",
             Icon::CopilotDisabled => "icons/copilot_disabled.svg",
+            Icon::CopilotError => "icons/copilot_error.svg",
+            Icon::CopilotInit => "icons/copilot_init.svg",
+            Icon::Copy => "icons/copy.svg",
             Icon::Dash => "icons/dash.svg",
             Icon::Delete => "icons/delete.svg",
             Icon::Disconnected => "icons/disconnected.svg",
             Icon::Ellipsis => "icons/ellipsis.svg",
             Icon::Envelope => "icons/feedback.svg",
+            Icon::Escape => "icons/escape.svg",
             Icon::ExclamationTriangle => "icons/warning.svg",
-            Icon::ExternalLink => "icons/external_link.svg",
             Icon::Exit => "icons/exit.svg",
+            Icon::ExternalLink => "icons/external_link.svg",
             Icon::File => "icons/file.svg",
             Icon::FileDoc => "icons/file_icons/book.svg",
             Icon::FileGeneric => "icons/file_icons/file.svg",
@@ -159,34 +167,36 @@ impl Icon {
             Icon::Hash => "icons/hash.svg",
             Icon::InlayHint => "icons/inlay_hint.svg",
             Icon::Link => "icons/link.svg",
-            Icon::MagicWand => "icons/magic-wand.svg",
+            Icon::MagicWand => "icons/magic_wand.svg",
             Icon::MagnifyingGlass => "icons/magnifying_glass.svg",
-            Icon::MailOpen => "icons/mail-open.svg",
+            Icon::MailOpen => "icons/mail_open.svg",
             Icon::Maximize => "icons/maximize.svg",
-            Icon::Minimize => "icons/minimize.svg",
             Icon::Menu => "icons/menu.svg",
             Icon::MessageBubbles => "icons/conversations.svg",
             Icon::Mic => "icons/mic.svg",
-            Icon::MicMute => "icons/mic-mute.svg",
+            Icon::MicMute => "icons/mic_mute.svg",
+            Icon::Minimize => "icons/minimize.svg",
+            Icon::Option => "icons/option.svg",
+            Icon::PageDown => "icons/page_down.svg",
+            Icon::PageUp => "icons/page_up.svg",
             Icon::Plus => "icons/plus.svg",
             Icon::Public => "icons/public.svg",
             Icon::Quote => "icons/quote.svg",
             Icon::Replace => "icons/replace.svg",
             Icon::ReplaceAll => "icons/replace_all.svg",
             Icon::ReplaceNext => "icons/replace_next.svg",
+            Icon::Return => "icons/return.svg",
             Icon::Screen => "icons/desktop.svg",
-            Icon::SelectAll => "icons/select-all.svg",
-            Icon::Split => "icons/split.svg",
+            Icon::SelectAll => "icons/select_all.svg",
+            Icon::Shift => "icons/shift.svg",
             Icon::Snip => "icons/snip.svg",
+            Icon::Space => "icons/space.svg",
+            Icon::Split => "icons/split.svg",
+            Icon::Tab => "icons/tab.svg",
             Icon::Terminal => "icons/terminal.svg",
+            Icon::Update => "icons/update.svg",
             Icon::WholeWord => "icons/word_search.svg",
             Icon::XCircle => "icons/error.svg",
-            Icon::Command => "icons/command.svg",
-            Icon::Control => "icons/control.svg",
-            Icon::Shift => "icons/shift.svg",
-            Icon::Option => "icons/option.svg",
-            Icon::Return => "icons/return.svg",
-            Icon::Update => "icons/update.svg",
             Icon::ZedXCopilot => "icons/zed_x_copilot.svg",
         }
     }

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

@@ -21,9 +21,9 @@ impl RenderOnce for KeyBinding {
                 h_stack()
                     .flex_none()
                     .gap_0p5()
-                    .bg(cx.theme().colors().element_background)
                     .p_0p5()
                     .rounded_sm()
+                    .text_color(cx.theme().colors().text_muted)
                     .when(keystroke.modifiers.function, |el| el.child(Key::new("fn")))
                     .when(keystroke.modifiers.control, |el| {
                         el.child(KeyIcon::new(Icon::Control))
@@ -70,6 +70,13 @@ impl KeyBinding {
             "down" => Some(Icon::ArrowDown),
             "backspace" => Some(Icon::Backspace),
             "delete" => Some(Icon::Delete),
+            "return" => Some(Icon::Return),
+            "enter" => Some(Icon::Return),
+            "tab" => Some(Icon::Tab),
+            "space" => Some(Icon::Space),
+            "escape" => Some(Icon::Escape),
+            "pagedown" => Some(Icon::PageDown),
+            "pageup" => Some(Icon::PageUp),
             _ => None,
         }
     }
@@ -100,7 +107,7 @@ impl RenderOnce for Key {
             .h(rems(14. / 16.))
             .text_ui()
             .line_height(relative(1.))
-            .text_color(cx.theme().colors().text)
+            .text_color(cx.theme().colors().text_muted)
             .child(self.key.clone())
     }
 }
@@ -118,9 +125,11 @@ pub struct KeyIcon {
 
 impl RenderOnce for KeyIcon {
     fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
-        div()
-            .w(rems(14. / 16.))
-            .child(IconElement::new(self.icon).size(IconSize::Small))
+        div().w(rems(14. / 16.)).child(
+            IconElement::new(self.icon)
+                .size(IconSize::Small)
+                .color(Color::Muted),
+        )
     }
 }