Skip to main content

dioxus_element_plug/components/
upload.rs

1use dioxus::prelude::*;
2
3/// Upload drag type
4#[derive(Clone, PartialEq)]
5pub enum UploadType {
6    Select,
7    Drag,
8}
9
10/// Upload props
11#[derive(Props, Clone, PartialEq)]
12pub struct UploadProps {
13    /// Upload URL
14    #[props(default)]
15    pub action: Option<String>,
16
17    /// Accepted file types
18    #[props(default)]
19    pub accept: Option<String>,
20
21    /// Whether to support multiple files
22    #[props(default = false)]
23    pub multiple: bool,
24
25    /// Whether to auto upload
26    #[props(default = true)]
27    pub auto_upload: bool,
28
29    /// Whether to show file list
30    #[props(default = true)]
31    pub show_file_list: bool,
32
33    /// Upload type
34    #[props(default = UploadType::Select)]
35    pub upload_type: UploadType,
36
37    /// Maximum number of files
38    #[props(default)]
39    pub limit: Option<u32>,
40
41    /// File list
42    #[props(default)]
43    pub file_list: Vec<String>,
44
45    /// Button text
46    #[props(default = "Upload".to_string())]
47    pub button_text: String,
48
49    /// Change event handler
50    #[props(default)]
51    pub on_change: Option<EventHandler<String>>,
52
53    #[props(default)]
54    pub class: Option<String>,
55
56    #[props(default)]
57    pub style: Option<String>,
58}
59
60/// Upload component for file uploads
61#[component]
62pub fn Upload(props: UploadProps) -> Element {
63    let mut class_names = vec!["el-upload".to_string()];
64    match props.upload_type {
65        UploadType::Drag => class_names.push("el-upload--drag".to_string()),
66        UploadType::Select => class_names.push("el-upload--select".to_string()),
67    }
68    if let Some(ref c) = props.class { class_names.push(c.clone()); }
69
70    rsx! {
71        div {
72            class: "{class_names.join(\" \")}",
73            style: props.style.clone().unwrap_or_default(),
74            input {
75                r#type: "file",
76                class: "el-upload__input",
77                accept: props.accept.clone().unwrap_or_default(),
78                multiple: props.multiple,
79                onchange: move |e| {
80                    if let Some(handler) = props.on_change {
81                        handler.call(e.value());
82                    }
83                },
84            }
85            if props.upload_type == UploadType::Drag {
86                div {
87                    class: "el-upload-dragger",
88                    i { class: "el-icon-upload" }
89                    div { class: "el-upload__text", "Drop file here or click to upload" }
90                }
91            } else {
92                button {
93                    class: "el-button el-button--primary",
94                    "{props.button_text}"
95                }
96            }
97            if props.show_file_list && !props.file_list.is_empty() {
98                ul {
99                    class: "el-upload-list",
100                    for file in props.file_list.iter() {
101                        li {
102                            class: "el-upload-list__item",
103                            span { class: "el-upload-list__item-name", "{file}" }
104                        }
105                    }
106                }
107            }
108        }
109    }
110}