Skip to main content

dioxus_element_plug/components/
image_viewer.rs

1use dioxus::prelude::*;
2
3/// ImageViewer props
4#[derive(Props, Clone, PartialEq)]
5pub struct ImageViewerProps {
6    /// Whether the viewer is visible
7    #[props(default = false)]
8    pub visible: bool,
9
10    /// List of image URLs
11    #[props(default)]
12    pub url_list: Vec<String>,
13
14    /// Initial image index
15    #[props(default = 0)]
16    pub initial_index: u32,
17
18    /// Whether to show close button
19    #[props(default = true)]
20    pub show_close: bool,
21
22    /// Close event handler
23    #[props(default)]
24    pub on_close: Option<EventHandler<()>>,
25
26    /// Additional CSS classes
27    #[props(default)]
28    pub class: Option<String>,
29}
30
31/// ImageViewer component for full-screen image preview
32#[component]
33pub fn ImageViewer(props: ImageViewerProps) -> Element {
34    if !props.visible || props.url_list.is_empty() {
35        return rsx! {};
36    }
37
38    let current_img = props.url_list.first().cloned().unwrap_or_default();
39
40    rsx! {
41        div {
42            class: "el-image-viewer__wrapper",
43            style: "position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 2001;",
44            div {
45                class: "el-image-viewer__mask",
46                style: "position: absolute; width: 100%; height: 100%; background: rgba(0,0,0,0.5);",
47                onclick: move |_| {
48                    if let Some(handler) = props.on_close {
49                        handler.call(());
50                    }
51                },
52            }
53            div {
54                class: "el-image-viewer__btn el-image-viewer__close",
55                onclick: move |_| {
56                    if let Some(handler) = props.on_close {
57                        handler.call(());
58                    }
59                },
60                "×"
61            }
62            img {
63                class: "el-image-viewer__img",
64                src: "{current_img}",
65                style: "position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); max-width: 100%; max-height: 100%;",
66            }
67        }
68    }
69}