From 3e8421c4954fa85709264060fea2c67394a0ae40 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sat, 29 Jun 2024 03:10:14 +0800 Subject: [PATCH] Fix Icon default use theme foreground and allows to override. --- crates/ui-story/src/lib.rs | 39 +++++++++++++++++++++-------- crates/ui-story/src/picker_story.rs | 4 +-- crates/ui/src/dropdown.rs | 8 ++++-- crates/ui/src/icon.rs | 32 +++++++++++++++++------ crates/ui/src/tab/tab.rs | 25 +++++++++--------- 5 files changed, 72 insertions(+), 36 deletions(-) diff --git a/crates/ui-story/src/lib.rs b/crates/ui-story/src/lib.rs index 2e322337..fcb86c04 100644 --- a/crates/ui-story/src/lib.rs +++ b/crates/ui-story/src/lib.rs @@ -17,7 +17,7 @@ use ui::{ divider::Divider, label::Label, tab::{Tab, TabBar}, - Selectable, + Icon, IconName, Selectable, }; use button_story::ButtonStory; @@ -141,25 +141,42 @@ impl Stories { .gap_4() .w_full() .child(TabBar::new("story-tabs").children(vec![ - self.tab("story-button", StoryType::Button, cx), - self.tab("story-input", StoryType::Input, cx), - self.tab("story-checkbox", StoryType::Checkbox, cx), - self.tab("story-switch", StoryType::Switch, cx), - self.tab("story-picker", StoryType::Picker, cx), - self.tab("story-dropdown", StoryType::Dropdown, cx), - self.tab("story-tooltip", StoryType::Tooltip, cx), + self.tab("story-button", StoryType::Button, Some(IconName::Close), cx), + self.tab("story-input", StoryType::Input, None, cx), + self.tab( + "story-checkbox", + StoryType::Checkbox, + Some(IconName::Check), + cx, + ), + self.tab("story-switch", StoryType::Switch, None, cx), + self.tab("story-picker", StoryType::Picker, None, cx), + self.tab("story-dropdown", StoryType::Dropdown, None, cx), + self.tab("story-tooltip", StoryType::Tooltip, None, cx), ])) } - fn tab(&self, id: &str, ty: StoryType, cx: &mut ViewContext) -> impl IntoElement { + fn tab( + &self, + id: &str, + ty: StoryType, + icon: Option>, + cx: &mut ViewContext, + ) -> impl IntoElement { let name = format!("{}", ty); let is_active = ty == self.active; - Tab::new(SharedString::from(id.to_string()), name) + let tab = Tab::new(SharedString::from(id.to_string()), name) .selected(is_active) .on_click(cx.listener(move |this, _, cx| { this.set_active(ty, cx); - })) + })); + + if let Some(icon) = icon { + tab.prefix(icon.into()) + } else { + tab + } } } diff --git a/crates/ui-story/src/picker_story.rs b/crates/ui-story/src/picker_story.rs index 60c8ef63..ec48da42 100644 --- a/crates/ui-story/src/picker_story.rs +++ b/crates/ui-story/src/picker_story.rs @@ -10,9 +10,7 @@ use ui::{ label::Label, list::ListItem, picker::{Picker, PickerDelegate}, - switch::{LabelSide, Switch}, - theme::{ActiveTheme, Colorize}, - v_flex, Clickable as _, Disableable as _, Selectable, StyledExt, + v_flex, Clickable as _, }; use super::story_case; diff --git a/crates/ui/src/dropdown.rs b/crates/ui/src/dropdown.rs index 45e6e656..7036bb29 100644 --- a/crates/ui/src/dropdown.rs +++ b/crates/ui/src/dropdown.rs @@ -24,7 +24,7 @@ use crate::{ list::ListItem, picker::{self, Picker, PickerDelegate}, theme::ActiveTheme, - v_flex, IconName, + v_flex, Icon, IconName, }; /// A trait for items that can be displayed in a dropdown. @@ -237,7 +237,11 @@ where .items_center() .justify_between() .child(div().flex_1().child(title)) - .child(div().w_4().h_4().child(IconName::ChevronsUpDown)), + .child( + Icon::new(IconName::ChevronsUpDown) + .size_4() + .text_color(cx.theme().muted_foreground), + ), ), ) .when(self.open, |this| { diff --git a/crates/ui/src/icon.rs b/crates/ui/src/icon.rs index e323877c..4f5038f7 100644 --- a/crates/ui/src/icon.rs +++ b/crates/ui/src/icon.rs @@ -1,9 +1,10 @@ -use gpui::{ - div, rgb, svg, Div, InteractiveElement, IntoElement, ParentElement as _, RenderOnce, - SharedString, StyleRefinement, Styled, Svg, TextStyle, TextStyleRefinement, WindowContext, -}; - use crate::theme::ActiveTheme; +use gpui::{ + div, rgb, svg, AnyElement, Div, Hsla, InteractiveElement, IntoElement, ParentElement as _, + RenderOnce, SharedString, StyleRefinement, Styled, Svg, TextStyle, TextStyleRefinement, + WindowContext, +}; +use windows::Win32::Foundation::NOERROR; #[derive(IntoElement)] pub enum IconName { @@ -49,13 +50,15 @@ impl RenderOnce for IconName { pub struct Icon { base: Svg, path: SharedString, + text_color: Option, } impl Icon { pub fn new(name: IconName) -> Self { Self { - base: svg().flex_none().size_4().text_color(rgb(0x000000)), + base: svg().flex_none().size_4(), path: name.path(), + text_color: None, } } @@ -72,10 +75,23 @@ impl Styled for Icon { fn style(&mut self) -> &mut StyleRefinement { self.base.style() } + + fn text_color(mut self, color: impl Into) -> Self { + self.text_color = Some(color.into()); + self + } } impl RenderOnce for Icon { - fn render(self, _cx: &mut WindowContext) -> impl IntoElement { - self.base.path(self.path) + fn render(self, cx: &mut WindowContext) -> impl IntoElement { + let text_color = self.text_color.unwrap_or_else(|| cx.theme().foreground); + + self.base.text_color(text_color).path(self.path) + } +} + +impl Into for Icon { + fn into(self) -> AnyElement { + self.into_any_element() } } diff --git a/crates/ui/src/tab/tab.rs b/crates/ui/src/tab/tab.rs index dc1cdde6..803b9910 100644 --- a/crates/ui/src/tab/tab.rs +++ b/crates/ui/src/tab/tab.rs @@ -1,8 +1,9 @@ use crate::selectable::Selectable; use crate::theme::{ActiveTheme, Colorize}; +use crate::Icon; use gpui::prelude::FluentBuilder as _; use gpui::{ - div, AnyElement, Div, IntoElement, ParentElement as _, RenderOnce, SharedString, Stateful, + div, px, AnyElement, Div, IntoElement, ParentElement as _, RenderOnce, SharedString, Stateful, StatefulInteractiveElement, WindowContext, }; use gpui::{InteractiveElement, Styled as _}; @@ -59,7 +60,11 @@ impl StatefulInteractiveElement for Tab {} impl RenderOnce for Tab { fn render(self, cx: &mut WindowContext) -> impl IntoElement { - let theme = cx.theme(); + let (text_color, bg_color) = match (self.selected, self.disabled) { + (true, _) => (cx.theme().foreground, cx.theme().background), + (false, true) => (cx.theme().foreground.opacity(0.5), cx.theme().muted), + (false, false) => (cx.theme().muted_foreground, cx.theme().muted), + }; self.base .flex() @@ -70,17 +75,13 @@ impl RenderOnce for Tab { .py_1() .px_3() .min_w_16() - .text_color(theme.muted_foreground) - .bg(theme.muted) - .when(self.selected, |this| { - this.text_color(theme.foreground) - .bg(theme.background) - .rounded_sm() + .text_color(text_color) + .bg(bg_color) + .when(self.selected, |this| this.rounded(px(6.))) + .when(self.disabled, |this| this) + .when_some(self.prefix, |this, prefix| { + this.child(prefix).text_color(text_color) }) - .when(self.disabled, |this| { - this.text_color(theme.foreground.opacity(0.5)) - }) - .when_some(self.prefix, |this, prefix| this.child(prefix)) .child(self.label.clone()) .when_some(self.suffix, |this, suffix| this.child(suffix)) }