Skip to main content

orbital_datatable/core/
mod.rs

1//! Shared DataTable context and helpers for product + subcomponents.
2
3mod chart_binding;
4mod column_drag;
5mod row_drag;
6
7use std::sync::Arc;
8
9use leptos::prelude::*;
10use orbital_data::DataRecord;
11use orbital_theme::Direction;
12
13use crate::types::{
14    DataTableEvents, DataTableFeatures, DataTableHeaderChromeConfig, DataTableLocale,
15    DataTableRowModel, DataTableSelectionMode, DataTableTableState, DataTableToolbarConfig,
16    GetRowId, PaginationDisplayFormat,
17};
18pub use chart_binding::{derive_schema_hints, provide_chart_binding, use_chart_binding};
19pub use column_drag::{column_drag_ghost_at_pointer, move_column_drag_ghost, ColumnDragGhost};
20pub use row_drag::{move_row_drag_ghost, row_drag_ghost_at_pointer, RowDragGhost};
21
22/// Reactive table state for custom toolbar/footer slot content.
23pub fn use_data_table_table_state() -> DataTableTableState {
24    expect_context::<DataTableTableState>()
25}
26
27/// Read shared context from the nearest [`crate::DataTable`].
28pub fn use_data_table_context() -> DataTableContext {
29    expect_context::<DataTableContext>()
30}
31
32/// Provides [`DataTableTableState`] to custom toolbar/footer slot children.
33#[component]
34pub fn DataTableTableStateProvider(
35    state: DataTableTableState,
36    children: ChildrenFn,
37) -> impl IntoView {
38    provide_context(state);
39    children()
40}
41
42/// Context shared by [`crate::DataTable`] and composable subcomponents.
43#[derive(Clone, Copy)]
44pub struct DataTableContext {
45    pub features: DataTableFeatures,
46    pub selection_mode: Signal<Option<DataTableSelectionMode>>,
47    pub events: StoredValue<Option<DataTableEvents>>,
48    pub get_row_id: StoredValue<Option<GetRowId>>,
49    pub row_detail: StoredValue<Option<Arc<dyn Fn(DataRecord) -> AnyView + Send + Sync>>>,
50    pub auto_row_height: bool,
51    pub locale: StoredValue<DataTableLocale>,
52    pub pagination_display: StoredValue<PaginationDisplayFormat>,
53    pub page_size_options: StoredValue<Option<Vec<u32>>>,
54    pub get_row_class: StoredValue<Option<Callback<(DataTableRowModel, usize), String>>>,
55    pub direction: Signal<Direction>,
56    pub toolbar_config: StoredValue<DataTableToolbarConfig>,
57    pub header_chrome: StoredValue<DataTableHeaderChromeConfig>,
58    /// Fallback drag source when `dataTransfer` is empty (e.g. synthetic DnD in tests).
59    pub drag_column_field: RwSignal<Option<String>>,
60    /// Floating label shown while a column is being drag-reordered.
61    pub column_drag_ghost: RwSignal<Option<ColumnDragGhost>>,
62    /// Full-row preview shown while a row is being drag-reordered.
63    pub row_drag_ghost: RwSignal<Option<RowDragGhost>>,
64    /// Fallback drag source for row reorder when `dataTransfer` is empty.
65    pub drag_row_id: RwSignal<Option<String>>,
66}
67
68#[component]
69pub fn DataTableProvider(
70    features: DataTableFeatures,
71    selection_mode: Signal<Option<DataTableSelectionMode>>,
72    events: StoredValue<Option<DataTableEvents>>,
73    get_row_id: StoredValue<Option<GetRowId>>,
74    row_detail: StoredValue<Option<Arc<dyn Fn(DataRecord) -> AnyView + Send + Sync>>>,
75    auto_row_height: bool,
76    locale: StoredValue<DataTableLocale>,
77    pagination_display: StoredValue<PaginationDisplayFormat>,
78    page_size_options: StoredValue<Option<Vec<u32>>>,
79    get_row_class: StoredValue<Option<Callback<(DataTableRowModel, usize), String>>>,
80    direction: Signal<Direction>,
81    toolbar_config: StoredValue<DataTableToolbarConfig>,
82    header_chrome: StoredValue<DataTableHeaderChromeConfig>,
83    children: Children,
84) -> impl IntoView {
85    provide_context(DataTableContext {
86        features,
87        selection_mode,
88        events,
89        get_row_id,
90        row_detail,
91        auto_row_height,
92        locale,
93        pagination_display,
94        page_size_options,
95        get_row_class,
96        direction,
97        toolbar_config,
98        header_chrome,
99        drag_column_field: RwSignal::new(None),
100        column_drag_ghost: RwSignal::new(None),
101        row_drag_ghost: RwSignal::new(None),
102        drag_row_id: RwSignal::new(None),
103    });
104    children()
105}