thaw/src/upload/mod.rs

96 lines
2.8 KiB
Rust
Raw Normal View History

2023-10-31 11:27:35 +08:00
mod theme;
2023-10-26 11:17:27 +08:00
mod upload_dragger;
2023-11-13 11:13:11 +08:00
use crate::{mount_style, utils::add_event_listener};
2023-10-22 22:48:17 +08:00
use leptos::*;
2023-10-31 11:27:35 +08:00
pub use theme::UploadTheme;
2023-10-26 11:17:27 +08:00
pub use upload_dragger::UploadDragger;
pub use web_sys::FileList;
2023-10-22 22:48:17 +08:00
#[component]
pub fn Upload(
#[prop(optional, into)] accept: MaybeSignal<String>,
#[prop(optional, into)] multiple: MaybeSignal<bool>,
2023-10-26 11:17:27 +08:00
#[prop(optional, into)] custom_request: Option<Callback<FileList, ()>>,
2023-10-22 22:48:17 +08:00
children: Children,
) -> impl IntoView {
mount_style("upload", include_str!("./upload.css"));
2023-11-13 11:13:11 +08:00
let input_ref = create_node_ref::<html::Input>();
let trigger_ref = create_node_ref::<html::Div>();
trigger_ref.on_load(move |trigger_ref| {
let handle = add_event_listener(trigger_ref.into_any(), ev::click, move |_| {
if let Some(input_ref) = input_ref.get_untracked() {
input_ref.click();
}
});
on_cleanup(move || {
handle.remove();
});
});
2023-10-24 17:39:09 +08:00
let on_file_addition = move |files: FileList| {
2023-10-26 11:17:27 +08:00
if let Some(custom_request) = custom_request {
custom_request.call(files);
}
2023-10-22 22:48:17 +08:00
};
2023-11-13 11:13:11 +08:00
2023-10-22 22:48:17 +08:00
let on_change = move |_| {
if let Some(input_ref) = input_ref.get_untracked() {
2023-10-24 17:39:09 +08:00
if let Some(files) = input_ref.files() {
on_file_addition(files);
}
2023-11-13 11:13:11 +08:00
input_ref.set_value("");
2023-10-22 22:48:17 +08:00
}
};
2023-11-05 20:10:21 +08:00
2023-11-06 17:33:52 +08:00
let is_trigger_dragover = create_rw_signal(false);
2023-11-05 20:10:21 +08:00
let on_trigger_drop = move |event: ev::DragEvent| {
event.prevent_default();
if let Some(data) = event.data_transfer() {
if let Some(files) = data.files() {
on_file_addition(files);
}
}
2023-11-06 17:33:52 +08:00
is_trigger_dragover.set(false);
2023-11-05 20:10:21 +08:00
};
let on_trigger_dragover = move |event: ev::DragEvent| {
event.prevent_default();
2023-11-06 17:33:52 +08:00
is_trigger_dragover.set(true);
2023-11-05 20:10:21 +08:00
};
let on_trigger_dragenter = move |event: ev::DragEvent| {
event.prevent_default();
};
let on_trigger_dragleave = move |event: ev::DragEvent| {
event.prevent_default();
2023-11-06 17:33:52 +08:00
is_trigger_dragover.set(false);
2023-11-05 20:10:21 +08:00
};
2023-10-22 22:48:17 +08:00
view! {
2023-11-06 17:33:52 +08:00
<div
class="thaw-upload"
class=("thaw-upload--drag-over", move || is_trigger_dragover.get())
>
2023-10-22 22:48:17 +08:00
<input
2023-11-05 16:03:58 +08:00
class="thaw-upload__input"
2023-10-22 22:48:17 +08:00
ref=input_ref
type="file"
accept=move || accept.get()
multiple=move || multiple.get()
on:change=on_change
/>
2023-11-05 20:10:21 +08:00
<div
class="thaw-upload__trigger"
2023-11-13 11:13:11 +08:00
ref=trigger_ref
2023-11-05 20:10:21 +08:00
on:drop=on_trigger_drop
on:dragover=on_trigger_dragover
on:dragenter=on_trigger_dragenter
on:dragleave=on_trigger_dragleave
>
2023-10-22 22:48:17 +08:00
{children()}
</div>
</div>
}
}