dioxus_leaflet/
components.rs

1use dioxus::prelude::*;
2use crate::types::*;
3use crate::utils::*;
4
5#[derive(Props, Clone, PartialEq)]
6pub struct MapProps {
7    /// Initial position of the map
8    #[props(default = MapPosition::default())]
9    pub initial_position: MapPosition,
10    
11    /// Markers to display on the map
12    #[props(default = vec![])]
13    pub markers: Vec<MapMarker>,
14    
15    /// Height of the map container
16    #[props(default = "500px".to_string())]
17    pub height: String,
18    
19    /// Width of the map container
20    #[props(default = "100%".to_string())]
21    pub width: String,
22    
23    /// Map configuration options
24    #[props(default = MapOptions::default())]
25    pub options: MapOptions,
26    
27    /// Custom CSS class for the map container
28    #[props(default = "".to_string())]
29    pub class: String,
30    
31    /// Custom CSS styles for the map container
32    #[props(default = "".to_string())]
33    pub style: String,
34    
35    /// Callback when marker is clicked
36    pub on_marker_click: Option<EventHandler<MapMarker>>,
37    
38    /// Callback when map is clicked
39    pub on_map_click: Option<EventHandler<MapPosition>>,
40    
41    /// Callback when map is moved
42    pub on_map_move: Option<EventHandler<MapPosition>>,
43}
44
45/// Main map component using Leaflet
46#[component]
47pub fn Map(props: MapProps) -> Element {
48    let map_id: Signal<String> = use_signal(|| generate_map_id());
49    let map_id_clone: String = map_id.read().clone();
50    
51    let init_script: String = generate_map_script(
52        &map_id_clone,
53        &props.initial_position,
54        &props.markers,
55        &props.options,
56    );
57    
58    let container_style = format!(
59        "position: relative; width: {}; height: {}; {}",
60        props.width, props.height, props.style
61    );
62    
63    let container_class = if props.class.is_empty() {
64        "dioxus-leaflet-container".to_string()
65    } else {
66        format!("dioxus-leaflet-container {}", props.class)
67    };
68    
69    rsx! {
70        div {
71            class: "{container_class}",
72            style: "{container_style}",
73            
74            // Leaflet CSS
75            link {
76                rel: "stylesheet",
77                href: "https://unpkg.com/leaflet@1.9.4/dist/leaflet.css",
78                integrity: "sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=",
79                crossorigin: ""
80            }
81            
82            // Map container
83            div {
84                id: "{map_id_clone}",
85                class: "dioxus-leaflet-map",
86                style: "width: 100%; height: 100%; z-index: 1;",
87            }
88            
89            // Leaflet JavaScript
90            script {
91                src: "https://unpkg.com/leaflet@1.9.4/dist/leaflet.js",
92                integrity: "sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=",
93                crossorigin: ""
94            }
95            
96            // Initialize map script
97            script {
98                dangerous_inner_html: "{init_script}"
99            }
100        }
101    }
102}