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