Detailed changes
@@ -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
@@ -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<Self>) {
+ window.focus_next();
+ cx.notify();
+ }
+
+ fn select_previous(&mut self, _: &SelectPrevious, window: &mut Window, cx: &mut Context<Self>) {
+ window.focus_prev();
+ cx.notify();
+ }
+}
+
impl Render for WelcomePage {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> 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| {
@@ -393,6 +393,11 @@ impl ButtonCommon for Button {
self
}
+ fn tab_index(mut self, tab_index: impl Into<isize>) -> Self {
+ self.base = self.base.tab_index(tab_index);
+ self
+ }
+
fn layer(mut self, elevation: ElevationIndex) -> Self {
self.base = self.base.layer(elevation);
self
@@ -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<isize>) -> Self;
+
fn layer(self, elevation: ElevationIndex) -> Self;
}
@@ -393,6 +395,7 @@ pub struct ButtonLike {
pub(super) width: Option<DefiniteLength>,
pub(super) height: Option<DefiniteLength>,
pub(super) layer: Option<ElevationIndex>,
+ tab_index: Option<isize>,
size: ButtonSize,
rounding: Option<ButtonLikeRounding>,
tooltip: Option<Box<dyn Fn(&mut Window, &mut App) -> 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<isize>) -> 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(
@@ -164,6 +164,11 @@ impl ButtonCommon for IconButton {
self
}
+ fn tab_index(mut self, tab_index: impl Into<isize>) -> Self {
+ self.base = self.base.tab_index(tab_index);
+ self
+ }
+
fn layer(mut self, elevation: ElevationIndex) -> Self {
self.base = self.base.layer(elevation);
self
@@ -121,6 +121,11 @@ impl ButtonCommon for ToggleButton {
self
}
+ fn tab_index(mut self, tab_index: impl Into<isize>) -> Self {
+ self.base = self.base.tab_index(tab_index);
+ self
+ }
+
fn layer(mut self, elevation: ElevationIndex) -> Self {
self.base = self.base.layer(elevation);
self