1use gpui::prelude::*;
6use gpui::*;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
10pub enum TooltipPlacement {
11 #[default]
13 Top,
14 Bottom,
16 Left,
18 Right,
20}
21
22pub struct Tooltip {
25 content: SharedString,
26 placement: TooltipPlacement,
27 delay_ms: u32,
28}
29
30impl Tooltip {
31 pub fn new(content: impl Into<SharedString>) -> Self {
33 Self {
34 content: content.into(),
35 placement: TooltipPlacement::default(),
36 delay_ms: 200,
37 }
38 }
39
40 pub fn placement(mut self, placement: TooltipPlacement) -> Self {
42 self.placement = placement;
43 self
44 }
45
46 pub fn delay(mut self, delay_ms: u32) -> Self {
48 self.delay_ms = delay_ms;
49 self
50 }
51
52 pub fn build(self) -> Div {
54 let mut tooltip = div()
55 .absolute()
56 .px_2()
57 .py_1()
58 .bg(rgb(0x1a1a1a))
59 .border_1()
60 .border_color(rgb(0x3a3a3a))
61 .rounded(px(4.0))
62 .shadow_lg()
63 .text_xs()
64 .text_color(rgb(0xffffff))
65 .whitespace_nowrap();
66
67 match self.placement {
69 TooltipPlacement::Top => {
70 tooltip = tooltip.bottom_full().left_0().mb_1();
71 }
72 TooltipPlacement::Bottom => {
73 tooltip = tooltip.top_full().left_0().mt_1();
74 }
75 TooltipPlacement::Left => {
76 tooltip = tooltip.right_full().top_0().mr_1();
77 }
78 TooltipPlacement::Right => {
79 tooltip = tooltip.left_full().top_0().ml_1();
80 }
81 }
82
83 tooltip.child(self.content)
84 }
85}
86
87impl IntoElement for Tooltip {
88 type Element = Div;
89
90 fn into_element(self) -> Self::Element {
91 self.build()
92 }
93}
94
95pub struct WithTooltip {
98 child: AnyElement,
99 tooltip: SharedString,
100 placement: TooltipPlacement,
101 show_tooltip: bool,
102}
103
104impl WithTooltip {
105 pub fn new(child: impl IntoElement, tooltip: impl Into<SharedString>) -> Self {
107 Self {
108 child: child.into_any_element(),
109 tooltip: tooltip.into(),
110 placement: TooltipPlacement::default(),
111 show_tooltip: false,
112 }
113 }
114
115 pub fn placement(mut self, placement: TooltipPlacement) -> Self {
117 self.placement = placement;
118 self
119 }
120
121 pub fn show(mut self, show: bool) -> Self {
123 self.show_tooltip = show;
124 self
125 }
126
127 pub fn build(self) -> Div {
129 let mut container = div().relative().child(self.child);
130
131 if self.show_tooltip {
132 container =
133 container.child(Tooltip::new(self.tooltip).placement(self.placement).build());
134 }
135
136 container
137 }
138}
139
140impl IntoElement for WithTooltip {
141 type Element = Div;
142
143 fn into_element(self) -> Self::Element {
144 self.build()
145 }
146}