1use gpui::{Action, AnyView, App, Context, IntoElement, SharedString, Window, div, prelude::*, px};
17
18use theme::{TextStyle, Theme, Typeset};
19
20use crate::{keys, popover, surface::Surfaced as _};
21
22pub struct Tooltip {
23 text: SharedString,
24 keystroke: Option<SharedString>,
26}
27
28impl Tooltip {
29 pub fn text(text: impl Into<SharedString>, _window: &mut Window, cx: &mut App) -> AnyView {
31 let text = text.into();
32 cx.new(|_| Self {
33 text,
34 keystroke: None,
35 })
36 .into()
37 }
38
39 pub fn with_keystroke(
42 text: impl Into<SharedString>,
43 keystroke: impl Into<SharedString>,
44 _window: &mut Window,
45 cx: &mut App,
46 ) -> AnyView {
47 let (text, keystroke) = (text.into(), keystroke.into());
48 cx.new(|_| Self {
49 text,
50 keystroke: Some(keystroke),
51 })
52 .into()
53 }
54
55 pub fn for_action(
64 text: impl Into<SharedString>,
65 action: &dyn Action,
66 window: &mut Window,
67 cx: &mut App,
68 ) -> AnyView {
69 let text = text.into();
70 let keystroke = keys::shortcut(action, window);
71 cx.new(|_| Self { text, keystroke }).into()
72 }
73
74 pub fn for_action_in(
77 text: impl Into<SharedString>,
78 action: &dyn Action,
79 context: &str,
80 window: &mut Window,
81 cx: &mut App,
82 ) -> AnyView {
83 let text = text.into();
84 let keystroke = keys::shortcut_in(action, context, window);
85 cx.new(|_| Self { text, keystroke }).into()
86 }
87}
88
89impl Tooltip {
90 pub fn card(
93 text: impl Into<SharedString>,
94 keystroke: Option<SharedString>,
95 cx: &App,
96 ) -> gpui::AnyElement {
97 let theme = Theme::of(cx).clone();
98 popover::popover_card(&theme)
101 .px(px(8.0))
102 .py(px(5.0))
103 .flex()
104 .flex_row()
105 .items_center()
106 .gap(px(Theme::SPACE))
107 .text_style(TextStyle::Callout)
108 .text_color(theme.text)
109 .child(text.into())
110 .when_some(keystroke, |card, keystroke| {
111 card.child(
112 div()
113 .text_style(TextStyle::Subheadline)
114 .text_color(theme.text_faint)
115 .child(keystroke),
116 )
117 })
118 .surface(&theme, theme.popover_surface)
119 .into_any_element()
120 }
121}
122
123impl Render for Tooltip {
124 fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
125 Self::card(self.text.clone(), self.keystroke.clone(), cx)
126 }
127}