Add icon position support to buttons
This commit is contained in:
+43
-4
@@ -106,6 +106,16 @@ pub trait ButtonVariants: Sized {
|
||||
}
|
||||
}
|
||||
|
||||
/// Which side of the label the icon sits on.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub enum IconPosition {
|
||||
/// Left of the label.
|
||||
#[default]
|
||||
Start,
|
||||
/// Right of the label.
|
||||
End,
|
||||
}
|
||||
|
||||
/// A Button element.
|
||||
#[derive(IntoElement)]
|
||||
#[allow(clippy::type_complexity)]
|
||||
@@ -125,6 +135,7 @@ pub struct Button {
|
||||
on_click: Option<Rc<dyn Fn(&ClickEvent, &mut Window, &mut App)>>,
|
||||
tab_stop: bool,
|
||||
selected: bool,
|
||||
icon_position: IconPosition,
|
||||
}
|
||||
|
||||
impl From<Button> for AnyElement {
|
||||
@@ -151,6 +162,7 @@ impl Button {
|
||||
loading: false,
|
||||
children: Vec::new(),
|
||||
tab_stop: true,
|
||||
icon_position: IconPosition::Start,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,6 +183,12 @@ impl Button {
|
||||
self
|
||||
}
|
||||
|
||||
/// Set which side of the label the icon sits on (default [`IconPosition::Start`]).
|
||||
pub fn icon_position(mut self, position: IconPosition) -> Self {
|
||||
self.icon_position = position;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn tooltip(mut self, tooltip: impl Into<SharedString>) -> Self {
|
||||
self.tooltip = Some(tooltip.into());
|
||||
self
|
||||
@@ -272,6 +290,7 @@ impl RenderOnce for Button {
|
||||
Size::Large => Size::Medium,
|
||||
_ => self.size,
|
||||
};
|
||||
let icon_start = self.icon_position == IconPosition::Start;
|
||||
|
||||
self.base
|
||||
.tab_index(0)
|
||||
@@ -318,7 +337,7 @@ impl RenderOnce for Button {
|
||||
}
|
||||
} else {
|
||||
// Normal Button
|
||||
match self.size {
|
||||
let this = match self.size {
|
||||
Size::Size(size) => this.px(size * 0.2),
|
||||
Size::XSmall => {
|
||||
if self.icon.is_some() {
|
||||
@@ -348,6 +367,16 @@ impl RenderOnce for Button {
|
||||
this.h_10().px_3()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if !icon_start && self.icon.is_some() {
|
||||
match self.size {
|
||||
Size::XSmall | Size::Small => this.pl_2p5().pr_2(),
|
||||
Size::Medium | Size::Large => this.pl_3p5().pr_3(),
|
||||
Size::Size(_) => this,
|
||||
}
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -369,16 +398,26 @@ impl RenderOnce for Button {
|
||||
Size::Small => this.text_style(TextStyle::Callout).gap_1p5(),
|
||||
_ => this.text_style(TextStyle::Callout).gap(px(theme::SPACE)),
|
||||
})
|
||||
.when(!self.loading, |this| {
|
||||
this.when_some(self.icon, |this, icon| {
|
||||
.when(!self.loading && icon_start, |this| {
|
||||
this.when_some(self.icon.clone(), |this, icon| {
|
||||
this.child(icon.with_size(icon_size))
|
||||
})
|
||||
})
|
||||
.when(self.loading, |this| this.child(Indicator::new()))
|
||||
.when(self.loading && icon_start, |this| {
|
||||
this.child(Indicator::new())
|
||||
})
|
||||
.when_some(self.label, |this, label| {
|
||||
this.child(div().flex_none().line_height(relative(1.)).child(label))
|
||||
})
|
||||
.children(self.children)
|
||||
.when(!self.loading && !icon_start, |this| {
|
||||
this.when_some(self.icon.clone(), |this, icon| {
|
||||
this.child(icon.with_size(icon_size))
|
||||
})
|
||||
})
|
||||
.when(self.loading && !icon_start, |this| {
|
||||
this.child(Indicator::new())
|
||||
})
|
||||
.when(self.caret, |this| {
|
||||
this.justify_between().gap_0p5().child(
|
||||
Icon::new(IconName::ChevronDown)
|
||||
|
||||
Reference in New Issue
Block a user