button: Add dropdown_caret option to show a caret icon to end of button. (#1637)
<img width="658" height="162" alt="image" src="https://github.com/user-attachments/assets/7c233982-04c3-408c-8ae4-f672f8b135a3" />
This commit is contained in:
parent
44dc2c7f38
commit
01082f11d2
6 changed files with 89 additions and 128 deletions
|
|
@ -1,12 +1,11 @@
|
|||
use gpui::{
|
||||
Action, App, AppContext as _, Axis, ClickEvent, Context, Corner, Entity, Focusable,
|
||||
InteractiveElement, IntoElement, ParentElement as _, Render, Styled as _, Window,
|
||||
prelude::FluentBuilder, px,
|
||||
Action, App, AppContext as _, Axis, ClickEvent, Context, Entity, Focusable, InteractiveElement,
|
||||
IntoElement, ParentElement as _, Render, Styled as _, Window, prelude::FluentBuilder, px,
|
||||
};
|
||||
|
||||
use gpui_component::{
|
||||
ActiveTheme, Disableable as _, Icon, IconName, Selectable as _, Sizable as _, Theme,
|
||||
button::{Button, ButtonCustomVariant, ButtonGroup, ButtonVariants as _, DropdownButton},
|
||||
button::{Button, ButtonCustomVariant, ButtonGroup, ButtonVariants as _},
|
||||
checkbox::Checkbox,
|
||||
h_flex, v_flex,
|
||||
};
|
||||
|
|
@ -441,6 +440,66 @@ impl Render for ButtonStory {
|
|||
.on_click(Self::on_click),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
section("With Dropdown Caret")
|
||||
.max_w_lg()
|
||||
.child(
|
||||
Button::new("button-outline-1")
|
||||
.primary()
|
||||
.dropdown_caret(true)
|
||||
.label("Primary Button")
|
||||
.disabled(disabled)
|
||||
.selected(selected)
|
||||
.loading(loading)
|
||||
.when(compact, |this| this.compact())
|
||||
.on_click(Self::on_click),
|
||||
)
|
||||
.child(
|
||||
Button::new("button-outline-2")
|
||||
.outline()
|
||||
.label("Secondary Button")
|
||||
.dropdown_caret(true)
|
||||
.disabled(disabled)
|
||||
.selected(selected)
|
||||
.loading(loading)
|
||||
.when(compact, |this| this.compact())
|
||||
.on_click(Self::on_click),
|
||||
)
|
||||
.child(
|
||||
Button::new("button-outline-5-ghost")
|
||||
.ghost()
|
||||
.dropdown_caret(true)
|
||||
.label("Ghost Button")
|
||||
.disabled(disabled)
|
||||
.selected(selected)
|
||||
.loading(loading)
|
||||
.when(compact, |this| this.compact())
|
||||
.on_click(Self::on_click),
|
||||
)
|
||||
.child(
|
||||
Button::new("button-outline-5-link")
|
||||
.link()
|
||||
.dropdown_caret(true)
|
||||
.label("Link Button")
|
||||
.disabled(disabled)
|
||||
.selected(selected)
|
||||
.loading(loading)
|
||||
.when(compact, |this| this.compact())
|
||||
.on_click(Self::on_click),
|
||||
)
|
||||
.child(
|
||||
Button::new("button-outline-5-text")
|
||||
.outline()
|
||||
.small()
|
||||
.dropdown_caret(true)
|
||||
.label("Small Button")
|
||||
.disabled(disabled)
|
||||
.selected(selected)
|
||||
.loading(loading)
|
||||
.when(compact, |this| this.compact())
|
||||
.on_click(Self::on_click),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
section("Small Size")
|
||||
.child(
|
||||
|
|
@ -690,120 +749,6 @@ impl Render for ButtonStory {
|
|||
})),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
section("Dropdown Button")
|
||||
.child(
|
||||
DropdownButton::new("dropdown-button1")
|
||||
.small()
|
||||
.button(Button::new("btn").label("Click Me"))
|
||||
.selected(selected)
|
||||
.dropdown_menu(move |this, _, _| {
|
||||
this.menu_with_check(
|
||||
"Disabled",
|
||||
disabled,
|
||||
Box::new(ButtonAction::Disabled),
|
||||
)
|
||||
.menu_with_check(
|
||||
"Loading",
|
||||
loading,
|
||||
Box::new(ButtonAction::Loading),
|
||||
)
|
||||
.menu_with_check(
|
||||
"Selected",
|
||||
selected,
|
||||
Box::new(ButtonAction::Selected),
|
||||
)
|
||||
.menu_with_check(
|
||||
"Compact",
|
||||
compact,
|
||||
Box::new(ButtonAction::Compact),
|
||||
)
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
DropdownButton::new("dropdown-button2")
|
||||
.button(Button::new("btn").label("Click Me"))
|
||||
.selected(selected)
|
||||
.dropdown_menu_with_anchor(Corner::BottomRight, move |this, _, _| {
|
||||
this.menu_with_check(
|
||||
"Disabled",
|
||||
disabled,
|
||||
Box::new(ButtonAction::Disabled),
|
||||
)
|
||||
.menu_with_check(
|
||||
"Loading",
|
||||
loading,
|
||||
Box::new(ButtonAction::Loading),
|
||||
)
|
||||
.menu_with_check(
|
||||
"Selected",
|
||||
selected,
|
||||
Box::new(ButtonAction::Selected),
|
||||
)
|
||||
.menu_with_check(
|
||||
"Compact",
|
||||
compact,
|
||||
Box::new(ButtonAction::Compact),
|
||||
)
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
DropdownButton::new("dropdown-button3")
|
||||
.outline()
|
||||
.button(Button::new("btn").label("Outline Dropdown"))
|
||||
.selected(selected)
|
||||
.dropdown_menu(move |this, _, _| {
|
||||
this.menu_with_check(
|
||||
"Disabled",
|
||||
disabled,
|
||||
Box::new(ButtonAction::Disabled),
|
||||
)
|
||||
.menu_with_check(
|
||||
"Loading",
|
||||
loading,
|
||||
Box::new(ButtonAction::Loading),
|
||||
)
|
||||
.menu_with_check(
|
||||
"Selected",
|
||||
selected,
|
||||
Box::new(ButtonAction::Selected),
|
||||
)
|
||||
.menu_with_check(
|
||||
"Compact",
|
||||
compact,
|
||||
Box::new(ButtonAction::Compact),
|
||||
)
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
DropdownButton::new("dropdown-button4")
|
||||
.ghost()
|
||||
.button(Button::new("btn").label("Ghost Dropdown"))
|
||||
.selected(selected)
|
||||
.dropdown_menu(move |this, _, _| {
|
||||
this.menu_with_check(
|
||||
"Disabled",
|
||||
disabled,
|
||||
Box::new(ButtonAction::Disabled),
|
||||
)
|
||||
.menu_with_check(
|
||||
"Loading",
|
||||
loading,
|
||||
Box::new(ButtonAction::Loading),
|
||||
)
|
||||
.menu_with_check(
|
||||
"Selected",
|
||||
selected,
|
||||
Box::new(ButtonAction::Selected),
|
||||
)
|
||||
.menu_with_check(
|
||||
"Compact",
|
||||
compact,
|
||||
Box::new(ButtonAction::Compact),
|
||||
)
|
||||
}),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
section("Icon Button")
|
||||
.child(
|
||||
|
|
|
|||
|
|
@ -416,6 +416,7 @@ impl Styled for StorySection {
|
|||
impl RenderOnce for StorySection {
|
||||
fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||
GroupBox::new()
|
||||
.id(self.title.clone())
|
||||
.outline()
|
||||
.title(
|
||||
h_flex()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::rc::Rc;
|
|||
|
||||
use crate::{
|
||||
h_flex, spinner::Spinner, tooltip::Tooltip, ActiveTheme, Colorize as _, Disableable,
|
||||
FocusableExt as _, Icon, Selectable, Sizable, Size, StyleSized, StyledExt,
|
||||
FocusableExt as _, Icon, IconName, Selectable, Sizable, Size, StyleSized, StyledExt,
|
||||
};
|
||||
use gpui::{
|
||||
div, prelude::FluentBuilder as _, px, relative, Action, AnyElement, App, ClickEvent, Corners,
|
||||
|
|
@ -189,6 +189,7 @@ pub struct Button {
|
|||
outline: bool,
|
||||
border_corners: Corners<bool>,
|
||||
border_edges: Edges<bool>,
|
||||
dropdown_caret: bool,
|
||||
size: Size,
|
||||
compact: bool,
|
||||
tooltip: Option<(
|
||||
|
|
@ -237,6 +238,7 @@ impl Button {
|
|||
outline: false,
|
||||
children: Vec::new(),
|
||||
loading_icon: None,
|
||||
dropdown_caret: false,
|
||||
tab_index: 0,
|
||||
tab_stop: true,
|
||||
}
|
||||
|
|
@ -352,6 +354,12 @@ impl Button {
|
|||
self
|
||||
}
|
||||
|
||||
/// Set to show a dropdown caret icon at the end of the button.
|
||||
pub fn dropdown_caret(mut self, dropdown_caret: bool) -> Self {
|
||||
self.dropdown_caret = dropdown_caret;
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn clickable(&self) -> bool {
|
||||
!(self.disabled || self.loading) && self.on_click.is_some()
|
||||
|
|
@ -579,6 +587,9 @@ impl RenderOnce for Button {
|
|||
this.child(div().flex_none().line_height(relative(1.)).child(label))
|
||||
})
|
||||
.children(self.children)
|
||||
.when(self.dropdown_caret, |this| {
|
||||
this.child(Icon::new(IconName::ChevronDown).with_size(icon_size))
|
||||
})
|
||||
})
|
||||
.when(self.loading && !self.disabled, |this| {
|
||||
this.bg(normal_style.bg.opacity(0.8))
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use gpui::{
|
|||
|
||||
use crate::{
|
||||
menu::{DropdownMenu, PopupMenu},
|
||||
Disableable, IconName, Selectable, Sizable, Size, StyledExt as _,
|
||||
Disableable, Selectable, Sizable, Size, StyledExt as _,
|
||||
};
|
||||
|
||||
use super::{Button, ButtonRounded, ButtonVariant, ButtonVariants};
|
||||
|
|
@ -178,7 +178,7 @@ impl RenderOnce for DropdownButton {
|
|||
.when_some(self.menu, |this, menu| {
|
||||
this.child(
|
||||
Button::new("popup")
|
||||
.icon(IconName::ChevronDown)
|
||||
.dropdown_caret(true)
|
||||
.rounded(self.rounded)
|
||||
.border_edges(Edges {
|
||||
left: rounded,
|
||||
|
|
|
|||
|
|
@ -845,13 +845,7 @@ where
|
|||
.when(!show_clean, |this| {
|
||||
let icon = match self.options.icon.clone() {
|
||||
Some(icon) => icon,
|
||||
None => {
|
||||
if self.open {
|
||||
Icon::new(IconName::ChevronUp)
|
||||
} else {
|
||||
Icon::new(IconName::ChevronDown)
|
||||
}
|
||||
}
|
||||
None => Icon::new(IconName::ChevronDown),
|
||||
};
|
||||
|
||||
this.child(icon.xsmall().text_color(match self.options.disabled {
|
||||
|
|
|
|||
|
|
@ -107,6 +107,16 @@ Button::new("btn")
|
|||
.label("Like")
|
||||
```
|
||||
|
||||
### With a dropdown caret icon
|
||||
|
||||
The `.dropdown_caret` method can allows adding a dropdown caret icon to end of the button.
|
||||
|
||||
```rust
|
||||
Button::new("btn")
|
||||
.label("Options")
|
||||
.dropdown_caret(true)
|
||||
```
|
||||
|
||||
### Button States
|
||||
|
||||
There have `disabled`, `loading`, `selected` state for buttons to indicate different statuses.
|
||||
|
|
|
|||
Loading…
Reference in a new issue