dioxus_leaflet/components/
map.rs1use crate::{LatLng, MapOptions, MapPosition, interop, types::Id};
2use dioxus::{core::{use_drop, spawn_forever}, prelude::*};
3use std::rc::Rc;
4
5const MAP_CSS: Asset = asset!("/assets/dioxus_leaflet.scss");
6
7#[component]
9pub fn Map(
10 #[props(default = MapPosition::default())]
12 initial_position: MapPosition,
13
14 #[props(into)]
16 height: Option<String>,
17
18 #[props(into)]
20 width: Option<String>,
21
22 options: Option<MapOptions>,
24
25 #[props(into)]
27 class: Option<String>,
28
29 #[props(into)]
31 style: Option<String>,
32
33 on_click: Option<EventHandler<LatLng>>,
35
36 on_move: Option<EventHandler<MapPosition>>,
38
39 children: Element,
40) -> Element {
41 let id = use_context_provider(|| Rc::new(Id::map(dioxus_core::current_scope_id().0)));
42 let options = options.unwrap_or(MapOptions::default());
43 let leaflet_css = options.leaflet_resources.css_url();
44 let leaflet_js = options.leaflet_resources.js_url();
45
46 let id2 = id.clone();
47 let load_error = use_resource(move || {
48 let id = id2.clone();
49 let pos = initial_position.clone();
50 let opts = options.clone();
51 async move {
52 interop::update_map(&id, &pos, &opts).await.map_err(|e| e.to_string())
53 }
54 });
55
56 let id2 = id.clone();
57 let _click_handle = use_resource(move || {
58 let id = id2.clone();
59 async move {
60 if let Some(on_click) = on_click {
61 interop::on_map_click(&id, on_click).await
62 }
63 else {
64 Ok(())
65 }
66 }
67 });
68
69 let id2 = id.clone();
70 let _move_handle = use_resource(move || {
71 let id = id2.clone();
72 async move {
73 if let Some(on_move) = on_move {
74 interop::on_map_move(&id, on_move).await
75 }
76 else {
77 Ok(())
78 }
79 }
80 });
81
82 let id2 = id.clone();
83 use_drop(move || {
84 let id = id2.clone();
85 spawn_forever(async move {
86 _ = interop::delete_map(&id).await;
87 });
88 });
89
90 rsx! {
91 document::Style { href: leaflet_css }
93
94 document::Style { href: MAP_CSS }
95
96 document::Script { src: leaflet_js }
98
99 document::Script { src: interop::DL_JS }
101
102 if let Some(Err(err)) = load_error() {
103 p {
104 "{err}"
105 }
106 }
107 else {
108 div {
110 class: "dioxus-leaflet-container {class.as_ref().map(|c| c.as_str()).unwrap_or(\"\")}",
111
112 div {
114 id: "dioxus-leaflet-{id}",
115 class: "dioxus-leaflet-map",
116 {children}
117 }
118 }
119 }
120 }
121}