2023-10-24 17:39:09 +08:00
|
|
|
use crate::{mount_style, utils::AsyncCallback};
|
2023-10-22 22:48:17 +08:00
|
|
|
use leptos::*;
|
2023-10-24 17:39:09 +08:00
|
|
|
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-24 17:39:09 +08:00
|
|
|
#[prop(optional, into)] on_before_upload: Option<AsyncCallback<FileList, bool>>,
|
2023-10-22 22:48:17 +08:00
|
|
|
children: Children,
|
|
|
|
) -> impl IntoView {
|
|
|
|
mount_style("upload", include_str!("./upload.css"));
|
|
|
|
|
2023-10-24 17:39:09 +08:00
|
|
|
let on_file_addition = move |files: FileList| {
|
|
|
|
spawn_local(async move {
|
|
|
|
if let Some(on_before_upload) = on_before_upload {
|
|
|
|
let is_allow = on_before_upload.call(files).await;
|
|
|
|
if is_allow {
|
|
|
|
//TODO submit
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2023-10-22 22:48:17 +08:00
|
|
|
};
|
|
|
|
let input_ref = create_node_ref::<html::Input>();
|
|
|
|
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-10-22 22:48:17 +08:00
|
|
|
}
|
|
|
|
};
|
2023-10-24 17:39:09 +08:00
|
|
|
let on_click = move |_| {
|
2023-10-22 22:48:17 +08:00
|
|
|
if let Some(input_ref) = input_ref.get_untracked() {
|
|
|
|
input_ref.click();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
view! {
|
|
|
|
<div class="melt-upload">
|
|
|
|
<input
|
|
|
|
class="melt-upload__input"
|
|
|
|
ref=input_ref
|
|
|
|
type="file"
|
|
|
|
accept=move || accept.get()
|
|
|
|
multiple=move || multiple.get()
|
|
|
|
on:change=on_change
|
|
|
|
/>
|
|
|
|
<div class="melt-upload__trigger" on:click=on_click>
|
|
|
|
{children()}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
}
|
|
|
|
}
|