use icondata::AiLeftOutlined;
use icondata::AiRightOutlined;
use leptos::{either::Either, prelude::*};
use orbital_base_components::{pagination_items, PaginationItem};
use orbital_macros::component_doc;
use orbital_style::inject_style;
use super::styles::pagination_styles;
use super::types::PaginationConfig;
use crate::{Button, ButtonAppearance};
#[component_doc(
category = "Navigation",
preview_slug = "pagination",
preview_label = "Pagination",
preview_icon = icondata::AiOrderedListOutlined,
)]
#[component]
pub fn Pagination(
config: PaginationConfig,
#[prop(optional, into)]
class: MaybeProp<String>,
) -> impl IntoView {
inject_style("orbital-pagination", pagination_styles());
let page = config.page.clone();
let page_count = config.page_count;
let sibling_count = config.sibling_count;
let no_next = Memo::new({
let page = page.clone();
move |_| page.get() >= page_count.get()
});
let no_previous = Memo::new({
let page = page.clone();
move |_| page.get() <= 1
});
let on_click_previous = {
let page = page.clone();
Callback::new(move |_| page.update(|val| *val = val.saturating_sub(1)))
};
let on_click_next = {
let page = page.clone();
Callback::new(move |_| page.update(|val| *val = val.saturating_add(1)))
};
view! {
<div class=move || {
let mut parts = vec!["orbital-pagination".to_string()];
if let Some(c) = class.get() {
parts.push(c);
}
parts.join(" ")
}>
<Button
class="orbital-pagination-item"
on_click=on_click_previous
icon=AiLeftOutlined
disabled=Signal::derive(move || no_previous.get())
attr:aria-label="Previous page"
/>
{move || {
pagination_items(page.get(), page_count.get(), sibling_count.get())
.into_iter()
.map(|item| match item {
PaginationItem::Number(nb) => {
let page = page.clone();
Either::Left(view! {
<Button
class="orbital-pagination-item"
appearance=Memo::new({
let page = page.clone();
move |_| {
if page.get() == nb {
ButtonAppearance::Primary
} else {
ButtonAppearance::Secondary
}
}
})
on_click=Callback::new({
let page = page.clone();
move |_| {
if page.get() != nb {
page.set(nb);
}
}
})
>
{nb}
</Button>
})
}
PaginationItem::DotLeft | PaginationItem::DotRight => {
Either::Right(view! { <div class="orbital-pagination-item">"..."</div> })
}
})
.collect_view()
}}
<Button
class="orbital-pagination-item"
on_click=on_click_next
icon=AiRightOutlined
disabled=Signal::derive(move || no_next.get())
attr:aria-label="Next page"
/>
</div>
}
}