use dioxus::prelude::*; #[component] pub fn Pagination( current_page: u64, total_pages: u64, on_page_change: EventHandler, ) -> 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 { 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 }