onboarding: Refine page and component designs (#35387)

Includes adding new variants to the Dropdown and Numeric Stepper
components.

Release Notes:

- N/A
This commit is contained in:
Danilo Leal 2025-07-31 02:32:18 -03:00 committed by GitHub
parent b1a7993544
commit 5488398986
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 563 additions and 327 deletions

View file

@ -8,6 +8,7 @@ use super::PopoverMenuHandle;
pub enum DropdownStyle {
#[default]
Solid,
Outlined,
Ghost,
}
@ -147,6 +148,23 @@ impl Component for DropdownMenu {
),
],
),
example_group_with_title(
"Styles",
vec![
single_example(
"Outlined",
DropdownMenu::new("outlined", "Outlined Dropdown", menu.clone())
.style(DropdownStyle::Outlined)
.into_any_element(),
),
single_example(
"Ghost",
DropdownMenu::new("ghost", "Ghost Dropdown", menu.clone())
.style(DropdownStyle::Ghost)
.into_any_element(),
),
],
),
example_group_with_title(
"States",
vec![single_example(
@ -170,10 +188,13 @@ pub struct DropdownTriggerStyle {
impl DropdownTriggerStyle {
pub fn for_style(style: DropdownStyle, cx: &App) -> Self {
let colors = cx.theme().colors();
let bg = match style {
DropdownStyle::Solid => colors.editor_background,
DropdownStyle::Outlined => colors.surface_background,
DropdownStyle::Ghost => colors.ghost_element_background,
};
Self { bg }
}
}
@ -244,17 +265,24 @@ impl RenderOnce for DropdownMenuTrigger {
let disabled = self.disabled;
let style = DropdownTriggerStyle::for_style(self.style, cx);
let is_outlined = matches!(self.style, DropdownStyle::Outlined);
h_flex()
.id("dropdown-menu-trigger")
.justify_between()
.rounded_sm()
.bg(style.bg)
.min_w_20()
.pl_2()
.pr_1p5()
.py_0p5()
.gap_2()
.min_w_20()
.justify_between()
.rounded_sm()
.bg(style.bg)
.hover(|s| s.bg(cx.theme().colors().element_hover))
.when(is_outlined, |this| {
this.border_1()
.border_color(cx.theme().colors().border)
.overflow_hidden()
})
.map(|el| {
if self.full_width {
el.w_full()

View file

@ -1,17 +1,24 @@
use gpui::ClickEvent;
use crate::{Divider, IconButtonShape, prelude::*};
use crate::{IconButtonShape, prelude::*};
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub enum NumericStepperStyle {
Outlined,
#[default]
Ghost,
}
#[derive(IntoElement, RegisterComponent)]
pub struct NumericStepper {
id: ElementId,
value: SharedString,
style: NumericStepperStyle,
on_decrement: Box<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>,
on_increment: Box<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>,
/// Whether to reserve space for the reset button.
reserve_space_for_reset: bool,
on_reset: Option<Box<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>>,
border: bool,
}
impl NumericStepper {
@ -24,14 +31,19 @@ impl NumericStepper {
Self {
id: id.into(),
value: value.into(),
style: NumericStepperStyle::default(),
on_decrement: Box::new(on_decrement),
on_increment: Box::new(on_increment),
border: false,
reserve_space_for_reset: false,
on_reset: None,
}
}
pub fn style(mut self, style: NumericStepperStyle) -> Self {
self.style = style;
self
}
pub fn reserve_space_for_reset(mut self, reserve_space_for_reset: bool) -> Self {
self.reserve_space_for_reset = reserve_space_for_reset;
self
@ -44,11 +56,6 @@ impl NumericStepper {
self.on_reset = Some(Box::new(on_reset));
self
}
pub fn border(mut self) -> Self {
self.border = true;
self
}
}
impl RenderOnce for NumericStepper {
@ -56,6 +63,8 @@ impl RenderOnce for NumericStepper {
let shape = IconButtonShape::Square;
let icon_size = IconSize::Small;
let is_outlined = matches!(self.style, NumericStepperStyle::Outlined);
h_flex()
.id(self.id)
.gap_1()
@ -81,31 +90,65 @@ impl RenderOnce for NumericStepper {
.child(
h_flex()
.gap_1()
.when(self.border, |this| {
this.border_1().border_color(cx.theme().colors().border)
})
.px_1()
.rounded_sm()
.bg(cx.theme().colors().editor_background)
.child(
IconButton::new("decrement", IconName::Dash)
.shape(shape)
.icon_size(icon_size)
.on_click(self.on_decrement),
)
.when(self.border, |this| {
this.child(Divider::vertical().color(super::DividerColor::Border))
.map(|this| {
if is_outlined {
this.overflow_hidden()
.bg(cx.theme().colors().surface_background)
.border_1()
.border_color(cx.theme().colors().border)
} else {
this.px_1().bg(cx.theme().colors().editor_background)
}
})
.child(Label::new(self.value))
.when(self.border, |this| {
this.child(Divider::vertical().color(super::DividerColor::Border))
.map(|decrement| {
if is_outlined {
decrement.child(
h_flex()
.id("decrement_button")
.p_1p5()
.size_full()
.justify_center()
.hover(|s| s.bg(cx.theme().colors().element_hover))
.border_r_1()
.border_color(cx.theme().colors().border)
.child(Icon::new(IconName::Dash).size(IconSize::Small))
.on_click(self.on_decrement),
)
} else {
decrement.child(
IconButton::new("decrement", IconName::Dash)
.shape(shape)
.icon_size(icon_size)
.on_click(self.on_decrement),
)
}
})
.child(
IconButton::new("increment", IconName::Plus)
.shape(shape)
.icon_size(icon_size)
.on_click(self.on_increment),
),
.when(is_outlined, |this| this)
.child(Label::new(self.value).mx_3())
.map(|increment| {
if is_outlined {
increment.child(
h_flex()
.id("increment_button")
.p_1p5()
.size_full()
.justify_center()
.hover(|s| s.bg(cx.theme().colors().element_hover))
.border_l_1()
.border_color(cx.theme().colors().border)
.child(Icon::new(IconName::Plus).size(IconSize::Small))
.on_click(self.on_increment),
)
} else {
increment.child(
IconButton::new("increment", IconName::Dash)
.shape(shape)
.icon_size(icon_size)
.on_click(self.on_increment),
)
}
}),
)
}
}
@ -116,7 +159,7 @@ impl Component for NumericStepper {
}
fn name() -> &'static str {
"NumericStepper"
"Numeric Stepper"
}
fn sort_name() -> &'static str {
@ -124,33 +167,39 @@ impl Component for NumericStepper {
}
fn description() -> Option<&'static str> {
Some("A button used to increment or decrement a numeric value. ")
Some("A button used to increment or decrement a numeric value.")
}
fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
Some(
v_flex()
.child(single_example(
"Borderless",
NumericStepper::new(
"numeric-stepper-component-preview",
"10",
move |_, _, _| {},
move |_, _, _| {},
)
.into_any_element(),
))
.child(single_example(
"Border",
NumericStepper::new(
"numeric-stepper-with-border-component-preview",
"10",
move |_, _, _| {},
move |_, _, _| {},
)
.border()
.into_any_element(),
))
.gap_6()
.children(vec![example_group_with_title(
"Styles",
vec![
single_example(
"Default",
NumericStepper::new(
"numeric-stepper-component-preview",
"10",
move |_, _, _| {},
move |_, _, _| {},
)
.into_any_element(),
),
single_example(
"Outlined",
NumericStepper::new(
"numeric-stepper-with-border-component-preview",
"10",
move |_, _, _| {},
move |_, _, _| {},
)
.style(NumericStepperStyle::Outlined)
.into_any_element(),
),
],
)])
.into_any_element(),
)
}