tooltip: Support render element (#605)

<img width="376" alt="image"
src="https://github.com/user-attachments/assets/52793001-03cb-46ca-80a3-42aa3db57ecb"
/>
This commit is contained in:
Floyd Wang 2025-02-06 16:05:44 +08:00 committed by GitHub
parent 99a4c793c5
commit e423497da6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 57 additions and 8 deletions

View file

@ -10,7 +10,7 @@ use ui::{
h_flex,
label::Label,
tooltip::Tooltip,
v_flex,
v_flex, ActiveTheme, IconName,
};
pub struct TooltipStory {
@ -72,15 +72,39 @@ impl Render for TooltipStory {
.justify_center()
.cursor(CursorStyle::PointingHand)
.child(Label::new("Hover me"))
.id("tooltip-3")
.id("tooltip-2")
.tooltip(|window, cx| Tooltip::new("This is a Label", window, cx)),
)
.child(
div()
.cursor(CursorStyle::PointingHand)
.child(Checkbox::new("check").label("Remember me").checked(true))
.id("tooltip-4")
.id("tooltip-3")
.tooltip(|window, cx| Tooltip::new("Checked!", window, cx)),
)
.child(
div()
.cursor(CursorStyle::PointingHand)
.child(
Button::new("button")
.label("Hover me")
.with_variant(ButtonVariant::Primary),
)
.id("tooltip-4")
.tooltip(|window, cx| {
Tooltip::new_element(window, cx, |_, cx| {
h_flex()
.gap_x_1()
.child(IconName::Info)
.child(
div()
.child("Muted Foreground")
.text_color(cx.theme().muted_foreground),
)
.child(div().child("Danger").text_color(cx.theme().danger))
.child(IconName::ArrowUp)
})
}),
)
}
}

View file

@ -1,22 +1,41 @@
use gpui::{
div, px, AnyView, App, AppContext, Context, IntoElement, ParentElement, Render, SharedString,
Styled, Window,
div, prelude::FluentBuilder, px, AnyElement, AnyView, App, AppContext, Context, IntoElement,
ParentElement, Render, SharedString, Styled, Window,
};
use crate::ActiveTheme;
pub struct Tooltip {
text: SharedString,
element_builder: Option<Box<dyn Fn(&mut Window, &mut App) -> AnyElement>>,
}
impl Tooltip {
pub fn new(text: impl Into<SharedString>, _: &mut Window, cx: &mut App) -> AnyView {
cx.new(|_| Self { text: text.into() }).into()
cx.new(|_| Self {
text: text.into(),
element_builder: None,
})
.into()
}
pub fn new_element<E, F>(_: &mut Window, cx: &mut App, builder: F) -> AnyView
where
E: IntoElement,
F: Fn(&mut Window, &mut App) -> E + 'static,
{
cx.new(|_| Self {
text: "".into(),
element_builder: Some(Box::new(move |window, cx| {
builder(window, cx).into_any_element()
})),
})
.into()
}
}
impl Render for Tooltip {
fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
div().child(
// Wrap in a child, to ensure the left margin is applied to the tooltip
div()
@ -32,7 +51,13 @@ impl Render for Tooltip {
.py_0p5()
.px_2()
.text_sm()
.child(self.text.clone()),
.map(|this| {
if let Some(builder) = &self.element_builder {
this.child(builder(window, cx))
} else {
this.child(self.text.clone())
}
}),
)
}
}