diff --git a/docs/pages/material-ui/api/table-pagination.json b/docs/pages/material-ui/api/table-pagination.json
index 0fe0e042df85bb..e4ffefc539a7d9 100644
--- a/docs/pages/material-ui/api/table-pagination.json
+++ b/docs/pages/material-ui/api/table-pagination.json
@@ -12,9 +12,14 @@
"page": { "type": { "name": "custom", "description": "integer" }, "required": true },
"rowsPerPage": { "type": { "name": "custom", "description": "integer" }, "required": true },
"ActionsComponent": { "type": { "name": "elementType" }, "default": "TablePaginationActions" },
- "backIconButtonProps": { "type": { "name": "object" } },
+ "backIconButtonProps": {
+ "type": { "name": "object" },
+ "deprecated": true,
+ "deprecationInfo": "Use slotProps.actions.previousButton
instead."
+ },
"classes": { "type": { "name": "object" }, "additionalInfo": { "cssApi": true } },
"component": { "type": { "name": "elementType" } },
+ "disabled": { "type": { "name": "bool" }, "default": "false" },
"getItemAriaLabel": {
"type": { "name": "func" },
"default": "function defaultGetAriaLabel(type) {\n return `Go to ${type} page`;\n}",
@@ -25,7 +30,11 @@
"default": "function defaultLabelDisplayedRows({ from, to, count }) {\n return `${from}–${to} of ${count !== -1 ? count : `more than ${to}`}`;\n}"
},
"labelRowsPerPage": { "type": { "name": "node" }, "default": "'Rows per page:'" },
- "nextIconButtonProps": { "type": { "name": "object" } },
+ "nextIconButtonProps": {
+ "type": { "name": "object" },
+ "deprecated": true,
+ "deprecationInfo": "Use slotProps.actions.nextButton
instead."
+ },
"onRowsPerPageChange": {
"type": { "name": "func" },
"signature": {
@@ -40,9 +49,21 @@
},
"default": "[10, 25, 50, 100]"
},
- "SelectProps": { "type": { "name": "object" }, "default": "{}" },
+ "SelectProps": {
+ "type": { "name": "object" },
+ "default": "{}",
+ "deprecated": true,
+ "deprecationInfo": "Use slotProps.select
instead."
+ },
"showFirstButton": { "type": { "name": "bool" }, "default": "false" },
"showLastButton": { "type": { "name": "bool" }, "default": "false" },
+ "slotProps": {
+ "type": {
+ "name": "shape",
+ "description": "{ actions?: { firstButton?: object, lastButton?: object, nextButton?: object, previousButton?: object }, select?: object }"
+ },
+ "default": "{}"
+ },
"sx": {
"type": {
"name": "union",
diff --git a/docs/translations/api-docs/table-pagination/table-pagination.json b/docs/translations/api-docs/table-pagination/table-pagination.json
index 25a5bd3cb7dd9e..21a7bb468b5699 100644
--- a/docs/translations/api-docs/table-pagination/table-pagination.json
+++ b/docs/translations/api-docs/table-pagination/table-pagination.json
@@ -5,7 +5,7 @@
"description": "The component used for displaying the actions. Either a string to use a HTML element or a component."
},
"backIconButtonProps": {
- "description": "Props applied to the back arrow IconButton
component."
+ "description": "Props applied to the back arrow IconButton
component.
This prop is an alias for slotProps.actions.previousButton
and will be overriden by it if both are used."
},
"classes": { "description": "Override or extend the styles applied to the component." },
"component": {
@@ -14,6 +14,7 @@
"count": {
"description": "The total number of rows.
To enable server side pagination for an unknown number of items, provide -1."
},
+ "disabled": { "description": "If true
, the component is disabled." },
"getItemAriaLabel": {
"description": "Accepts a function which returns a string value that provides a user-friendly name for the current page. This is important for screen reader users.
For localization purposes, you can use the provided translations.",
"typeDescriptions": {
@@ -27,7 +28,7 @@
"description": "Customize the rows per page label.
For localization purposes, you can use the provided translations."
},
"nextIconButtonProps": {
- "description": "Props applied to the next arrow IconButton
element."
+ "description": "Props applied to the next arrow IconButton
element.
This prop is an alias for slotProps.actions.nextButton
and will be overriden by it if both are used."
},
"onPageChange": {
"description": "Callback fired when the page is changed.",
@@ -48,10 +49,11 @@
"description": "Customizes the options of the rows per page select field. If less than two options are available, no select field will be displayed. Use -1 for the value with a custom label to show all the rows."
},
"SelectProps": {
- "description": "Props applied to the rows per page Select
element."
+ "description": "Props applied to the rows per page Select
element.
This prop is an alias for slotProps.select
and will be overriden by it if both are used."
},
"showFirstButton": { "description": "If true
, show the first-page button." },
"showLastButton": { "description": "If true
, show the last-page button." },
+ "slotProps": { "description": "The props used for each slot inside the TablePagination." },
"sx": {
"description": "The system prop that allows defining system overrides as well as additional CSS styles."
}
diff --git a/packages/mui-material/src/TablePagination/TablePagination.d.ts b/packages/mui-material/src/TablePagination/TablePagination.d.ts
index 3c72b57d9186b9..609b420e726941 100644
--- a/packages/mui-material/src/TablePagination/TablePagination.d.ts
+++ b/packages/mui-material/src/TablePagination/TablePagination.d.ts
@@ -29,6 +29,9 @@ export interface TablePaginationOwnProps extends TablePaginationBaseProps {
ActionsComponent?: React.ElementType;
/**
* Props applied to the back arrow [`IconButton`](/material-ui/api/icon-button/) component.
+ *
+ * This prop is an alias for `slotProps.actions.previousButton` and will be overriden by it if both are used.
+ * @deprecated Use `slotProps.actions.previousButton` instead.
*/
backIconButtonProps?: Partial;
/**
@@ -41,6 +44,11 @@ export interface TablePaginationOwnProps extends TablePaginationBaseProps {
* To enable server side pagination for an unknown number of items, provide -1.
*/
count: number;
+ /**
+ * If `true`, the component is disabled.
+ * @default false
+ */
+ disabled?: boolean;
/**
* Accepts a function which returns a string value that provides a user-friendly name for the current page.
* This is important for screen reader users.
@@ -72,6 +80,9 @@ export interface TablePaginationOwnProps extends TablePaginationBaseProps {
labelRowsPerPage?: React.ReactNode;
/**
* Props applied to the next arrow [`IconButton`](/material-ui/api/icon-button/) element.
+ *
+ * This prop is an alias for `slotProps.actions.nextButton` and will be overriden by it if both are used.
+ * @deprecated Use `slotProps.actions.nextButton` instead.
*/
nextIconButtonProps?: Partial;
/**
@@ -106,6 +117,10 @@ export interface TablePaginationOwnProps extends TablePaginationBaseProps {
rowsPerPageOptions?: Array;
/**
* Props applied to the rows per page [`Select`](/material-ui/api/select/) element.
+ *
+ * This prop is an alias for `slotProps.select` and will be overriden by it if both are used.
+ * @deprecated Use `slotProps.select` instead.
+ *
* @default {}
*/
SelectProps?: Partial;
@@ -119,6 +134,14 @@ export interface TablePaginationOwnProps extends TablePaginationBaseProps {
* @default false
*/
showLastButton?: boolean;
+ /**
+ * The props used for each slot inside the TablePagination.
+ * @default {}
+ */
+ slotProps?: {
+ actions?: TablePaginationActionsProps['slotProps'];
+ select?: Partial;
+ };
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
diff --git a/packages/mui-material/src/TablePagination/TablePagination.js b/packages/mui-material/src/TablePagination/TablePagination.js
index 4e040523cac251..d3d515d46b1383 100644
--- a/packages/mui-material/src/TablePagination/TablePagination.js
+++ b/packages/mui-material/src/TablePagination/TablePagination.js
@@ -145,6 +145,7 @@ const TablePagination = React.forwardRef(function TablePagination(inProps, ref)
colSpan: colSpanProp,
component = TableCell,
count,
+ disabled = false,
getItemAriaLabel = defaultGetAriaLabel,
labelDisplayedRows = defaultLabelDisplayedRows,
labelRowsPerPage = 'Rows per page:',
@@ -157,21 +158,24 @@ const TablePagination = React.forwardRef(function TablePagination(inProps, ref)
SelectProps = {},
showFirstButton = false,
showLastButton = false,
+ slotProps,
...other
} = props;
const ownerState = props;
const classes = useUtilityClasses(ownerState);
- const MenuItemComponent = SelectProps.native ? 'option' : TablePaginationMenuItem;
+ const selectProps = slotProps?.select ?? SelectProps;
+
+ const MenuItemComponent = selectProps.native ? 'option' : TablePaginationMenuItem;
let colSpan;
if (component === TableCell || component === 'td') {
colSpan = colSpanProp || 1000; // col-span over everything
}
- const selectId = useId(SelectProps.id);
- const labelId = useId(SelectProps.labelId);
+ const selectId = useId(selectProps.id);
+ const labelId = useId(selectProps.labelId);
const getLabelDisplayedRowsTo = () => {
if (count === -1) {
@@ -200,20 +204,21 @@ const TablePagination = React.forwardRef(function TablePagination(inProps, ref)
{rowsPerPageOptions.length > 1 && (
})}
+ {...(!selectProps.variant && { input: })}
value={rowsPerPage}
onChange={onRowsPerPageChange}
id={selectId}
labelId={labelId}
- {...SelectProps}
+ {...selectProps}
classes={{
- ...SelectProps.classes,
+ ...selectProps.classes,
// TODO v5 remove `classes.input`
- root: clsx(classes.input, classes.selectRoot, (SelectProps.classes || {}).root),
- select: clsx(classes.select, (SelectProps.classes || {}).select),
+ root: clsx(classes.input, classes.selectRoot, (selectProps.classes || {}).root),
+ select: clsx(classes.select, (selectProps.classes || {}).select),
// TODO v5 remove `selectIcon`
- icon: clsx(classes.selectIcon, (SelectProps.classes || {}).icon),
+ icon: clsx(classes.selectIcon, (selectProps.classes || {}).icon),
}}
+ disabled={disabled}
>
{rowsPerPageOptions.map((rowsPerPageOption) => (
@@ -268,6 +275,9 @@ TablePagination.propTypes /* remove-proptypes */ = {
ActionsComponent: PropTypes.elementType,
/**
* Props applied to the back arrow [`IconButton`](/material-ui/api/icon-button/) component.
+ *
+ * This prop is an alias for `slotProps.actions.previousButton` and will be overriden by it if both are used.
+ * @deprecated Use `slotProps.actions.previousButton` instead.
*/
backIconButtonProps: PropTypes.object,
/**
@@ -293,6 +303,11 @@ TablePagination.propTypes /* remove-proptypes */ = {
* To enable server side pagination for an unknown number of items, provide -1.
*/
count: integerPropType.isRequired,
+ /**
+ * If `true`, the component is disabled.
+ * @default false
+ */
+ disabled: PropTypes.bool,
/**
* Accepts a function which returns a string value that provides a user-friendly name for the current page.
* This is important for screen reader users.
@@ -324,6 +339,9 @@ TablePagination.propTypes /* remove-proptypes */ = {
labelRowsPerPage: PropTypes.node,
/**
* Props applied to the next arrow [`IconButton`](/material-ui/api/icon-button/) element.
+ *
+ * This prop is an alias for `slotProps.actions.nextButton` and will be overriden by it if both are used.
+ * @deprecated Use `slotProps.actions.nextButton` instead.
*/
nextIconButtonProps: PropTypes.object,
/**
@@ -381,6 +399,10 @@ TablePagination.propTypes /* remove-proptypes */ = {
),
/**
* Props applied to the rows per page [`Select`](/material-ui/api/select/) element.
+ *
+ * This prop is an alias for `slotProps.select` and will be overriden by it if both are used.
+ * @deprecated Use `slotProps.select` instead.
+ *
* @default {}
*/
SelectProps: PropTypes.object,
@@ -394,6 +416,19 @@ TablePagination.propTypes /* remove-proptypes */ = {
* @default false
*/
showLastButton: PropTypes.bool,
+ /**
+ * The props used for each slot inside the TablePagination.
+ * @default {}
+ */
+ slotProps: PropTypes.shape({
+ actions: PropTypes.shape({
+ firstButton: PropTypes.object,
+ lastButton: PropTypes.object,
+ nextButton: PropTypes.object,
+ previousButton: PropTypes.object,
+ }),
+ select: PropTypes.object,
+ }),
/**
* The system prop that allows defining system overrides as well as additional CSS styles.
*/
diff --git a/packages/mui-material/src/TablePagination/TablePagination.test.js b/packages/mui-material/src/TablePagination/TablePagination.test.js
index 36958b7a1be69b..5b044a54687d00 100644
--- a/packages/mui-material/src/TablePagination/TablePagination.test.js
+++ b/packages/mui-material/src/TablePagination/TablePagination.test.js
@@ -353,6 +353,112 @@ describe('', () => {
});
});
+ describe('prop: backIconButtonProps', () => {
+ it('should apply props to the back button', () => {
+ const backIconButtonPropsDisabled = true;
+
+ const { getByRole } = render(
+ ,
+ );
+
+ const backButton = getByRole('button', { name: 'Go to previous page' });
+ expect(backButton).to.have.property('disabled', backIconButtonPropsDisabled);
+ });
+ });
+
+ describe('prop: nextIconButtonProps', () => {
+ it('should apply props to the next button', () => {
+ const nextIconButtonPropsDisabled = true;
+
+ const { getByRole } = render(
+ ,
+ );
+
+ const nextButton = getByRole('button', { name: 'Go to next page' });
+ expect(nextButton).to.have.property('disabled', nextIconButtonPropsDisabled);
+ });
+ });
+
+ describe('prop: disabled', () => {
+ it('should disable the first, last, next, and back buttons', () => {
+ const { getByRole } = render(
+ ,
+ );
+
+ const firstButton = getByRole('button', { name: 'Go to first page' });
+ const lastButton = getByRole('button', { name: 'Go to last page' });
+ const nextButton = getByRole('button', { name: 'Go to next page' });
+ const backButton = getByRole('button', { name: 'Go to previous page' });
+ expect(firstButton).to.have.property('disabled', true);
+ expect(lastButton).to.have.property('disabled', true);
+ expect(nextButton).to.have.property('disabled', true);
+ expect(backButton).to.have.property('disabled', true);
+ });
+
+ it('should disable TablePaginationSelect', () => {
+ const { getByRole } = render(
+ ,
+ );
+
+ const combobox = getByRole('combobox');
+ expect(combobox.parentElement).to.have.class(inputClasses.disabled);
+ });
+ });
+
describe('warnings', () => {
beforeEach(() => {
PropTypes.resetWarningCache();
@@ -458,6 +564,103 @@ describe('', () => {
});
});
+ describe('prop: slotProps', () => {
+ describe('actions', () => {
+ describe('previousButton', () => {
+ it('should override backIconButtonProps', () => {
+ const slotPropsDisabled = false;
+ const backIconButtonPropsDisabled = true;
+
+ const { getByRole } = render(
+ ,
+ );
+
+ const backButton = getByRole('button', { name: 'Go to previous page' });
+ expect(slotPropsDisabled).not.to.equal(backIconButtonPropsDisabled);
+ expect(backButton).to.have.property('disabled', slotPropsDisabled);
+ });
+ });
+
+ describe('nextButton', () => {
+ it('should override nextIconButtonProps', () => {
+ const slotPropsDisabled = false;
+ const nextIconButtonPropsDisabled = true;
+
+ const { getByRole } = render(
+ ,
+ );
+
+ const nextButton = getByRole('button', { name: 'Go to next page' });
+ expect(slotPropsDisabled).not.to.equal(nextIconButtonPropsDisabled);
+ expect(nextButton).to.have.property('disabled', slotPropsDisabled);
+ });
+ });
+ });
+
+ describe('select', () => {
+ it('should override SelectProps', () => {
+ const slotPropsDisabled = false;
+ const SelectPropsDisabled = true;
+
+ const { getByRole } = render(
+ ,
+ );
+
+ const combobox = getByRole('combobox');
+ expect(slotPropsDisabled).not.to.equal(SelectPropsDisabled);
+ expect(combobox.parentElement).not.to.have.class(inputClasses.disabled);
+ });
+ });
+ });
+
describe('duplicated keys', () => {
it('should not raise a warning due to duplicated keys', () => {
render(
diff --git a/packages/mui-material/src/TablePagination/TablePaginationActions.d.ts b/packages/mui-material/src/TablePagination/TablePaginationActions.d.ts
index 843b2fdd5ee61b..d0d555421360e1 100644
--- a/packages/mui-material/src/TablePagination/TablePaginationActions.d.ts
+++ b/packages/mui-material/src/TablePagination/TablePaginationActions.d.ts
@@ -2,12 +2,21 @@ import * as React from 'react';
import { IconButtonProps } from '../IconButton/IconButton';
export interface TablePaginationActionsProps extends React.HTMLAttributes {
+ /**
+ * This prop is an alias for `slotProps.previousButton` and will be overriden by it if both are used.
+ * @deprecated Use `slotProps.previousButton` instead.
+ */
backIconButtonProps?: Partial;
/**
* Override or extend the styles applied to the component.
*/
classes?: {};
count: number;
+ /**
+ * If `true`, the component is disabled.
+ * @default false
+ */
+ disabled?: boolean;
/**
* Accepts a function which returns a string value that provides a user-friendly name for the current page.
* This is important for screen reader users.
@@ -17,12 +26,22 @@ export interface TablePaginationActionsProps extends React.HTMLAttributes string;
+ /**
+ * This prop is an alias for `slotProps.nextButton` and will be overriden by it if both are used.
+ * @deprecated Use `slotProps.nextButton` instead.
+ */
nextIconButtonProps?: Partial;
onPageChange: (event: React.MouseEvent | null, page: number) => void;
page: number;
rowsPerPage: number;
showFirstButton: boolean;
showLastButton: boolean;
+ slotProps?: {
+ firstButton?: Partial;
+ lastButton?: Partial;
+ nextButton?: Partial;
+ previousButton?: Partial;
+ };
}
declare const TablePaginationActions: React.JSXElementConstructor;
diff --git a/packages/mui-material/src/TablePagination/TablePaginationActions.js b/packages/mui-material/src/TablePagination/TablePaginationActions.js
index 9e3e1d61d4249c..6d9ab6cedf1e6b 100644
--- a/packages/mui-material/src/TablePagination/TablePaginationActions.js
+++ b/packages/mui-material/src/TablePagination/TablePaginationActions.js
@@ -15,6 +15,7 @@ const TablePaginationActions = React.forwardRef(function TablePaginationActions(
const {
backIconButtonProps,
count,
+ disabled = false,
getItemAriaLabel,
nextIconButtonProps,
onPageChange,
@@ -22,6 +23,7 @@ const TablePaginationActions = React.forwardRef(function TablePaginationActions(
rowsPerPage,
showFirstButton,
showLastButton,
+ slotProps,
...other
} = props;
@@ -48,39 +50,41 @@ const TablePaginationActions = React.forwardRef(function TablePaginationActions(
{showFirstButton && (
{theme.direction === 'rtl' ? : }
)}
{theme.direction === 'rtl' ? : }
= Math.ceil(count / rowsPerPage) - 1 : false}
+ disabled={disabled || (count !== -1 ? page >= Math.ceil(count / rowsPerPage) - 1 : false)}
color="inherit"
aria-label={getItemAriaLabel('next', page)}
title={getItemAriaLabel('next', page)}
- {...nextIconButtonProps}
+ {...(slotProps?.nextButton ?? nextIconButtonProps)}
>
{theme.direction === 'rtl' ? : }
{showLastButton && (
= Math.ceil(count / rowsPerPage) - 1}
+ disabled={disabled || page >= Math.ceil(count / rowsPerPage) - 1}
aria-label={getItemAriaLabel('last', page)}
title={getItemAriaLabel('last', page)}
+ {...(slotProps?.lastButton ?? {})}
>
{theme.direction === 'rtl' ? : }
@@ -98,6 +102,11 @@ TablePaginationActions.propTypes = {
* The total number of rows.
*/
count: PropTypes.number.isRequired,
+ /**
+ * If `true`, the component is disabled.
+ * @default false
+ */
+ disabled: PropTypes.bool,
/**
* Accepts a function which returns a string value that provides a user-friendly name for the current page.
*
@@ -135,6 +144,16 @@ TablePaginationActions.propTypes = {
* If `true`, show the last-page button.
*/
showLastButton: PropTypes.bool.isRequired,
+ /**
+ * The props used for each slot inside the TablePaginationActions.
+ * @default {}
+ */
+ slotProps: PropTypes.shape({
+ firstButton: PropTypes.object,
+ lastButton: PropTypes.object,
+ nextButton: PropTypes.object,
+ previousButton: PropTypes.object,
+ }),
};
export default TablePaginationActions;