Skip to content

Commit

Permalink
feat: improve showFirstLastPageButtons (#634)
Browse files Browse the repository at this point in the history
Co-authored-by: Domino987 <[email protected]>
  • Loading branch information
Domino987 and Domino987 authored Oct 3, 2022
1 parent 7834cc4 commit 8dc35d8
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 13 deletions.
130 changes: 130 additions & 0 deletions __tests__/showPaginationButtons.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import * as React from 'react';
import {
screen,
render,
waitForElementToBeRemoved
} from '@testing-library/react';
import MaterialTable from '../src';
import '@testing-library/jest-dom';

describe('Show Pagination Buttons', () => {
test('Show no buttons', async () => {
render(
<MaterialTable
data={[
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' }
]}
columns={[
{ title: 'Name', field: 'name', width: 40 },
{ title: 'Notes', field: 'notes', width: 200 }
]}
options={{
showFirstLastPageButtons: false
}}
/>
);
screen.getByRole('button', { name: /previous page/i });
screen.getByRole('button', { name: /next page/i });
expect(screen.queryByRole('button', { name: /first page/i })).toBeNull();
expect(screen.queryByRole('button', { name: /last page/i })).toBeNull();
});
test('Show first buttons', async () => {
render(
<MaterialTable
data={[
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' }
]}
columns={[
{ title: 'Name', field: 'name', width: 40 },
{ title: 'Notes', field: 'notes', width: 200 }
]}
options={{
showFirstLastPageButtons: { last: false }
}}
/>
);
screen.getByRole('button', { name: /previous page/i });
screen.getByRole('button', { name: /next page/i });
screen.getByRole('button', { name: /first page/i });
expect(screen.queryByRole('button', { name: /last page/i })).toBeNull();
});
test('Show last buttons', async () => {
render(
<MaterialTable
data={[
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' }
]}
columns={[
{ title: 'Name', field: 'name', width: 40 },
{ title: 'Notes', field: 'notes', width: 200 }
]}
options={{
showFirstLastPageButtons: { first: false }
}}
/>
);
screen.getByRole('button', { name: /previous page/i });
screen.getByRole('button', { name: /next page/i });
screen.getByRole('button', { name: /last page/i });
expect(screen.queryByRole('button', { name: /first page/i })).toBeNull();
});
test('Show all buttons', async () => {
render(
<MaterialTable
data={[
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' },
{ name: 'Smith', notes: 'A common name' }
]}
columns={[
{ title: 'Name', field: 'name', width: 40 },
{ title: 'Notes', field: 'notes', width: 200 }
]}
options={{}}
/>
);

screen.getByRole('button', { name: /previous page/i });
screen.getByRole('button', { name: /next page/i });
screen.getByRole('button', { name: /first page/i });
screen.getByRole('button', { name: /last page/i });
});
});
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@
},
"homepage": "https://material-table-core.com",
"devDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0",
"react": ">=18.2.0",
"react-dom": ">=18.2.0",
"@babel/cli": "^7.12.10",
"@babel/core": "^7.12.10",
"@babel/plugin-proposal-class-properties": "^7.12.1",
Expand All @@ -65,8 +65,8 @@
"@babel/preset-react": "^7.12.10",
"@mui/styles": ">=5.0.0",
"@material-table/exporters": "^1.0.12",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.0.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@types/jest": "^26.0.20",
"@webpack-cli/serve": "^1.2.1",
"@wojtekmaj/enzyme-adapter-react-17": "^0.4.1",
Expand Down
15 changes: 12 additions & 3 deletions src/components/MTablePagination/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import PropTypes from 'prop-types';
import React from 'react';
import { Box } from '@mui/material';
import { useTheme } from '@mui/material/styles';
import * as CommonValues from '../../utils/common-values';
import { useLocalizationStore, useIconStore } from '@store/LocalizationStore';
/* eslint-enable no-unused-vars */

Expand Down Expand Up @@ -40,6 +41,11 @@ function MTablePagination(props) {
};

const { count, page, rowsPerPage, showFirstLastPageButtons } = props;

const { first, last } = CommonValues.parseFirstLastPageButtons(
showFirstLastPageButtons,
theme.direction === 'rtl'
);
return (
<Box
sx={{
Expand All @@ -50,7 +56,7 @@ function MTablePagination(props) {
}}
ref={props.forwardedRef}
>
{showFirstLastPageButtons && (
{first && (
<Tooltip title={localization.firstTooltip}>
<span>
<IconButton
Expand Down Expand Up @@ -118,7 +124,7 @@ function MTablePagination(props) {
</IconButton>
</span>
</Tooltip>
{showFirstLastPageButtons && (
{last && (
<Tooltip title={localization.lastTooltip}>
<span>
<IconButton
Expand Down Expand Up @@ -147,7 +153,10 @@ MTablePagination.propTypes = {
rowsPerPage: PropTypes.number,
classes: PropTypes.object,
localization: PropTypes.object,
showFirstLastPageButtons: PropTypes.bool,
showFirstLastPageButtons: PropTypes.oneOfType([
PropTypes.object,
PropTypes.bool
]),
forwardedRef: PropTypes.func
};

Expand Down
15 changes: 11 additions & 4 deletions src/components/MTableSteppedPaginationInner/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Button from '@mui/material/Button';
import PropTypes from 'prop-types';
import React from 'react';
import { useTheme } from '@mui/material/styles';
import * as CommonValues from '../../utils/common-values';
import { useLocalizationStore, useIconStore } from '@store';

function MTablePaginationInner(props) {
Expand Down Expand Up @@ -81,7 +82,10 @@ function MTablePaginationInner(props) {

const pageStart = Math.max(page - 1, 0);
const pageEnd = Math.min(maxPages, page + 1);

const { first, last } = CommonValues.parseFirstLastPageButtons(
showFirstLastPageButtons,
theme.direction === 'rtl'
);
return (
<Box
sx={{
Expand All @@ -93,7 +97,7 @@ function MTablePaginationInner(props) {
}}
ref={props.forwardedRef}
>
{showFirstLastPageButtons && (
{first && (
<Tooltip title={localization.firstTooltip}>
<span>
<IconButton
Expand Down Expand Up @@ -141,7 +145,7 @@ function MTablePaginationInner(props) {
</IconButton>
</span>
</Tooltip>
{showFirstLastPageButtons && (
{last && (
<Tooltip title={localization.lastTooltip}>
<span>
<IconButton
Expand Down Expand Up @@ -172,7 +176,10 @@ MTablePaginationInner.propTypes = {
numberOfPagesAround: PropTypes.number,
classes: PropTypes.object,
theme: PropTypes.any,
showFirstLastPageButtons: PropTypes.bool
showFirstLastPageButtons: PropTypes.oneOfType([
PropTypes.object,
PropTypes.bool
])
};

MTablePaginationInner.defaultProps = {
Expand Down
5 changes: 4 additions & 1 deletion src/prop-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,10 @@ export const propTypes = {
selection: PropTypes.bool,
selectionProps: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
showEmptyDataSourceMessage: PropTypes.bool,
showFirstLastPageButtons: PropTypes.bool,
showFirstLastPageButtons: PropTypes.oneOfType([
PropTypes.object,
PropTypes.bool
]),
showSelectAllCheckbox: PropTypes.bool,
showSelectGroupCheckbox: PropTypes.bool,
showTitle: PropTypes.bool,
Expand Down
16 changes: 16 additions & 0 deletions src/utils/common-values.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,19 @@ export const widthToNumber = (width) => {
if (!width || !width.match(/^\s*\d+(px)?\s*$/)) return NaN;
return Number(width.replace(/px$/, ''));
};

export const parseFirstLastPageButtons = (showFirstLastPageButtons, isRTL) => {
let result = { first: true, last: true };
if (typeof showFirstLastPageButtons === 'boolean') {
result = {
first: showFirstLastPageButtons,
last: showFirstLastPageButtons
};
} else if (typeof showFirstLastPageButtons === 'object') {
result = { ...result, ...showFirstLastPageButtons };
}
if (isRTL) {
result = { first: result.last, last: result.first };
}
return result;
};
4 changes: 3 additions & 1 deletion types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,9 @@ export interface Options<RowData extends object> {
| React.CSSProperties
| ((data: RowData, index: number, level: number) => React.CSSProperties);
showEmptyDataSourceMessage?: boolean;
showFirstLastPageButtons?: boolean;
showFirstLastPageButtons?:
| boolean
| Partial<{ first: boolean; last: boolean }>;
showSelectAllCheckbox?: boolean;
showSelectGroupCheckbox?: boolean;
showTitle?: boolean;
Expand Down

0 comments on commit 8dc35d8

Please sign in to comment.