core/panel/ui/Pagination.tsx

118 lines
3.7 KiB
TypeScript
Raw Normal View History

2025-06-30 18:25:26 +00:00
import { For } from 'solid-js'
import styles from '../styles/Pagination.module.css'
interface PaginationProps {
currentPage: number
totalPages: number
total: number
limit: number
onPageChange: (page: number) => void
onPerPageChange?: (limit: number) => void
perPageOptions?: number[]
}
const Pagination = (props: PaginationProps) => {
2025-07-02 19:30:21 +00:00
const perPageOptions = props.perPageOptions || [20, 50, 100, 200]
2025-06-30 18:25:26 +00:00
// Генерируем массив страниц для отображения
const pages = () => {
const result: (number | string)[] = []
const maxVisiblePages = 5 // Максимальное количество видимых страниц
// Всегда показываем первую страницу
result.push(1)
// Вычисляем диапазон страниц вокруг текущей
let startPage = Math.max(2, props.currentPage - Math.floor(maxVisiblePages / 2))
const endPage = Math.min(props.totalPages - 1, startPage + maxVisiblePages - 2)
// Корректируем диапазон, если он выходит за границы
if (endPage - startPage < maxVisiblePages - 2) {
startPage = Math.max(2, endPage - maxVisiblePages + 2)
}
// Добавляем многоточие после первой страницы, если нужно
if (startPage > 2) {
result.push('...')
}
// Добавляем страницы из диапазона
for (let i = startPage; i <= endPage; i++) {
result.push(i)
}
// Добавляем многоточие перед последней страницей, если нужно
if (endPage < props.totalPages - 1) {
result.push('...')
}
// Всегда показываем последнюю страницу, если есть больше одной страницы
if (props.totalPages > 1) {
result.push(props.totalPages)
}
return result
}
const startIndex = () => (props.currentPage - 1) * props.limit + 1
const endIndex = () => Math.min(props.currentPage * props.limit, props.total)
return (
<div class={styles.pagination}>
<div class={styles['pagination-info']}>
Показано {startIndex()} - {endIndex()} из {props.total}
</div>
<div class={styles['pagination-controls']}>
<button
class={styles.pageButton}
onClick={() => props.onPageChange(props.currentPage - 1)}
disabled={props.currentPage === 1}
>
</button>
<For each={pages()}>
{(page) => (
<>
{page === '...' ? (
<span class={styles['pagination-ellipsis']}>...</span>
) : (
<button
class={`${styles.pageButton} ${page === props.currentPage ? styles.currentPage : ''}`}
onClick={() => props.onPageChange(Number(page))}
>
{page}
</button>
)}
</>
)}
</For>
<button
class={styles.pageButton}
onClick={() => props.onPageChange(props.currentPage + 1)}
disabled={props.currentPage === props.totalPages}
>
</button>
</div>
{props.onPerPageChange && (
<div class={styles['pagination-per-page']}>
На странице:
<select
class={styles.perPageSelect}
value={props.limit}
onChange={(e) => props.onPerPageChange!(Number(e.target.value))}
>
<For each={perPageOptions}>{(option) => <option value={option}>{option}</option>}</For>
</select>
</div>
)}
</div>
)
}
export default Pagination