diff --git a/assets/icons/arrow_down.svg b/assets/icons/arrow_down.svg new file mode 100644 index 0000000000..7d78497e6d --- /dev/null +++ b/assets/icons/arrow_down.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/arrow_left.svg b/assets/icons/arrow_left.svg index 186c9c7457..57ee750490 100644 --- a/assets/icons/arrow_left.svg +++ b/assets/icons/arrow_left.svg @@ -1,3 +1,3 @@ - - + + diff --git a/assets/icons/arrow_right.svg b/assets/icons/arrow_right.svg index 7bae7f4801..7a5b1174eb 100644 --- a/assets/icons/arrow_right.svg +++ b/assets/icons/arrow_right.svg @@ -1,3 +1,3 @@ - - + + diff --git a/assets/icons/arrow_up.svg b/assets/icons/arrow_up.svg new file mode 100644 index 0000000000..81dfee8042 --- /dev/null +++ b/assets/icons/arrow_up.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/command.svg b/assets/icons/command.svg new file mode 100644 index 0000000000..d38389aea4 --- /dev/null +++ b/assets/icons/command.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/control.svg b/assets/icons/control.svg new file mode 100644 index 0000000000..94189dc07d --- /dev/null +++ b/assets/icons/control.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/option.svg b/assets/icons/option.svg new file mode 100644 index 0000000000..9d54a6f34b --- /dev/null +++ b/assets/icons/option.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/return.svg b/assets/icons/return.svg new file mode 100644 index 0000000000..683519c306 --- /dev/null +++ b/assets/icons/return.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/icons/shift.svg b/assets/icons/shift.svg new file mode 100644 index 0000000000..0232114777 --- /dev/null +++ b/assets/icons/shift.svg @@ -0,0 +1,3 @@ + + + diff --git a/crates/command_palette2/src/command_palette.rs b/crates/command_palette2/src/command_palette.rs index b0d18c593d..076a2625a1 100644 --- a/crates/command_palette2/src/command_palette.rs +++ b/crates/command_palette2/src/command_palette.rs @@ -79,7 +79,7 @@ impl Render for CommandPalette { type Element = Div; fn render(&mut self, _cx: &mut ViewContext) -> Self::Element { - v_stack().w_96().child(self.picker.clone()) + v_stack().min_w_96().child(self.picker.clone()) } } @@ -303,6 +303,7 @@ impl PickerDelegate for CommandPaletteDelegate { Some( ListItem::new(ix).inset(true).selected(selected).child( h_stack() + .w_full() .justify_between() .child(HighlightedLabel::new( command.name.clone(), diff --git a/crates/theme2/src/default_colors.rs b/crates/theme2/src/default_colors.rs index 91efecbfb3..4a47bc0536 100644 --- a/crates/theme2/src/default_colors.rs +++ b/crates/theme2/src/default_colors.rs @@ -23,15 +23,15 @@ impl ThemeColors { surface_background: neutral().light().step_2(), background: neutral().light().step_1(), element_background: neutral().light().step_3(), - element_hover: neutral().light().step_4(), - element_active: neutral().light().step_5(), - element_selected: neutral().light().step_5(), + element_hover: neutral().light_alpha().step_4(), + element_active: neutral().light_alpha().step_5(), + element_selected: neutral().light_alpha().step_5(), element_disabled: neutral().light_alpha().step_3(), drop_target_background: blue().light_alpha().step_2(), ghost_element_background: system.transparent, - ghost_element_hover: neutral().light().step_4(), - ghost_element_active: neutral().light().step_5(), - ghost_element_selected: neutral().light().step_5(), + ghost_element_hover: neutral().light_alpha().step_4(), + ghost_element_active: neutral().light_alpha().step_5(), + ghost_element_selected: neutral().light_alpha().step_5(), ghost_element_disabled: neutral().light_alpha().step_3(), text: yellow().light().step_9(), text_muted: neutral().light().step_11(), @@ -95,15 +95,15 @@ impl ThemeColors { surface_background: neutral().dark().step_2(), background: neutral().dark().step_1(), element_background: neutral().dark().step_3(), - element_hover: neutral().dark().step_4(), - element_active: neutral().dark().step_5(), - element_selected: neutral().dark().step_5(), + element_hover: neutral().dark_alpha().step_4(), + element_active: neutral().dark_alpha().step_5(), + element_selected: neutral().dark_alpha().step_5(), element_disabled: neutral().dark_alpha().step_3(), drop_target_background: blue().dark_alpha().step_2(), ghost_element_background: system.transparent, - ghost_element_hover: neutral().dark().step_4(), - ghost_element_active: neutral().dark().step_5(), - ghost_element_selected: neutral().dark().step_5(), + ghost_element_hover: neutral().dark_alpha().step_4(), + ghost_element_active: neutral().dark_alpha().step_5(), + ghost_element_selected: neutral().dark_alpha().step_5(), ghost_element_disabled: neutral().dark_alpha().step_3(), text: neutral().dark().step_12(), text_muted: neutral().dark().step_11(), diff --git a/crates/theme2/src/one_themes.rs b/crates/theme2/src/one_themes.rs index 2802bd17b5..2f663618a6 100644 --- a/crates/theme2/src/one_themes.rs +++ b/crates/theme2/src/one_themes.rs @@ -20,7 +20,7 @@ pub fn one_family() -> ThemeFamily { pub(crate) fn one_dark() -> Theme { let bg = hsla(215. / 360., 12. / 100., 15. / 100., 1.); let editor = hsla(220. / 360., 12. / 100., 18. / 100., 1.); - let elevated_surface = hsla(220. / 360., 12. / 100., 18. / 100., 1.); + let elevated_surface = hsla(225. / 360., 12. / 100., 17. / 100., 1.); let blue = hsla(207.8 / 360., 81. / 100., 66. / 100., 1.0); let gray = hsla(218.8 / 360., 10. / 100., 40. / 100., 1.0); @@ -48,7 +48,7 @@ pub(crate) fn one_dark() -> Theme { elevated_surface_background: elevated_surface, surface_background: bg, background: bg, - element_background: elevated_surface, + element_background: hsla(223.0 / 360., 13. / 100., 21. / 100., 1.0), element_hover: hsla(225.0 / 360., 11.8 / 100., 26.7 / 100., 1.0), element_active: hsla(220.0 / 360., 11.8 / 100., 20.0 / 100., 1.0), element_selected: hsla(224.0 / 360., 11.3 / 100., 26.1 / 100., 1.0), diff --git a/crates/ui2/src/components/icon.rs b/crates/ui2/src/components/icon.rs index 8190871767..34b1bacdb9 100644 --- a/crates/ui2/src/components/icon.rs +++ b/crates/ui2/src/components/icon.rs @@ -14,6 +14,8 @@ pub enum IconSize { pub enum Icon { Ai, ArrowLeft, + ArrowUp, + ArrowDown, ArrowRight, ArrowUpRight, AtSign, @@ -71,6 +73,11 @@ pub enum Icon { Terminal, WholeWord, XCircle, + Command, + Control, + Shift, + Option, + Return, } impl Icon { @@ -79,6 +86,8 @@ impl Icon { Icon::Ai => "icons/ai.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", @@ -135,6 +144,11 @@ impl Icon { Icon::Terminal => "icons/terminal.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", } } } @@ -151,8 +165,8 @@ impl RenderOnce for IconElement { fn render(self, cx: &mut WindowContext) -> Self::Rendered { let svg_size = match self.size { - IconSize::Small => rems(0.75), - IconSize::Medium => rems(0.9375), + IconSize::Small => rems(14. / 16.), + IconSize::Medium => rems(16. / 16.), }; svg() diff --git a/crates/ui2/src/components/keybinding.rs b/crates/ui2/src/components/keybinding.rs index 78300ebe54..993e2f323e 100644 --- a/crates/ui2/src/components/keybinding.rs +++ b/crates/ui2/src/components/keybinding.rs @@ -1,5 +1,5 @@ -use crate::prelude::*; -use gpui::{Action, Div, IntoElement}; +use crate::{h_stack, prelude::*, Icon, IconElement, IconSize}; +use gpui::{relative, rems, Action, Div, IntoElement, Keystroke}; #[derive(IntoElement, Clone)] pub struct KeyBinding { @@ -13,20 +13,36 @@ pub struct KeyBinding { impl RenderOnce for KeyBinding { type Rendered = Div; - fn render(self, _cx: &mut WindowContext) -> Self::Rendered { - div() - .flex() + fn render(self, cx: &mut WindowContext) -> Self::Rendered { + h_stack() + .flex_none() .gap_2() .children(self.key_binding.keystrokes().iter().map(|keystroke| { - div() - .flex() - .gap_1() + let key_icon = Self::icon_for_key(&keystroke); + + h_stack() + .flex_none() + .gap_0p5() + .bg(cx.theme().colors().element_background) + .p_0p5() + .rounded_sm() .when(keystroke.modifiers.function, |el| el.child(Key::new("fn"))) - .when(keystroke.modifiers.control, |el| el.child(Key::new("^"))) - .when(keystroke.modifiers.alt, |el| el.child(Key::new("⌥"))) - .when(keystroke.modifiers.command, |el| el.child(Key::new("⌘"))) - .when(keystroke.modifiers.shift, |el| el.child(Key::new("⇧"))) - .child(Key::new(keystroke.key.clone())) + .when(keystroke.modifiers.control, |el| { + el.child(KeyIcon::new(Icon::Control)) + }) + .when(keystroke.modifiers.alt, |el| { + el.child(KeyIcon::new(Icon::Option)) + }) + .when(keystroke.modifiers.command, |el| { + el.child(KeyIcon::new(Icon::Command)) + }) + .when(keystroke.modifiers.shift, |el| { + el.child(KeyIcon::new(Icon::Shift)) + }) + .when_some(key_icon, |el, icon| el.child(KeyIcon::new(icon))) + .when(key_icon.is_none(), |el| { + el.child(Key::new(keystroke.key.to_uppercase().clone())) + }) })) } } @@ -39,6 +55,22 @@ impl KeyBinding { Some(Self::new(key_binding)) } + fn icon_for_key(keystroke: &Keystroke) -> Option { + let mut icon: Option = None; + + if keystroke.key == "left".to_string() { + icon = Some(Icon::ArrowLeft); + } else if keystroke.key == "right".to_string() { + icon = Some(Icon::ArrowRight); + } else if keystroke.key == "up".to_string() { + icon = Some(Icon::ArrowUp); + } else if keystroke.key == "down".to_string() { + icon = Some(Icon::ArrowDown); + } + + icon + } + pub fn new(key_binding: gpui::KeyBinding) -> Self { Self { key_binding } } @@ -53,13 +85,18 @@ impl RenderOnce for Key { type Rendered = Div; fn render(self, cx: &mut WindowContext) -> Self::Rendered { + let single_char = self.key.len() == 1; + div() - .px_2() .py_0() - .rounded_md() - .text_ui_sm() + .when(single_char, |el| { + el.w(rems(14. / 16.)).flex().flex_none().justify_center() + }) + .when(!single_char, |el| el.px_0p5()) + .h(rems(14. / 16.)) + .text_ui() + .line_height(relative(1.)) .text_color(cx.theme().colors().text) - .bg(cx.theme().colors().element_background) .child(self.key.clone()) } } @@ -69,3 +106,24 @@ impl Key { Self { key: key.into() } } } + +#[derive(IntoElement)] +pub struct KeyIcon { + icon: Icon, +} + +impl RenderOnce for KeyIcon { + type Rendered = Div; + + fn render(self, _cx: &mut WindowContext) -> Self::Rendered { + div() + .w(rems(14. / 16.)) + .child(IconElement::new(self.icon).size(IconSize::Small)) + } +} + +impl KeyIcon { + pub fn new(icon: Icon) -> Self { + Self { icon } + } +}