diff --git a/src/lib/components/Pagination/Pagination.spec.tsx b/src/lib/components/Pagination/Pagination.spec.tsx index 286fda185..156a3af97 100644 --- a/src/lib/components/Pagination/Pagination.spec.tsx +++ b/src/lib/components/Pagination/Pagination.spec.tsx @@ -61,6 +61,29 @@ describe('Pagination', () => { expect(pages()).toEqual([1, 2, 3, 4, 5]); expect(currentPage()).toEqual(4); }); + + it('should disable previous button when on 1st page', async () => { + render(); + + const firstButton = buttons()[0]; + + expect(currentPage()).toEqual(1); + expect(firstButton).toBeDisabled(); + }); + + it('should disable next button when on last page', async () => { + const user = userEvent.setup(); + render(); + + const lastButton = buttons()[buttons().length - 1]; + + for (let i = 0; i < 5; ++i) { + await user.click(nextButton()); + } + + expect(currentPage()).toEqual(5); + expect(lastButton).toBeDisabled(); + }); }); describe('Props', () => { diff --git a/src/lib/components/Pagination/Pagination.tsx b/src/lib/components/Pagination/Pagination.tsx index 6ef181252..9a527f021 100644 --- a/src/lib/components/Pagination/Pagination.tsx +++ b/src/lib/components/Pagination/Pagination.tsx @@ -6,7 +6,7 @@ import { mergeDeep } from '../../helpers/mergeDeep'; import range from '../../helpers/range'; import { useTheme } from '../Flowbite/ThemeContext'; import type { FlowbitePaginationButtonTheme, PaginationButtonProps } from './PaginationButton'; -import PaginationButton from './PaginationButton'; +import { PaginationButton, PaginationNavigation } from './PaginationButton'; export interface FlowbitePaginationTheme { base: string; @@ -87,16 +87,14 @@ const PaginationComponent: FC = ({ )}
  • - {renderPaginationButton({ - className: classNames(classNames(theme.pages.previous.base, showIcon && theme.pages.showIcon)), - onClick: goToPreviousPage, - children: ( - <> - {showIcon && } - {previousLabel} - - ), - })} + + {showIcon && } + {previousLabel} +
  • {layout === 'pagination' && range(firstPage, lastPage).map((page: number) => ( @@ -112,16 +110,14 @@ const PaginationComponent: FC = ({ ))}
  • - {renderPaginationButton({ - className: classNames(theme.pages.next.base, showIcon && theme.pages.showIcon), - onClick: goToNextPage, - children: ( - <> - {nextLabel} - {showIcon && } - - ), - })} + + {nextLabel} + {showIcon && } +
diff --git a/src/lib/components/Pagination/PaginationButton.tsx b/src/lib/components/Pagination/PaginationButton.tsx index 7fb8d0ac2..3d69b8acc 100644 --- a/src/lib/components/Pagination/PaginationButton.tsx +++ b/src/lib/components/Pagination/PaginationButton.tsx @@ -7,6 +7,7 @@ import { useTheme } from '../Flowbite/ThemeContext'; export interface FlowbitePaginationButtonTheme { base: string; active: string; + disabled: string; } export interface PaginationButtonProps extends ComponentProps<'button'> { @@ -17,7 +18,11 @@ export interface PaginationButtonProps extends ComponentProps<'button'> { theme?: DeepPartial; } -const PaginationButton: FC = ({ +export interface PaginationPrevButtonProps extends Omit { + disabled?: boolean; +} + +export const PaginationButton: FC = ({ active, children, className, @@ -44,4 +49,32 @@ const PaginationButton: FC = ({ }; PaginationButton.displayName = 'Pagination.Button'; -export default PaginationButton; + +export const PaginationNavigation: FC = ({ + children, + className, + onClick, + theme: customTheme = {}, + disabled = false, + ...props +}) => { + const theme = mergeDeep(useTheme().theme.pagination, customTheme); + + return ( + + ); +}; + +PaginationNavigation.displayName = 'Pagination.Navigation'; diff --git a/src/lib/theme/default.ts b/src/lib/theme/default.ts index df999fac9..2dd38848c 100644 --- a/src/lib/theme/default.ts +++ b/src/lib/theme/default.ts @@ -633,6 +633,7 @@ const theme: FlowbiteTheme = { base: 'w-12 border border-gray-300 bg-white py-2 leading-tight text-gray-500 hover:bg-gray-100 hover:text-gray-700 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white', active: 'bg-blue-50 text-blue-600 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white', + disabled: 'opacity-50 cursor-normal', }, }, },