leptos-struct-table 0.18.0

Generate a complete batteries included leptos data table component from a struct definition.
Documentation
use crate::wrapper_render_fn;
use crate::{ColumnSort, DragStateRwSignal, HeadDragHandler, TableHeadEvent};
use leptos::prelude::*;

wrapper_render_fn!(
    /// thead
    DefaultTableHeadRenderer,
    thead,
);

wrapper_render_fn!(
    /// thead row
    DefaultTableHeadRowRenderer,
    tr,
);

/// The default table header renderer. Renders roughly
/// ```html
/// <th>
///    <span>Title</span>
/// </th>
/// ```
#[component]
pub fn DefaultTableHeaderCellRenderer<F, Column>(
    /// The class attribute for the head element. Generated by the classes provider.
    #[prop(into)]
    class: Signal<String>,
    /// The class attribute for the inner element. Generated by the classes provider.
    #[prop(into)]
    inner_class: String,
    /// The index of the column.
    /// Information on column indexes is available at: the [Column index type](crate#column-index-type) section.
    index: Column,
    /// The sort priority of the column. `None` if the column is not sorted. `0` means the column is the primary sort column.
    #[prop(into)]
    sort_priority: Signal<Option<usize>>,
    /// The sort direction of the column. See [`ColumnSort`].
    #[prop(into)]
    sort_direction: Signal<ColumnSort>,
    /// The event handler for the click event. Has to be called with [`TableHeadEvent`].
    on_click: F,
    /// Drag state
    drag_state: DragStateRwSignal<Column>,
    /// Drag handlers
    drag_handler: HeadDragHandler<Column>,
    /// The visible ordered columns of the table.
    columns: RwSignal<Vec<Column>>,
    children: Children,
) -> impl IntoView
where
    F: Fn(TableHeadEvent<Column>) + 'static,
    Column: PartialEq + Copy + Send + Sync + std::fmt::Debug + 'static,
{
    let style = default_th_sorting_style(sort_priority, sort_direction);

    let drag_classes = drag_handler.0.get_drag_classes(drag_state, index, columns);

    view! {
        <th
            class=move || format!("{} {}", class.get(), drag_classes.get())
            style=style
            draggable="true"
            on:click=move |mouse_event| on_click(TableHeadEvent {
                index,
                mouse_event,
            })
            on:drop={
                let drag_handler = drag_handler.clone();
                move |evt| {
                    drag_handler.0.received_drop(drag_state, columns, index, evt);
                }
            }
            on:dragover={
                let drag_handler = drag_handler.clone();
                move |evt| {
                    drag_handler.0.dragging_over(drag_state, index, evt);
                }
            }
            on:dragleave={
                let drag_handler = drag_handler.clone();
                move |evt| {
                    drag_handler.0.drag_leave(drag_state, index, evt);
                }
            }
            on:dragstart={
                let drag_handler = drag_handler.clone();
                move |evt| {
                    drag_handler.0.drag_start(drag_state, index, evt);
                }
            }
            on:dragend=move |evt| {
                drag_handler.0.drag_end(drag_state, columns, index, evt);
            }
        >
            <span class=inner_class>{children()}</span>
        </th>
    }
}

/// You can use this function to implement your own custom table header cell renderer.
///
/// See the implementation of [`DefaultTableHeaderCellRenderer`].
pub fn default_th_sorting_style(
    sort_priority: Signal<Option<usize>>,
    sort_direction: Signal<ColumnSort>,
) -> Signal<String> {
    Signal::derive(move || {
        let sort = match sort_direction.get() {
            ColumnSort::Ascending => "--sort-icon: '▲';",
            ColumnSort::Descending => "--sort-icon: '▼';",
            ColumnSort::None => "--sort-icon: '';",
        };

        let priority = match sort_priority.get() {
            Some(priority) => format!("--sort-priority: '{}';", priority + 1),
            None => "--sort-priority: '';".to_string(),
        };

        format!("{} {}", sort, &priority)
    })
}