yew_nav_link/components/page_item.rs
1// SPDX-FileCopyrightText: 2024-2026 RAprogramm <andrey.rozanov-vl@gmail.com>
2// SPDX-License-Identifier: MIT
3
4//! # `PageItem`
5//!
6//! A single page button within a [`Pagination`](super::Pagination) component.
7//! Renders an `<li>` with the `page-item` class and active/disabled state.
8//!
9//! # Example
10//!
11//! ```rust
12//! use yew::prelude::*;
13//! use yew_nav_link::components::{PageItem, PageLink};
14//!
15//! #[component]
16//! fn PaginationNav() -> Html {
17//! html! {
18//! <nav><ul class="pagination">
19//! <PageItem page={1} active=true>
20//! <PageLink href={None}>{ "1" }</PageLink>
21//! </PageItem>
22//! <PageItem page={2}>
23//! <PageLink href={Some("/page/2")}>{ "2" }</PageLink>
24//! </PageItem>
25//! </ul></nav>
26//! }
27//! }
28//! ```
29//!
30//! # CSS Classes
31//!
32//! | Class | Condition |
33//! |-------|-----------|
34//! | `page-item` | Always applied |
35//! | `active` | Applied when `active` is `true` |
36//! | `disabled` | Applied when `disabled` is `true` |
37//!
38//! # Props
39//!
40//! | Prop | Type | Default | Description |
41//! |------|------|---------|-------------|
42//! | `page` | `u32` | — | Page number (required) |
43//! | `active` | `bool` | `false` | Currently active page |
44//! | `disabled` | `bool` | `false` | Disabled state |
45//! | `classes` | `Classes` | — | Additional CSS classes |
46//! | `children` | `Children` | — | Content |
47
48use yew::prelude::*;
49
50/// Properties for the [`PageItem`] component.
51///
52/// | Prop | Type | Default | Description |
53/// |------|------|---------|-------------|
54/// | `page` | `u32` | — | Page number (required) |
55/// | `active` | `bool` | `false` | Currently active page |
56/// | `disabled` | `bool` | `false` | Disabled state |
57/// | `classes` | `Classes` | — | Additional CSS classes |
58/// | `children` | `Children` | — | Content |
59#[derive(Properties, Clone, PartialEq, Debug)]
60pub struct PageItemProps {
61 /// Additional CSS classes applied to the page item.
62 #[prop_or_default]
63 pub classes: Classes,
64
65 /// Page number this item represents.
66 pub page: u32,
67
68 /// Whether this page item is the currently active page.
69 #[prop_or(false)]
70 pub active: bool,
71
72 /// Whether this page item is disabled (e.g. an ellipsis).
73 #[prop_or(false)]
74 pub disabled: bool,
75
76 /// Content rendered inside the page item.
77 #[prop_or_default]
78 pub children: Children
79}
80
81/// A single page button within a [`Pagination`](super::Pagination) component.
82///
83/// # CSS Classes
84///
85/// - `page-item` - Always applied
86/// - `active` - Applied when `active` is `true`
87/// - `disabled` - Applied when `disabled` is `true`
88#[function_component]
89pub fn PageItem(props: &PageItemProps) -> Html {
90 let mut classes = props.classes.clone();
91 classes.push("page-item");
92
93 if props.active {
94 classes.push("active");
95 }
96
97 if props.disabled {
98 classes.push("disabled");
99 }
100
101 html! {
102 <li {classes}>
103 <span class="page-link">
104 { for props.children.iter() }
105 </span>
106 </li>
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113
114 #[test]
115 fn page_item_props() {
116 let props = PageItemProps {
117 classes: Classes::default(),
118 page: 1,
119 active: false,
120 disabled: false,
121 children: Children::new(vec![])
122 };
123
124 assert_eq!(props.page, 1);
125 assert!(!props.active);
126 assert!(!props.disabled);
127 }
128}