Skip to content

Commit

Permalink
feat(component): theme support to pagination (#195)
Browse files Browse the repository at this point in the history
* feat(component): theme support to pagination

* fix(review): adjust based on feedback

* fix(a11y): missing aria-hidden
  • Loading branch information
rluders authored Jun 5, 2022
1 parent 2d5b556 commit 80b7e2a
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 23 deletions.
25 changes: 25 additions & 0 deletions src/lib/components/Flowbite/FlowbiteTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,31 @@ export interface FlowbiteTheme {
};
};
};
pagination: {
base: string;
layout: {
table: {
base: string;
span: string;
};
};
pages: {
base: string;
showIcon: string;
previous: {
base: string;
icon: string;
};
next: {
base: string;
icon: string;
};
selector: {
base: string;
active: string;
};
};
};
spinner: {
base: string;
color: SpinnerColors;
Expand Down
43 changes: 20 additions & 23 deletions src/lib/components/Pagination/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import classNames from 'classnames';
import type { ComponentProps, FC, PropsWithChildren } from 'react';
import { HiChevronLeft, HiChevronRight } from 'react-icons/hi';
import { excludeClassName } from '../../helpers/exclude';
import range from '../../helpers/range';
import { useTheme } from '../Flowbite/ThemeContext';

export type PaginationProps = PropsWithChildren<Pagination>;
interface Pagination extends ComponentProps<'nav'> {
interface Pagination extends Omit<ComponentProps<'nav'>, 'className'> {
currentPage: number;
layout?: 'navigation' | 'pagination' | 'table';
onPageChange: (page: number) => void;
Expand All @@ -18,11 +20,14 @@ export const Pagination: FC<PaginationProps> = ({
onPageChange,
showIcons: showIcon = false,
totalPages,
...rest
...props
}): JSX.Element => {
const firstPage = Math.max(1, currentPage - 3);
const lastPage = Math.min(currentPage + 3, totalPages);

const theme = useTheme().theme.pagination;
const theirProps = excludeClassName(props);

const goToNextPage = (): void => {
onPageChange(Math.min(currentPage + 1, totalPages));
};
Expand All @@ -32,24 +37,21 @@ export const Pagination: FC<PaginationProps> = ({
};

return (
<nav {...rest}>
<nav className={theme.base} {...theirProps}>
{layout === 'table' && (
<div className="text-sm text-gray-700 dark:text-gray-400">
Showing <span className="font-semibold text-gray-900 dark:text-white">{firstPage}</span> to&nbsp;
<span className="font-semibold text-gray-900 dark:text-white">{lastPage}</span> of&nbsp;
<span className="font-semibold text-gray-900 dark:text-white">{totalPages}</span> Entries
<div className={theme.layout.table.base}>
Showing <span className={theme.layout.table.span}>{firstPage}</span> to&nbsp;
<span className={theme.layout.table.span}>{lastPage}</span> of&nbsp;
<span className={theme.layout.table.span}>{totalPages}</span> Entries
</div>
)}
<ul className="xs:mt-0 mt-2 inline-flex items-center -space-x-px">
<ul className={theme.pages.base}>
<li>
<button
className={classNames(
'ml-0 rounded-l-lg border border-gray-300 bg-white py-2 px-3 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',
showIcon ? 'inline-flex' : '',
)}
className={classNames(theme.pages.previous.base, showIcon && theme.pages.showIcon)}
onClick={() => goToPreviousPage()}
>
{showIcon && <HiChevronLeft aria-hidden="true" className="h-5 w-5" />}
{showIcon && <HiChevronLeft aria-hidden className={theme.pages.previous.icon} />}
Previous
</button>
</li>
Expand All @@ -58,11 +60,9 @@ export const Pagination: FC<PaginationProps> = ({
(page: number): JSX.Element => (
<li aria-current={page === currentPage ? 'page' : undefined} key={page}>
<button
className={classNames(
'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',
currentPage === page &&
'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',
)}
className={classNames(theme.pages.selector.base, {
[theme.pages.selector.active]: currentPage === page,
})}
onClick={() => onPageChange(page)}
>
{page}
Expand All @@ -72,14 +72,11 @@ export const Pagination: FC<PaginationProps> = ({
)}
<li>
<button
className={classNames(
'rounded-r-lg border border-gray-300 bg-white py-2 px-3 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',
showIcon ? 'inline-flex' : '',
)}
className={classNames(theme.pages.next.base, showIcon && theme.pages.showIcon)}
onClick={() => goToNextPage()}
>
Next
{showIcon && <HiChevronRight aria-hidden="true" className="h-5 w-5" />}
{showIcon && <HiChevronRight aria-hidden className={theme.pages.showIcon} />}
</button>
</li>
</ul>
Expand Down
26 changes: 26 additions & 0 deletions src/lib/theme/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,32 @@ export default {
},
},
},
pagination: {
base: '',
layout: {
table: {
base: 'text-sm text-gray-700 dark:text-gray-400',
span: 'font-semibold text-gray-900 dark:text-white',
},
},
pages: {
base: 'xs:mt-0 mt-2 inline-flex items-center -space-x-px',
showIcon: 'inline-flex',
previous: {
base: 'ml-0 rounded-l-lg border border-gray-300 bg-white py-2 px-3 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',
icon: 'h-5 w-5',
},
next: {
base: 'rounded-r-lg border border-gray-300 bg-white py-2 px-3 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',
icon: 'h-5 w-5',
},
selector: {
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',
},
},
},
spinner: {
base: 'inline animate-spin text-gray-200',
color: {
Expand Down

0 comments on commit 80b7e2a

Please sign in to comment.