diff --git a/packages/base/Pagination/src/Pagination/Pagination.tsx b/packages/base/Pagination/src/Pagination/Pagination.tsx index 049fcec1db..bfd1f7c5e8 100644 --- a/packages/base/Pagination/src/Pagination/Pagination.tsx +++ b/packages/base/Pagination/src/Pagination/Pagination.tsx @@ -9,21 +9,39 @@ import { Typography } from '@toptal/picasso-typography' import { getRange, ELLIPSIS } from './utils' import { PaginationButton } from '../PaginationButton' -export interface Props extends BaseProps, HTMLAttributes { +interface CommonProps extends BaseProps, HTMLAttributes { /** Value of the current highlighted page */ activePage: number /** Shows `Pagination` in disabled state when pages are not changeable */ disabled?: boolean /** Callback invoked when any page number is clicked */ onPageChange: (page: number) => void - /** Value of total pages of the data set used for calculation of page buttons */ - totalPages: number /** Number of the active page siblings */ siblingCount?: number + /** Shows the next button as disabled. */ + nextDisabled?: boolean +} + +interface DefaultVariantProps { + /** Variant of the pagination representation */ + variant?: 'default' + /** Value of total pages of the data set used for calculation of page buttons. */ + totalPages: number +} + +interface CompactVariantProps { /** Variant of the pagination representation */ - variant?: 'default' | 'compact' + variant: 'compact' + /** Value of total pages of the data set used for calculation of page buttons. + * Only optional for the `compact` variant. + * When not provided the last page can't be detected, so next button will always be enabled. + * Use `nextDisabled=true` to disable it when rendering the last page. + * */ + totalPages?: number } +export type Props = CommonProps & (DefaultVariantProps | CompactVariantProps) + export const Pagination = forwardRef(function Pagination( props, ref @@ -35,15 +53,17 @@ export const Pagination = forwardRef(function Pagination( onPageChange, siblingCount = 2, variant, + nextDisabled, ...rest } = props const pages = useMemo( - () => getRange({ activePage, totalPages, siblingCount }), + () => + totalPages ? getRange({ activePage, totalPages, siblingCount }) : [], [activePage, totalPages, siblingCount] ) - if (pages.length <= 1) { + if (totalPages !== undefined && totalPages <= 1) { return null } @@ -92,7 +112,7 @@ export const Pagination = forwardRef(function Pagination( + + + + +`; + exports[`Pagination renders disabled 1`] = `
`; + +exports[`Pagination renders with next disabled 1`] = ` +
+
+
+ + +
+
+
+`; diff --git a/packages/base/Pagination/src/Pagination/story/Variants.example.tsx b/packages/base/Pagination/src/Pagination/story/Variants.example.tsx index 70cc2608e7..8f0e7d347e 100644 --- a/packages/base/Pagination/src/Pagination/story/Variants.example.tsx +++ b/packages/base/Pagination/src/Pagination/story/Variants.example.tsx @@ -26,7 +26,6 @@ const Example = () => ( diff --git a/packages/base/Pagination/src/Pagination/test.tsx b/packages/base/Pagination/src/Pagination/test.tsx index a7697aa7e2..c0a5e84dff 100644 --- a/packages/base/Pagination/src/Pagination/test.tsx +++ b/packages/base/Pagination/src/Pagination/test.tsx @@ -6,7 +6,14 @@ import type { Props } from './Pagination' import { Pagination } from './Pagination' const renderPagination = (props: OmitInternalProps) => { - const { activePage, disabled, onPageChange, totalPages } = props + const { + activePage, + disabled, + onPageChange, + totalPages, + nextDisabled, + variant, + } = props return render( ) => { disabled={disabled} onPageChange={onPageChange} totalPages={totalPages} + nextDisabled={nextDisabled} + variant={variant} /> ) } @@ -29,6 +38,16 @@ describe('Pagination', () => { expect(container).toMatchSnapshot() }) + it('renders compact without totalPages', () => { + const { container } = renderPagination({ + activePage: 5, + variant: 'compact', + onPageChange: () => {}, + }) + + expect(container).toMatchSnapshot() + }) + it('renders disabled', () => { const { container } = renderPagination({ activePage: 5, @@ -40,6 +59,17 @@ describe('Pagination', () => { expect(container).toMatchSnapshot() }) + it('renders with next disabled', () => { + const { container } = renderPagination({ + activePage: 5, + variant: 'compact', + nextDisabled: true, + onPageChange: () => {}, + }) + + expect(container).toMatchSnapshot() + }) + it('renders nothing for 1 page', () => { const { container } = renderPagination({ activePage: 1,