leptos_struct_table/components/
thead.rs

1use crate::wrapper_render_fn;
2use crate::{ColumnSort, DragStateRwSignal, HeadDragHandler, TableHeadEvent};
3use leptos::prelude::*;
4
5wrapper_render_fn!(
6    /// thead
7    DefaultTableHeadRenderer,
8    thead,
9);
10
11wrapper_render_fn!(
12    /// thead row
13    DefaultTableHeadRowRenderer,
14    tr,
15);
16
17/// The default table header renderer. Renders roughly
18/// ```html
19/// <th>
20///    <span>Title</span>
21/// </th>
22/// ```
23#[component]
24pub fn DefaultTableHeaderCellRenderer<F, Column>(
25    /// The class attribute for the head element. Generated by the classes provider.
26    #[prop(into)]
27    class: Signal<String>,
28    /// The class attribute for the inner element. Generated by the classes provider.
29    #[prop(into)]
30    inner_class: String,
31    /// The index of the column.
32    /// Information on column indexes is available at: the [Column index type](crate#column-index-type) section.
33    index: Column,
34    /// The sort priority of the column. `None` if the column is not sorted. `0` means the column is the primary sort column.
35    #[prop(into)]
36    sort_priority: Signal<Option<usize>>,
37    /// The sort direction of the column. See [`ColumnSort`].
38    #[prop(into)]
39    sort_direction: Signal<ColumnSort>,
40    /// The event handler for the click event. Has to be called with [`TableHeadEvent`].
41    on_click: F,
42    /// Drag state
43    drag_state: DragStateRwSignal<Column>,
44    /// Drag handlers
45    drag_handler: HeadDragHandler<Column>,
46    /// The visible ordered columns of the table.
47    columns: RwSignal<Vec<Column>>,
48    children: Children,
49) -> impl IntoView
50where
51    F: Fn(TableHeadEvent<Column>) + 'static,
52    Column: PartialEq + Copy + Send + Sync + std::fmt::Debug + 'static,
53{
54    let style = default_th_sorting_style(sort_priority, sort_direction);
55
56    let drag_classes = drag_handler.0.get_drag_classes(drag_state, index, columns);
57
58    view! {
59        <th
60            class=move || format!("{} {}", class.get(), drag_classes.get())
61            style=style
62            draggable="true"
63            on:click=move |mouse_event| on_click(TableHeadEvent {
64                index,
65                mouse_event,
66            })
67            on:drop={
68                let drag_handler = drag_handler.clone();
69                move |evt| {
70                    drag_handler.0.received_drop(drag_state, columns, index, evt);
71                }
72            }
73            on:dragover={
74                let drag_handler = drag_handler.clone();
75                move |evt| {
76                    drag_handler.0.dragging_over(drag_state, index, evt);
77                }
78            }
79            on:dragleave={
80                let drag_handler = drag_handler.clone();
81                move |evt| {
82                    drag_handler.0.drag_leave(drag_state, index, evt);
83                }
84            }
85            on:dragstart={
86                let drag_handler = drag_handler.clone();
87                move |evt| {
88                    drag_handler.0.drag_start(drag_state, index, evt);
89                }
90            }
91            on:dragend=move |evt| {
92                drag_handler.0.drag_end(drag_state, columns, index, evt);
93            }
94        >
95            <span class=inner_class>{children()}</span>
96        </th>
97    }
98}
99
100/// You can use this function to implement your own custom table header cell renderer.
101///
102/// See the implementation of [`DefaultTableHeaderCellRenderer`].
103pub fn default_th_sorting_style(
104    sort_priority: Signal<Option<usize>>,
105    sort_direction: Signal<ColumnSort>,
106) -> Signal<String> {
107    Signal::derive(move || {
108        let sort = match sort_direction.get() {
109            ColumnSort::Ascending => "--sort-icon: '▲';",
110            ColumnSort::Descending => "--sort-icon: '▼';",
111            ColumnSort::None => "--sort-icon: '';",
112        };
113
114        let priority = match sort_priority.get() {
115            Some(priority) => format!("--sort-priority: '{}';", priority + 1),
116            None => "--sort-priority: '';".to_string(),
117        };
118
119        format!("{} {}", sort, &priority)
120    })
121}