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