From e423497da60ccce3d6412b4cf830b93a62df0a54 Mon Sep 17 00:00:00 2001 From: Floyd Wang Date: Thu, 6 Feb 2025 16:05:44 +0800 Subject: [PATCH] tooltip: Support render element (#605) image --- crates/story/src/tooltip_story.rs | 30 +++++++++++++++++++++++--- crates/ui/src/tooltip.rs | 35 ++++++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/crates/story/src/tooltip_story.rs b/crates/story/src/tooltip_story.rs index 2f7e921f..7183f64f 100644 --- a/crates/story/src/tooltip_story.rs +++ b/crates/story/src/tooltip_story.rs @@ -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) + }) + }), + ) } } diff --git a/crates/ui/src/tooltip.rs b/crates/ui/src/tooltip.rs index 33779635..3f4f2f62 100644 --- a/crates/ui/src/tooltip.rs +++ b/crates/ui/src/tooltip.rs @@ -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 AnyElement>>, } impl Tooltip { pub fn new(text: impl Into, _: &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(_: &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) -> impl IntoElement { + fn render(&mut self, window: &mut Window, cx: &mut Context) -> 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()) + } + }), ) } }