Skip to content

Commit ae3c251

Browse files
[Table] Add React node support to TablePagination.labelRowsPerPage (#21226)
1 parent 4da1c06 commit ae3c251

File tree

4 files changed

+52
-10
lines changed

4 files changed

+52
-10
lines changed

docs/pages/api-docs/table-pagination.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ The `MuiTablePagination` name can be used for providing [default props](/customi
3535
| <span class="prop-name">component</span> | <span class="prop-type">elementType</span> | <span class="prop-default">TableCell</span> | The component used for the root node. Either a string to use a HTML element or a component. |
3636
| <span class="prop-name required">count&nbsp;*</span> | <span class="prop-type">number</span> | | The total number of rows.<br>To enable server side pagination for an unknown number of items, provide -1. |
3737
| <span class="prop-name">labelDisplayedRows</span> | <span class="prop-type">func</span> | <span class="prop-default">({ from, to, count }) =>`${from}-${to} of ${count !== -1 ? count : `more than ${to}`}`</span> | Customize the displayed rows label. Invoked with a `{ from, to, count, page }` object.<br>For localization purposes, you can use the provided [translations](/guides/localization/). |
38-
| <span class="prop-name">labelRowsPerPage</span> | <span class="prop-type">string</span> | <span class="prop-default">'Rows per page:'</span> | Customize the rows per page label.<br>For localization purposes, you can use the provided [translations](/guides/localization/). |
38+
| <span class="prop-name">labelRowsPerPage</span> | <span class="prop-type">node</span> | <span class="prop-default">'Rows per page:'</span> | Customize the rows per page label.<br>For localization purposes, you can use the provided [translations](/guides/localization/). |
3939
| <span class="prop-name">nextIconButtonProps</span> | <span class="prop-type">object</span> | | Props applied to the next arrow [`IconButton`](/api/icon-button/) element. |
4040
| <span class="prop-name">nextIconButtonText</span> | <span class="prop-type">string</span> | <span class="prop-default">'Next page'</span> | Text label for the next arrow icon button.<br>For localization purposes, you can use the provided [translations](/guides/localization/). |
4141
| <span class="prop-name required">onChangePage&nbsp;*</span> | <span class="prop-type">func</span> | | Callback fired when the page is changed.<br><br>**Signature:**<br>`function(event: object, page: number) => void`<br>*event:* The event source of the callback.<br>*page:* The page selected. |

packages/material-ui/src/TablePagination/TablePagination.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export interface TablePaginationTypeMap<P, D extends React.ElementType> {
2121
backIconButtonProps?: Partial<IconButtonProps>;
2222
count: number;
2323
labelDisplayedRows?: (paginationInfo: LabelDisplayedRowsArgs) => React.ReactNode;
24-
labelRowsPerPage?: string;
24+
labelRowsPerPage?: React.ReactNode;
2525
nextIconButtonProps?: Partial<IconButtonProps>;
2626
nextIconButtonText?: string;
2727
onChangePage: (event: React.MouseEvent<HTMLButtonElement> | null, page: number) => void;

packages/material-ui/src/TablePagination/TablePagination.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import TableCell from '../TableCell';
1010
import Toolbar from '../Toolbar';
1111
import Typography from '../Typography';
1212
import TablePaginationActions from './TablePaginationActions';
13+
import useId from '../utils/unstable_useId';
1314

1415
export const styles = (theme) => ({
1516
/* Styles applied to the root element. */
@@ -101,14 +102,16 @@ const TablePagination = React.forwardRef(function TablePagination(props, ref) {
101102
colSpan = colSpanProp || 1000; // col-span over everything
102103
}
103104

105+
const selectId = useId();
106+
const labelId = useId();
104107
const MenuItemComponent = SelectProps.native ? 'option' : MenuItem;
105108

106109
return (
107110
<Component className={clsx(classes.root, className)} colSpan={colSpan} ref={ref} {...other}>
108111
<Toolbar className={classes.toolbar}>
109112
<div className={classes.spacer} />
110113
{rowsPerPageOptions.length > 1 && (
111-
<Typography color="inherit" variant="body2" className={classes.caption}>
114+
<Typography color="inherit" variant="body2" className={classes.caption} id={labelId}>
112115
{labelRowsPerPage}
113116
</Typography>
114117
)}
@@ -121,7 +124,8 @@ const TablePagination = React.forwardRef(function TablePagination(props, ref) {
121124
input={<InputBase className={clsx(classes.input, classes.selectRoot)} />}
122125
value={rowsPerPage}
123126
onChange={onChangeRowsPerPage}
124-
inputProps={{ 'aria-label': labelRowsPerPage }}
127+
id={selectId}
128+
labelId={labelId}
125129
{...SelectProps}
126130
>
127131
{rowsPerPageOptions.map((rowsPerPageOption) => (
@@ -217,7 +221,7 @@ TablePagination.propTypes = {
217221
*
218222
* For localization purposes, you can use the provided [translations](/guides/localization/).
219223
*/
220-
labelRowsPerPage: PropTypes.string,
224+
labelRowsPerPage: PropTypes.node,
221225
/**
222226
* Props applied to the next arrow [`IconButton`](/api/icon-button/) element.
223227
*/

packages/material-ui/src/TablePagination/TablePagination.test.js

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe('<TablePagination />', () => {
4545
}),
4646
);
4747

48-
describe('render', () => {
48+
describe('prop: labelDisplayedRows', () => {
4949
it('should use the labelDisplayedRows callback', () => {
5050
let labelDisplayedRowsCalled = false;
5151
function labelDisplayedRows({ from, to, count, page }) {
@@ -76,9 +76,11 @@ describe('<TablePagination />', () => {
7676
expect(labelDisplayedRowsCalled).to.equal(true);
7777
expect(container.innerHTML.includes('Page 1')).to.equal(true);
7878
});
79+
});
7980

80-
it('should use labelRowsPerPage', () => {
81-
const { container } = render(
81+
describe('prop: labelRowsPerPage', () => {
82+
it('labels the select for the current page', () => {
83+
const { getAllByRole } = render(
8284
<table>
8385
<TableFooter>
8486
<TableRow>
@@ -88,15 +90,47 @@ describe('<TablePagination />', () => {
8890
onChangePage={noop}
8991
onChangeRowsPerPage={noop}
9092
rowsPerPage={10}
91-
labelRowsPerPage="Zeilen pro Seite:"
93+
labelRowsPerPage="lines per page:"
9294
/>
9395
</TableRow>
9496
</TableFooter>
9597
</table>,
9698
);
97-
expect(container.innerHTML.includes('Zeilen pro Seite:')).to.equal(true);
99+
100+
// will be `getByRole('combobox')` in aria 1.2
101+
const [combobox] = getAllByRole('button');
102+
expect(combobox).toHaveAccessibleName('lines per page: 10');
98103
});
99104

105+
it('accepts React nodes', () => {
106+
const { getAllByRole } = render(
107+
<table>
108+
<TableFooter>
109+
<TableRow>
110+
<TablePagination
111+
count={1}
112+
page={0}
113+
onChangePage={noop}
114+
onChangeRowsPerPage={noop}
115+
rowsPerPage={10}
116+
labelRowsPerPage={
117+
<React.Fragment>
118+
<em>lines</em> per page:
119+
</React.Fragment>
120+
}
121+
/>
122+
</TableRow>
123+
</TableFooter>
124+
</table>,
125+
);
126+
127+
// will be `getByRole('combobox')` in aria 1.2
128+
const [combobox] = getAllByRole('button');
129+
expect(combobox).toHaveAccessibleName('lines per page: 10');
130+
});
131+
});
132+
133+
describe('prop: page', () => {
100134
it('should disable the back button on the first page', () => {
101135
const { getByRole } = render(
102136
<table>
@@ -141,7 +175,9 @@ describe('<TablePagination />', () => {
141175
expect(backButton).to.have.property('disabled', false);
142176
expect(nextButton).to.have.property('disabled', true);
143177
});
178+
});
144179

180+
describe('prop: onChangePage', () => {
145181
it('should handle next button clicks properly', () => {
146182
let page = 1;
147183
const { getByRole } = render(
@@ -191,7 +227,9 @@ describe('<TablePagination />', () => {
191227
fireEvent.click(backButton);
192228
expect(page).to.equal(0);
193229
});
230+
});
194231

232+
describe('label', () => {
195233
it('should display 0 as start number if the table is empty ', () => {
196234
const { container } = render(
197235
<table>

0 commit comments

Comments
 (0)