use topcoat::{Result, context::Cx, view::*};
use super::{
FileControl,
panel::{INPUT_CLASS, StoredTile, move_button, remove_toggle, upload_panel},
};
use crate::schema::fields::{Field, render_field};
impl Field {
pub(in crate::schema::fields) fn render_files<'a>(
&self,
file: &FileControl,
cx: &'a Cx,
paths: &[String],
error: Option<&crate::values::FieldError>,
id: String,
disabled: bool,
) -> Result<BoxView<'a>> {
let name = self.name().to_string();
let chrome = self.chrome(cx, id.clone(), error, None);
let hint_id = format!("{id}-hint");
let image = file.image;
let paths: Vec<String> = paths
.iter()
.map(|path| path.trim().to_string())
.filter(|path| !path.is_empty())
.collect();
let editable = !paths.is_empty() && !disabled;
let movable = paths.len() > 1 && !disabled;
let keep_name = format!("keep_{name}");
let clear_name = format!("clear_{name}");
let tiles: Vec<BoxView<'a>> = paths
.into_iter()
.enumerate()
.map(|(index, path)| {
let name_id = format!("{id}-file-{index}");
let remove = (!disabled).then(|| {
remove_toggle(
cx,
clear_name.clone(),
path.clone(),
format!("clear_{id}_{index}"),
name_id.clone(),
image,
"tablo-files-remove",
)
});
let moves = movable.then(|| {
let (up, down) = (
move_button(cx, true, name_id.clone(), image),
move_button(cx, false, name_id.clone(), image),
);
view! {
(up)
(down)
}
.boxed()
});
StoredTile {
path,
name_id,
image,
remove,
moves,
keep: (!disabled).then(|| keep_name.clone()),
movable,
}
.render(cx)
})
.collect();
let described_by = [chrome.described_by(), editable.then(|| hint_id.clone())]
.into_iter()
.flatten()
.reduce(|ids, id| format!("{ids} {id}"));
let aria_invalid = chrome.aria_invalid();
let accept = file.accept();
let list_name = name.clone();
let stored = view! {
<div class="contents" role="list" data-file-list=(list_name)>
for tile in tiles {
(tile)
}
</div>
}
.boxed();
let input = view! {
<input
class=(INPUT_CLASS)
id=(id)
type="file"
name=(name)
accept=(accept)
multiple=(true)
disabled=(disabled)
aria-invalid=(aria_invalid)
aria-describedby=(described_by)
>
}
.boxed();
let hint = editable.then(|| {
view! {
<div class="sr-only" id=(hint_id)>
(crate::t!(cx, "tablo-files-add"))
</div>
}
.boxed()
});
let control = upload_panel(cx, image, input, "tablo-files-drop", Some(stored), hint);
render_field(cx, &chrome, &self.label(), false, attributes! {}, control)
}
}