ui: Use `focus_visible` method for some components (#41077)

Danilo Leal created

Using the cool, [recently
added](https://github.com/zed-industries/zed/pull/40940) `focus-visible`
support in some components. This will be particularly nice in the
settings UI, as it will not display the focus styles if you're
navigating it with a pointer device as opposed to the keyboard.

Release Notes:

- N/A

Change summary

crates/settings_ui/src/settings_ui.rs          |  7 ++---
crates/ui/src/components/button/button_like.rs | 22 ++++++++++---------
crates/ui/src/components/toggle.rs             |  2 
crates/ui/src/components/tree_view_item.rs     |  2 
crates/ui_input/src/number_field.rs            |  2 
5 files changed, 18 insertions(+), 17 deletions(-)

Detailed changes

crates/settings_ui/src/settings_ui.rs 🔗

@@ -3195,7 +3195,8 @@ fn render_toggle_button<B: Into<bool> + From<bool> + Copy>(
     };
 
     Switch::new("toggle_button", toggle_state)
-        .color(ui::SwitchColor::Accent)
+        .tab_index(0_isize)
+        .color(SwitchColor::Accent)
         .on_click({
             move |state, _window, cx| {
                 let state = *state == ui::ToggleState::Selected;
@@ -3205,8 +3206,6 @@ fn render_toggle_button<B: Into<bool> + From<bool> + Copy>(
                 .log_err(); // todo(settings_ui) don't log err
             }
         })
-        .tab_index(0_isize)
-        .color(SwitchColor::Accent)
         .into_any_element()
 }
 
@@ -3290,13 +3289,13 @@ where
             })
         }),
     )
+    .tab_index(0)
     .trigger_size(ButtonSize::Medium)
     .style(DropdownStyle::Outlined)
     .offset(gpui::Point {
         x: px(0.0),
         y: px(2.0),
     })
-    .tab_index(0)
     .into_any_element()
 }
 

crates/ui/src/components/button/button_like.rs 🔗

@@ -640,6 +640,11 @@ impl RenderOnce for ButtonLike {
             .filter(|_| self.selected)
             .unwrap_or(self.style);
 
+        let is_outlined = matches!(
+            self.style,
+            ButtonStyle::Outlined | ButtonStyle::OutlinedGhost
+        );
+
         self.base
             .h_flex()
             .id(self.id.clone())
@@ -654,13 +659,7 @@ impl RenderOnce for ButtonLike {
             .when_some(self.width, |this, width| {
                 this.w(width).justify_center().text_center()
             })
-            .when(
-                matches!(
-                    self.style,
-                    ButtonStyle::Outlined | ButtonStyle::OutlinedGhost
-                ),
-                |this| this.border_1(),
-            )
+            .when(is_outlined, |this| this.border_1())
             .when_some(self.rounding, |this, rounding| {
                 this.when(rounding.top_left, |this| this.rounded_tl_sm())
                     .when(rounding.top_right, |this| this.rounded_tr_sm())
@@ -688,13 +687,16 @@ impl RenderOnce for ButtonLike {
                 let hovered_style = style.hovered(self.layer, cx);
                 let focus_color =
                     |refinement: StyleRefinement| refinement.bg(hovered_style.background);
+
                 this.cursor(self.cursor_style)
                     .hover(focus_color)
                     .map(|this| {
-                        if matches!(self.style, ButtonStyle::Outlined) {
-                            this.focus(|s| s.border_color(cx.theme().colors().border_focused))
+                        if is_outlined {
+                            this.focus_visible(|s| {
+                                s.border_color(cx.theme().colors().border_focused)
+                            })
                         } else {
-                            this.focus(focus_color)
+                            this.focus_visible(focus_color)
                         }
                     })
                     .active(|active| active.bg(style.active(cx).background))

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

@@ -514,7 +514,7 @@ impl RenderOnce for Switch {
                 self.tab_index.filter(|_| !self.disabled),
                 |this, tab_index| {
                     this.tab_index(tab_index)
-                        .focus(|mut style| {
+                        .focus_visible(|mut style| {
                             style.border_color = Some(cx.theme().colors().border_focused);
                             style
                         })

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

@@ -159,7 +159,7 @@ impl RenderOnce for TreeViewItem {
                     .rounded_sm()
                     .border_1()
                     .border_color(transparent_border)
-                    .focus(|s| s.border_color(focused_border))
+                    .focus_visible(|s| s.border_color(focused_border))
                     .when(self.selected, |this| {
                         this.border_color(selected_border).bg(selected_bg)
                     })

crates/ui_input/src/number_field.rs 🔗

@@ -338,7 +338,7 @@ impl<T: NumberFieldType> RenderOnce for NumberField<T> {
                 .border_color(border_color)
                 .bg(bg_color)
                 .hover(|s| s.bg(hover_bg_color))
-                .focus(|s| s.border_color(focus_border_color).bg(hover_bg_color))
+                .focus_visible(|s| s.border_color(focus_border_color).bg(hover_bg_color))
                 .child(Icon::new(icon).size(IconSize::Small))
         };