diff --git a/docs/pages/api-docs/table-pagination.json b/docs/pages/api-docs/table-pagination.json index 5351d8ff87bebf..3fcc8860fe1d20 100644 --- a/docs/pages/api-docs/table-pagination.json +++ b/docs/pages/api-docs/table-pagination.json @@ -28,7 +28,8 @@ }, "SelectProps": { "type": { "name": "object" }, "default": "{}" }, "showFirstButton": { "type": { "name": "bool" } }, - "showLastButton": { "type": { "name": "bool" } } + "showLastButton": { "type": { "name": "bool" } }, + "sx": { "type": { "name": "object" } } }, "name": "TablePagination", "styles": { @@ -53,6 +54,6 @@ "filename": "/packages/material-ui/src/TablePagination/TablePagination.js", "inheritance": { "component": "TableCell", "pathname": "/api/table-cell/" }, "demos": "", - "styledComponent": false, + "styledComponent": true, "cssComponent": false } diff --git a/docs/translations/api-docs/table-pagination/table-pagination.json b/docs/translations/api-docs/table-pagination/table-pagination.json index 8e89ce9e1a643a..052666ae29709a 100644 --- a/docs/translations/api-docs/table-pagination/table-pagination.json +++ b/docs/translations/api-docs/table-pagination/table-pagination.json @@ -17,7 +17,8 @@ "rowsPerPageOptions": "Customizes the options of the rows per page select field. If less than two options are available, no select field will be displayed.", "SelectProps": "Props applied to the rows per page Select element.", "showFirstButton": "If true, show the first-page button.", - "showLastButton": "If true, show the last-page button." + "showLastButton": "If true, show the last-page button.", + "sx": "The system prop that allows defining system overrides as well as additional CSS styles. See the `sx` page for more details." }, "classDescriptions": { "root": { "description": "Styles applied to the root element." }, @@ -35,7 +36,7 @@ }, "selectRoot": { "description": "Styles applied to {{nodeName}}.", - "nodeName": "the Select component root element" + "nodeName": "the Select component `root` element" }, "select": { "description": "Styles applied to {{nodeName}}.", @@ -47,7 +48,7 @@ }, "input": { "description": "Styles applied to {{nodeName}}.", - "nodeName": "the InputBase component" + "nodeName": "the Select component `root` element" }, "menuItem": { "description": "Styles applied to {{nodeName}}.", diff --git a/packages/material-ui/src/TablePagination/TablePagination.d.ts b/packages/material-ui/src/TablePagination/TablePagination.d.ts index 20ff5b3695448a..e4560b24274200 100644 --- a/packages/material-ui/src/TablePagination/TablePagination.d.ts +++ b/packages/material-ui/src/TablePagination/TablePagination.d.ts @@ -1,4 +1,6 @@ import * as React from 'react'; +import { SxProps } from '@material-ui/system'; +import { Theme } from '../styles'; import { OverridableComponent, OverrideProps } from '../OverridableComponent'; import { TablePaginationActionsProps } from './TablePaginationActions'; import { TableCellProps } from '../TableCell'; @@ -37,13 +39,13 @@ export interface TablePaginationTypeMap { spacer?: string; /** Styles applied to the select label Typography element. */ selectLabel?: string; - /** Styles applied to the Select component root element. */ + /** Styles applied to the Select component `root` element. */ selectRoot?: string; /** Styles applied to the Select component `select` class. */ select?: string; /** Styles applied to the Select component `icon` class. */ selectIcon?: string; - /** Styles applied to the InputBase component. */ + /** Styles applied to the Select component `root` element. */ input?: string; /** Styles applied to the MenuItem component. */ menuItem?: string; @@ -135,6 +137,10 @@ export interface TablePaginationTypeMap { * @default false */ showLastButton?: boolean; + /** + * The system prop that allows defining system overrides as well as additional CSS styles. + */ + sx?: SxProps; }; defaultComponent: D; } diff --git a/packages/material-ui/src/TablePagination/TablePagination.js b/packages/material-ui/src/TablePagination/TablePagination.js index 89297e961b0192..1cb4c478ddd0cd 100644 --- a/packages/material-ui/src/TablePagination/TablePagination.js +++ b/packages/material-ui/src/TablePagination/TablePagination.js @@ -1,75 +1,138 @@ import * as React from 'react'; import PropTypes from 'prop-types'; -import { chainPropTypes, integerPropType } from '@material-ui/utils'; import clsx from 'clsx'; -import withStyles from '../styles/withStyles'; +import { chainPropTypes, integerPropType } from '@material-ui/utils'; +import { unstable_composeClasses as composeClasses, isHostComponent } from '@material-ui/unstyled'; +import experimentalStyled from '../styles/experimentalStyled'; +import useThemeProps from '../styles/useThemeProps'; import InputBase from '../InputBase'; import MenuItem from '../MenuItem'; import Select from '../Select'; import TableCell from '../TableCell'; import Toolbar from '../Toolbar'; -import Typography from '../Typography'; import TablePaginationActions from './TablePaginationActions'; import useId from '../utils/useId'; +import tablePaginationClasses, { getTablePaginationUtilityClass } from './tablePaginationClasses'; + +const TablePaginationRoot = experimentalStyled( + TableCell, + {}, + { + name: 'MuiTablePagination', + slot: 'Root', + overridesResolver: (props, styles) => styles.root, + }, +)(({ theme }) => ({ + overflow: 'auto', + color: theme.palette.text.primary, + fontSize: theme.typography.pxToRem(14), + // Increase the specificity to override TableCell. + '&:last-child': { + padding: 0, + }, +})); -export const styles = (theme) => ({ - /* Styles applied to the root element. */ - root: { - color: theme.palette.text.primary, - fontSize: theme.typography.pxToRem(14), - overflow: 'auto', - // Increase the specificity to override TableCell. - '&:last-child': { - padding: 0, - }, +const TablePaginationToolbar = experimentalStyled( + Toolbar, + {}, + { + name: 'MuiTablePagination', + slot: 'Toolbar', + overridesResolver: (props, styles) => ({ + [`& .${tablePaginationClasses.actions}`]: styles.actions, + ...styles.toolbar, + }), }, - /* Styles applied to the Toolbar component. */ - toolbar: { +)(({ theme }) => ({ + minHeight: 52, + paddingRight: 2, + [`${theme.breakpoints.up('xs')} and (orientation: landscape)`]: { minHeight: 52, - paddingRight: 2, }, - /* Styles applied to the spacer element. */ - spacer: { - flex: '1 1 100%', + [theme.breakpoints.up('sm')]: { + minHeight: 52, + paddingRight: 2, }, - /* Styles applied to the select label Typography element. */ - selectLabel: { + [`& .${tablePaginationClasses.actions}`]: { flexShrink: 0, + marginLeft: 20, + }, +})); + +const TablePaginationSpacer = experimentalStyled( + 'div', + {}, + { + name: 'MuiTablePagination', + slot: 'Spacer', + overridesResolver: (props, styles) => styles.spacer, }, - // TODO v5: `.selectRoot` should be merged with `.input` - /* Styles applied to the Select component root element. */ - selectRoot: { - marginRight: 32, - marginLeft: 8, +)({ + flex: '1 1 100%', +}); + +const TablePaginationSelectLabel = experimentalStyled( + 'p', + {}, + { + name: 'MuiTablePagination', + slot: 'SelectLabel', + overridesResolver: (props, styles) => styles.selectLabel, + }, +)(({ theme }) => ({ + ...theme.typography.body2, + flexShrink: 0, +})); + +const TablePaginationSelect = experimentalStyled( + Select, + {}, + { + name: 'MuiTablePagination', + slot: 'Select', + overridesResolver: (props, styles) => ({ + [`& .${tablePaginationClasses.selectIcon}`]: styles.selectIcon, + [`& .${tablePaginationClasses.select}`]: styles.select, + ...styles.input, + ...styles.selectRoot, + }), }, - /* Styles applied to the Select component `select` class. */ - select: { +)({ + color: 'inherit', + fontSize: 'inherit', + flexShrink: 0, + marginRight: 32, + marginLeft: 8, + [`& .${tablePaginationClasses.input}`]: { paddingLeft: 8, paddingRight: 24, textAlign: 'right', textAlignLast: 'right', // Align - } + input={} value={rowsPerPage} onChange={onRowsPerPageChange} id={selectId} labelId={labelId} {...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), + // TODO v5 remove `selectIcon` + icon: clsx(classes.selectIcon, (SelectProps.classes || {}).icon), + }} > {rowsPerPageOptions.map((rowsPerPageOption) => ( ))} - + )} - + {labelDisplayedRows({ from: count === 0 ? 0 : page * rowsPerPage + 1, to: getLabelDisplayedRowsTo(), count: count === -1 ? -1 : count, page, })} - + - - + + ); }); @@ -321,6 +420,10 @@ TablePagination.propTypes /* remove-proptypes */ = { * @default false */ showLastButton: PropTypes.bool, + /** + * The system prop that allows defining system overrides as well as additional CSS styles. + */ + sx: PropTypes.object, }; -export default withStyles(styles, { name: 'MuiTablePagination' })(TablePagination); +export default TablePagination; diff --git a/packages/material-ui/src/TablePagination/TablePagination.test.js b/packages/material-ui/src/TablePagination/TablePagination.test.js index 910c5bddb990df..66358d789ec7c3 100644 --- a/packages/material-ui/src/TablePagination/TablePagination.test.js +++ b/packages/material-ui/src/TablePagination/TablePagination.test.js @@ -2,35 +2,34 @@ import * as React from 'react'; import { expect } from 'chai'; import { spy } from 'sinon'; import PropTypes from 'prop-types'; -import { - getClasses, - createMount, - describeConformance, - fireEvent, - createClientRender, -} from 'test/utils'; +import { createMount, describeConformanceV5, fireEvent, createClientRender } from 'test/utils'; import TableFooter from '@material-ui/core/TableFooter'; import TableCell from '@material-ui/core/TableCell'; import TableRow from '@material-ui/core/TableRow'; -import TablePagination from '@material-ui/core/TablePagination'; +import TablePagination, { + tablePaginationClasses as classes, +} from '@material-ui/core/TablePagination'; describe('', () => { const noop = () => {}; - let classes; const mount = createMount(); const render = createClientRender(); - before(() => { - classes = getClasses( - , - ); - }); - - describeConformance( + describeConformanceV5( , () => ({ classes, inheritComponent: TableCell, + render: (node) => { + const { container, ...other } = render( + + + {node} + +
, + ); + return { container: container.firstChild.firstChild.firstChild, ...other }; + }, mount: (node) => { const wrapper = mount( @@ -41,10 +40,12 @@ describe('', () => { ); return wrapper.find('tr').childAt(0); }, - + muiName: 'MuiTablePagination', refInstanceof: window.HTMLTableCellElement, - // can only use `td` in a tr so we just fake a different component - testComponentPropWith: (props) =>
, + testComponentPropWith: 'td', + testComponentsRootPropWith: 'td', + testDeepOverrides: { slotName: 'toolbar', slotClassName: classes.toolbar }, + skip: ['themeVariants', 'componentsProps'], }), ); @@ -360,7 +361,7 @@ describe('', () => { it('should raise a warning if the page prop is out of range', () => { expect(() => { PropTypes.checkPropTypes( - TablePagination.Naked.propTypes, + TablePagination.propTypes, { classes: {}, page: 2, diff --git a/packages/material-ui/src/TablePagination/index.d.ts b/packages/material-ui/src/TablePagination/index.d.ts index 317abad03391f0..2df08ab13db13f 100644 --- a/packages/material-ui/src/TablePagination/index.d.ts +++ b/packages/material-ui/src/TablePagination/index.d.ts @@ -1,2 +1,5 @@ export { default } from './TablePagination'; export * from './TablePagination'; + +export { default as tablePaginationClasses } from './tablePaginationClasses'; +export * from './tablePaginationClasses'; diff --git a/packages/material-ui/src/TablePagination/index.js b/packages/material-ui/src/TablePagination/index.js index 9bb978387b1b36..a331f1abcf6e48 100644 --- a/packages/material-ui/src/TablePagination/index.js +++ b/packages/material-ui/src/TablePagination/index.js @@ -1 +1,4 @@ export { default } from './TablePagination'; + +export { default as tablePaginationClasses } from './tablePaginationClasses'; +export * from './tablePaginationClasses'; diff --git a/packages/material-ui/src/TablePagination/tablePaginationClasses.d.ts b/packages/material-ui/src/TablePagination/tablePaginationClasses.d.ts new file mode 100644 index 00000000000000..bf9438c53585ed --- /dev/null +++ b/packages/material-ui/src/TablePagination/tablePaginationClasses.d.ts @@ -0,0 +1,9 @@ +import { TablePaginationClassKey } from './TablePagination'; + +export type TablePaginationClasses = Record; + +declare const tablePaginationClasses: TablePaginationClasses; + +export function getTablePaginationUtilityClass(slot: string): string; + +export default tablePaginationClasses; diff --git a/packages/material-ui/src/TablePagination/tablePaginationClasses.js b/packages/material-ui/src/TablePagination/tablePaginationClasses.js new file mode 100644 index 00000000000000..a5df1bd63abcf7 --- /dev/null +++ b/packages/material-ui/src/TablePagination/tablePaginationClasses.js @@ -0,0 +1,21 @@ +import { generateUtilityClass, generateUtilityClasses } from '@material-ui/unstyled'; + +export function getTablePaginationUtilityClass(slot) { + return generateUtilityClass('MuiTablePagination', slot); +} + +const tablePaginationClasses = generateUtilityClasses('MuiTablePagination', [ + 'root', + 'toolbar', + 'spacer', + 'selectLabel', + 'selectRoot', + 'select', + 'selectIcon', + 'input', + 'menuItem', + 'displayedRows', + 'actions', +]); + +export default tablePaginationClasses;