use derive_more::Display;
use yew::events::MouseEvent;
use yew::prelude::*;
use crate::{Alignment, Size};
#[derive(Clone, Debug, Properties, PartialEq)]
pub struct PaginationProps {
#[prop_or_default]
pub children: Children,
#[prop_or_default]
pub classes: Classes,
#[prop_or_default]
pub size: Option<Size>,
#[prop_or_default]
pub alignment: Option<Alignment>,
#[prop_or_default]
pub rounded: bool,
pub previous: Html,
pub next: Html,
}
#[function_component(Pagination)]
pub fn pagination(props: &PaginationProps) -> Html {
let class = classes!(
"pagination",
props.classes.clone(),
props.size.as_ref().map(|size| size.to_string()),
props.alignment.as_ref().map(|alignment| alignment.to_string()),
props.rounded.then_some("is-rounded"),
);
html! {
<nav {class} role="navigation" aria-label="pagination">
{props.previous.clone()}
{props.next.clone()}
<ul class="pagination-list">
{props.children.clone()}
</ul>
</nav>
}
}
#[derive(Clone, Debug, Properties, PartialEq)]
pub struct PaginationItemProps {
pub children: Children,
pub item_type: PaginationItemType,
#[prop_or_default]
pub label: String,
#[prop_or_default]
pub onclick: Callback<MouseEvent>,
}
#[function_component(PaginationItem)]
pub fn pagination_item(props: &PaginationItemProps) -> Html {
html! {
<a class={props.item_type.to_string()} aria-label={props.label.clone()} onclick={props.onclick.clone()}>
{props.children.clone()}
</a>
}
}
#[derive(Clone, Debug, Display, PartialEq, Eq)]
#[display(fmt = "pagination-{}")]
pub enum PaginationItemType {
#[display(fmt = "link")]
Link,
#[display(fmt = "next")]
Next,
#[display(fmt = "previous")]
Previous,
}
#[derive(Clone, Debug, Properties, PartialEq)]
pub struct PaginationEllipsisProps {
#[prop_or_else(|| "…".into())]
pub character: String,
}
#[function_component(PaginationEllipsis)]
pub fn pagination_ellipsis(props: &PaginationEllipsisProps) -> Html {
html! {<span class="pagination-ellipsis">{&props.character}</span>}
}
#[cfg(feature = "router")]
mod router {
use super::*;
use serde::Serialize;
use yew_router::components::Link;
use yew_router::Routable;
#[derive(Clone, Properties, PartialEq)]
pub struct RouterProps<R: Routable + Clone + PartialEq + 'static> {
pub route: R,
#[prop_or_default]
pub children: Children,
pub item_type: PaginationItemType,
}
pub struct PaginationItemRouter<R: Routable + Clone + PartialEq + 'static, Q: Clone + PartialEq + Serialize + 'static = ()> {
_route: std::marker::PhantomData<R>,
_query: std::marker::PhantomData<Q>,
}
impl<R: Routable + Clone + PartialEq + 'static, Q: Clone + PartialEq + Serialize + 'static> Component for PaginationItemRouter<R, Q> {
type Message = ();
type Properties = RouterProps<R>;
fn create(_ctx: &Context<Self>) -> Self {
Self {
_route: std::marker::PhantomData,
_query: std::marker::PhantomData,
}
}
fn view(&self, ctx: &Context<Self>) -> Html {
html! {
<Link<R, Q>
to={ctx.props().route.clone()}
children={ctx.props().children.clone()}
classes={classes!(ctx.props().item_type.to_string())}
/>
}
}
}
}
#[cfg(feature = "router")]
pub use router::PaginationItemRouter;