leptos_struct_table/
display_strategy.rs

1use leptos::*;
2
3/// The display acceleration strategy. Defaults to `Virtualization`.
4#[derive(Copy, Clone, Default)]
5pub enum DisplayStrategy {
6    /// Only visible rows (plus some extra) will be displayed but the scrollbar
7    /// will seem as if all rows are there.
8    ///
9    /// If the data provider doesn't know how many rows there are (i.e. [`TableDataProvider::row_count`]
10    /// returns `None`), this will be the same as `InfiniteScroll`.
11    #[default]
12    Virtualization,
13
14    /// Only the amount of rows specified is shown. Once the user scrolls down,
15    /// more rows will be loaded. The scrollbar handle will shrink progressively
16    /// as more and more rows are loaded.
17    InfiniteScroll,
18
19    // TODO : LoadMore(usize),
20    /// Only the amount of rows specified is shown at a time. You can use the
21    /// `controller` to manipulate which page of rows is shown.
22    /// Scrolling will have no effect on what rows are loaded.
23    ///
24    /// > Please note that this will work wether your data source implements
25    /// > [`PaginatedTableDataProvider`] or [`TableDataProvider`] directly.
26    /// > Also `row_count` can be different from `PaginatedTableDataProvider::PAGE_ROW_COUNT`.
27    Pagination {
28        row_count: usize,
29        controller: PaginationController,
30    },
31}
32
33impl DisplayStrategy {
34    pub(crate) fn set_row_count(&self, row_count: usize) {
35        match self {
36            Self::Pagination {
37                row_count: page_row_count,
38                controller,
39            } => {
40                controller
41                    .page_count_signal
42                    .set(Some(row_count / *page_row_count + 1));
43            }
44            _ => {
45                // do nothing
46            }
47        }
48    }
49}
50
51/// Allows to control what page is displayed as well as reading the page count and current page
52#[derive(Copy, Clone)]
53pub struct PaginationController {
54    /// The current page. The first page is `0`.
55    pub current_page: RwSignal<usize>,
56    page_count_signal: RwSignal<Option<usize>>,
57}
58
59impl Default for PaginationController {
60    fn default() -> Self {
61        Self {
62            // the value here doesn't really matter. We'll react only to changes later
63            current_page: create_rw_signal(0),
64            page_count_signal: create_rw_signal(None),
65        }
66    }
67}
68
69impl PaginationController {
70    /// Call this to go to the next page
71    pub fn next(&self) {
72        self.current_page.set(self.current_page.get_untracked() + 1);
73    }
74
75    /// Call this to go to the previous page
76    pub fn previous(&self) {
77        self.current_page
78            .set(self.current_page.get_untracked().saturating_sub(1));
79    }
80
81    /// Returns a `Signal` of the page count once loaded. Depending on your table data provider
82    /// this might not be available and thus always be `None`.
83    pub fn page_count(&self) -> Signal<Option<usize>> {
84        self.page_count_signal.into()
85    }
86}