1use gpui::{Hsla, Pixels, SharedString, linear_color_stop, linear_gradient, px};
2
3use crate::prelude::*;
4
5/// A gradient overlay that fades from a solid color to transparent.
6#[derive(IntoElement)]
7pub struct GradientFade {
8 base_bg: Hsla,
9 hover_bg: Hsla,
10 active_bg: Hsla,
11 width: Pixels,
12 right: Pixels,
13 gradient_stop: f32,
14 group_name: Option<SharedString>,
15}
16
17impl GradientFade {
18 pub fn new(base_bg: Hsla, hover_bg: Hsla, active_bg: Hsla) -> Self {
19 Self {
20 base_bg,
21 hover_bg,
22 active_bg,
23 width: px(48.0),
24 right: px(0.0),
25 gradient_stop: 0.6,
26 group_name: None,
27 }
28 }
29
30 pub fn width(mut self, width: Pixels) -> Self {
31 self.width = width;
32 self
33 }
34
35 pub fn right(mut self, right: Pixels) -> Self {
36 self.right = right;
37 self
38 }
39
40 pub fn gradient_stop(mut self, stop: f32) -> Self {
41 self.gradient_stop = stop;
42 self
43 }
44
45 pub fn group_name(mut self, name: impl Into<SharedString>) -> Self {
46 self.group_name = Some(name.into());
47 self
48 }
49}
50
51impl RenderOnce for GradientFade {
52 fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
53 let stop = self.gradient_stop;
54 let hover_bg = self.hover_bg;
55 let active_bg = self.active_bg;
56
57 div()
58 .id("gradient_fade")
59 .absolute()
60 .top_0()
61 .right(self.right)
62 .w(self.width)
63 .h_full()
64 .bg(linear_gradient(
65 90.,
66 linear_color_stop(self.base_bg, stop),
67 linear_color_stop(self.base_bg.opacity(0.0), 0.),
68 ))
69 .when_some(self.group_name.clone(), |element, group_name| {
70 element.group_hover(group_name, move |s| {
71 s.bg(linear_gradient(
72 90.,
73 linear_color_stop(hover_bg, stop),
74 linear_color_stop(hover_bg.opacity(0.0), 0.),
75 ))
76 })
77 })
78 .when_some(self.group_name, |element, group_name| {
79 element.group_active(group_name, move |s| {
80 s.bg(linear_gradient(
81 90.,
82 linear_color_stop(active_bg, stop),
83 linear_color_stop(active_bg.opacity(0.0), 0.),
84 ))
85 })
86 })
87 }
88}