feat: Add Styled trait support to UI components

Added style support to Label, Panel, List, and Modal components by
implementing the gpui::Styled trait. This allows applying styles
directly to components without wrapping them in divs. Updated sidebar to
use Label component directly with styles instead of nested divs.
This commit is contained in:
Ignacio Perez
2025-12-26 12:37:32 -03:00
parent c4ab603176
commit 3c10f8fdb8
6 changed files with 59 additions and 22 deletions
+1 -4
View File
@@ -57,10 +57,7 @@ pub enum IconName {}
impl IconNamed for IconName {
fn path(&self) -> SharedString {
match self {
// Mapear cada variante a su path SVG
// IconName::Check => "icons/check.svg".into(),
// IconName::Close => "icons/close.svg".into(),
_ => "".into(),
_ => todo!(),
}
}
}
+17 -9
View File
@@ -5,27 +5,35 @@ use crate::theme::ActiveTheme;
#[derive(gpui::IntoElement)]
pub struct Label {
text: gpui::SharedString,
style: gpui::StyleRefinement,
}
impl Label {
pub fn new(text: impl Into<gpui::SharedString>) -> Self {
Self { text: text.into() }
Self {
text: text.into(),
style: gpui::StyleRefinement::default(),
}
}
}
// impl gpui::Styled for Label {
// fn style(&mut self) -> &mut gpui::StyleRefinement {
// &mut self.style
// }
// }
impl gpui::Styled for Label {
fn style(&mut self) -> &mut gpui::StyleRefinement {
&mut self.style
}
}
impl RenderOnce for Label {
fn render(self, _window: &mut gpui::Window, cx: &mut gpui::App) -> impl gpui::IntoElement {
fn render(mut self, _window: &mut gpui::Window, cx: &mut gpui::App) -> impl gpui::IntoElement {
let theme = cx.theme();
gpui::div()
let mut div = gpui::div()
.line_height(gpui::rems(1.25))
.text_color(theme.foreground)
.child(gpui::StyledText::new(&self.text))
.child(gpui::StyledText::new(&self.text));
*div.style() = self.style;
div
}
}
+10
View File
@@ -29,6 +29,7 @@ pub struct List {
items: Vec<ListItem>,
selected_index: Option<usize>,
height: Option<gpui::Pixels>,
style: gpui::StyleRefinement,
on_click: Option<Arc<dyn Fn(usize, &ListItem, &mut gpui::Context<Self>) + Send + Sync>>,
on_hover: Option<Arc<dyn Fn(usize, bool, &ListItem, &mut gpui::Context<Self>) + Send + Sync>>,
}
@@ -40,6 +41,7 @@ impl List {
items: Vec::new(),
selected_index: None,
height: None,
style: gpui::StyleRefinement::default(),
on_click: None,
on_hover: None,
}
@@ -127,6 +129,12 @@ impl List {
}
}
impl gpui::Styled for List {
fn style(&mut self) -> &mut gpui::StyleRefinement {
&mut self.style
}
}
impl gpui::Render for List {
fn render(
&mut self,
@@ -193,6 +201,8 @@ impl gpui::Render for List {
container = container.h(height);
}
*container.style() = self.style.clone();
container
}
}
+8
View File
@@ -28,6 +28,7 @@ pub struct Modal {
open: bool,
close_on_backdrop: bool,
last_action: Option<ModalAction>,
style: gpui::StyleRefinement,
on_close: Option<Arc<dyn Fn(ModalAction, &mut gpui::Context<Self>) + Send + Sync>>,
on_save: Option<Arc<dyn Fn(&mut gpui::Context<Self>) + Send + Sync>>,
on_cancel: Option<Arc<dyn Fn(&mut gpui::Context<Self>) + Send + Sync>>,
@@ -45,6 +46,7 @@ impl Modal {
open: false,
close_on_backdrop: true,
last_action: None,
style: gpui::StyleRefinement::default(),
on_close: None,
on_save: None,
on_cancel: None,
@@ -222,6 +224,12 @@ impl Modal {
}
}
impl gpui::Styled for Modal {
fn style(&mut self) -> &mut gpui::StyleRefinement {
&mut self.style
}
}
impl gpui::Render for Modal {
fn render(
&mut self,
+14 -2
View File
@@ -8,6 +8,7 @@ pub struct Panel {
title: Option<String>,
border: f32,
padding: f32,
style: gpui::StyleRefinement,
}
impl Panel {
@@ -17,6 +18,7 @@ impl Panel {
title: None,
border: 1.0,
padding: 8.0,
style: gpui::StyleRefinement::default(),
}
}
@@ -50,6 +52,12 @@ impl Panel {
}
}
impl gpui::Styled for Panel {
fn style(&mut self) -> &mut gpui::StyleRefinement {
&mut self.style
}
}
impl gpui::RenderOnce for Panel {
fn render(mut self, _window: &mut gpui::Window, cx: &mut gpui::App) -> impl IntoElement {
let theme = cx.theme();
@@ -81,7 +89,7 @@ impl gpui::RenderOnce for Panel {
})
.collect();
gpui::div()
let mut div = gpui::div()
.size_full()
.bg(theme.panel)
.border(gpui::px(self.border))
@@ -92,6 +100,10 @@ impl gpui::RenderOnce for Panel {
.flex_col()
.h_full()
.children(header)
.children(children)
.children(children);
*div.style() = self.style;
div
}
}
+9 -7
View File
@@ -1,4 +1,8 @@
use crate::components::{divider::Divider, panel::Panel};
use crate::components::{
icon::{Icon, IconName, IconSize},
label::Label,
panel::Panel,
};
use crate::models::{FilterState, ProjectTree};
use crate::theme::ActiveTheme;
use gpui::{Context, Div, Entity, IntoElement, Window, div, prelude::*, px};
@@ -299,11 +303,10 @@ impl Render for Sidebar {
.border_b_1()
.border_color(theme.border)
.child(
div()
Label::new("PROJECTS")
.text_sm()
.font_weight(gpui::FontWeight::BOLD)
.text_color(theme.foreground)
.child("PROJECTS"),
.text_color(theme.foreground),
),
)
.child(
@@ -337,11 +340,10 @@ impl Render for Sidebar {
.border_b_1()
.border_color(theme.border)
.child(
div()
Label::new("TAGS")
.text_sm()
.font_weight(gpui::FontWeight::BOLD)
.text_color(theme.foreground)
.child("TAGS"),
.text_color(theme.foreground),
),
)
.child(