use leptos::prelude::*;
use crate::topology::{NodeId, NodeView};
use crate::ui::column::{BrowserColumn, ColumnSizeConfig};
use crate::ui::icons::{IconRenderer, container_leaf_icon_renderer};
use crate::ui::state::DrillPath;
use crate::ui::style;
#[allow(unreachable_pub, clippy::needless_pass_by_value)]
#[component]
pub fn BrowserView(
columns_data: Signal<Vec<Vec<NodeView>>>,
path: Signal<DrillPath>,
#[prop(default = 3)]
visible_cols: usize,
on_select: Callback<(usize, String)>,
on_open: Callback<String>,
on_pop: Callback<()>,
#[prop(default = container_leaf_icon_renderer())]
icon_renderer: IconRenderer,
#[prop(default = ColumnSizeConfig::default())]
size_config: ColumnSizeConfig,
) -> impl IntoView {
let focus_request: RwSignal<Option<usize>> = RwSignal::new(None);
let on_root_keydown = move |ev: leptos::ev::KeyboardEvent| {
match ev.key().as_str() {
"ArrowRight" => {
ev.prevent_default();
let total = columns_data.get_untracked().len();
if total > 0 {
focus_request.set(Some(total - 1));
}
}
"ArrowLeft" | "Escape" => {
ev.prevent_default();
on_pop.run(());
}
_ => {}
}
};
view! {
<div
class={style::BROWSER_ROOT}
on:keydown=on_root_keydown
>
{move || {
let data = columns_data.get();
let total = data.len();
let start = total.saturating_sub(visible_cols);
data.into_iter()
.enumerate()
.skip(start)
.map(|(col_idx, items)| {
let selected_id = Memo::new(move |_| {
path.get().at(col_idx).map(NodeId::canonical)
});
view! {
<BrowserColumn
items=items
col_idx=col_idx
selected_id=selected_id.into()
on_select=on_select
on_open=on_open
icon_renderer=icon_renderer.clone()
size_config=size_config
focus_request=focus_request
/>
}
})
.collect::<Vec<_>>()
}}
</div>
}
}