use std::sync::Arc;
use leptos::prelude::*;
use orbital_data::DataRecord;
pub type RowDetailView = Arc<dyn Fn(DataRecord) -> AnyView + Send + Sync>;
#[derive(Default)]
pub struct DataTableSlots {
pub toolbar: Option<DataTableToolbarSlot>,
pub footer: Option<DataTableFooterSlot>,
pub empty_view: Option<DataTableEmptyView>,
pub no_results_view: Option<DataTableNoResultsView>,
pub loading_view: Option<DataTableLoadingView>,
pub row_detail: Option<DataTableRowDetail>,
}
impl DataTableSlots {
#[allow(clippy::too_many_arguments)]
pub fn from_slot_props(
toolbar: Option<DataTableToolbarSlot>,
footer: Option<DataTableFooterSlot>,
empty_view: Option<DataTableEmptyView>,
no_results_view: Option<DataTableNoResultsView>,
loading_view: Option<DataTableLoadingView>,
row_detail: Option<DataTableRowDetail>,
) -> Self {
Self {
toolbar,
footer,
empty_view,
no_results_view,
loading_view,
row_detail,
}
}
pub fn row_detail_view(&self, legacy: Option<RowDetailView>) -> Option<RowDetailView> {
if let Some(slot) = &self.row_detail {
return Some(slot.render.clone());
}
legacy
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
#[test]
fn row_detail_view_prefers_slot() {
let legacy: RowDetailView = Arc::new(|_| ().into_any());
let slot_view: RowDetailView = Arc::new(|_| ().into_any());
let slots = DataTableSlots {
row_detail: Some(DataTableRowDetail { render: slot_view }),
..Default::default()
};
let resolved = slots.row_detail_view(Some(legacy));
assert!(resolved.is_some());
}
}
#[slot]
pub struct DataTableToolbarSlot {
pub(crate) children: ChildrenFn,
}
#[slot]
pub struct DataTableFooterSlot {
pub(crate) children: ChildrenFn,
}
#[slot]
pub struct DataTableEmptyView {
pub(crate) children: ChildrenFn,
}
#[slot]
pub struct DataTableNoResultsView {
pub(crate) children: ChildrenFn,
}
#[slot]
pub struct DataTableLoadingView {
pub(crate) children: ChildrenFn,
}
#[slot]
pub struct DataTableRowDetail {
#[prop(into)]
pub render: RowDetailView,
}