dropdown_button: Add new component (#551)

## Regular
<img width="162" alt="image"
src="https://github.com/user-attachments/assets/4e597d0b-41d1-4b0e-9939-728cae71fe65"
/>

## Active
<img width="162" alt="image"
src="https://github.com/user-attachments/assets/0871ed6b-3188-44dd-93d4-5996f9213edc"
/>
<br />
<img width="162" alt="image"
src="https://github.com/user-attachments/assets/b05ccdc6-e405-47d0-97e7-470afadbbd38"
/>


## Break Change
Move `ButtonGroup` into the `button`.
This commit is contained in:
Floyd Wang 2025-01-17 14:16:24 +08:00 committed by GitHub
parent 04d720f3a7
commit 569a4e7262
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 119 additions and 7 deletions

View file

@ -3,8 +3,12 @@ use gpui::{
VisualContext as _, WindowContext,
};
use ui::{
accordion::Accordion, button::Button, button_group::ButtonGroup, checkbox::Checkbox, h_flex,
switch::Switch, v_flex, IconName, Selectable, Sizable, Size,
accordion::Accordion,
button::{Button, ButtonGroup},
checkbox::Checkbox,
h_flex,
switch::Switch,
v_flex, IconName, Selectable, Sizable, Size,
};
pub struct AccordionStory {

View file

@ -1,11 +1,10 @@
use gpui::{
px, ClickEvent, FocusableView, IntoElement, ParentElement as _, Render, Styled as _, View,
ViewContext, VisualContext as _, WindowContext,
actions, px, ClickEvent, FocusableView, InteractiveElement, IntoElement, ParentElement as _,
Render, Styled as _, View, ViewContext, VisualContext as _, WindowContext,
};
use ui::{
button::{Button, ButtonCustomVariant, ButtonVariants as _},
button_group::ButtonGroup,
button::{Button, ButtonCustomVariant, ButtonGroup, ButtonVariants as _, DropdownButton},
checkbox::Checkbox,
h_flex,
prelude::FluentBuilder,
@ -15,6 +14,8 @@ use ui::{
use crate::section;
actions!(button_story, [Disabled, Loading, Selected, Compact]);
pub struct ButtonStory {
focus_handle: gpui::FocusHandle,
disabled: bool,
@ -74,6 +75,10 @@ impl Render for ButtonStory {
let toggle_multiple = self.toggle_multiple;
v_flex()
.on_action(cx.listener(|this, _: &Disabled, _| this.disabled = !this.disabled))
.on_action(cx.listener(|this, _: &Loading, _| this.loading = !this.loading))
.on_action(cx.listener(|this, _: &Selected, _| this.selected = !this.selected))
.on_action(cx.listener(|this, _: &Compact, _| this.compact = !this.compact))
.gap_6()
.child(
h_flex()
@ -546,6 +551,18 @@ impl Render for ButtonStory {
),
),
)
.child(
section("Dropdown Button", cx).child(
DropdownButton::new("dropdown-button")
.button(Button::new("dropdown-button-button").label("Click Me"))
.popup_menu(move |this, _| {
this.menu("Disabled", Box::new(Disabled))
.menu("Loading", Box::new(Loading))
.menu("Selected", Box::new(Selected))
.menu("Compact", Box::new(Compact))
}),
),
)
.child(
section("Icon Button", cx)
.child(

View file

@ -0,0 +1,85 @@
use gpui::{
prelude::FluentBuilder, Corner, Corners, Edges, ElementId, IntoElement, ParentElement,
RenderOnce, ViewContext, WindowContext,
};
use crate::{
h_flex,
popup_menu::{PopupMenu, PopupMenuExt},
IconName,
};
use super::Button;
#[derive(IntoElement)]
pub struct DropdownButton {
id: ElementId,
button: Option<Button>,
popup_menu: Option<Box<dyn Fn(PopupMenu, &mut ViewContext<PopupMenu>) -> PopupMenu + 'static>>,
}
impl DropdownButton {
pub fn new(id: impl Into<ElementId>) -> Self {
Self {
id: id.into(),
button: None,
popup_menu: None,
}
}
pub fn button(mut self, button: Button) -> Self {
self.button = Some(
button
.border_corners(Corners {
top_left: true,
top_right: false,
bottom_left: true,
bottom_right: false,
})
.border_edges(Edges {
left: true,
top: true,
right: true,
bottom: true,
}),
);
self
}
pub fn popup_menu(
mut self,
popup_menu: impl Fn(PopupMenu, &mut ViewContext<PopupMenu>) -> PopupMenu + 'static,
) -> Self {
self.popup_menu = Some(Box::new(popup_menu));
self
}
}
impl RenderOnce for DropdownButton {
fn render(self, _: &mut WindowContext) -> impl IntoElement {
h_flex().when_some(self.button, |this, button| {
this.child(button)
.when_some(self.popup_menu, |this, popup_menu| {
this.child(
Button::new(self.id)
.icon(IconName::ChevronDown)
.border_edges(Edges {
left: false,
top: true,
right: true,
bottom: true,
})
.border_corners(Corners {
top_left: false,
top_right: true,
bottom_left: false,
bottom_right: true,
})
.popup_menu_with_anchor(Corner::TopRight, move |this, cx| {
popup_menu(this, cx)
}),
)
})
})
}
}

View file

@ -0,0 +1,7 @@
mod button;
mod button_group;
mod dropdown_button;
pub use button::*;
pub use button_group::*;
pub use dropdown_button::*;

View file

@ -14,7 +14,6 @@ pub mod animation;
pub mod badge;
pub mod breadcrumb;
pub mod button;
pub mod button_group;
pub mod checkbox;
pub mod clipboard;
pub mod color_picker;