leptos_leaflet/components/
control.rs1use leaflet::Control;
2use leaflet::ControlOptions;
3use leptos::html::Div;
4use leptos::prelude::*;
5use wasm_bindgen::JsCast;
6use web_sys::HtmlDivElement;
7
8use crate::prelude::LeafletMapContext;
9
10#[component]
12pub fn Control(
13 #[prop(optional, default = false)]
15 leaflet_bar: bool,
16 #[prop(optional, into, default = Signal::derive(|| "topleft".to_string()))]
18 position: Signal<String>,
19 children: ChildrenFn,
20) -> impl IntoView {
21 let control = StoredValue::new_local(None::<Control>);
22
23 let options = ControlOptions::new();
24 options.set_position(position.get_untracked());
25
26 let ready_signal = Trigger::new();
27 let control_view_ref = NodeRef::<Div>::new();
28 let control_view = move || {
29 view! {
30 <div node_ref=control_view_ref>
31 { children() }
32 </div>
33 }
34 };
35
36 Effect::new(move |_| {
37 let Some(map) = use_context::<LeafletMapContext>()
38 .expect("Leaflet context not available. Could not initialize Control component.")
39 .map()
40 else {
41 return;
42 };
43
44 let c = Control::new(&options);
45
46 c.on_add(move |_| {
48 let control_html: HtmlDivElement = document()
49 .create_element("div")
50 .expect("Could not create element.")
51 .unchecked_into();
52 if leaflet_bar {
53 control_html.set_class_name("leaflet-bar");
54 }
55
56 control_html.unchecked_into()
57 });
58
59 c.add_to(&map);
60 control.set_value(Some(c));
61 ready_signal.notify();
62 });
63
64 on_cleanup(move || {
65 control.with_value(|contr| {
66 if let Some(c) = contr {
67 c.remove();
68 }
69 });
70 control.set_value(None);
71 });
72
73 let update_position = move || {
74 let position = position.get();
75 let Some(c) = control.get_value() else {
76 return;
77 };
78 c.set_position(&position);
79 };
80
81 let move_control_view = move || {
82 ready_signal.track();
83 let c = control.get_value();
84 if let Some(ch) = c {
85 ch.get_container()
86 .prepend_with_node_1(&control_view_ref.get().unwrap())
87 .expect("append_child failed");
88 }
89 };
90
91 view! {
92 { control_view }
93 { update_position }
94 { move_control_view }
95 }
96}