Add Icon Button support. (#11)

When the Button have no label present, it will use the Icon mode.

<img width="891" alt="image"
src="https://github.com/huacnlee/gpui-component/assets/5518/ca6240d5-02c8-4201-9a79-4afdf9938dd8">
This commit is contained in:
Jason Lee 2024-07-01 21:32:03 +08:00 committed by GitHub
parent f9e075113e
commit cbbd20867f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 358 additions and 147 deletions

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle-x"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg>

After

Width:  |  Height:  |  Size: 291 B

1
assets/icons/delete.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-delete"><path d="M20 5H9l-7 7 7 7h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2Z"/><line x1="18" x2="12" y1="9" y2="15"/><line x1="12" x2="18" y1="9" y2="15"/></svg>delete

After

Width:  |  Height:  |  Size: 360 B

1
assets/icons/search.svg Normal file
View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-search"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>

After

Width:  |  Height:  |  Size: 273 B

View file

@ -218,7 +218,7 @@ impl Render for StoryWorkspace {
.items_center()
.justify_end()
.px_2()
.on_mouse_move(|_, cx| cx.stop_propagation())
.mr_3()
.child(
Switch::new("theme-mode")
.size(ButtonSize::Small)

View file

@ -1,6 +1,6 @@
use gpui::{
px, ClickEvent, IntoElement, ParentElement as _, Render, Styled as _, View, ViewContext,
VisualContext as _, WindowContext,
div, ClickEvent, Div, IntoElement, ParentElement as _, Render, SharedString, Styled as _, View,
ViewContext, VisualContext as _, WindowContext,
};
use ui::{
@ -21,117 +21,224 @@ impl ButtonStory {
}
impl Render for ButtonStory {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
fn section(title: impl Into<SharedString>, cx: &ViewContext<ButtonStory>) -> Div {
use ui::theme::ActiveTheme;
let theme = cx.theme();
h_flex()
.items_center()
.gap_4()
.p_4()
.w_full()
.rounded_lg()
.border_1()
.border_color(theme.border)
.flex_wrap()
.justify_around()
.child(div().flex_none().w_full().child(title.into()))
}
v_flex()
.w_full()
.justify_start()
.gap_6()
.child(
v_flex()
.w(px(360.))
h_flex()
.gap_6()
.child(
Button::new("button-1", "Primary Button")
.style(ButtonStyle::Primary)
.on_click(Self::on_click),
section("Normal Button", cx)
.child(
Button::new("button-1")
.label("Primary Button")
.style(ButtonStyle::Primary)
.on_click(Self::on_click),
)
.child(
Button::new("button-2")
.label("Secondary Button")
.style(ButtonStyle::Secondary)
.on_click(Self::on_click),
)
.child(
Button::new("button-4")
.label("Danger Button")
.style(ButtonStyle::Danger)
.on_click(Self::on_click),
),
)
.child(
Button::new("button-2", "Secondary Button")
.style(ButtonStyle::Secondary)
.on_click(Self::on_click),
)
.child(
Button::new("button-4", "Danger Button")
.style(ButtonStyle::Danger)
.on_click(Self::on_click),
section("Button with Icon", cx)
.child(
Button::new("button-icon-1")
.label("Confirm")
.icon(IconName::Check)
.style(ButtonStyle::Primary)
.on_click(Self::on_click),
)
.child(
Button::new("button-icon-2")
.label("Abort")
.icon(IconName::Close)
.style(ButtonStyle::Secondary)
.on_click(Self::on_click),
)
.child(
Button::new("button-icon-3")
.label("Maximize")
.icon(Icon::new(IconName::Maximize))
.style(ButtonStyle::Secondary)
.on_click(Self::on_click),
),
),
)
.child(
h_flex()
.gap_6()
.child(
Button::new("button-icon-1", "Confirm")
.icon(IconName::Check)
.style(ButtonStyle::Primary)
.on_click(Self::on_click),
section("Small Size", cx)
.child(
Button::new("button-6")
.label("Primary Button")
.style(ButtonStyle::Primary)
.size(ButtonSize::Small)
.on_click(Self::on_click),
)
.child(
Button::new("button-7")
.label("Secondary Button")
.style(ButtonStyle::Secondary)
.size(ButtonSize::Small)
.on_click(Self::on_click),
)
.child(
Button::new("button-8")
.label("Danger Button")
.style(ButtonStyle::Danger)
.size(ButtonSize::Small)
.on_click(Self::on_click),
),
)
.child(
Button::new("button-icon-2", "Abort")
section("XSmall Size", cx)
.child(
Button::new("button-xs-1")
.label("Primary Button")
.style(ButtonStyle::Primary)
.size(ButtonSize::XSmall)
.on_click(Self::on_click),
)
.child(
Button::new("button-xs-2")
.label("Secondary Button")
.style(ButtonStyle::Secondary)
.size(ButtonSize::XSmall)
.on_click(Self::on_click),
)
.child(
Button::new("button-xs-3")
.label("Danger Button")
.style(ButtonStyle::Danger)
.size(ButtonSize::XSmall)
.on_click(Self::on_click),
),
),
)
.child(
h_flex()
.gap_6()
.child(
section("Disabled Button", cx)
.child(
Button::new("button-disabled1")
.label("Disabled Button")
.style(ButtonStyle::Primary)
.on_click(Self::on_click)
.disabled(true),
)
.child(
Button::new("button-disabled1")
.label("Disabled Button")
.style(ButtonStyle::Secondary)
.on_click(Self::on_click)
.disabled(true),
)
.child(
Button::new("button-disabled1")
.label("Disabled Button")
.style(ButtonStyle::Danger)
.on_click(Self::on_click)
.disabled(true),
),
)
.child(
section("Selected Style", cx)
.child(
Button::new("button-selected-1")
.label("Selected Button")
.style(ButtonStyle::Primary)
.selected(true),
)
.child(
Button::new("button-selected-2")
.label("Selected Button")
.style(ButtonStyle::Secondary)
.selected(true),
)
.child(
Button::new("button-selected-3")
.label("Selected Button")
.style(ButtonStyle::Danger)
.selected(true),
),
),
)
.child(
section("Icon Button", cx)
.child(
Button::new("icon-button-0")
.icon(IconName::Search)
.style(ButtonStyle::Primary),
)
.child(Button::new("icon-button-1").icon(IconName::Info))
.child(
Button::new("icon-button-2")
.icon(IconName::Close)
.style(ButtonStyle::Secondary)
.on_click(Self::on_click),
.style(ButtonStyle::Danger),
)
.child(
Button::new("button-icon-3", "Maximize")
.icon(Icon::new(IconName::Maximize))
.style(ButtonStyle::Secondary)
.on_click(Self::on_click),
),
)
.child(
h_flex()
.items_center()
.gap_6()
.child(
Button::new("button-disabled1", "Disabled Button")
.style(ButtonStyle::Primary)
.on_click(Self::on_click)
.disabled(true),
)
.child(
Button::new("button-disabled1", "Disabled Button")
.style(ButtonStyle::Secondary)
.on_click(Self::on_click)
.disabled(true),
)
.child(
Button::new("button-disabled1", "Disabled Button")
.style(ButtonStyle::Danger)
.on_click(Self::on_click)
.disabled(true),
),
)
.child(
h_flex()
.items_center()
.gap_6()
.child(
Button::new("button-6", "Primary Button")
.style(ButtonStyle::Primary)
Button::new("icon-button-3")
.icon(IconName::Search)
.size(ButtonSize::Small)
.on_click(Self::on_click),
.style(ButtonStyle::Primary),
)
.child(
Button::new("button-7", "Secondary Button")
.style(ButtonStyle::Secondary)
Button::new("icon-button-4")
.icon(IconName::Info)
.size(ButtonSize::Small),
)
.child(
Button::new("icon-button-5")
.icon(IconName::Close)
.size(ButtonSize::Small)
.on_click(Self::on_click),
.style(ButtonStyle::Danger),
)
.child(
Button::new("button-8", "Danger Button")
.style(ButtonStyle::Danger)
.size(ButtonSize::Small)
.on_click(Self::on_click),
),
)
.child(
h_flex()
.items_center()
.gap_6()
.child(
Button::new("button-6", "Selected Button")
.style(ButtonStyle::Primary)
.selected(true),
Button::new("icon-button-6")
.icon(IconName::Search)
.size(ButtonSize::XSmall)
.style(ButtonStyle::Primary),
)
.child(
Button::new("button-7", "Selected Button")
.style(ButtonStyle::Secondary)
.selected(true),
Button::new("icon-button-7")
.icon(IconName::Info)
.size(ButtonSize::XSmall),
)
.child(
Button::new("button-8", "Selected Button")
.style(ButtonStyle::Danger)
.selected(true),
Button::new("icon-button-8")
.icon(IconName::Close)
.size(ButtonSize::XSmall)
.style(ButtonStyle::Danger),
),
)
}

View file

@ -39,13 +39,15 @@ impl Render for CheckboxStory {
h_flex()
.items_center()
.gap_6()
.child(Checkbox::new("check1", cx).checked(self.check1).on_click(
cx.listener(|v, _, _| {
v.check1 = v.check1.inverse();
}),
))
.child(
Checkbox::new("check2", cx)
Checkbox::new("check1")
.checked(self.check1)
.on_click(cx.listener(|v, _, _| {
v.check1 = v.check1.inverse();
})),
)
.child(
Checkbox::new("check2")
.checked(self.check2)
.label("Subscribe to newsletter")
.on_click(cx.listener(|v, _, _| {
@ -53,7 +55,7 @@ impl Render for CheckboxStory {
})),
)
.child(
Checkbox::new("check3", cx)
Checkbox::new("check3")
.checked(self.check3)
.label("Remember me")
.on_click(cx.listener(|v, _, _| {
@ -68,19 +70,19 @@ impl Render for CheckboxStory {
.items_center()
.gap_6()
.child(
Checkbox::new("check3", cx)
Checkbox::new("check3")
.label("Disabled Checked")
.checked(Selection::Selected)
.disabled(true),
)
.child(
Checkbox::new("check3_1", cx)
Checkbox::new("check3_1")
.label("Disabled Unchecked")
.checked(Selection::Unselected)
.disabled(true),
)
.child(
Checkbox::new("check3_2", cx)
Checkbox::new("check3_2")
.label("Disabled Indeterminate")
.checked(Selection::Indeterminate)
.disabled(true),

View file

@ -9,7 +9,7 @@ use ui::{
h_flex,
list::ListItem,
picker::{Picker, PickerDelegate},
v_flex, Clickable as _,
v_flex, Clickable as _, IconName,
};
actions!(picker_story, [DismissPicker]);
@ -197,7 +197,9 @@ impl Render for PickerStory {
.gap_6()
.child(
v_flex().items_start().child(
Button::new("show-picker", "Show Picker...")
Button::new("show-picker")
.label("Show Picker...")
.icon(IconName::Search)
.style(ButtonStyle::Primary)
.on_click(cx.listener(|this, _, cx| {
this.open = !this.open;

View file

@ -75,7 +75,7 @@ impl Render for PopoverStory {
.child(
v_flex().gap_4().child(
Popover::new("info-top-left")
.trigger(Button::new("info-top-left", "Top Left"))
.trigger(Button::new("info-top-left").label("Top Left"))
.content(|cx| {
PopoverContent::new(cx, |_| {
v_flex()
@ -83,7 +83,8 @@ impl Render for PopoverStory {
.child("Hello, this is a Popover.")
.child(Divider::horizontal())
.child(
Button::new("info1", "Yes")
Button::new("info1")
.label("Yes")
.width(px(80.))
.size(ButtonSize::Small),
)
@ -95,7 +96,7 @@ impl Render for PopoverStory {
.child(
Popover::new("info-top-right")
.anchor(AnchorCorner::TopRight)
.trigger(Button::new("info-top-right", "Top Right"))
.trigger(Button::new("info-top-right").label("Top Right"))
.content(|cx| {
PopoverContent::new(cx, |_| {
v_flex()
@ -103,7 +104,8 @@ impl Render for PopoverStory {
.child("Hello, this is a Popover on the Top Right.")
.child(Divider::horizontal())
.child(
Button::new("info1", "Yes")
Button::new("info1")
.label("Yes")
.width(px(80.))
.size(ButtonSize::Small),
)
@ -120,14 +122,20 @@ impl Render for PopoverStory {
.child(
Popover::new("info-bottom-left")
.anchor(AnchorCorner::BottomLeft)
.trigger(Button::new("pop", "Popup with Form").width(px(300.)))
.trigger(
Button::new("pop").label("Popup with Form").width(px(300.)),
)
.content(move |_| form.clone()),
)
.child(
Popover::new("info-bottom-right")
.anchor(AnchorCorner::BottomRight)
.mouse_button(MouseButton::Right)
.trigger(Button::new("pop", "Mouse Right Click").width(px(300.)))
.trigger(
Button::new("pop")
.label("Mouse Right Click")
.width(px(300.)),
)
.content(|cx| {
PopoverContent::new(cx, |_| {
v_flex()
@ -135,7 +143,8 @@ impl Render for PopoverStory {
.child("Hello, this is a Popover on the Bottom Right.")
.child(Divider::horizontal())
.child(
Button::new("info1", "Yes")
Button::new("info1")
.label("Yes")
.width(px(80.))
.size(ButtonSize::Small),
)

View file

@ -25,14 +25,18 @@ impl TooltipStory {
}
impl Render for TooltipStory {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl gpui::IntoElement {
fn render(&mut self, _cx: &mut gpui::ViewContext<Self>) -> impl gpui::IntoElement {
v_flex()
.w(px(360.))
.gap_5()
.child(
div()
.cursor(CursorStyle::PointingHand)
.child(Button::new("button", "Hover me").style(ButtonStyle::Primary))
.child(
Button::new("button")
.label("Hover me")
.style(ButtonStyle::Primary),
)
.id("tooltip-1")
.tooltip(|cx| Tooltip::text("This is a Button", cx)),
)
@ -40,7 +44,8 @@ impl Render for TooltipStory {
div()
.cursor(CursorStyle::PointingHand)
.child(
Button::new("button-meta", "With meta, Hover me")
Button::new("button-meta")
.label("With meta, Hover me")
.style(ButtonStyle::Primary),
)
.id("tooltip-2")
@ -58,7 +63,7 @@ impl Render for TooltipStory {
div()
.cursor(CursorStyle::PointingHand)
.child(
Checkbox::new("check", cx)
Checkbox::new("check")
.label("Remember me")
.checked(Selection::Selected),
)

View file

@ -18,6 +18,7 @@ pub enum ButtonRounded {
#[derive(Clone, Copy)]
pub enum ButtonSize {
XSmall,
Small,
Medium,
}
@ -34,7 +35,7 @@ pub struct Button {
pub base: Div,
id: ElementId,
icon: Option<Icon>,
label: SharedString,
label: Option<SharedString>,
disabled: bool,
selected: bool,
width: Option<DefiniteLength>,
@ -47,12 +48,12 @@ pub struct Button {
}
impl Button {
pub fn new(id: impl Into<ElementId>, label: impl Into<SharedString>) -> Self {
pub fn new(id: impl Into<ElementId>) -> Self {
Self {
base: div(),
id: id.into(),
icon: None,
label: label.into(),
label: None,
disabled: false,
selected: false,
style: ButtonStyle::Secondary,
@ -66,15 +67,15 @@ impl Button {
}
pub fn primary(id: impl Into<ElementId>, label: impl Into<SharedString>) -> Self {
Self::new(id, label).style(ButtonStyle::Primary)
Self::new(id).label(label).style(ButtonStyle::Primary)
}
pub fn danger(id: impl Into<ElementId>, label: impl Into<SharedString>) -> Self {
Self::new(id, label).style(ButtonStyle::Danger)
Self::new(id).label(label).style(ButtonStyle::Danger)
}
pub fn small(id: impl Into<ElementId>, label: impl Into<SharedString>) -> Self {
Self::new(id, label).size(ButtonSize::Small)
Self::new(id).label(label).size(ButtonSize::Small)
}
pub fn width(mut self, width: impl Into<DefiniteLength>) -> Self {
@ -97,6 +98,12 @@ impl Button {
self
}
pub fn label(mut self, label: impl Into<SharedString>) -> Self {
self.label = Some(label.into());
self
}
/// Set the icon of the button, if the Button have no label, the button well in Icon Button mode.
pub fn icon(mut self, icon: impl Into<Icon>) -> Self {
self.icon = Some(icon.into());
self
@ -147,9 +154,20 @@ impl RenderOnce for Button {
.justify_center()
.when_some(self.width, |this, width| this.w(width))
.when_some(self.height, |this, height| this.h(height))
.map(|this| match self.size {
ButtonSize::Small => this.px_3().py_2().h_6(),
ButtonSize::Medium => this.px_4().py_2().h_8(),
.map(|this| {
if self.label.is_none() {
match self.size {
ButtonSize::XSmall => this.size_5(),
ButtonSize::Small => this.size_6(),
ButtonSize::Medium => this.size_8(),
}
} else {
match self.size {
ButtonSize::XSmall => this.px_1().py_1().h_5(),
ButtonSize::Small => this.px_3().py_2().h_6(),
ButtonSize::Medium => this.px_4().py_2().h_8(),
}
}
})
.map(|this| match self.rounded {
ButtonRounded::Small => this.rounded(px(cx.theme().radius * 0.5)),
@ -214,10 +232,11 @@ impl RenderOnce for Button {
.gap_2()
.text_color(text_color)
.when_some(self.icon, |this, icon| {
this.child(icon.text_color(text_color))
this.child(icon.size(self.size).text_color(text_color))
})
.child(self.label)
.when_some(self.label, |this, label| this.child(label))
.map(|this| match self.size {
ButtonSize::XSmall => this.text_xs(),
ButtonSize::Small => this.text_sm(),
ButtonSize::Medium => this.text_base(),
})
@ -250,9 +269,9 @@ impl ButtonStyle {
fn border_color(&self, cx: &WindowContext) -> Hsla {
match self {
ButtonStyle::Primary => cx.theme().primary.darken(0.05),
ButtonStyle::Primary => cx.theme().primary,
ButtonStyle::Secondary => cx.theme().border,
ButtonStyle::Danger => cx.theme().destructive.darken(0.05),
ButtonStyle::Danger => cx.theme().destructive,
}
}
@ -265,8 +284,11 @@ impl ButtonStyle {
}
fn hovered(&self, cx: &WindowContext) -> ButtonStyles {
// Hover color = color/90
let bg = self.bg_color(cx);
let bg = match self {
ButtonStyle::Primary => cx.theme().primary_hover,
ButtonStyle::Secondary => cx.theme().secondary_hover,
ButtonStyle::Danger => cx.theme().destructive_hover,
};
let border = self.border_color(cx);
let fg = self.text_color(cx);
@ -274,17 +296,25 @@ impl ButtonStyle {
}
fn active(&self, cx: &WindowContext) -> ButtonStyles {
let bg = self.bg_color(cx).darken(0.05);
let bg = match self {
ButtonStyle::Primary => cx.theme().primary_active,
ButtonStyle::Secondary => cx.theme().secondary_active,
ButtonStyle::Danger => cx.theme().destructive_active,
};
let border = self.border_color(cx);
let fg = self.text_color(cx).darken(0.05);
let fg = self.text_color(cx);
ButtonStyles { bg, border, fg }
}
fn selected(&self, cx: &WindowContext) -> ButtonStyles {
let bg = self.bg_color(cx).darken(0.07);
let bg = match self {
ButtonStyle::Primary => cx.theme().primary_active,
ButtonStyle::Secondary => cx.theme().secondary_active,
ButtonStyle::Danger => cx.theme().destructive_active,
};
let border = self.border_color(cx);
let fg = self.text_color(cx).darken(0.07);
let fg = self.text_color(cx);
ButtonStyles { bg, border, fg }
}

View file

@ -23,7 +23,7 @@ pub struct Checkbox {
}
impl Checkbox {
pub fn new(id: impl Into<ElementId>, _: &mut WindowContext) -> Self {
pub fn new(id: impl Into<ElementId>) -> Self {
Self {
id: id.into(),
checked: Selection::Unselected,

View file

@ -1,7 +1,7 @@
use crate::theme::ActiveTheme;
use crate::{button::ButtonSize, theme::ActiveTheme};
use gpui::{
svg, AnyElement, Hsla, IntoElement, RenderOnce, SharedString, StyleRefinement, Styled, Svg,
WindowContext,
prelude::FluentBuilder as _, svg, AnyElement, Hsla, IntoElement, RenderOnce, SharedString,
StyleRefinement, Styled, Svg, WindowContext,
};
#[derive(IntoElement)]
@ -18,6 +18,9 @@ pub enum IconName {
Info,
Ellipsis,
EllipsisVertical,
Search,
Delete,
CicleX,
}
impl IconName {
@ -35,6 +38,9 @@ impl IconName {
IconName::Info => "icons/info.svg",
IconName::Ellipsis => "icons/ellipsis.svg",
IconName::EllipsisVertical => "icons/ellipsis-vertical.svg",
IconName::Search => "icons/search.svg",
IconName::Delete => "icons/delete.svg",
IconName::CicleX => "icons/circle-x.svg",
}
.into()
}
@ -57,6 +63,7 @@ pub struct Icon {
base: Svg,
path: SharedString,
text_color: Option<Hsla>,
size: ButtonSize,
}
impl Icon {
@ -65,6 +72,7 @@ impl Icon {
base: svg().flex_none().size_4(),
path: name.path(),
text_color: None,
size: ButtonSize::Medium,
}
}
@ -75,6 +83,12 @@ impl Icon {
self.path = path.into();
self
}
pub fn size(mut self, size: ButtonSize) -> Self {
self.size = size;
self
}
}
impl Styled for Icon {
@ -92,7 +106,14 @@ impl RenderOnce for Icon {
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)
self.base
.text_color(text_color)
.map(|this| match self.size {
ButtonSize::XSmall => this.size_3(),
ButtonSize::Small => this.size_3p5(),
ButtonSize::Medium => this.size_4(),
})
.path(self.path)
}
}

View file

@ -109,7 +109,7 @@ impl RenderOnce for Switch {
self.base
.map(|this| match self.size {
ButtonSize::Medium => this.w_11().h_6().rounded_xl(),
ButtonSize::Small => this.w_8().h_4().rounded_lg(),
ButtonSize::XSmall | ButtonSize::Small => this.w_8().h_4().rounded_lg(),
})
.flex()
.items_center()
@ -127,21 +127,24 @@ impl RenderOnce for Switch {
.bg(toggle_bg)
.map(|this| match self.size {
ButtonSize::Medium => this.w_5().h_5(),
ButtonSize::Small => this.w_3().h_3(),
ButtonSize::XSmall | ButtonSize::Small => this.w_3().h_3(),
}),
),
)
.when_some(self.label, |this, label| {
this.child(div().child(label).map(|this| match self.size {
ButtonSize::Medium => this.text_base(),
ButtonSize::Small => this.text_sm(),
ButtonSize::XSmall | ButtonSize::Small => this.text_sm(),
}))
})
.when_some(
self.on_click.filter(|_| !self.disabled),
|this, on_click| {
cx.stop_propagation();
this.on_click(move |ev, cx| on_click(ev, cx))
this.on_click(move |ev, cx| {
dbg!("---- switch clicked");
cx.stop_propagation();
on_click(ev, cx);
})
},
)
}

View file

@ -83,7 +83,6 @@ impl Colorize for Hsla {
#[derive(Debug, Clone, Copy)]
struct Colors {
pub title_bar_background: Hsla,
pub background: Hsla,
pub foreground: Hsla,
pub card: Hsla,
@ -91,15 +90,21 @@ struct Colors {
pub popover: Hsla,
pub popover_foreground: Hsla,
pub primary: Hsla,
pub primary_hover: Hsla,
pub primary_active: Hsla,
pub primary_foreground: Hsla,
pub secondary: Hsla,
pub secondary_hover: Hsla,
pub secondary_active: Hsla,
pub secondary_foreground: Hsla,
pub destructive: Hsla,
pub destructive_hover: Hsla,
pub destructive_active: Hsla,
pub destructive_foreground: Hsla,
pub muted: Hsla,
pub muted_foreground: Hsla,
pub accent: Hsla,
pub accent_foreground: Hsla,
pub destructive: Hsla,
pub destructive_foreground: Hsla,
pub border: Hsla,
pub input: Hsla,
pub ring: Hsla,
@ -145,15 +150,21 @@ impl Colors {
popover: hsl(0.0, 0.0, 100.0),
popover_foreground: hsl(240.0, 10.0, 3.9),
primary: hsl(240.0, 5.9, 10.0),
primary_hover: hsl(240.0, 5.9, 30.0),
primary_active: hsl(240.0, 5.9, 45.0),
primary_foreground: hsl(0.0, 0.0, 98.0),
secondary: hsl(240.0, 4.8, 95.9),
secondary_hover: hsl(240.0, 4.8, 99.),
secondary_active: hsl(240.0, 5.9, 94.0),
secondary_foreground: hsl(240.0, 59.0, 10.0),
destructive: hsl(0.0, 84.2, 60.2),
destructive_hover: hsl(0.0, 84.2, 65.0),
destructive_active: hsl(0.0, 84.2, 47.0),
destructive_foreground: hsl(0.0, 0.0, 98.0),
muted: hsl(240.0, 4.8, 95.9),
muted_foreground: hsl(240.0, 3.8, 46.1),
accent: hsl(240.0, 5.0, 96.0),
accent_foreground: hsl(240.0, 5.9, 10.0),
destructive: hsl(0.0, 84.2, 60.2),
destructive_foreground: hsl(0.0, 0.0, 98.0),
border: hsl(240.0, 5.9, 90.0),
input: hsl(240.0, 5.9, 90.0),
ring: hsl(240.0, 5.9, 10.0),
@ -198,15 +209,21 @@ impl Colors {
popover: hsl(240.0, 10.0, 3.9),
popover_foreground: hsl(0.0, 0.0, 98.0),
primary: hsl(0.0, 0.0, 98.0),
primary_hover: hsl(0.0, 0.0, 85.0),
primary_active: hsl(0.0, 0.0, 60.0),
primary_foreground: hsl(240.0, 5.9, 10.0),
secondary: hsl(240.0, 3.7, 15.9),
secondary_hover: hsl(240.0, 3.7, 20.9),
secondary_active: hsl(240.0, 3.7, 8.9),
secondary_foreground: hsl(0.0, 0.0, 98.0),
destructive: hsl(0.0, 62.8, 30.6),
destructive_hover: hsl(0.0, 62.8, 35.6),
destructive_active: hsl(0.0, 62.8, 20.6),
destructive_foreground: hsl(0.0, 0.0, 98.0),
muted: hsl(240.0, 3.7, 15.9),
muted_foreground: hsl(240.0, 5.0, 64.9),
accent: hsl(240.0, 3.7, 15.9),
accent_foreground: hsl(0.0, 0.0, 98.0),
destructive: hsl(0.0, 62.8, 30.6),
destructive_foreground: hsl(0.0, 0.0, 98.0),
border: hsl(240.0, 3.7, 15.9),
input: hsl(240.0, 3.7, 15.9),
ring: hsl(240.0, 4.9, 83.9),
@ -233,15 +250,21 @@ pub struct Theme {
pub popover: Hsla,
pub popover_foreground: Hsla,
pub primary: Hsla,
pub primary_hover: Hsla,
pub primary_active: Hsla,
pub primary_foreground: Hsla,
pub secondary: Hsla,
pub secondary_hover: Hsla,
pub secondary_active: Hsla,
pub secondary_foreground: Hsla,
pub destructive: Hsla,
pub destructive_hover: Hsla,
pub destructive_active: Hsla,
pub destructive_foreground: Hsla,
pub muted: Hsla,
pub muted_foreground: Hsla,
pub accent: Hsla,
pub accent_foreground: Hsla,
pub destructive: Hsla,
pub destructive_foreground: Hsla,
pub border: Hsla,
pub input: Hsla,
pub ring: Hsla,
@ -276,15 +299,21 @@ impl From<Colors> for Theme {
popover: colors.popover,
popover_foreground: colors.popover_foreground,
primary: colors.primary,
primary_hover: colors.primary_hover,
primary_active: colors.primary_active,
primary_foreground: colors.primary_foreground,
secondary: colors.secondary,
secondary_hover: colors.secondary_hover,
secondary_active: colors.secondary_active,
secondary_foreground: colors.secondary_foreground,
destructive: colors.destructive,
destructive_hover: colors.destructive_hover,
destructive_active: colors.destructive_active,
destructive_foreground: colors.destructive_foreground,
muted: colors.muted,
muted_foreground: colors.muted_foreground,
accent: colors.accent,
accent_foreground: colors.accent_foreground,
destructive: colors.destructive,
destructive_foreground: colors.destructive_foreground,
border: colors.border,
input: colors.input,
ring: colors.ring,