Skip to main content

leptos_struct_table/
display_strategy.rs

1use leptos::prelude::*;
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.page_count_signal.set(if *page_row_count != 0 {
41                    Some(row_count.div_ceil(*page_row_count))
42                } else {
43                    None
44                });
45            }
46            _ => {
47                // do nothing
48            }
49        }
50    }
51}
52
53/// Allows to control what page is displayed as well as reading the page count and current page
54#[derive(Copy, Clone)]
55pub struct PaginationController {
56    /// The current page. The first page is `0`.
57    pub current_page: RwSignal<usize>,
58    page_count_signal: RwSignal<Option<usize>>,
59}
60
61impl Default for PaginationController {
62    fn default() -> Self {
63        Self {
64            // the value here doesn't really matter. We'll react only to changes later
65            current_page: RwSignal::new(0),
66            page_count_signal: RwSignal::new(None),
67        }
68    }
69}
70
71impl PaginationController {
72    /// Call this to go to the next page
73    pub fn next(&self) {
74        self.current_page.set(self.current_page.get_untracked() + 1);
75    }
76
77    /// Call this to go to the previous page
78    pub fn previous(&self) {
79        self.current_page
80            .set(self.current_page.get_untracked().saturating_sub(1));
81    }
82
83    /// Returns a `Signal` of the page count once loaded. Depending on your table data provider
84    /// this might not be available and thus always be `None`.
85    pub fn page_count(&self) -> Signal<Option<usize>> {
86        self.page_count_signal.into()
87    }
88}