chore: lint with tabwidth: 2

This commit is contained in:
2023-12-28 12:05:50 +01:00
parent 53be7b5e15
commit d12769107c
78 changed files with 2378 additions and 2414 deletions

View File

@@ -7,194 +7,187 @@ import { clsx } from 'clsx'
import s from './pagination.module.scss'
type PaginationConditionals =
| {
onPerPageChange: (itemPerPage: number) => void
perPage: number
perPageOptions: number[]
}
| {
onPerPageChange?: never
perPage?: null
perPageOptions?: never
}
| {
onPerPageChange: (itemPerPage: number) => void
perPage: number
perPageOptions: number[]
}
| {
onPerPageChange?: never
perPage?: null
perPageOptions?: never
}
export type PaginationProps = {
count: number
onChange: (page: number) => void
onPerPageChange?: (itemPerPage: number) => void
page: number
perPage?: number
perPageOptions?: number[]
siblings?: number
count: number
onChange: (page: number) => void
onPerPageChange?: (itemPerPage: number) => void
page: number
perPage?: number
perPageOptions?: number[]
siblings?: number
} & PaginationConditionals
const classNames = {
container: s.container,
dots: s.dots,
icon: s.icon,
item: s.item,
pageButton(selected?: boolean) {
return clsx(this.item, selected && s.selected)
},
root: s.root,
select: s.select,
selectBox: s.selectBox,
container: s.container,
dots: s.dots,
icon: s.icon,
item: s.item,
pageButton(selected?: boolean) {
return clsx(this.item, selected && s.selected)
},
root: s.root,
select: s.select,
selectBox: s.selectBox,
}
export const Pagination: FC<PaginationProps> = ({
count,
onChange,
onPerPageChange,
page,
perPage = null,
perPageOptions,
siblings,
}) => {
const {
handleMainPageClicked,
handleNextPageClicked,
handlePreviousPageClicked,
isFirstPage,
isLastPage,
paginationRange,
} = usePagination({
count,
onChange,
onPerPageChange,
page,
perPage = null,
perPageOptions,
siblings,
}) => {
const {
handleMainPageClicked,
handleNextPageClicked,
handlePreviousPageClicked,
isFirstPage,
isLastPage,
paginationRange,
} = usePagination({
count,
onChange,
page,
siblings,
})
})
const showPerPageSelect = !!perPage && !!perPageOptions && !!onPerPageChange
const showPerPageSelect = !!perPage && !!perPageOptions && !!onPerPageChange
return (
<div className={classNames.root}>
<div className={classNames.container}>
<PrevButton disabled={isFirstPage} onClick={handlePreviousPageClicked} />
return (
<div className={classNames.root}>
<div className={classNames.container}>
<PrevButton disabled={isFirstPage} onClick={handlePreviousPageClicked} />
<MainPaginationButtons
currentPage={page}
onClick={handleMainPageClicked}
paginationRange={paginationRange}
/>
<MainPaginationButtons
currentPage={page}
onClick={handleMainPageClicked}
paginationRange={paginationRange}
/>
<NextButton disabled={isLastPage} onClick={handleNextPageClicked} />
</div>
<NextButton disabled={isLastPage} onClick={handleNextPageClicked} />
</div>
{showPerPageSelect && (
<PerPageSelect
{...{
onPerPageChange,
perPage,
perPageOptions,
}}
/>
)}
</div>
)
{showPerPageSelect && (
<PerPageSelect
{...{
onPerPageChange,
perPage,
perPageOptions,
}}
/>
)}
</div>
)
}
type NavigationButtonProps = {
disabled?: boolean
onClick: () => void
disabled?: boolean
onClick: () => void
}
type PageButtonProps = NavigationButtonProps & {
page: number
selected: boolean
page: number
selected: boolean
}
const Dots: FC = () => {
return <span className={classNames.dots}>&#8230;</span>
return <span className={classNames.dots}>&#8230;</span>
}
const PageButton: FC<PageButtonProps> = ({ disabled, onClick, page, selected }) => {
return (
<button
className={classNames.pageButton(selected)}
disabled={selected || disabled}
onClick={onClick}
>
{page}
</button>
)
return (
<button
className={classNames.pageButton(selected)}
disabled={selected || disabled}
onClick={onClick}
>
{page}
</button>
)
}
const PrevButton: FC<NavigationButtonProps> = ({ disabled, onClick }) => {
return (
<button className={classNames.item} disabled={disabled} onClick={onClick}>
<KeyboardArrowLeft className={classNames.icon} />
</button>
)
return (
<button className={classNames.item} disabled={disabled} onClick={onClick}>
<KeyboardArrowLeft className={classNames.icon} />
</button>
)
}
const NextButton: FC<NavigationButtonProps> = ({ disabled, onClick }) => {
return (
<button className={classNames.item} disabled={disabled} onClick={onClick}>
<KeyboardArrowRight className={classNames.icon} />
</button>
)
return (
<button className={classNames.item} disabled={disabled} onClick={onClick}>
<KeyboardArrowRight className={classNames.icon} />
</button>
)
}
type MainPaginationButtonsProps = {
currentPage: number
onClick: (pageNumber: number) => () => void
paginationRange: (number | string)[]
currentPage: number
onClick: (pageNumber: number) => () => void
paginationRange: (number | string)[]
}
const MainPaginationButtons: FC<MainPaginationButtonsProps> = ({
currentPage,
onClick,
paginationRange,
currentPage,
onClick,
paginationRange,
}) => {
return (
<>
{paginationRange.map((page: number | string, index) => {
const isSelected = page === currentPage
return (
<>
{paginationRange.map((page: number | string, index) => {
const isSelected = page === currentPage
if (typeof page !== 'number') {
return <Dots key={index} />
}
if (typeof page !== 'number') {
return <Dots key={index} />
}
return (
<PageButton
key={index}
onClick={onClick(page)}
page={page}
selected={isSelected}
/>
)
})}
</>
)
return <PageButton key={index} onClick={onClick(page)} page={page} selected={isSelected} />
})}
</>
)
}
export type PerPageSelectProps = {
onPerPageChange: (itemPerPage: number) => void
perPage: number
perPageOptions: number[]
onPerPageChange: (itemPerPage: number) => void
perPage: number
perPageOptions: number[]
}
export const PerPageSelect: FC<PerPageSelectProps> = (
{
// perPage,
// perPageOptions,
// onPerPageChange,
}
{
// perPage,
// perPageOptions,
// onPerPageChange,
}
) => {
// const selectOptions = perPageOptions.map(value => ({
// label: value,
// value,
// }))
// const selectOptions = perPageOptions.map(value => ({
// label: value,
// value,
// }))
return (
<div className={classNames.selectBox}>
Показать
{/*<Select*/}
{/* className={classNames.select}*/}
{/* value={perPage}*/}
{/* options={selectOptions}*/}
{/* onChange={onPerPageChange}*/}
{/* variant="pagination"*/}
{/*/>*/}
на странице
</div>
)
return (
<div className={classNames.selectBox}>
Показать
{/*<Select*/}
{/* className={classNames.select}*/}
{/* value={perPage}*/}
{/* options={selectOptions}*/}
{/* onChange={onPerPageChange}*/}
{/* variant="pagination"*/}
{/*/>*/}
на странице
</div>
)
}

View File

@@ -3,110 +3,110 @@ import { useCallback, useMemo } from 'react'
// original code: https://www.freecodecamp.org/news/build-a-custom-pagination-component-in-react/
const range = (start: number, end: number) => {
const length = end - start + 1
const length = end - start + 1
/*
/*
Create an array of certain length and set the elements within it from
start value to end value.
*/
return Array.from({ length }, (_, idx) => idx + start)
return Array.from({ length }, (_, idx) => idx + start)
}
const DOTS = '...'
type UsePaginationParamType = {
count: number
onChange: (pageNumber: number) => void
page: number
siblings?: number
count: number
onChange: (pageNumber: number) => void
page: number
siblings?: number
}
type PaginationRange = ('...' | number)[]
export const usePagination = ({ count, onChange, page, siblings = 1 }: UsePaginationParamType) => {
const paginationRange = useMemo(() => {
// Pages count is determined as siblingCount + firstPage + lastPage + page + 2*DOTS
const totalPageNumbers = siblings + 5
const paginationRange = useMemo(() => {
// Pages count is determined as siblingCount + firstPage + lastPage + page + 2*DOTS
const totalPageNumbers = siblings + 5
/*
/*
Case 1:
If the number of pages is less than the page numbers we want to show in our
paginationComponent, we return the range [1..totalPageCount]
*/
if (totalPageNumbers >= count) {
return range(1, count)
}
if (totalPageNumbers >= count) {
return range(1, count)
}
/*
/*
Calculate left and right sibling index and make sure they are within range 1 and totalPageCount
*/
const leftSiblingIndex = Math.max(page - siblings, 1)
const rightSiblingIndex = Math.min(page + siblings, count)
const leftSiblingIndex = Math.max(page - siblings, 1)
const rightSiblingIndex = Math.min(page + siblings, count)
/*
/*
We do not show dots when there is only one page number to be inserted
between the extremes of siblings and the page limits i.e 1 and totalPageCount.
Hence, we are using leftSiblingIndex > 2 and rightSiblingIndex < totalPageCount - 2
*/
const shouldShowLeftDots = leftSiblingIndex > 2
const shouldShowRightDots = rightSiblingIndex < count - 2
const shouldShowLeftDots = leftSiblingIndex > 2
const shouldShowRightDots = rightSiblingIndex < count - 2
const firstPageIndex = 1
const lastPageIndex = count
const firstPageIndex = 1
const lastPageIndex = count
/*
/*
Case 2: No left dots to show, but rights dots to be shown
*/
if (!shouldShowLeftDots && shouldShowRightDots) {
const leftItemCount = 3 + 2 * siblings
const leftRange = range(1, leftItemCount)
if (!shouldShowLeftDots && shouldShowRightDots) {
const leftItemCount = 3 + 2 * siblings
const leftRange = range(1, leftItemCount)
return [...leftRange, DOTS, count]
}
return [...leftRange, DOTS, count]
}
/*
/*
Case 3: No right dots to show, but left dots to be shown
*/
if (shouldShowLeftDots && !shouldShowRightDots) {
const rightItemCount = 3 + 2 * siblings
const rightRange = range(count - rightItemCount + 1, count)
if (shouldShowLeftDots && !shouldShowRightDots) {
const rightItemCount = 3 + 2 * siblings
const rightRange = range(count - rightItemCount + 1, count)
return [firstPageIndex, DOTS, ...rightRange]
}
return [firstPageIndex, DOTS, ...rightRange]
}
/*
/*
Case 4: Both left and right dots to be shown
*/
if (shouldShowLeftDots && shouldShowRightDots) {
const middleRange = range(leftSiblingIndex, rightSiblingIndex)
if (shouldShowLeftDots && shouldShowRightDots) {
const middleRange = range(leftSiblingIndex, rightSiblingIndex)
return [firstPageIndex, DOTS, ...middleRange, DOTS, lastPageIndex]
}
}, [siblings, page, count]) as PaginationRange
const lastPage = paginationRange.at(-1)
const isFirstPage = page === 1
const isLastPage = page === lastPage
const handleNextPageClicked = useCallback(() => {
onChange(page + 1)
}, [page, onChange])
const handlePreviousPageClicked = useCallback(() => {
onChange(page - 1)
}, [page, onChange])
function handleMainPageClicked(pageNumber: number) {
return () => onChange(pageNumber)
return [firstPageIndex, DOTS, ...middleRange, DOTS, lastPageIndex]
}
}, [siblings, page, count]) as PaginationRange
return {
handleMainPageClicked,
handleNextPageClicked,
handlePreviousPageClicked,
isFirstPage,
isLastPage,
paginationRange,
}
const lastPage = paginationRange.at(-1)
const isFirstPage = page === 1
const isLastPage = page === lastPage
const handleNextPageClicked = useCallback(() => {
onChange(page + 1)
}, [page, onChange])
const handlePreviousPageClicked = useCallback(() => {
onChange(page - 1)
}, [page, onChange])
function handleMainPageClicked(pageNumber: number) {
return () => onChange(pageNumber)
}
return {
handleMainPageClicked,
handleNextPageClicked,
handlePreviousPageClicked,
isFirstPage,
isLastPage,
paginationRange,
}
}