use gpui::{ div, prelude::FluentBuilder as _, relative, AnyElement, App, ClickEvent, Div, ElementId, Hsla, InteractiveElement, IntoElement, MouseButton, ParentElement, RenderOnce, SharedString, StatefulInteractiveElement as _, Styled, Window, }; use theme::ActiveTheme; use crate::{ indicator::Indicator, tooltip::Tooltip, Disableable, Icon, Selectable, Sizable, Size, StyledExt, }; pub enum ButtonRounded { Normal, Full, } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ButtonCustomVariant { color: Hsla, foreground: Hsla, hover: Hsla, active: Hsla, } pub trait ButtonVariants: Sized { fn with_variant(self, variant: ButtonVariant) -> Self; /// With the primary style for the Button. fn primary(self) -> Self { self.with_variant(ButtonVariant::Primary) } /// With the secondary style for the Button. fn secondary(self) -> Self { self.with_variant(ButtonVariant::Secondary) } /// With the ghost style for the Button. fn ghost(self) -> Self { self.with_variant(ButtonVariant::Ghost) } /// With the transparent style for the Button. fn transparent(self) -> Self { self.with_variant(ButtonVariant::Transparent) } /// With the custom style for the Button. fn custom(self, style: ButtonCustomVariant) -> Self { self.with_variant(ButtonVariant::Custom(style)) } } impl ButtonCustomVariant { pub fn new(_window: &Window, cx: &App) -> Self { Self { color: cx.theme().element_background, foreground: cx.theme().element_foreground, hover: cx.theme().element_hover, active: cx.theme().element_active, } } pub fn color(mut self, color: Hsla) -> Self { self.color = color; self } pub fn foreground(mut self, color: Hsla) -> Self { self.foreground = color; self } pub fn hover(mut self, color: Hsla) -> Self { self.hover = color; self } pub fn active(mut self, color: Hsla) -> Self { self.active = color; self } } /// The variant of the Button. #[derive(Clone, Copy, PartialEq, Eq)] pub enum ButtonVariant { Primary, Secondary, Ghost, Transparent, Custom(ButtonCustomVariant), } impl Default for ButtonVariant { fn default() -> Self { Self::Primary } } type OnClick = Option>; /// A Button element. #[derive(IntoElement)] pub struct Button { pub base: Div, id: ElementId, icon: Option, label: Option, children: Vec, disabled: bool, variant: ButtonVariant, rounded: ButtonRounded, size: Size, reverse: bool, bold: bool, tooltip: Option, on_click: OnClick, loading: bool, loading_icon: Option, pub(crate) selected: bool, pub(crate) stop_propagation: bool, } impl From