leptos_leaflet/components/
tooltip.rs

1use leptos::html::Div;
2use leptos::prelude::*;
3use wasm_bindgen::prelude::*;
4
5use crate::core::{IntoThreadSafeJsValue, JsSignal};
6
7use super::{LeafletMapContext, LeafletOverlayContainerContext, Position};
8
9/// A tooltip component.
10#[component]
11pub fn Tooltip(
12    #[prop(into, optional)] position: JsSignal<Position>,
13    #[prop(into, optional)] permanent: Signal<bool>,
14    #[prop(into, optional, default="auto".into())] direction: Signal<String>,
15    #[prop(into, optional)] sticky: Signal<bool>,
16    #[prop(into, optional, default=0.9.into())] opacity: Signal<f64>,
17    children: Children,
18) -> impl IntoView {
19    let map_context = use_context::<LeafletMapContext>();
20    let overlay_context = use_context::<LeafletOverlayContainerContext>();
21
22    let content = NodeRef::<Div>::new();
23    // let content = view! { <div>{children()}</div>};
24    Effect::new(move |_| {
25        let options = leaflet::TooltipOptions::default();
26        options.set_permanent(permanent.get_untracked());
27        options.set_direction(direction.get_untracked());
28        options.set_sticky(sticky.get_untracked());
29        options.set_opacity(opacity.get_untracked());
30
31        if let Some(overlay_context) = overlay_context {
32            if let Some(layer) = overlay_context.container::<leaflet::Layer>() {
33                let tooltip = leaflet::Tooltip::new(&options, Some(layer.unchecked_ref()))
34                    .into_thread_safe_js_value();
35                let content = content.get_untracked().expect("content ref");
36                tooltip.set_content(content.unchecked_ref());
37                layer.bind_tooltip(&tooltip);
38                on_cleanup(move || {
39                    tooltip.remove();
40                });
41            }
42        } else if let Some(map) = map_context.expect("Map context not found").map() {
43            let tooltip = leaflet::Tooltip::new_with_lat_lng(
44                &position.get_untracked().as_lat_lng(),
45                &options,
46            )
47            .into_thread_safe_js_value();
48            let content = content.get_untracked().expect("content ref");
49            let html_view: &JsValue = content.unchecked_ref();
50            tooltip.set_content(html_view);
51            tooltip.open_on(&map);
52            on_cleanup(move || {
53                tooltip.remove();
54            });
55        }
56    });
57
58    view! { <div style="visibility:collapse"><div node_ref=content>{children()}</div></div> }
59}