leptos_pagination/components/
controls.rs1use leptos::prelude::*;
2use reactive_stores::Store;
3
4use crate::{
5 PaginationControls, PaginationState, PaginationStateStoreFields, UsePaginationControlsOptions,
6 use_pagination_controls,
7};
8
9#[component]
16pub fn PaginationPages(
17 state: Store<PaginationState>,
19
20 #[prop(default = 5)]
27 display_page_count: usize,
28
29 #[prop(default = 1)]
33 margin_page_count: usize,
34
35 #[prop(into, default = "⋯".into())]
39 separator: Signal<String>,
40
41 #[prop(into, optional)]
43 anchor_class: Signal<String>,
44
45 #[prop(into, optional)]
47 li_class: Signal<String>,
48
49 #[prop(into, optional)]
52 active_class: Signal<String>,
53
54 #[prop(into, optional)]
57 ul_class: Signal<String>,
58
59 #[prop(into, optional)]
61 separator_class: Signal<String>,
62) -> impl IntoView {
63 let PaginationControls {
64 current_page,
65 start_range,
66 end_range,
67 current_range,
68 show_separator_before,
69 show_separator_after,
70 page_count_error,
71 } = use_pagination_controls(
72 state,
73 UsePaginationControlsOptions::default()
74 .display_page_count(display_page_count)
75 .margin_page_count(margin_page_count),
76 );
77
78 view! {
79 {move || {
80 page_count_error.get().map(|error| view! { <div class="error-message">{error}</div> })
81 }}
82 <PaginationRange
83 state
84 current_page
85 range=start_range
86 ul_class
87 anchor_class
88 li_class
89 active_class
90 />
91 <Show when=move || show_separator_before.get()>
92 <div class=separator_class>{separator}</div>
93 </Show>
94 <PaginationRange
95 state
96 current_page
97 range=current_range
98 ul_class
99 anchor_class
100 li_class
101 active_class
102 />
103 <Show when=move || show_separator_after.get()>
104 <div class=separator_class>{separator}</div>
105 </Show>
106 <PaginationRange
107 state
108 current_page
109 range=end_range
110 ul_class
111 anchor_class
112 li_class
113 active_class
114 />
115 }
116}
117
118#[component]
120pub fn PaginationRange(
121 state: Store<PaginationState>,
122 current_page: Signal<usize>,
123 range: Signal<Vec<usize>>,
124 ul_class: Signal<String>,
125 li_class: Signal<String>,
126 anchor_class: Signal<String>,
127 active_class: Signal<String>,
128) -> impl IntoView {
129 view! {
130 <Show when=move || !range.get().is_empty()>
131 <ul class=ul_class>
132 <For
133 each=move || range.get()
134 key=|i| *i
135 children=move |index| {
136 let class = Signal::derive(move || {
137 if current_page.get() == index {
138 active_class.get()
139 } else {
140 li_class.get()
141 }
142 });
143
144 view! {
145 <li class=class>
146 <a
147 class=anchor_class
148 on:click=move |evt| {
149 evt.prevent_default();
150 state.current_page().set(index);
151 }
152 >
153 {index + 1}
154 </a>
155 </li>
156 }
157 }
158 />
159 </ul>
160 </Show>
161 }
162}
163
164#[component]
165pub fn PaginationNext(
167 state: Store<PaginationState>,
169 children: Children,
170) -> impl IntoView {
171 view! {
172 <button
173 on:click=move |_| PaginationState::next(state)
174 prop:disabled=move || PaginationState::is_last_page(state)
175 >
176 {children()}
177 </button>
178 }
179}
180
181#[component]
182pub fn PaginationPrev(
184 state: Store<PaginationState>,
186 children: Children,
187) -> impl IntoView {
188 view! {
189 <button
190 on:click=move |_| PaginationState::prev(state)
191 prop:disabled=move || PaginationState::is_first_page(state)
192 >
193 {children()}
194 </button>
195 }
196}