refactor: impl RenderOnce for button

This commit is contained in:
2026-04-22 22:12:28 +01:00
parent aa28a03e3c
commit 02932411fb

View File

@@ -1,35 +1,29 @@
use gpui::{AnyElement, FontWeight, InteractiveElement, ParentElement, Styled, div}; use gpui::{
AnyElement, FontWeight, InteractiveElement, IntoElement, ParentElement,
StatefulInteractiveElement, Styled, div, prelude::FluentBuilder,
};
use crate::{app, component::text::Text}; use crate::{app, component::text::Text};
#[derive(gpui::IntoElement)]
pub struct Button { pub struct Button {
div: gpui::Stateful<gpui::Div>, id: gpui::ElementId,
text_color: gpui::Rgba, text_color: gpui::Rgba,
label: Option<gpui::AnyElement>, label: Option<gpui::AnyElement>,
leading: Option<gpui::Svg>, leading: Option<gpui::Svg>,
trailing: Option<gpui::Svg>, trailing: Option<gpui::Svg>,
on_click: Option<Box<dyn Fn(&gpui::ClickEvent, &mut gpui::Window, &mut gpui::App)>>,
} }
pub fn button<E>(id: impl Into<gpui::ElementId>, cx: &gpui::Context<E>) -> Button { pub fn button<E>(id: impl Into<gpui::ElementId>, cx: &gpui::Context<E>) -> Button {
let theme = app::current_theme(cx); let theme = app::current_theme(cx);
Button { Button {
div: div() id: id.into(),
.id(id)
.flex()
.flex_row()
.gap_2()
.items_center()
.rounded_sm()
.bg(theme.colors.accent)
.text_xs()
.text_color(theme.colors.accent_text)
.font_weight(FontWeight(500.))
.px_2p5()
.py_0p5(),
text_color: theme.colors.accent_text, text_color: theme.colors.accent_text,
label: None, label: None,
leading: None, leading: None,
trailing: None, trailing: None,
on_click: None,
} }
} }
@@ -48,12 +42,13 @@ impl Button {
self.trailing = Some(s.text_color(self.text_color)); self.trailing = Some(s.text_color(self.text_color));
self self
} }
pub fn on_click(mut self, fn: impl Fn(&gpui::ClickEvent, &mut gpui::Window, &mut gpui::App)) -> Self {
}
} }
impl gpui::IntoElement for Button { impl gpui::RenderOnce for Button {
type Element = gpui::Stateful<gpui::Div>; fn render(self, _window: &mut gpui::Window, cx: &mut gpui::App) -> impl gpui::IntoElement {
fn into_element(self) -> Self::Element {
let mut children: Vec<AnyElement> = Vec::with_capacity(3); let mut children: Vec<AnyElement> = Vec::with_capacity(3);
if let Some(leading) = self.leading { if let Some(leading) = self.leading {
children.push(leading.into_any_element()); children.push(leading.into_any_element());
@@ -64,6 +59,25 @@ impl gpui::IntoElement for Button {
if let Some(trailing) = self.trailing { if let Some(trailing) = self.trailing {
children.push(trailing.into_any_element()); children.push(trailing.into_any_element());
} }
self.div.children(children)
let theme = cx.global::<app::Global>().current_theme;
div()
.id(self.id)
.flex()
.flex_row()
.gap_2()
.items_center()
.rounded_sm()
.bg(theme.colors.accent)
.text_xs()
.text_color(theme.colors.accent_text)
.font_weight(FontWeight(500.))
.px_2p5()
.py_0p5()
.children(children)
.when(self.on_click.is_some(), |div| {
div.on_click(self.on_click.unwrap())
})
} }
} }