Last active
October 6, 2021 19:03
-
-
Save mnzsss/f2e54aa22c591148a5bb6af95673d10a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable indent */ | |
import { Stack, Text } from '@chakra-ui/react' | |
import { PaginationItem } from './PaginationItem' | |
type PaginationProps = { | |
onPageChange: (page: number) => void | |
currentPage: number | |
lastPage: number | |
nextPages: number[] | |
previousPages: number[] | |
siblingsCount: number | |
} | |
export function Pagination({ | |
currentPage, | |
lastPage, | |
previousPages, | |
nextPages, | |
siblingsCount, | |
onPageChange | |
}: PaginationProps) { | |
return ( | |
<Stack direction="row" mt="8" justify="flex-end" align="center" spacing="6"> | |
<Stack direction="row" spacing="4"> | |
{currentPage > 1 + siblingsCount ? ( | |
<> | |
<PaginationItem onPageChange={onPageChange} page={1} /> | |
{currentPage > 2 + siblingsCount ? ( | |
<Text color="gray.300" w="8" textAlign="center"> | |
... | |
</Text> | |
) : null} | |
</> | |
) : null} | |
{previousPages.length > 0 | |
? previousPages.map(page => ( | |
<PaginationItem | |
onPageChange={onPageChange} | |
page={page} | |
key={page} | |
/> | |
)) | |
: null} | |
<PaginationItem | |
onPageChange={onPageChange} | |
page={currentPage} | |
isCurrent | |
/> | |
{nextPages.length > 0 | |
? nextPages.map(page => ( | |
<PaginationItem | |
onPageChange={onPageChange} | |
page={page} | |
key={page} | |
/> | |
)) | |
: null} | |
{currentPage + siblingsCount < lastPage ? ( | |
<> | |
{currentPage + 1 + siblingsCount < lastPage ? ( | |
<Text color="gray.300" w="8" textAlign="center"> | |
... | |
</Text> | |
) : null} | |
<PaginationItem onPageChange={onPageChange} page={lastPage} /> | |
</> | |
) : null} | |
</Stack> | |
</Stack> | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Button } from '@chakra-ui/react' | |
type PaginationItemProps = { | |
isCurrent?: boolean | |
page: number | |
onPageChange: (page: number) => void | |
} | |
export function PaginationItem({ | |
isCurrent = false, | |
page, | |
onPageChange | |
}: PaginationItemProps) { | |
if (isCurrent) { | |
return ( | |
<Button | |
size="sm" | |
fontSize="xs" | |
width="4" | |
colorScheme="teal" | |
disabled | |
_disabled={{ | |
bg: 'teal.500', | |
cursor: 'pointer' | |
}} | |
> | |
{page} | |
</Button> | |
) | |
} | |
return ( | |
<Button | |
size="sm" | |
fontSize="xs" | |
width="4" | |
bg="gray.100" | |
_hover={{ | |
bg: 'gray.300' | |
}} | |
onClick={() => onPageChange(page)} | |
> | |
{page} | |
</Button> | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
Table as ChakraTable, | |
Thead, | |
Tbody, | |
Tr, | |
Th, | |
Td, | |
Box | |
} from '@chakra-ui/react' | |
import { usePagination } from '@hooks/usePagination' | |
import { Fragment } from 'react' | |
import { Column, useTable } from 'react-table' | |
import { Pagination } from './Pagination' | |
interface TableProps { | |
columns: Array<Column> | |
data: any[] | |
page: number | |
totalRegisters: number | |
onPageChange: (page: number) => void | |
noShadow?: boolean | |
} | |
export function Table({ | |
page, | |
onPageChange, | |
totalRegisters, | |
data = [], | |
columns = [], | |
noShadow = false | |
}: TableProps) { | |
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = | |
useTable({ columns, data }) | |
const pagination = usePagination({ | |
totalRegisters, | |
page | |
}) | |
return ( | |
<Box | |
py="6" | |
px="8" | |
borderRadius="8" | |
boxShadow={noShadow ? 'unset' : 'md'} | |
w="full" | |
h="100%" | |
> | |
<ChakraTable {...getTableProps()}> | |
<Thead> | |
{headerGroups.map(headerGroup => ( | |
<Tr {...headerGroup.getHeaderGroupProps()} key={headerGroup.id}> | |
{headerGroup.headers.map(column => ( | |
<Fragment key={column.id}> | |
<Th {...column.getHeaderProps()}> | |
{column.render('Header')} | |
</Th> | |
</Fragment> | |
))} | |
</Tr> | |
))} | |
</Thead> | |
<Tbody {...getTableBodyProps()}> | |
{rows.map(row => { | |
prepareRow(row) | |
return ( | |
<Tr {...row.getRowProps()} key={row.id}> | |
{row.cells.map((cell, index) => ( | |
<Fragment key={cell.column.id + index}> | |
<Td {...cell.getCellProps()}>{cell.render('Cell')}</Td> | |
</Fragment> | |
))} | |
</Tr> | |
) | |
})} | |
</Tbody> | |
</ChakraTable> | |
<Pagination {...pagination} onPageChange={onPageChange} /> | |
</Box> | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable indent */ | |
type Options = { | |
totalRegisters: number | |
page: number | |
} | |
type Pagination = { | |
totalPages: number | |
registersPerPage: number | |
currentPage: number | |
lastPage: number | |
nextPages: number[] | |
previousPages: number[] | |
siblingsCount: number | |
} | |
// Default Values | |
const SIBLINGS_COUNT = 1 | |
const REGISTERS_PER_PAGE = 10 | |
function generatePagesArray(from: number, to: number): number[] { | |
return [...new Array(to - from)] | |
.map((_, index) => from + index + 1) | |
.filter(page => page > 0) | |
} | |
export function usePagination({ totalRegisters, page }: Options): Pagination { | |
const currentPage = page | |
const lastPage = Math.ceil(totalRegisters / REGISTERS_PER_PAGE) | |
const totalPages = lastPage === 0 ? 1 : lastPage | |
const previousPages = | |
currentPage > 1 | |
? generatePagesArray(currentPage - 1 - SIBLINGS_COUNT, currentPage - 1) | |
: [] | |
const nextPages = | |
currentPage < lastPage | |
? generatePagesArray( | |
currentPage, | |
Math.min(currentPage + SIBLINGS_COUNT, lastPage) | |
) | |
: [] | |
return { | |
currentPage, | |
totalPages, | |
lastPage, | |
nextPages, | |
previousPages, | |
registersPerPage: REGISTERS_PER_PAGE, | |
siblingsCount: SIBLINGS_COUNT | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment