assistant2: Navigate context strip with keyboard (#23128)
Context pills are now focusable and intractable via the keyboard. - <kbd>←</kbd> and <kbd>→</kbd> move the focus to the previous or next item (wrapping if necessary) - <kbd>↓</kbd> and <kbd>↑</kbd> move the focus vertically - If the cursor is in the first/last row of the assistant/inline editor, they will move the focus to the strip - Inside the strip, they will move the focus to the pill horizontally overlapping the most - If already in the first/last row of the strip, they will move to the first/last pill (like in editors) - If the first/last pill is focused, they will move the focus back to the editor - <kbd>⌫</kbd> removes the focused pill (unless it's the suggested one) - <kbd>⏎</kbd> accepts the suggested pill if focused https://github.com/user-attachments/assets/040bc71c-a3ae-4961-9886-2d5c3d290a73 Release Notes: - N/A
This commit is contained in:
parent
78fd5b5f02
commit
39ac6e4a75
9 changed files with 405 additions and 70 deletions
|
@ -10,13 +10,16 @@ pub enum ContextPill {
|
|||
Added {
|
||||
context: ContextSnapshot,
|
||||
dupe_name: bool,
|
||||
focused: bool,
|
||||
on_click: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext)>>,
|
||||
on_remove: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext)>>,
|
||||
},
|
||||
Suggested {
|
||||
name: SharedString,
|
||||
icon_path: Option<SharedString>,
|
||||
kind: ContextKind,
|
||||
on_add: Rc<dyn Fn(&ClickEvent, &mut WindowContext)>,
|
||||
focused: bool,
|
||||
on_click: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext)>>,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -24,12 +27,15 @@ impl ContextPill {
|
|||
pub fn new_added(
|
||||
context: ContextSnapshot,
|
||||
dupe_name: bool,
|
||||
focused: bool,
|
||||
on_remove: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext)>>,
|
||||
) -> Self {
|
||||
Self::Added {
|
||||
context,
|
||||
dupe_name,
|
||||
on_remove,
|
||||
focused,
|
||||
on_click: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,16 +43,29 @@ impl ContextPill {
|
|||
name: SharedString,
|
||||
icon_path: Option<SharedString>,
|
||||
kind: ContextKind,
|
||||
on_add: Rc<dyn Fn(&ClickEvent, &mut WindowContext)>,
|
||||
focused: bool,
|
||||
) -> Self {
|
||||
Self::Suggested {
|
||||
name,
|
||||
icon_path,
|
||||
kind,
|
||||
on_add,
|
||||
focused,
|
||||
on_click: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_click(mut self, listener: Rc<dyn Fn(&ClickEvent, &mut WindowContext)>) -> Self {
|
||||
match &mut self {
|
||||
ContextPill::Added { on_click, .. } => {
|
||||
*on_click = Some(listener);
|
||||
}
|
||||
ContextPill::Suggested { on_click, .. } => {
|
||||
*on_click = Some(listener);
|
||||
}
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn id(&self) -> ElementId {
|
||||
match self {
|
||||
Self::Added { context, .. } => {
|
||||
|
@ -93,9 +112,15 @@ impl RenderOnce for ContextPill {
|
|||
context,
|
||||
dupe_name,
|
||||
on_remove,
|
||||
focused,
|
||||
on_click,
|
||||
} => base_pill
|
||||
.bg(color.element_background)
|
||||
.border_color(color.border.opacity(0.5))
|
||||
.border_color(if *focused {
|
||||
color.border_focused
|
||||
} else {
|
||||
color.border.opacity(0.5)
|
||||
})
|
||||
.pr(if on_remove.is_some() { px(2.) } else { px(4.) })
|
||||
.child(
|
||||
h_flex()
|
||||
|
@ -128,16 +153,25 @@ impl RenderOnce for ContextPill {
|
|||
move |event, cx| on_remove(event, cx)
|
||||
}),
|
||||
)
|
||||
})
|
||||
.when_some(on_click.as_ref(), |element, on_click| {
|
||||
let on_click = on_click.clone();
|
||||
element.on_click(move |event, cx| on_click(event, cx))
|
||||
}),
|
||||
ContextPill::Suggested {
|
||||
name,
|
||||
icon_path: _,
|
||||
kind,
|
||||
on_add,
|
||||
focused,
|
||||
on_click,
|
||||
} => base_pill
|
||||
.cursor_pointer()
|
||||
.pr_1()
|
||||
.border_color(color.border_variant.opacity(0.5))
|
||||
.border_color(if *focused {
|
||||
color.border_focused
|
||||
} else {
|
||||
color.border_variant.opacity(0.5)
|
||||
})
|
||||
.hover(|style| style.bg(color.element_hover.opacity(0.5)))
|
||||
.child(
|
||||
Label::new(name.clone())
|
||||
|
@ -162,9 +196,9 @@ impl RenderOnce for ContextPill {
|
|||
.into_any_element(),
|
||||
)
|
||||
.tooltip(|cx| Tooltip::with_meta("Suggested Context", None, "Click to add it", cx))
|
||||
.on_click({
|
||||
let on_add = on_add.clone();
|
||||
move |event, cx| on_add(event, cx)
|
||||
.when_some(on_click.as_ref(), |element, on_click| {
|
||||
let on_click = on_click.clone();
|
||||
element.on_click(move |event, cx| on_click(event, cx))
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue