pinakes/crates/pinakes-ui/src/components/pagination.rs
NotAShelf 6a73d11c4b
initial commit
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I4a6b498153eccd5407510dd541b7f4816a6a6964
2026-01-31 15:20:30 +03:00

102 lines
2.6 KiB
Rust

use dioxus::prelude::*;
#[component]
pub fn Pagination(
current_page: u64,
total_pages: u64,
on_page_change: EventHandler<u64>,
) -> Element {
if total_pages <= 1 {
return rsx! {};
}
let pages = pagination_range(current_page, total_pages);
rsx! {
div { class: "pagination",
button {
class: "btn btn-sm btn-secondary",
disabled: current_page == 0,
onclick: move |_| {
if current_page > 0 {
on_page_change.call(current_page - 1);
}
},
"Prev"
}
for page in pages {
if page == u64::MAX {
span { class: "page-ellipsis", "..." }
} else {
{
let btn_class = if page == current_page {
"btn btn-sm btn-primary page-btn"
} else {
"btn btn-sm btn-ghost page-btn"
};
rsx! {
button {
key: "page-{page}",
class: "{btn_class}",
onclick: move |_| on_page_change.call(page),
"{page + 1}"
}
}
}
}
}
button {
class: "btn btn-sm btn-secondary",
disabled: current_page >= total_pages - 1,
onclick: move |_| {
if current_page < total_pages - 1 {
on_page_change.call(current_page + 1);
}
},
"Next"
}
}
}
}
/// Compute a range of page numbers to display (with ellipsis as u64::MAX).
pub fn pagination_range(current: u64, total: u64) -> Vec<u64> {
let mut pages = Vec::new();
if total <= 7 {
for i in 0..total {
pages.push(i);
}
return pages;
}
pages.push(0);
if current > 2 {
pages.push(u64::MAX);
}
let start = if current <= 2 { 1 } else { current - 1 };
let end = if current >= total - 3 {
total - 1
} else {
current + 2
};
for i in start..end {
if !pages.contains(&i) {
pages.push(i);
}
}
if current < total - 3 {
pages.push(u64::MAX);
}
if !pages.contains(&(total - 1)) {
pages.push(total - 1);
}
pages
}