settings_ui: Improve keyboard nav (#39819)
Closes #ISSUE
From notes:
```markdown
- [x] Clicking on the disclsoure icon button in the root-level tree view item should steal focus and move it to the root item (not the icon button)
- [x] [@ben] Allow left/right arrow keys to expand/collapse root tree view items in the nav
- [x] With this, make enter/space work the same as clicking (activate page, don't expand root items, focus moves to the content and leaves nav — becomes consistent with mouse interaction)
- [x] Smart cmd-shift-e: toggling focus should take you to the selected item
- [x] [@ben] pageup + pagedown in nav -> jump between root items
- [x] [@ben] home + end buttons should work
- in nav:
- home always goes to first section header
- end always goes to last _visible_ item (does not expand)
```
Release Notes:
- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
@@ -21,6 +21,7 @@ pub struct TreeViewItem {
|
||||
on_toggle: Option<Arc<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>>,
|
||||
on_secondary_mouse_down: Option<Box<dyn Fn(&MouseDownEvent, &mut Window, &mut App) + 'static>>,
|
||||
tab_index: Option<isize>,
|
||||
focus_handle: Option<gpui::FocusHandle>,
|
||||
}
|
||||
|
||||
impl TreeViewItem {
|
||||
@@ -41,6 +42,7 @@ impl TreeViewItem {
|
||||
on_toggle: None,
|
||||
on_secondary_mouse_down: None,
|
||||
tab_index: None,
|
||||
focus_handle: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +109,11 @@ impl TreeViewItem {
|
||||
self.focused = focused;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn track_focus(mut self, focus_handle: &gpui::FocusHandle) -> Self {
|
||||
self.focus_handle = Some(focus_handle.clone());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Disableable for TreeViewItem {
|
||||
@@ -163,6 +170,9 @@ impl RenderOnce for TreeViewItem {
|
||||
})
|
||||
.focus(|s| s.border_color(focused_border))
|
||||
.hover(|s| s.bg(cx.theme().colors().element_hover))
|
||||
.when_some(self.focus_handle, |this, handle| {
|
||||
this.track_focus(&handle)
|
||||
})
|
||||
.when_some(self.tab_index, |this, index| this.tab_index(index))
|
||||
.child(
|
||||
Disclosure::new("toggle", self.expanded)
|
||||
@@ -182,22 +192,7 @@ impl RenderOnce for TreeViewItem {
|
||||
.when_some(self.on_hover, |this, on_hover| this.on_hover(on_hover))
|
||||
.when_some(
|
||||
self.on_click.filter(|_| !self.disabled),
|
||||
|this, on_click| {
|
||||
if self.root_item
|
||||
&& let Some(on_toggle) = self.on_toggle.clone()
|
||||
{
|
||||
this.on_click(move |event, window, cx| {
|
||||
if event.is_keyboard() {
|
||||
on_click(event, window, cx);
|
||||
on_toggle(event, window, cx);
|
||||
} else {
|
||||
on_click(event, window, cx);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.on_click(on_click)
|
||||
}
|
||||
},
|
||||
|this, on_click| this.on_click(on_click),
|
||||
)
|
||||
.when_some(self.on_secondary_mouse_down, |this, on_mouse_down| {
|
||||
this.on_mouse_down(
|
||||
@@ -221,6 +216,9 @@ impl RenderOnce for TreeViewItem {
|
||||
})
|
||||
.focus(|s| s.border_color(focused_border))
|
||||
.hover(|s| s.bg(cx.theme().colors().element_hover))
|
||||
.when_some(self.focus_handle, |this, handle| {
|
||||
this.track_focus(&handle)
|
||||
})
|
||||
.when_some(self.tab_index, |this, index| this.tab_index(index))
|
||||
.child(
|
||||
Label::new(label)
|
||||
|
||||
Reference in New Issue
Block a user