tweak pagination

This commit is contained in:
Pig Fang 2020-07-04 16:41:30 +08:00
parent c798b4cb25
commit 5a5c255f77
No known key found for this signature in database
GPG Key ID: A8198F548DADA9E2
3 changed files with 48 additions and 14 deletions

View File

@ -1,4 +1,5 @@
import React from 'react'
import { t } from '@/scripts/i18n'
import PaginationItem from './PaginationItem'
interface Props {
@ -7,7 +8,7 @@ interface Props {
onChange(page: number): void | Promise<void>
}
export const labels = {
const labels = {
prev: '',
next: '',
}
@ -21,13 +22,21 @@ const Pagination: React.FC<Props> = (props) => {
return (
<ul className="pagination">
<PaginationItem disabled={page === 1} onClick={() => onChange(page - 1)}>
<PaginationItem
title={t('vendor.datatable.prev')}
disabled={page === 1}
onClick={() => onChange(page - 1)}
>
{labels.prev}
<span className="d-inline d-sm-none ml-1">
{t('vendor.datatable.prev')}
</span>
</PaginationItem>
{totalPages < 8 ? (
Array.from({ length: totalPages }).map((_, i) => (
<PaginationItem
key={i}
className="d-none d-sm-block"
active={page === i + 1}
onClick={() => onChange(i + 1)}
>
@ -40,6 +49,7 @@ const Pagination: React.FC<Props> = (props) => {
[1, 2, 3, 4].map((n) => (
<PaginationItem
key={n}
className="d-none d-sm-block"
active={page === n}
onClick={() => onChange(n)}
>
@ -47,21 +57,31 @@ const Pagination: React.FC<Props> = (props) => {
</PaginationItem>
))
) : (
<PaginationItem onClick={() => onChange(1)}>1</PaginationItem>
<PaginationItem
className="d-none d-sm-block"
onClick={() => onChange(1)}
>
1
</PaginationItem>
)}
<PaginationItem disabled>...</PaginationItem>
<PaginationItem className="d-none d-sm-block" disabled>
...
</PaginationItem>
{page > 3 && page < totalPages - 2 && (
<>
{[page - 1, page, page + 1].map((n) => (
<PaginationItem
key={n}
className="d-none d-sm-block"
active={page === n}
onClick={() => onChange(n)}
>
{n}
</PaginationItem>
))}
<PaginationItem disabled>...</PaginationItem>
<PaginationItem className="d-none d-sm-block" disabled>
...
</PaginationItem>
</>
)}
{totalPages - page < 3 ? (
@ -69,6 +89,7 @@ const Pagination: React.FC<Props> = (props) => {
(n) => (
<PaginationItem
key={n}
className="d-none d-sm-block"
active={page === n}
onClick={() => onChange(n)}
>
@ -77,16 +98,23 @@ const Pagination: React.FC<Props> = (props) => {
),
)
) : (
<PaginationItem onClick={() => onChange(totalPages)}>
<PaginationItem
className="d-none d-sm-block"
onClick={() => onChange(totalPages)}
>
{totalPages}
</PaginationItem>
)}
</>
)}
<PaginationItem
title={t('vendor.datatable.next')}
disabled={page === totalPages}
onClick={() => onChange(page + 1)}
>
<span className="d-inline d-sm-none mr-1">
{t('vendor.datatable.next')}
</span>
{labels.next}
</PaginationItem>
</ul>

View File

@ -3,6 +3,8 @@ import React from 'react'
interface Props {
disabled?: boolean
active?: boolean
title?: string
className?: string
onClick?(): void
}
@ -14,6 +16,9 @@ const PaginationItem: React.FC<Props> = (props) => {
if (props.disabled) {
classes.push('disabled')
}
if (props.className) {
classes.push(props.className)
}
const handleClick = (event: React.MouseEvent) => {
event.preventDefault()
@ -23,7 +28,7 @@ const PaginationItem: React.FC<Props> = (props) => {
}
return (
<li className={classes.join(' ')} onClick={handleClick}>
<li className={classes.join(' ')} title={props.title} onClick={handleClick}>
<a href="#" className="page-link" aria-disabled={props.disabled}>
{props.children}
</a>

View File

@ -1,13 +1,14 @@
import React from 'react'
import { render, fireEvent } from '@testing-library/react'
import Pagination, { labels } from '@/components/Pagination'
import { t } from '@/scripts/i18n'
import Pagination from '@/components/Pagination'
test('hide when total pages is invalid', () => {
const { queryByText } = render(
<Pagination page={1} totalPages={0} onChange={() => {}} />,
)
expect(queryByText(labels.prev)).not.toBeInTheDocument()
expect(queryByText(labels.next)).not.toBeInTheDocument()
expect(queryByText(t('vendor.datatable.prev'))).not.toBeInTheDocument()
expect(queryByText(t('vendor.datatable.next'))).not.toBeInTheDocument()
})
describe('previous page', () => {
@ -16,7 +17,7 @@ describe('previous page', () => {
const { getByText } = render(
<Pagination page={3} totalPages={5} onChange={mock} />,
)
fireEvent.click(getByText(labels.prev))
fireEvent.click(getByText(t('vendor.datatable.prev')))
expect(mock).toBeCalledWith(2)
})
@ -25,7 +26,7 @@ describe('previous page', () => {
const { getByText } = render(
<Pagination page={1} totalPages={5} onChange={mock} />,
)
fireEvent.click(getByText(labels.prev))
fireEvent.click(getByText(t('vendor.datatable.prev')))
expect(mock).not.toBeCalled()
})
})
@ -36,7 +37,7 @@ describe('next page', () => {
const { getByText } = render(
<Pagination page={3} totalPages={5} onChange={mock} />,
)
fireEvent.click(getByText(labels.next))
fireEvent.click(getByText(t('vendor.datatable.next')))
expect(mock).toBeCalledWith(4)
})
@ -45,7 +46,7 @@ describe('next page', () => {
const { getByText } = render(
<Pagination page={5} totalPages={5} onChange={mock} />,
)
fireEvent.click(getByText(labels.next))
fireEvent.click(getByText(t('vendor.datatable.next')))
expect(mock).not.toBeCalled()
})
})