use topcoat::{
Result,
icon::{icon, iconify::iconify_icon},
view::{Attributes, Child, StaticClass, View, attributes, class, component, view},
};
use super::button::{ButtonSize, ButtonVariant, button_variants};
#[component]
pub async fn pagination(
#[default] mut attrs: Attributes,
#[default] child: Child<'_>,
) -> Result<impl View> {
Ok(view! {
<nav
aria-label="pagination"
class=(class!(
"@container mx-auto flex w-full justify-center",
attrs.remove("class"),
))
(attrs)
>
(child)
</nav>
})
}
#[component]
pub async fn pagination_content(
#[default] mut attrs: Attributes,
#[default] child: Child<'_>,
) -> Result<impl View> {
Ok(view! {
<ul
class=(class!(
"flex flex-row flex-wrap items-center justify-center gap-1",
attrs.remove("class"),
))
(attrs)
>
(child)
</ul>
})
}
#[component]
pub async fn pagination_item(
#[default] mut attrs: Attributes,
#[default] child: Child<'_>,
) -> Result<impl View> {
Ok(view! { <li class=(attrs.remove("class")) (attrs)>(child)</li> })
}
#[component]
pub async fn pagination_link(
#[default]
active: bool,
#[default]
mut attrs: Attributes,
#[default]
child: Child<'_>,
) -> Result<impl View> {
let variant = if active {
ButtonVariant::Outline
} else {
ButtonVariant::Ghost
};
Ok(view! {
<a
aria-current=(active.then_some("page"))
class=(class!(
button_variants(variant, ButtonSize::Icon),
attrs.remove("class"),
))
(attrs)
>
(child)
</a>
})
}
const LABEL: StaticClass = class!("sr-only @xs:not-sr-only");
#[component]
pub async fn pagination_previous(
#[into]
#[default(String::from("Previous"))]
label: String,
#[default]
mut attrs: Attributes,
) -> Result<impl View> {
Ok(view! {
<a
class=(class!(
button_variants(ButtonVariant::Ghost, ButtonSize::Md),
attrs.remove("class"),
))
(attrs)
>
icon(data: iconify_icon!("lucide:chevron-left"))
<span class=(LABEL)>(label)</span>
</a>
})
}
#[component]
pub async fn pagination_next(
#[into]
#[default(String::from("Next"))]
label: String,
#[default]
mut attrs: Attributes,
) -> Result<impl View> {
Ok(view! {
<a
class=(class!(
button_variants(ButtonVariant::Ghost, ButtonSize::Md),
attrs.remove("class"),
))
(attrs)
>
<span class=(LABEL)>(label)</span>
icon(data: iconify_icon!("lucide:chevron-right"))
</a>
})
}
#[component]
pub async fn pagination_ellipsis(#[default] mut attrs: Attributes) -> Result<impl View> {
Ok(view! {
<span
class=(class!(
"flex size-9 items-center justify-center text-muted-foreground",
attrs.remove("class"),
))
(attrs)
>
icon(
data: iconify_icon!("lucide:ellipsis"),
attrs: attributes! { class="size-4" }
)
<span class="sr-only">"More pages"</span>
</span>
})
}