diff --git a/crates/onboarding/Cargo.toml b/crates/onboarding/Cargo.toml index 7e76b150a9..436c714cf3 100644 --- a/crates/onboarding/Cargo.toml +++ b/crates/onboarding/Cargo.toml @@ -15,13 +15,13 @@ path = "src/onboarding.rs" default = [] [dependencies] -anyhow.workspace = true ai_onboarding.workspace = true +anyhow.workspace = true client.workspace = true command_palette_hooks.workspace = true component.workspace = true -documented.workspace = true db.workspace = true +documented.workspace = true editor.workspace = true feature_flags.workspace = true fs.workspace = true diff --git a/crates/onboarding/src/welcome.rs b/crates/onboarding/src/welcome.rs index 213032f1b3..d4d6c3f701 100644 --- a/crates/onboarding/src/welcome.rs +++ b/crates/onboarding/src/welcome.rs @@ -2,6 +2,7 @@ use gpui::{ Action, App, Context, Entity, EventEmitter, FocusHandle, Focusable, InteractiveElement, NoAction, ParentElement, Render, Styled, Window, actions, }; +use menu::{SelectNext, SelectPrevious}; use ui::{ButtonLike, Divider, DividerColor, KeyBinding, Vector, VectorName, prelude::*}; use workspace::{ NewFile, Open, WorkspaceId, @@ -124,6 +125,7 @@ impl SectionEntry { cx: &App, ) -> impl IntoElement { ButtonLike::new(("onboarding-button-id", button_index)) + .tab_index(button_index as isize) .full_width() .size(ButtonSize::Medium) .child( @@ -153,10 +155,23 @@ pub struct WelcomePage { focus_handle: FocusHandle, } +impl WelcomePage { + fn select_next(&mut self, _: &SelectNext, window: &mut Window, cx: &mut Context) { + window.focus_next(); + cx.notify(); + } + + fn select_previous(&mut self, _: &SelectPrevious, window: &mut Window, cx: &mut Context) { + window.focus_prev(); + cx.notify(); + } +} + impl Render for WelcomePage { fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { - let (first_section, second_entries) = CONTENT; + let (first_section, second_section) = CONTENT; let first_section_entries = first_section.entries.len(); + let last_index = first_section_entries + second_section.entries.len(); h_flex() .size_full() @@ -165,6 +180,8 @@ impl Render for WelcomePage { .bg(cx.theme().colors().editor_background) .key_context("Welcome") .track_focus(&self.focus_handle(cx)) + .on_action(cx.listener(Self::select_previous)) + .on_action(cx.listener(Self::select_next)) .child( h_flex() .px_12() @@ -202,7 +219,7 @@ impl Render for WelcomePage { window, cx, )) - .child(second_entries.render( + .child(second_section.render( first_section_entries, &self.focus_handle, window, @@ -220,6 +237,7 @@ impl Render for WelcomePage { .border_dashed() .child( Button::new("welcome-exit", "Return to Setup") + .tab_index(last_index as isize) .full_width() .label_size(LabelSize::XSmall) .on_click(|_, window, cx| { diff --git a/crates/ui/src/components/button/button.rs b/crates/ui/src/components/button/button.rs index cae5d0e2ca..19f782fb98 100644 --- a/crates/ui/src/components/button/button.rs +++ b/crates/ui/src/components/button/button.rs @@ -393,6 +393,11 @@ impl ButtonCommon for Button { self } + fn tab_index(mut self, tab_index: impl Into) -> Self { + self.base = self.base.tab_index(tab_index); + self + } + fn layer(mut self, elevation: ElevationIndex) -> Self { self.base = self.base.layer(elevation); self diff --git a/crates/ui/src/components/button/button_like.rs b/crates/ui/src/components/button/button_like.rs index 03f7964f35..15ab00e7e5 100644 --- a/crates/ui/src/components/button/button_like.rs +++ b/crates/ui/src/components/button/button_like.rs @@ -1,7 +1,7 @@ use documented::Documented; use gpui::{ AnyElement, AnyView, ClickEvent, CursorStyle, DefiniteLength, Hsla, MouseButton, - MouseDownEvent, MouseUpEvent, Rems, relative, transparent_black, + MouseDownEvent, MouseUpEvent, Rems, StyleRefinement, relative, transparent_black, }; use smallvec::SmallVec; @@ -37,6 +37,8 @@ pub trait ButtonCommon: Clickable + Disableable { /// exceptions might a scroll bar, or a slider. fn tooltip(self, tooltip: impl Fn(&mut Window, &mut App) -> AnyView + 'static) -> Self; + fn tab_index(self, tab_index: impl Into) -> Self; + fn layer(self, elevation: ElevationIndex) -> Self; } @@ -393,6 +395,7 @@ pub struct ButtonLike { pub(super) width: Option, pub(super) height: Option, pub(super) layer: Option, + tab_index: Option, size: ButtonSize, rounding: Option, tooltip: Option AnyView>>, @@ -421,6 +424,7 @@ impl ButtonLike { on_click: None, on_right_click: None, layer: None, + tab_index: None, } } @@ -525,6 +529,11 @@ impl ButtonCommon for ButtonLike { self } + fn tab_index(mut self, tab_index: impl Into) -> Self { + self.tab_index = Some(tab_index.into()); + self + } + fn layer(mut self, elevation: ElevationIndex) -> Self { self.layer = Some(elevation); self @@ -554,6 +563,7 @@ impl RenderOnce for ButtonLike { self.base .h_flex() .id(self.id.clone()) + .when_some(self.tab_index, |this, tab_index| this.tab_index(tab_index)) .font_ui(cx) .group("") .flex_none() @@ -591,8 +601,12 @@ impl RenderOnce for ButtonLike { } }) .when(!self.disabled, |this| { + let hovered_style = style.hovered(self.layer, cx); + let focus_color = + |refinement: StyleRefinement| refinement.bg(hovered_style.background); this.cursor(self.cursor_style) - .hover(|hover| hover.bg(style.hovered(self.layer, cx).background)) + .hover(focus_color) + .focus(focus_color) .active(|active| active.bg(style.active(cx).background)) }) .when_some( diff --git a/crates/ui/src/components/button/icon_button.rs b/crates/ui/src/components/button/icon_button.rs index e5d13e09cd..8d8718a634 100644 --- a/crates/ui/src/components/button/icon_button.rs +++ b/crates/ui/src/components/button/icon_button.rs @@ -164,6 +164,11 @@ impl ButtonCommon for IconButton { self } + fn tab_index(mut self, tab_index: impl Into) -> Self { + self.base = self.base.tab_index(tab_index); + self + } + fn layer(mut self, elevation: ElevationIndex) -> Self { self.base = self.base.layer(elevation); self diff --git a/crates/ui/src/components/button/toggle_button.rs b/crates/ui/src/components/button/toggle_button.rs index a1e4d65a24..d4d47da9b6 100644 --- a/crates/ui/src/components/button/toggle_button.rs +++ b/crates/ui/src/components/button/toggle_button.rs @@ -121,6 +121,11 @@ impl ButtonCommon for ToggleButton { self } + fn tab_index(mut self, tab_index: impl Into) -> Self { + self.base = self.base.tab_index(tab_index); + self + } + fn layer(mut self, elevation: ElevationIndex) -> Self { self.base = self.base.layer(elevation); self