use crate::{ h_flex, indicator::Indicator, styled_ext::Sizable, theme::{ActiveTheme, Colorize as _}, Clickable, Disableable, Icon, Selectable, Size, }; use gpui::{ div, prelude::FluentBuilder as _, px, AnyElement, ClickEvent, Div, ElementId, FocusHandle, Hsla, InteractiveElement, IntoElement, MouseButton, ParentElement, Pixels, RenderOnce, SharedString, StatefulInteractiveElement as _, Styled, WindowContext, }; pub enum ButtonRounded { None, Small, Medium, Large, Size(Pixels), } impl From for ButtonRounded { fn from(px: Pixels) -> Self { ButtonRounded::Size(px) } } #[derive(Clone, Copy, PartialEq, Eq)] pub struct ButtonCustomStyle { color: Hsla, foreground: Hsla, border: Hsla, hover: Hsla, active: Hsla, } impl ButtonCustomStyle { pub fn new(cx: &WindowContext) -> Self { Self { color: cx.theme().secondary, foreground: cx.theme().secondary_foreground, border: cx.theme().border, hover: cx.theme().secondary_hover, active: cx.theme().secondary_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 border(mut self, color: Hsla) -> Self { self.border = 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 } } #[derive(Clone, Copy, PartialEq, Eq)] pub enum ButtonStyle { Primary, Secondary, Danger, Outline, Ghost, Link, Text, Custom(ButtonCustomStyle), } impl ButtonStyle { fn is_link(&self) -> bool { matches!(self, Self::Link) } fn is_text(&self) -> bool { matches!(self, Self::Text) } fn no_padding(&self) -> bool { self.is_link() || self.is_text() } } #[derive(IntoElement)] pub struct Button { pub base: Div, id: ElementId, focus_handle: FocusHandle, icon: Option, label: Option, children: Vec, disabled: bool, selected: bool, style: ButtonStyle, rounded: ButtonRounded, size: Size, compact: bool, tooltip: Option, on_click: Option>, loading: bool, } impl From