Fix Icon default use theme foreground and allows to override.

This commit is contained in:
Jason Lee 2024-06-29 03:10:14 +08:00
parent 3c4891cb69
commit 3e8421c495
5 changed files with 72 additions and 36 deletions

View file

@ -17,7 +17,7 @@ use ui::{
divider::Divider, divider::Divider,
label::Label, label::Label,
tab::{Tab, TabBar}, tab::{Tab, TabBar},
Selectable, Icon, IconName, Selectable,
}; };
use button_story::ButtonStory; use button_story::ButtonStory;
@ -141,25 +141,42 @@ impl Stories {
.gap_4() .gap_4()
.w_full() .w_full()
.child(TabBar::new("story-tabs").children(vec![ .child(TabBar::new("story-tabs").children(vec![
self.tab("story-button", StoryType::Button, cx), self.tab("story-button", StoryType::Button, Some(IconName::Close), cx),
self.tab("story-input", StoryType::Input, cx), self.tab("story-input", StoryType::Input, None, cx),
self.tab("story-checkbox", StoryType::Checkbox, cx), self.tab(
self.tab("story-switch", StoryType::Switch, cx), "story-checkbox",
self.tab("story-picker", StoryType::Picker, cx), StoryType::Checkbox,
self.tab("story-dropdown", StoryType::Dropdown, cx), Some(IconName::Check),
self.tab("story-tooltip", StoryType::Tooltip, cx), 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<Self>) -> impl IntoElement { fn tab(
&self,
id: &str,
ty: StoryType,
icon: Option<impl Into<Icon>>,
cx: &mut ViewContext<Self>,
) -> impl IntoElement {
let name = format!("{}", ty); let name = format!("{}", ty);
let is_active = ty == self.active; 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) .selected(is_active)
.on_click(cx.listener(move |this, _, cx| { .on_click(cx.listener(move |this, _, cx| {
this.set_active(ty, cx); this.set_active(ty, cx);
})) }));
if let Some(icon) = icon {
tab.prefix(icon.into())
} else {
tab
}
} }
} }

View file

@ -10,9 +10,7 @@ use ui::{
label::Label, label::Label,
list::ListItem, list::ListItem,
picker::{Picker, PickerDelegate}, picker::{Picker, PickerDelegate},
switch::{LabelSide, Switch}, v_flex, Clickable as _,
theme::{ActiveTheme, Colorize},
v_flex, Clickable as _, Disableable as _, Selectable, StyledExt,
}; };
use super::story_case; use super::story_case;

View file

@ -24,7 +24,7 @@ use crate::{
list::ListItem, list::ListItem,
picker::{self, Picker, PickerDelegate}, picker::{self, Picker, PickerDelegate},
theme::ActiveTheme, theme::ActiveTheme,
v_flex, IconName, v_flex, Icon, IconName,
}; };
/// A trait for items that can be displayed in a dropdown. /// A trait for items that can be displayed in a dropdown.
@ -237,7 +237,11 @@ where
.items_center() .items_center()
.justify_between() .justify_between()
.child(div().flex_1().child(title)) .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| { .when(self.open, |this| {

View file

@ -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 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)] #[derive(IntoElement)]
pub enum IconName { pub enum IconName {
@ -49,13 +50,15 @@ impl RenderOnce for IconName {
pub struct Icon { pub struct Icon {
base: Svg, base: Svg,
path: SharedString, path: SharedString,
text_color: Option<Hsla>,
} }
impl Icon { impl Icon {
pub fn new(name: IconName) -> Self { pub fn new(name: IconName) -> Self {
Self { Self {
base: svg().flex_none().size_4().text_color(rgb(0x000000)), base: svg().flex_none().size_4(),
path: name.path(), path: name.path(),
text_color: None,
} }
} }
@ -72,10 +75,23 @@ impl Styled for Icon {
fn style(&mut self) -> &mut StyleRefinement { fn style(&mut self) -> &mut StyleRefinement {
self.base.style() self.base.style()
} }
fn text_color(mut self, color: impl Into<Hsla>) -> Self {
self.text_color = Some(color.into());
self
}
} }
impl RenderOnce for Icon { impl RenderOnce for Icon {
fn render(self, _cx: &mut WindowContext) -> impl IntoElement { fn render(self, cx: &mut WindowContext) -> impl IntoElement {
self.base.path(self.path) let text_color = self.text_color.unwrap_or_else(|| cx.theme().foreground);
self.base.text_color(text_color).path(self.path)
}
}
impl Into<AnyElement> for Icon {
fn into(self) -> AnyElement {
self.into_any_element()
} }
} }

View file

@ -1,8 +1,9 @@
use crate::selectable::Selectable; use crate::selectable::Selectable;
use crate::theme::{ActiveTheme, Colorize}; use crate::theme::{ActiveTheme, Colorize};
use crate::Icon;
use gpui::prelude::FluentBuilder as _; use gpui::prelude::FluentBuilder as _;
use gpui::{ use gpui::{
div, AnyElement, Div, IntoElement, ParentElement as _, RenderOnce, SharedString, Stateful, div, px, AnyElement, Div, IntoElement, ParentElement as _, RenderOnce, SharedString, Stateful,
StatefulInteractiveElement, WindowContext, StatefulInteractiveElement, WindowContext,
}; };
use gpui::{InteractiveElement, Styled as _}; use gpui::{InteractiveElement, Styled as _};
@ -59,7 +60,11 @@ impl StatefulInteractiveElement for Tab {}
impl RenderOnce for Tab { impl RenderOnce for Tab {
fn render(self, cx: &mut WindowContext) -> impl IntoElement { 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 self.base
.flex() .flex()
@ -70,17 +75,13 @@ impl RenderOnce for Tab {
.py_1() .py_1()
.px_3() .px_3()
.min_w_16() .min_w_16()
.text_color(theme.muted_foreground) .text_color(text_color)
.bg(theme.muted) .bg(bg_color)
.when(self.selected, |this| { .when(self.selected, |this| this.rounded(px(6.)))
this.text_color(theme.foreground) .when(self.disabled, |this| this)
.bg(theme.background) .when_some(self.prefix, |this, prefix| {
.rounded_sm() 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()) .child(self.label.clone())
.when_some(self.suffix, |this, suffix| this.child(suffix)) .when_some(self.suffix, |this, suffix| this.child(suffix))
} }