onboarding: Wire up tab index (#35659)
Closes #ISSUE Allows tabbing through everything in all three pages. Until #35075 is merged it is not possible to actually "click" tab focused buttons with the keyboard. Additionally adds an action `onboarding::Finish` and displays the keybind. The action corresponds to both the "Skip all" and "Start Building" buttons, with the keybind displayed similar to how it is for the page nav buttons Release Notes: - N/A *or* Added/Fixed/Improved ... --------- Co-authored-by: MrSubidubi <finn@zed.dev>
This commit is contained in:
@@ -424,6 +424,7 @@ pub struct Switch {
|
||||
label: Option<SharedString>,
|
||||
key_binding: Option<KeyBinding>,
|
||||
color: SwitchColor,
|
||||
tab_index: Option<isize>,
|
||||
}
|
||||
|
||||
impl Switch {
|
||||
@@ -437,6 +438,7 @@ impl Switch {
|
||||
label: None,
|
||||
key_binding: None,
|
||||
color: SwitchColor::default(),
|
||||
tab_index: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -472,6 +474,11 @@ impl Switch {
|
||||
self.key_binding = key_binding.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn tab_index(mut self, tab_index: impl Into<isize>) -> Self {
|
||||
self.tab_index = Some(tab_index.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderOnce for Switch {
|
||||
@@ -501,6 +508,20 @@ impl RenderOnce for Switch {
|
||||
.w(DynamicSpacing::Base32.rems(cx))
|
||||
.h(DynamicSpacing::Base20.rems(cx))
|
||||
.group(group_id.clone())
|
||||
.border_1()
|
||||
.p(px(1.0))
|
||||
.border_color(cx.theme().colors().border_transparent)
|
||||
.rounded_full()
|
||||
.id((self.id.clone(), "switch"))
|
||||
.when_some(
|
||||
self.tab_index.filter(|_| !self.disabled),
|
||||
|this, tab_index| {
|
||||
this.tab_index(tab_index).focus(|mut style| {
|
||||
style.border_color = Some(cx.theme().colors().border_focused);
|
||||
style
|
||||
})
|
||||
},
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.when(is_on, |on| on.justify_end())
|
||||
@@ -572,6 +593,7 @@ pub struct SwitchField {
|
||||
disabled: bool,
|
||||
color: SwitchColor,
|
||||
tooltip: Option<Rc<dyn Fn(&mut Window, &mut App) -> AnyView>>,
|
||||
tab_index: Option<isize>,
|
||||
}
|
||||
|
||||
impl SwitchField {
|
||||
@@ -591,6 +613,7 @@ impl SwitchField {
|
||||
disabled: false,
|
||||
color: SwitchColor::Accent,
|
||||
tooltip: None,
|
||||
tab_index: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -615,14 +638,33 @@ impl SwitchField {
|
||||
self.tooltip = Some(Rc::new(tooltip));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn tab_index(mut self, tab_index: isize) -> Self {
|
||||
self.tab_index = Some(tab_index);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl RenderOnce for SwitchField {
|
||||
fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
|
||||
let tooltip = self.tooltip;
|
||||
let tooltip = self.tooltip.map(|tooltip_fn| {
|
||||
h_flex()
|
||||
.gap_0p5()
|
||||
.child(Label::new(self.label.clone()))
|
||||
.child(
|
||||
IconButton::new("tooltip_button", IconName::Info)
|
||||
.icon_size(IconSize::XSmall)
|
||||
.icon_color(Color::Muted)
|
||||
.shape(crate::IconButtonShape::Square)
|
||||
.tooltip({
|
||||
let tooltip = tooltip_fn.clone();
|
||||
move |window, cx| tooltip(window, cx)
|
||||
}),
|
||||
)
|
||||
});
|
||||
|
||||
h_flex()
|
||||
.id(SharedString::from(format!("{}-container", self.id)))
|
||||
.id((self.id.clone(), "container"))
|
||||
.when(!self.disabled, |this| {
|
||||
this.hover(|this| this.cursor_pointer())
|
||||
})
|
||||
@@ -630,25 +672,11 @@ impl RenderOnce for SwitchField {
|
||||
.gap_4()
|
||||
.justify_between()
|
||||
.flex_wrap()
|
||||
.child(match (&self.description, &tooltip) {
|
||||
.child(match (&self.description, tooltip) {
|
||||
(Some(description), Some(tooltip)) => v_flex()
|
||||
.gap_0p5()
|
||||
.max_w_5_6()
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_0p5()
|
||||
.child(Label::new(self.label.clone()))
|
||||
.child(
|
||||
IconButton::new("tooltip_button", IconName::Info)
|
||||
.icon_size(IconSize::XSmall)
|
||||
.icon_color(Color::Muted)
|
||||
.shape(crate::IconButtonShape::Square)
|
||||
.tooltip({
|
||||
let tooltip = tooltip.clone();
|
||||
move |window, cx| tooltip(window, cx)
|
||||
}),
|
||||
),
|
||||
)
|
||||
.child(tooltip)
|
||||
.child(Label::new(description.clone()).color(Color::Muted))
|
||||
.into_any_element(),
|
||||
(Some(description), None) => v_flex()
|
||||
@@ -657,35 +685,23 @@ impl RenderOnce for SwitchField {
|
||||
.child(Label::new(self.label.clone()))
|
||||
.child(Label::new(description.clone()).color(Color::Muted))
|
||||
.into_any_element(),
|
||||
(None, Some(tooltip)) => h_flex()
|
||||
.gap_0p5()
|
||||
.child(Label::new(self.label.clone()))
|
||||
.child(
|
||||
IconButton::new("tooltip_button", IconName::Info)
|
||||
.icon_size(IconSize::XSmall)
|
||||
.icon_color(Color::Muted)
|
||||
.shape(crate::IconButtonShape::Square)
|
||||
.tooltip({
|
||||
let tooltip = tooltip.clone();
|
||||
move |window, cx| tooltip(window, cx)
|
||||
}),
|
||||
)
|
||||
.into_any_element(),
|
||||
(None, Some(tooltip)) => tooltip.into_any_element(),
|
||||
(None, None) => Label::new(self.label.clone()).into_any_element(),
|
||||
})
|
||||
.child(
|
||||
Switch::new(
|
||||
SharedString::from(format!("{}-switch", self.id)),
|
||||
self.toggle_state,
|
||||
)
|
||||
.color(self.color)
|
||||
.disabled(self.disabled)
|
||||
.on_click({
|
||||
let on_click = self.on_click.clone();
|
||||
move |state, window, cx| {
|
||||
(on_click)(state, window, cx);
|
||||
}
|
||||
}),
|
||||
Switch::new((self.id.clone(), "switch"), self.toggle_state)
|
||||
.color(self.color)
|
||||
.disabled(self.disabled)
|
||||
.when_some(
|
||||
self.tab_index.filter(|_| !self.disabled),
|
||||
|this, tab_index| this.tab_index(tab_index),
|
||||
)
|
||||
.on_click({
|
||||
let on_click = self.on_click.clone();
|
||||
move |state, window, cx| {
|
||||
(on_click)(state, window, cx);
|
||||
}
|
||||
}),
|
||||
)
|
||||
.when(!self.disabled, |this| {
|
||||
this.on_click({
|
||||
|
||||
Reference in New Issue
Block a user