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,
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<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 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
}
}
}

View file

@ -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;

View file

@ -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| {

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 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<Hsla>,
}
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<Hsla>) -> 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<AnyElement> for Icon {
fn into(self) -> AnyElement {
self.into_any_element()
}
}

View file

@ -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))
}