button: Add warning, success, info variant to Button. (#745)
<img width="1342" alt="SCR-20250327-jfzq" src="https://github.com/user-attachments/assets/7c44458a-9467-4095-9cd6-1dcb35cc351b" /> <img width="1342" alt="SCR-20250327-jgak" src="https://github.com/user-attachments/assets/07d33d60-f581-46d4-9a54-174e56ab82ca" />
This commit is contained in:
parent
e582d22f11
commit
17926cea16
5 changed files with 178 additions and 22 deletions
|
|
@ -96,7 +96,7 @@ impl Render for Example {
|
||||||
.title("Error!"),
|
.title("Error!"),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Alert::info("Custom info alert with icon.")
|
Alert::info("Custom icon with info alert.")
|
||||||
.with_size(self.size)
|
.with_size(self.size)
|
||||||
.icon(IconName::Bell),
|
.icon(IconName::Bell),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ use gpui::{
|
||||||
use gpui_component::{
|
use gpui_component::{
|
||||||
button::{Button, ButtonCustomVariant, ButtonGroup, ButtonVariants as _, DropdownButton},
|
button::{Button, ButtonCustomVariant, ButtonGroup, ButtonVariants as _, DropdownButton},
|
||||||
checkbox::Checkbox,
|
checkbox::Checkbox,
|
||||||
green_600, green_700, green_800, green_950, h_flex, v_flex, white, ActiveTheme,
|
h_flex, indigo, v_flex, white, ActiveTheme, Disableable as _, Icon, IconName, Selectable as _,
|
||||||
Disableable as _, Icon, IconName, Selectable as _, Sizable as _, Theme,
|
Sizable as _, Theme,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::section;
|
use crate::section;
|
||||||
|
|
@ -74,9 +74,9 @@ impl Render for ButtonStory {
|
||||||
|
|
||||||
let custom_variant = ButtonCustomVariant::new(cx)
|
let custom_variant = ButtonCustomVariant::new(cx)
|
||||||
.color(if cx.theme().mode.is_dark() {
|
.color(if cx.theme().mode.is_dark() {
|
||||||
green_800()
|
indigo(800)
|
||||||
} else {
|
} else {
|
||||||
green_600()
|
indigo(600)
|
||||||
})
|
})
|
||||||
.foreground(if cx.theme().mode.is_dark() {
|
.foreground(if cx.theme().mode.is_dark() {
|
||||||
white()
|
white()
|
||||||
|
|
@ -84,19 +84,19 @@ impl Render for ButtonStory {
|
||||||
white()
|
white()
|
||||||
})
|
})
|
||||||
.border(if cx.theme().mode.is_dark() {
|
.border(if cx.theme().mode.is_dark() {
|
||||||
green_800()
|
indigo(800)
|
||||||
} else {
|
} else {
|
||||||
green_700()
|
indigo(600)
|
||||||
})
|
})
|
||||||
.hover(if cx.theme().mode.is_dark() {
|
.hover(if cx.theme().mode.is_dark() {
|
||||||
green_800()
|
indigo(900)
|
||||||
} else {
|
} else {
|
||||||
green_600()
|
indigo(700)
|
||||||
})
|
})
|
||||||
.active(if cx.theme().mode.is_dark() {
|
.active(if cx.theme().mode.is_dark() {
|
||||||
green_950()
|
indigo(950)
|
||||||
} else {
|
} else {
|
||||||
green_700()
|
indigo(700)
|
||||||
});
|
});
|
||||||
|
|
||||||
v_flex()
|
v_flex()
|
||||||
|
|
@ -191,6 +191,36 @@ impl Render for ButtonStory {
|
||||||
.when(compact, |this| this.compact())
|
.when(compact, |this| this.compact())
|
||||||
.on_click(Self::on_click),
|
.on_click(Self::on_click),
|
||||||
)
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("button-4-warning")
|
||||||
|
.warning()
|
||||||
|
.label("Warning Button")
|
||||||
|
.disabled(disabled)
|
||||||
|
.selected(selected)
|
||||||
|
.loading(loading)
|
||||||
|
.when(compact, |this| this.compact())
|
||||||
|
.on_click(Self::on_click),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("button-4-success")
|
||||||
|
.success()
|
||||||
|
.label("Success Button")
|
||||||
|
.disabled(disabled)
|
||||||
|
.selected(selected)
|
||||||
|
.loading(loading)
|
||||||
|
.when(compact, |this| this.compact())
|
||||||
|
.on_click(Self::on_click),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("button-5-info")
|
||||||
|
.info()
|
||||||
|
.label("Info Button")
|
||||||
|
.disabled(disabled)
|
||||||
|
.selected(selected)
|
||||||
|
.loading(loading)
|
||||||
|
.when(compact, |this| this.compact())
|
||||||
|
.on_click(Self::on_click),
|
||||||
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("button-5-ghost")
|
Button::new("button-5-ghost")
|
||||||
.ghost()
|
.ghost()
|
||||||
|
|
@ -342,7 +372,7 @@ impl Render for ButtonStory {
|
||||||
.on_click(Self::on_click),
|
.on_click(Self::on_click),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("button-outline-4")
|
Button::new("button-outline-4-danger")
|
||||||
.danger()
|
.danger()
|
||||||
.outline()
|
.outline()
|
||||||
.label("Danger Button")
|
.label("Danger Button")
|
||||||
|
|
@ -352,6 +382,39 @@ impl Render for ButtonStory {
|
||||||
.when(compact, |this| this.compact())
|
.when(compact, |this| this.compact())
|
||||||
.on_click(Self::on_click),
|
.on_click(Self::on_click),
|
||||||
)
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("button-outline-4-warning")
|
||||||
|
.warning()
|
||||||
|
.outline()
|
||||||
|
.label("Warning Button")
|
||||||
|
.disabled(disabled)
|
||||||
|
.selected(selected)
|
||||||
|
.loading(loading)
|
||||||
|
.when(compact, |this| this.compact())
|
||||||
|
.on_click(Self::on_click),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("button-outline-4-success")
|
||||||
|
.success()
|
||||||
|
.outline()
|
||||||
|
.label("Success Button")
|
||||||
|
.disabled(disabled)
|
||||||
|
.selected(selected)
|
||||||
|
.loading(loading)
|
||||||
|
.when(compact, |this| this.compact())
|
||||||
|
.on_click(Self::on_click),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("button-outline-5-info")
|
||||||
|
.info()
|
||||||
|
.outline()
|
||||||
|
.label("Info Button")
|
||||||
|
.disabled(disabled)
|
||||||
|
.selected(selected)
|
||||||
|
.loading(loading)
|
||||||
|
.when(compact, |this| this.compact())
|
||||||
|
.on_click(Self::on_click),
|
||||||
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("button-outline-6-custom")
|
Button::new("button-outline-6-custom")
|
||||||
.outline()
|
.outline()
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ impl RenderOnce for Alert {
|
||||||
.rounded(radius)
|
.rounded(radius)
|
||||||
.border_1()
|
.border_1()
|
||||||
.border_color(color)
|
.border_color(color)
|
||||||
.bg(color.opacity(0.05))
|
.bg(color.opacity(0.1))
|
||||||
.text_color(self.variant.fg(cx))
|
.text_color(self.variant.fg(cx))
|
||||||
.px(padding_x)
|
.px(padding_x)
|
||||||
.py(padding_y)
|
.py(padding_y)
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,21 @@ pub trait ButtonVariants: Sized {
|
||||||
self.with_variant(ButtonVariant::Danger)
|
self.with_variant(ButtonVariant::Danger)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// With the warning style for the Button.
|
||||||
|
fn warning(self) -> Self {
|
||||||
|
self.with_variant(ButtonVariant::Warning)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// With the success style for the Button.
|
||||||
|
fn success(self) -> Self {
|
||||||
|
self.with_variant(ButtonVariant::Success)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// With the info style for the Button.
|
||||||
|
fn info(self) -> Self {
|
||||||
|
self.with_variant(ButtonVariant::Info)
|
||||||
|
}
|
||||||
|
|
||||||
/// With the ghost style for the Button.
|
/// With the ghost style for the Button.
|
||||||
fn ghost(self) -> Self {
|
fn ghost(self) -> Self {
|
||||||
self.with_variant(ButtonVariant::Ghost)
|
self.with_variant(ButtonVariant::Ghost)
|
||||||
|
|
@ -116,6 +131,9 @@ pub enum ButtonVariant {
|
||||||
Primary,
|
Primary,
|
||||||
Secondary,
|
Secondary,
|
||||||
Danger,
|
Danger,
|
||||||
|
Info,
|
||||||
|
Success,
|
||||||
|
Warning,
|
||||||
Ghost,
|
Ghost,
|
||||||
Link,
|
Link,
|
||||||
Text,
|
Text,
|
||||||
|
|
@ -482,6 +500,9 @@ impl ButtonVariant {
|
||||||
ButtonVariant::Primary => cx.theme().primary,
|
ButtonVariant::Primary => cx.theme().primary,
|
||||||
ButtonVariant::Secondary => cx.theme().secondary,
|
ButtonVariant::Secondary => cx.theme().secondary,
|
||||||
ButtonVariant::Danger => cx.theme().danger,
|
ButtonVariant::Danger => cx.theme().danger,
|
||||||
|
ButtonVariant::Warning => cx.theme().warning,
|
||||||
|
ButtonVariant::Success => cx.theme().success,
|
||||||
|
ButtonVariant::Info => cx.theme().info,
|
||||||
ButtonVariant::Ghost | ButtonVariant::Link | ButtonVariant::Text => {
|
ButtonVariant::Ghost | ButtonVariant::Link | ButtonVariant::Text => {
|
||||||
cx.theme().transparent
|
cx.theme().transparent
|
||||||
}
|
}
|
||||||
|
|
@ -506,6 +527,27 @@ impl ButtonVariant {
|
||||||
cx.theme().danger_foreground
|
cx.theme().danger_foreground
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ButtonVariant::Warning => {
|
||||||
|
if outline {
|
||||||
|
cx.theme().warning
|
||||||
|
} else {
|
||||||
|
cx.theme().warning_foreground
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ButtonVariant::Success => {
|
||||||
|
if outline {
|
||||||
|
cx.theme().success
|
||||||
|
} else {
|
||||||
|
cx.theme().success_foreground
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ButtonVariant::Info => {
|
||||||
|
if outline {
|
||||||
|
cx.theme().info
|
||||||
|
} else {
|
||||||
|
cx.theme().info_foreground
|
||||||
|
}
|
||||||
|
}
|
||||||
ButtonVariant::Link => cx.theme().link,
|
ButtonVariant::Link => cx.theme().link,
|
||||||
ButtonVariant::Text => cx.theme().foreground,
|
ButtonVariant::Text => cx.theme().foreground,
|
||||||
ButtonVariant::Custom(colors) => {
|
ButtonVariant::Custom(colors) => {
|
||||||
|
|
@ -523,6 +565,9 @@ impl ButtonVariant {
|
||||||
ButtonVariant::Primary => cx.theme().primary,
|
ButtonVariant::Primary => cx.theme().primary,
|
||||||
ButtonVariant::Secondary => cx.theme().border,
|
ButtonVariant::Secondary => cx.theme().border,
|
||||||
ButtonVariant::Danger => cx.theme().danger,
|
ButtonVariant::Danger => cx.theme().danger,
|
||||||
|
ButtonVariant::Info => cx.theme().info,
|
||||||
|
ButtonVariant::Warning => cx.theme().warning,
|
||||||
|
ButtonVariant::Success => cx.theme().success,
|
||||||
ButtonVariant::Ghost | ButtonVariant::Link | ButtonVariant::Text => {
|
ButtonVariant::Ghost | ButtonVariant::Link | ButtonVariant::Text => {
|
||||||
cx.theme().transparent
|
cx.theme().transparent
|
||||||
}
|
}
|
||||||
|
|
@ -578,6 +623,27 @@ impl ButtonVariant {
|
||||||
cx.theme().danger_hover
|
cx.theme().danger_hover
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ButtonVariant::Warning => {
|
||||||
|
if outline {
|
||||||
|
cx.theme().secondary_hover
|
||||||
|
} else {
|
||||||
|
cx.theme().warning_hover
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ButtonVariant::Success => {
|
||||||
|
if outline {
|
||||||
|
cx.theme().secondary_hover
|
||||||
|
} else {
|
||||||
|
cx.theme().success_hover
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ButtonVariant::Info => {
|
||||||
|
if outline {
|
||||||
|
cx.theme().secondary_hover
|
||||||
|
} else {
|
||||||
|
cx.theme().info_hover
|
||||||
|
}
|
||||||
|
}
|
||||||
ButtonVariant::Ghost => {
|
ButtonVariant::Ghost => {
|
||||||
if cx.theme().mode.is_dark() {
|
if cx.theme().mode.is_dark() {
|
||||||
cx.theme().secondary.lighten(0.1).opacity(0.8)
|
cx.theme().secondary.lighten(0.1).opacity(0.8)
|
||||||
|
|
@ -638,6 +704,27 @@ impl ButtonVariant {
|
||||||
cx.theme().danger_active
|
cx.theme().danger_active
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ButtonVariant::Warning => {
|
||||||
|
if outline {
|
||||||
|
cx.theme().warning_active.opacity(0.1)
|
||||||
|
} else {
|
||||||
|
cx.theme().warning_active
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ButtonVariant::Success => {
|
||||||
|
if outline {
|
||||||
|
cx.theme().success_active.opacity(0.1)
|
||||||
|
} else {
|
||||||
|
cx.theme().success_active
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ButtonVariant::Info => {
|
||||||
|
if outline {
|
||||||
|
cx.theme().info_active.opacity(0.1)
|
||||||
|
} else {
|
||||||
|
cx.theme().info_active
|
||||||
|
}
|
||||||
|
}
|
||||||
ButtonVariant::Link => cx.theme().transparent,
|
ButtonVariant::Link => cx.theme().transparent,
|
||||||
ButtonVariant::Text => cx.theme().transparent,
|
ButtonVariant::Text => cx.theme().transparent,
|
||||||
ButtonVariant::Custom(colors) => {
|
ButtonVariant::Custom(colors) => {
|
||||||
|
|
@ -671,6 +758,9 @@ impl ButtonVariant {
|
||||||
ButtonVariant::Primary => cx.theme().primary_active,
|
ButtonVariant::Primary => cx.theme().primary_active,
|
||||||
ButtonVariant::Secondary | ButtonVariant::Ghost => cx.theme().secondary_active,
|
ButtonVariant::Secondary | ButtonVariant::Ghost => cx.theme().secondary_active,
|
||||||
ButtonVariant::Danger => cx.theme().danger_active,
|
ButtonVariant::Danger => cx.theme().danger_active,
|
||||||
|
ButtonVariant::Warning => cx.theme().warning_active,
|
||||||
|
ButtonVariant::Success => cx.theme().success_active,
|
||||||
|
ButtonVariant::Info => cx.theme().info_active,
|
||||||
ButtonVariant::Link => cx.theme().transparent,
|
ButtonVariant::Link => cx.theme().transparent,
|
||||||
ButtonVariant::Text => cx.theme().transparent,
|
ButtonVariant::Text => cx.theme().transparent,
|
||||||
ButtonVariant::Custom(colors) => colors.active,
|
ButtonVariant::Custom(colors) => colors.active,
|
||||||
|
|
@ -701,6 +791,9 @@ impl ButtonVariant {
|
||||||
}
|
}
|
||||||
ButtonVariant::Primary => cx.theme().primary.opacity(0.15),
|
ButtonVariant::Primary => cx.theme().primary.opacity(0.15),
|
||||||
ButtonVariant::Danger => cx.theme().danger.opacity(0.15),
|
ButtonVariant::Danger => cx.theme().danger.opacity(0.15),
|
||||||
|
ButtonVariant::Warning => cx.theme().warning.opacity(0.15),
|
||||||
|
ButtonVariant::Success => cx.theme().success.opacity(0.15),
|
||||||
|
ButtonVariant::Info => cx.theme().info.opacity(0.15),
|
||||||
ButtonVariant::Secondary => cx.theme().secondary.opacity(1.5),
|
ButtonVariant::Secondary => cx.theme().secondary.opacity(1.5),
|
||||||
ButtonVariant::Custom(style) => style.color.opacity(0.15),
|
ButtonVariant::Custom(style) => style.color.opacity(0.15),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -342,10 +342,10 @@ impl ThemeColor {
|
||||||
card: hsl(0.0, 0.0, 8.0),
|
card: hsl(0.0, 0.0, 8.0),
|
||||||
card_foreground: hsl(0.0, 0.0, 78.0),
|
card_foreground: hsl(0.0, 0.0, 78.0),
|
||||||
caret: hsl(0., 0., 78.),
|
caret: hsl(0., 0., 78.),
|
||||||
danger: crate::red_900(),
|
danger: crate::red_800(),
|
||||||
danger_active: crate::red_900().darken(0.2),
|
danger_active: crate::red_800().darken(0.2),
|
||||||
danger_foreground: crate::red_50(),
|
danger_foreground: crate::red_50(),
|
||||||
danger_hover: crate::red_900().opacity(0.9),
|
danger_hover: crate::red_800().opacity(0.9),
|
||||||
description_list_label: hsl(240.0, 0., 13.0),
|
description_list_label: hsl(240.0, 0., 13.0),
|
||||||
description_list_label_foreground: hsl(0.0, 0.0, 78.0),
|
description_list_label_foreground: hsl(0.0, 0.0, 78.0),
|
||||||
drag_border: crate::blue_500(),
|
drag_border: crate::blue_500(),
|
||||||
|
|
@ -393,10 +393,10 @@ impl ThemeColor {
|
||||||
skeleton: hsla(223.0, 0.0, 98.0, 0.1),
|
skeleton: hsla(223.0, 0.0, 98.0, 0.1),
|
||||||
slider_bar: hsl(223.0, 0.0, 98.0),
|
slider_bar: hsl(223.0, 0.0, 98.0),
|
||||||
slider_thumb: hsl(0.0, 0.0, 8.0),
|
slider_thumb: hsl(0.0, 0.0, 8.0),
|
||||||
success: crate::green_900(),
|
success: crate::green_800(),
|
||||||
success_active: crate::green_900().darken(0.2),
|
success_active: crate::green_800().darken(0.2),
|
||||||
success_foreground: crate::green_50(),
|
success_foreground: crate::green_50(),
|
||||||
success_hover: crate::green_900().opacity(0.8),
|
success_hover: crate::green_800().opacity(0.8),
|
||||||
tab: gpui::transparent_black(),
|
tab: gpui::transparent_black(),
|
||||||
tab_active: hsl(0.0, 0.0, 8.0),
|
tab_active: hsl(0.0, 0.0, 8.0),
|
||||||
tab_active_foreground: hsl(0., 0., 78.),
|
tab_active_foreground: hsl(0., 0., 78.),
|
||||||
|
|
@ -414,10 +414,10 @@ impl ThemeColor {
|
||||||
tiles: hsl(0.0, 0.0, 5.0),
|
tiles: hsl(0.0, 0.0, 5.0),
|
||||||
title_bar: hsl(0., 0., 9.7),
|
title_bar: hsl(0., 0., 9.7),
|
||||||
title_bar_border: hsl(240.0, 3.7, 15.9),
|
title_bar_border: hsl(240.0, 3.7, 15.9),
|
||||||
warning: crate::yellow_900(),
|
warning: crate::yellow_800(),
|
||||||
warning_active: crate::yellow_900().darken(0.2),
|
warning_active: crate::yellow_800().darken(0.2),
|
||||||
warning_foreground: crate::yellow_50(),
|
warning_foreground: crate::yellow_50(),
|
||||||
warning_hover: crate::yellow_900().opacity(0.9),
|
warning_hover: crate::yellow_800().opacity(0.9),
|
||||||
window_border: hsl(240.0, 3.7, 28.0),
|
window_border: hsl(240.0, 3.7, 28.0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue