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}