Skip to main content

dioxus_bootstrap/
pagination.rs

1use dioxus::prelude::*;
2use dioxus_router::navigation::NavigationTarget;
3use dioxus_router::components::Link;
4use super::size::Size;
5
6#[derive(Clone, Props, PartialEq)]
7pub struct PaginationProps {
8    #[props(optional)]
9    id: String,
10    #[props(optional, default = "".to_string())]
11    class: String,
12    #[props(optional, default = Size::Normal)]
13    size: Size,
14    children: Element,
15}
16
17#[component]
18pub fn Pagination(props: PaginationProps) -> Element {
19    let mut class_list = vec!["pagination".to_string()];
20    
21    let size: &str = props.size.into();
22    if props.size != Size::Normal {
23        class_list.push(format!("pagination-{}", size));
24    }
25    
26    if !props.class.is_empty() {
27        class_list.push(props.class.clone());
28    }
29    
30    let class_list = class_list.join(" ");
31    
32    rsx! {
33        nav {
34            id: props.id,
35            "aria-label": "Page navigation",
36            ul {
37                class: class_list,
38                {props.children}
39            }
40        }
41    }
42}
43
44#[derive(Clone, Props, PartialEq)]
45pub struct PaginationItemProps {
46    #[props(optional)]
47    id: String,
48    #[props(optional, default = "".to_string())]
49    class: String,
50    #[props(optional, default = false)]
51    active: bool,
52    #[props(optional, default = false)]
53    disabled: bool,
54    #[props(optional)]
55    href: Option<String>,
56    #[props(optional)]
57    link_to: Option<NavigationTarget>,
58    #[props(optional)]
59    onclick: EventHandler<MouseEvent>,
60    children: Element,
61}
62
63#[component]
64pub fn PaginationItem(props: PaginationItemProps) -> Element {
65    let mut class_list = vec!["page-item".to_string()];
66    
67    if props.active {
68        class_list.push("active".to_string());
69    }
70    
71    if props.disabled {
72        class_list.push("disabled".to_string());
73    }
74    
75    if !props.class.is_empty() {
76        class_list.push(props.class.clone());
77    }
78    
79    let class_list = class_list.join(" ");
80    
81    rsx! {
82        li {
83            id: props.id,
84            class: class_list,
85            match props.link_to {
86                Some(to) if !props.disabled => rsx! {
87                    Link {
88                        to: to,
89                        class: "page-link",
90                        onclick: props.onclick,
91                        {props.children}
92                    }
93                },
94                None if !props.disabled => rsx! {
95                    a {
96                        class: "page-link",
97                        href: props.href.unwrap_or("#".to_string()),
98                        onclick: props.onclick,
99                        {props.children}
100                    }
101                },
102                _ => rsx! {
103                    span {
104                        class: "page-link",
105                        {props.children}
106                    }
107                }
108            }
109        }
110    }
111}
112
113#[derive(Clone, Props, PartialEq)]
114pub struct PaginationLinkProps {
115    #[props(optional)]
116    id: String,
117    #[props(optional, default = "".to_string())]
118    class: String,
119    #[props(optional, default = false)]
120    disabled: bool,
121    #[props(optional)]
122    href: Option<String>,
123    #[props(optional)]
124    link_to: Option<NavigationTarget>,
125    #[props(optional)]
126    onclick: EventHandler<MouseEvent>,
127    children: Element,
128}
129
130#[component]
131pub fn PaginationLink(props: PaginationLinkProps) -> Element {
132    let mut class_list = vec!["page-link".to_string()];
133    
134    if !props.class.is_empty() {
135        class_list.push(props.class.clone());
136    }
137    
138    let class_list = class_list.join(" ");
139    
140    if props.disabled {
141        rsx! {
142            span {
143                id: props.id,
144                class: class_list,
145                {props.children}
146            }
147        }
148    } else {
149        match props.link_to {
150            Some(to) => rsx! {
151                Link {
152                    id: props.id,
153                    class: class_list,
154                    to: to,
155                    onclick: props.onclick,
156                    {props.children}
157                }
158            },
159            None => rsx! {
160                a {
161                    id: props.id,
162                    class: class_list,
163                    href: props.href.unwrap_or("#".to_string()),
164                    onclick: props.onclick,
165                    {props.children}
166                }
167            }
168        }
169    }
170}