From 6dc3e643b457b578ae4180f84c9fe887baa4d6ff Mon Sep 17 00:00:00 2001
From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
Date: Sat, 11 Oct 2025 10:32:20 -0300
Subject: [PATCH] onboarding: Add some UI improvements (#40016)
Includes improvements in button padding, ways we space elements out,
more consistent use of some components, and cleaning up redundant
buttons styles. Pretty much nothing changes in the design, though.
Release Notes:
- N/A
---
assets/icons/editor_cursor.svg | 8 +---
crates/onboarding/src/basics_page.rs | 48 +++++++++----------
crates/onboarding/src/onboarding.rs | 47 +++++++++---------
.../ui/src/components/button/button_like.rs | 41 ++--------------
4 files changed, 49 insertions(+), 95 deletions(-)
diff --git a/assets/icons/editor_cursor.svg b/assets/icons/editor_cursor.svg
index 338697be8a621e80099c308b3dda0a4e11fcfd61..e20013917d3c8b9d28f4fab631ae2fbd99b9297f 100644
--- a/assets/icons/editor_cursor.svg
+++ b/assets/icons/editor_cursor.svg
@@ -1,9 +1,3 @@
diff --git a/crates/onboarding/src/basics_page.rs b/crates/onboarding/src/basics_page.rs
index 92e434176fb4b1187b0b31918b850d304b0915da..eaf9c41a53dc6c4b0d8ef9a93a9ed8423ddf2db6 100644
--- a/crates/onboarding/src/basics_page.rs
+++ b/crates/onboarding/src/basics_page.rs
@@ -9,7 +9,7 @@ use theme::{
ThemeSettings,
};
use ui::{
- ButtonLike, ParentElement as _, StatefulInteractiveElement, SwitchField, TintColor,
+ Divider, ParentElement as _, StatefulInteractiveElement, SwitchField, TintColor,
ToggleButtonGroup, ToggleButtonGroupSize, ToggleButtonSimple, ToggleButtonWithIcon, prelude::*,
rems_from_px,
};
@@ -221,10 +221,7 @@ fn render_telemetry_section(tab_index: &mut isize, cx: &App) -> impl IntoElement
let fs = ::global(cx);
v_flex()
- .pt_6()
.gap_4()
- .border_t_1()
- .border_color(cx.theme().colors().border_variant.opacity(0.5))
.child(
SwitchField::new(
"onboarding-telemetry-metrics",
@@ -410,27 +407,23 @@ fn render_setting_import_button(
imported: bool,
) -> impl IntoElement + 'static {
let action = action.boxed_clone();
- h_flex().w_full().child(
- ButtonLike::new(label.clone())
- .style(ButtonStyle::OutlinedTransparent)
- .selected_style(ButtonStyle::Tinted(TintColor::Accent))
- .toggle_state(imported)
- .size(ButtonSize::Medium)
- .tab_index(tab_index)
- .child(
- h_flex()
- .w_full()
- .justify_between()
- .when(imported, |this| {
- this.child(Icon::new(IconName::Check).color(Color::Success))
- })
- .child(Label::new(label.clone()).mx_2().size(LabelSize::Small)),
- )
- .on_click(move |_, window, cx| {
- telemetry::event!("Welcome Import Settings", import_source = label,);
- window.dispatch_action(action.boxed_clone(), cx);
- }),
- )
+
+ Button::new(label.clone(), label.clone())
+ .style(ButtonStyle::OutlinedGhost)
+ .size(ButtonSize::Medium)
+ .label_size(LabelSize::Small)
+ .selected_style(ButtonStyle::Tinted(TintColor::Accent))
+ .toggle_state(imported)
+ .tab_index(tab_index)
+ .when(imported, |this| {
+ this.icon(IconName::Check)
+ .icon_size(IconSize::Small)
+ .color(Color::Success)
+ })
+ .on_click(move |_, window, cx| {
+ telemetry::event!("Welcome Import Settings", import_source = label,);
+ window.dispatch_action(action.boxed_clone(), cx);
+ })
}
fn render_import_settings_section(tab_index: &mut isize, cx: &mut App) -> impl IntoElement {
@@ -454,6 +447,9 @@ fn render_import_settings_section(tab_index: &mut isize, cx: &mut App) -> impl I
});
h_flex()
+ .gap_2()
+ .flex_wrap()
+ .justify_between()
.child(
v_flex()
.gap_0p5()
@@ -464,7 +460,6 @@ fn render_import_settings_section(tab_index: &mut isize, cx: &mut App) -> impl I
.color(Color::Muted),
),
)
- .child(div().w_full())
.child(h_flex().gap_1().child(vscode).child(cursor))
}
@@ -477,5 +472,6 @@ pub(crate) fn render_basics_page(cx: &mut App) -> impl IntoElement {
.child(render_base_keymap_section(&mut tab_index, cx))
.child(render_import_settings_section(&mut tab_index, cx))
.child(render_vim_mode_switch(&mut tab_index, cx))
+ .child(Divider::horizontal().color(ui::DividerColor::BorderVariant))
.child(render_telemetry_section(&mut tab_index, cx))
}
diff --git a/crates/onboarding/src/onboarding.rs b/crates/onboarding/src/onboarding.rs
index 70e1524ab4e7d432a5fcbef1e18385bab1320d83..9273f0d7d87851b5118d7835244074502fc128c7 100644
--- a/crates/onboarding/src/onboarding.rs
+++ b/crates/onboarding/src/onboarding.rs
@@ -14,7 +14,7 @@ use serde::Deserialize;
use settings::{SettingsStore, VsCodeSettingsSource};
use std::sync::Arc;
use ui::{
- KeyBinding, ParentElement as _, StatefulInteractiveElement, Vector, VectorName,
+ Divider, KeyBinding, ParentElement as _, StatefulInteractiveElement, Vector, VectorName,
WithScrollbar as _, prelude::*, rems_from_px,
};
pub use ui_input::font_picker;
@@ -294,44 +294,45 @@ impl Render for Onboarding {
.child(
div()
.max_w(Rems(48.0))
- .w_full()
- .mx_auto()
.size_full()
- .gap_6()
+ .mx_auto()
.child(
v_flex()
- .m_auto()
.id("page-content")
- .gap_6()
+ .m_auto()
+ .p_12()
.size_full()
.max_w_full()
.min_w_0()
- .p_12()
- .border_color(cx.theme().colors().border_variant.opacity(0.5))
+ .gap_6()
.overflow_y_scroll()
.child(
h_flex()
.w_full()
.gap_4()
- .child(Vector::square(VectorName::ZedLogo, rems(2.5)))
+ .justify_between()
.child(
- v_flex()
- .child(
- Headline::new("Welcome to Zed")
- .size(HeadlineSize::Small),
- )
+ h_flex()
+ .gap_4()
+ .child(Vector::square(VectorName::ZedLogo, rems(2.5)))
.child(
- Label::new("The editor for what's next")
- .color(Color::Muted)
- .size(LabelSize::Small)
- .italic(),
+ v_flex()
+ .child(
+ Headline::new("Welcome to Zed")
+ .size(HeadlineSize::Small),
+ )
+ .child(
+ Label::new("The editor for what's next")
+ .color(Color::Muted)
+ .size(LabelSize::Small)
+ .italic(),
+ ),
),
)
- .child(div().w_full())
.child({
Button::new("finish_setup", "Finish Setup")
.style(ButtonStyle::Filled)
- .size(ButtonSize::Large)
+ .size(ButtonSize::Medium)
.width(Rems(12.0))
.key_binding(
KeyBinding::for_action_in(
@@ -345,11 +346,9 @@ impl Render for Onboarding {
.on_click(|_, window, cx| {
window.dispatch_action(Finish.boxed_clone(), cx);
})
- })
- .pb_6()
- .border_b_1()
- .border_color(cx.theme().colors().border_variant.opacity(0.5)),
+ }),
)
+ .child(Divider::horizontal().color(ui::DividerColor::BorderVariant))
.child(self.render_page(cx))
.track_scroll(&self.scroll_handle),
)
diff --git a/crates/ui/src/components/button/button_like.rs b/crates/ui/src/components/button/button_like.rs
index 40c75f5918fe1e70c3d52374dce2a463314b5cc7..0c8893e2cccb64243f373126429a823b919bca42 100644
--- a/crates/ui/src/components/button/button_like.rs
+++ b/crates/ui/src/components/button/button_like.rs
@@ -135,9 +135,6 @@ pub enum ButtonStyle {
/// a fully transparent button.
Outlined,
- /// Transparent button that always has an outline.
- OutlinedTransparent,
-
/// A more de-emphasized version of the outlined button.
OutlinedGhost,
@@ -228,12 +225,6 @@ impl ButtonStyle {
label_color: Color::Default.color(cx),
icon_color: Color::Default.color(cx),
},
- ButtonStyle::OutlinedTransparent => ButtonLikeStyles {
- background: cx.theme().colors().ghost_element_background,
- border_color: cx.theme().colors().border_variant,
- label_color: Color::Default.color(cx),
- icon_color: Color::Default.color(cx),
- },
ButtonStyle::OutlinedGhost => ButtonLikeStyles {
background: transparent_black(),
border_color: cx.theme().colors().border_variant,
@@ -285,14 +276,8 @@ impl ButtonStyle {
label_color: Color::Default.color(cx),
icon_color: Color::Default.color(cx),
},
- ButtonStyle::OutlinedTransparent => ButtonLikeStyles {
- background: cx.theme().colors().ghost_element_hover,
- border_color: cx.theme().colors().border,
- label_color: Color::Default.color(cx),
- icon_color: Color::Default.color(cx),
- },
ButtonStyle::OutlinedGhost => ButtonLikeStyles {
- background: transparent_black(),
+ background: cx.theme().colors().ghost_element_hover,
border_color: cx.theme().colors().border,
label_color: Color::Default.color(cx),
icon_color: Color::Default.color(cx),
@@ -335,12 +320,6 @@ impl ButtonStyle {
label_color: Color::Default.color(cx),
icon_color: Color::Default.color(cx),
},
- ButtonStyle::OutlinedTransparent => ButtonLikeStyles {
- background: cx.theme().colors().ghost_element_active,
- border_color: cx.theme().colors().border_variant,
- label_color: Color::Default.color(cx),
- icon_color: Color::Default.color(cx),
- },
ButtonStyle::OutlinedGhost => ButtonLikeStyles {
background: transparent_black(),
border_color: cx.theme().colors().border_variant,
@@ -380,12 +359,6 @@ impl ButtonStyle {
label_color: Color::Default.color(cx),
icon_color: Color::Default.color(cx),
},
- ButtonStyle::OutlinedTransparent => ButtonLikeStyles {
- background: cx.theme().colors().ghost_element_background,
- border_color: cx.theme().colors().border,
- label_color: Color::Default.color(cx),
- icon_color: Color::Default.color(cx),
- },
ButtonStyle::OutlinedGhost => ButtonLikeStyles {
background: transparent_black(),
border_color: cx.theme().colors().border,
@@ -428,12 +401,6 @@ impl ButtonStyle {
label_color: Color::Default.color(cx),
icon_color: Color::Default.color(cx),
},
- ButtonStyle::OutlinedTransparent => ButtonLikeStyles {
- background: cx.theme().colors().ghost_element_disabled,
- border_color: cx.theme().colors().border_disabled,
- label_color: Color::Default.color(cx),
- icon_color: Color::Default.color(cx),
- },
ButtonStyle::OutlinedGhost => ButtonLikeStyles {
background: transparent_black(),
border_color: cx.theme().colors().border_disabled,
@@ -690,9 +657,7 @@ impl RenderOnce for ButtonLike {
.when(
matches!(
self.style,
- ButtonStyle::Outlined
- | ButtonStyle::OutlinedTransparent
- | ButtonStyle::OutlinedGhost
+ ButtonStyle::Outlined | ButtonStyle::OutlinedGhost
),
|this| this.border_1(),
)
@@ -704,7 +669,7 @@ impl RenderOnce for ButtonLike {
})
.gap(DynamicSpacing::Base04.rems(cx))
.map(|this| match self.size {
- ButtonSize::Large | ButtonSize::Medium => this.px(DynamicSpacing::Base06.rems(cx)),
+ ButtonSize::Large | ButtonSize::Medium => this.px(DynamicSpacing::Base08.rems(cx)),
ButtonSize::Default | ButtonSize::Compact => {
this.px(DynamicSpacing::Base04.rems(cx))
}