From b12ac64d74ab60b8688e0402a1e3d26a7e09a3ce Mon Sep 17 00:00:00 2001 From: leMaik Date: Sat, 16 Feb 2019 22:12:05 +0100 Subject: [PATCH] [Table] Add dense support --- .../CustomPaginationActionsTable.hooks.js | 4 +- docs/src/pages/demos/tables/DenseTable.js | 79 +++++++++ .../pages/demos/tables/EnhancedTable.hooks.js | 152 ++++++++++-------- docs/src/pages/demos/tables/EnhancedTable.js | 152 ++++++++++-------- .../demos/tables/ReactVirtualizedTable.js | 21 +-- docs/src/pages/demos/tables/SimpleTable.js | 2 +- docs/src/pages/demos/tables/tables.md | 6 + packages/material-ui/src/Table/Table.d.ts | 5 +- packages/material-ui/src/Table/Table.js | 52 +++--- packages/material-ui/src/Table/Table.test.js | 2 +- .../material-ui/src/Table/TableContext.d.ts | 3 +- .../material-ui/src/TableBody/TableBody.js | 6 +- .../material-ui/src/TableCell/TableCell.d.ts | 5 +- .../material-ui/src/TableCell/TableCell.js | 148 ++++++++--------- .../src/TableCell/TableCell.test.js | 6 +- .../src/TableFooter/TableFooter.js | 6 +- .../material-ui/src/TableHead/TableHead.js | 6 +- packages/material-ui/src/TableRow/TableRow.js | 52 +++--- pages/api/table-cell.md | 7 +- pages/api/table-row.md | 4 +- pages/api/table.md | 3 +- .../tests/Table/DenseCheckboxTable.js | 86 ++++++++++ test/regressions/tests/Table/PaddingTable.js | 62 ------- 23 files changed, 500 insertions(+), 369 deletions(-) create mode 100644 docs/src/pages/demos/tables/DenseTable.js create mode 100644 test/regressions/tests/Table/DenseCheckboxTable.js delete mode 100644 test/regressions/tests/Table/PaddingTable.js diff --git a/docs/src/pages/demos/tables/CustomPaginationActionsTable.hooks.js b/docs/src/pages/demos/tables/CustomPaginationActionsTable.hooks.js index 025e9efd6a0a8e..1c6e13a0b71289 100644 --- a/docs/src/pages/demos/tables/CustomPaginationActionsTable.hooks.js +++ b/docs/src/pages/demos/tables/CustomPaginationActionsTable.hooks.js @@ -141,8 +141,8 @@ function CustomPaginationActionsTable() { {row.name} - {row.calories} - {row.fat} + {row.calories} + {row.fat} ))} {emptyRows > 0 && ( diff --git a/docs/src/pages/demos/tables/DenseTable.js b/docs/src/pages/demos/tables/DenseTable.js new file mode 100644 index 00000000000000..fde876e598eca7 --- /dev/null +++ b/docs/src/pages/demos/tables/DenseTable.js @@ -0,0 +1,79 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import Table from '@material-ui/core/Table'; +import TableBody from '@material-ui/core/TableBody'; +import TableCell from '@material-ui/core/TableCell'; +import TableHead from '@material-ui/core/TableHead'; +import TableRow from '@material-ui/core/TableRow'; +import Paper from '@material-ui/core/Paper'; + +const styles = theme => ({ + root: { + width: '100%', + }, + paper: { + marginTop: theme.spacing(3), + width: '100%', + overflowX: 'auto', + marginBottom: theme.spacing(2), + }, + table: { + minWidth: 650, + }, +}); + +let id = 0; +function createData(name, calories, fat, carbs, protein) { + id += 1; + return { id, name, calories, fat, carbs, protein }; +} + +const rows = [ + createData('Frozen yoghurt', 159, 6.0, 24, 4.0), + createData('Ice cream sandwich', 237, 9.0, 37, 4.3), + createData('Eclair', 262, 16.0, 24, 6.0), + createData('Cupcake', 305, 3.7, 67, 4.3), + createData('Gingerbread', 356, 16.0, 49, 3.9), +]; + +function DenseTable(props) { + const { classes } = props; + + return ( +
+ + + + + Dessert (100g serving) + Calories + Fat (g) + Carbs (g) + Protein (g) + + + + {rows.map(row => ( + + + {row.name} + + {row.calories} + {row.fat} + {row.carbs} + {row.protein} + + ))} + +
+
+
+ ); +} + +DenseTable.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(DenseTable); diff --git a/docs/src/pages/demos/tables/EnhancedTable.hooks.js b/docs/src/pages/demos/tables/EnhancedTable.hooks.js index aafbd75fdeea19..04d946311748c6 100644 --- a/docs/src/pages/demos/tables/EnhancedTable.hooks.js +++ b/docs/src/pages/demos/tables/EnhancedTable.hooks.js @@ -15,6 +15,8 @@ import Paper from '@material-ui/core/Paper'; import Checkbox from '@material-ui/core/Checkbox'; import IconButton from '@material-ui/core/IconButton'; import Tooltip from '@material-ui/core/Tooltip'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import Switch from '@material-ui/core/Switch'; import DeleteIcon from '@material-ui/icons/Delete'; import FilterListIcon from '@material-ui/icons/FilterList'; import { lighten } from '@material-ui/core/styles/colorManipulator'; @@ -77,7 +79,7 @@ function EnhancedTableHead(props) { row => ( @@ -108,6 +110,7 @@ EnhancedTableHead.propTypes = { const useToolbarStyles = makeStyles(theme => ({ root: { + paddingLeft: theme.spacing(2), paddingRight: theme.spacing(1), }, highlight: @@ -181,8 +184,12 @@ const useStyles = makeStyles(theme => ({ width: '100%', marginTop: theme.spacing(3), }, + paper: { + width: '100%', + marginBottom: theme.spacing(2), + }, table: { - minWidth: 1020, + minWidth: 750, }, tableWrapper: { overflowX: 'auto', @@ -210,6 +217,7 @@ function EnhancedTable() { createData('Oreo', 437, 18.0, 63, 4.0), ]); const [page, setPage] = React.useState(0); + const [dense, setDense] = React.useState(false); const [rowsPerPage, setRowsPerPage] = React.useState(5); function handleRequestSort(event, property) { @@ -255,75 +263,89 @@ function EnhancedTable() { setRowsPerPage(event.target.value); } + function handleChangeDense(event) { + setDense(event.target.checked); + } + const isSelected = id => selected.indexOf(id) !== -1; const emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - page * rowsPerPage); return ( - - -
- - - - {stableSort(data, getSorting(order, orderBy)) - .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) - .map(n => { - const isItemSelected = isSelected(n.id); - return ( - handleClick(event, n.id)} - role="checkbox" - aria-checked={isItemSelected} - tabIndex={-1} - key={n.id} - selected={isItemSelected} - > - - - - - {n.name} - - {n.calories} - {n.fat} - {n.carbs} - {n.protein} - - ); - })} - {emptyRows > 0 && ( - - - - )} - -
-
- + + +
+ + + + {stableSort(data, getSorting(order, orderBy)) + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map(n => { + const isItemSelected = isSelected(n.id); + return ( + handleClick(event, n.id)} + role="checkbox" + aria-checked={isItemSelected} + tabIndex={-1} + key={n.id} + selected={isItemSelected} + > + + + + + {n.name} + + {n.calories} + {n.fat} + {n.carbs} + {n.protein} + + ); + })} + {emptyRows > 0 && ( + + + + )} + +
+
+ +
+ } + label="Dense padding" /> -
+ ); } diff --git a/docs/src/pages/demos/tables/EnhancedTable.js b/docs/src/pages/demos/tables/EnhancedTable.js index 043cd3e49ff70d..2cccc9526907d9 100644 --- a/docs/src/pages/demos/tables/EnhancedTable.js +++ b/docs/src/pages/demos/tables/EnhancedTable.js @@ -15,6 +15,8 @@ import Paper from '@material-ui/core/Paper'; import Checkbox from '@material-ui/core/Checkbox'; import IconButton from '@material-ui/core/IconButton'; import Tooltip from '@material-ui/core/Tooltip'; +import FormControlLabel from '@material-ui/core/FormControlLabel'; +import Switch from '@material-ui/core/Switch'; import DeleteIcon from '@material-ui/icons/Delete'; import FilterListIcon from '@material-ui/icons/FilterList'; import { lighten } from '@material-ui/core/styles/colorManipulator'; @@ -111,6 +113,7 @@ EnhancedTableHead.propTypes = { const toolbarStyles = theme => ({ root: { + paddingLeft: theme.spacing(2), paddingRight: theme.spacing(1), }, highlight: @@ -186,8 +189,12 @@ const styles = theme => ({ width: '100%', marginTop: theme.spacing(3), }, + paper: { + width: '100%', + marginBottom: theme.spacing(2), + }, table: { - minWidth: 1020, + minWidth: 750, }, tableWrapper: { overflowX: 'auto', @@ -214,6 +221,7 @@ class EnhancedTable extends React.Component { createData('Nougat', 360, 19.0, 9, 37.0), createData('Oreo', 437, 18.0, 63, 4.0), ], + dense: false, page: 0, rowsPerPage: 5, }; @@ -266,78 +274,92 @@ class EnhancedTable extends React.Component { this.setState({ rowsPerPage: event.target.value }); }; + handleChangeDense = event => { + this.setState({ dense: event.target.checked }); + }; + isSelected = id => this.state.selected.indexOf(id) !== -1; render() { const { classes } = this.props; - const { data, order, orderBy, selected, rowsPerPage, page } = this.state; + const { data, order, orderBy, selected, rowsPerPage, dense, page } = this.state; const emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - page * rowsPerPage); return ( - - -
- - - - {stableSort(data, getSorting(order, orderBy)) - .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) - .map(n => { - const isSelected = this.isSelected(n.id); - return ( - this.handleClick(event, n.id)} - role="checkbox" - aria-checked={isSelected} - tabIndex={-1} - key={n.id} - selected={isSelected} - > - - - - - {n.name} - - {n.calories} - {n.fat} - {n.carbs} - {n.protein} - - ); - })} - {emptyRows > 0 && ( - - - - )} - -
-
- + + +
+ + + + {stableSort(data, getSorting(order, orderBy)) + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map(n => { + const isSelected = this.isSelected(n.id); + return ( + this.handleClick(event, n.id)} + role="checkbox" + aria-checked={isSelected} + tabIndex={-1} + key={n.id} + selected={isSelected} + > + + + + + {n.name} + + {n.calories} + {n.fat} + {n.carbs} + {n.protein} + + ); + })} + {emptyRows > 0 && ( + + + + )} + +
+
+ +
+ } + label="Dense padding" /> -
+ ); } } diff --git a/docs/src/pages/demos/tables/ReactVirtualizedTable.js b/docs/src/pages/demos/tables/ReactVirtualizedTable.js index 20648dabab9522..61e947915f0096 100644 --- a/docs/src/pages/demos/tables/ReactVirtualizedTable.js +++ b/docs/src/pages/demos/tables/ReactVirtualizedTable.js @@ -10,9 +10,6 @@ import Paper from '@material-ui/core/Paper'; import { AutoSizer, Column, SortDirection, Table } from 'react-virtualized'; const styles = theme => ({ - table: { - fontFamily: theme.typography.fontFamily, - }, flexContainer: { display: 'flex', alignItems: 'center', @@ -94,13 +91,7 @@ class MuiVirtualizedTable extends React.PureComponent { return ( {({ height, width }) => ( - +
{columns.map(({ cellContentRenderer = null, className, dataKey, ...other }, index) => { let renderer; if (cellContentRenderer != null) { @@ -153,11 +144,13 @@ MuiVirtualizedTable.propTypes = { }; MuiVirtualizedTable.defaultProps = { - headerHeight: 56, - rowHeight: 56, + headerHeight: 48, + rowHeight: 48, }; -const WrappedVirtualizedTable = withStyles(styles)(MuiVirtualizedTable); +const VirtualizedTable = withStyles(styles)(MuiVirtualizedTable); + +// --- const data = [ ['Frozen yoghurt', 159, 6.0, 24, 4.0], @@ -183,7 +176,7 @@ for (let i = 0; i < 200; i += 1) { function ReactVirtualizedTable() { return ( - rows[index]} onRowClick={event => console.log(event)} diff --git a/docs/src/pages/demos/tables/SimpleTable.js b/docs/src/pages/demos/tables/SimpleTable.js index ebe5eb41d42055..be9598b8265f32 100644 --- a/docs/src/pages/demos/tables/SimpleTable.js +++ b/docs/src/pages/demos/tables/SimpleTable.js @@ -15,7 +15,7 @@ const styles = theme => ({ overflowX: 'auto', }, table: { - minWidth: 700, + minWidth: 650, }, }); diff --git a/docs/src/pages/demos/tables/tables.md b/docs/src/pages/demos/tables/tables.md index e23fe7142619dc..2ef6cfdcb164fe 100644 --- a/docs/src/pages/demos/tables/tables.md +++ b/docs/src/pages/demos/tables/tables.md @@ -31,6 +31,12 @@ A simple example with no frills. {{"demo": "pages/demos/tables/SimpleTable.js"}} +## Dense Table + +A simple example of a dense table with no frills. + +{{"demo": "pages/demos/tables/DenseTable.js"}} + ## Sorting & Selecting This example demonstrates the use of `Checkbox` and clickable rows for selection, with a custom `Toolbar`. It uses the `TableSortLabel` component to help style column headings. diff --git a/packages/material-ui/src/Table/Table.d.ts b/packages/material-ui/src/Table/Table.d.ts index 498f13d2578486..5d2714df3d1b20 100644 --- a/packages/material-ui/src/Table/Table.d.ts +++ b/packages/material-ui/src/Table/Table.d.ts @@ -4,11 +4,14 @@ import { StandardProps } from '..'; export interface TableProps extends StandardProps { component?: React.ReactType; padding?: Padding; + size?: Size; } export type TableBaseProps = React.TableHTMLAttributes; -export type Padding = 'default' | 'checkbox' | 'dense' | 'none'; +export type Padding = 'default' | 'checkbox' | 'none'; + +export type Size = 'small' | 'medium'; export type TableClassKey = 'root'; diff --git a/packages/material-ui/src/Table/Table.js b/packages/material-ui/src/Table/Table.js index 92c75f61cf3275..81d260355393c8 100644 --- a/packages/material-ui/src/Table/Table.js +++ b/packages/material-ui/src/Table/Table.js @@ -2,49 +2,28 @@ import React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; import withStyles from '../styles/withStyles'; -import withForwardedRef from '../utils/withForwardedRef'; import TableContext from './TableContext'; -export const styles = theme => ({ +export const styles = { /* Styles applied to the root element. */ root: { display: 'table', - fontFamily: theme.typography.fontFamily, width: '100%', borderCollapse: 'collapse', borderSpacing: 0, }, -}); - -class Table extends React.Component { - memoizedContextValue = {}; - - // To replace with the corresponding Hook once Material-UI v4 is out: - // https://reactjs.org/docs/hooks-reference.html#usememo - useMemo(contextValue) { - const objectKeys = Object.keys(contextValue); - - for (let i = 0; i < objectKeys.length; i += 1) { - const objectKey = objectKeys[i]; - - if (contextValue[objectKey] !== this.memoizedContextValue[objectKey]) { - this.memoizedContextValue = contextValue; - break; - } - } - return this.memoizedContextValue; - } +}; - render() { - const { classes, className, component: Component, innerRef, padding, ...other } = this.props; +const Table = React.forwardRef(function Table(props, ref) { + const { classes, className, component: Component, padding, size, ...other } = props; + const table = React.useMemo(() => ({ padding, size }), [padding, size]); - return ( - - - - ); - } -} + return ( + + + + ); +}); Table.propTypes = { /** @@ -73,12 +52,17 @@ Table.propTypes = { /** * Allows TableCells to inherit padding of the Table. */ - padding: PropTypes.oneOf(['default', 'checkbox', 'dense', 'none']), + padding: PropTypes.oneOf(['default', 'checkbox', 'none']), + /** + * Allows TableCells to inherit size of the Table. + */ + size: PropTypes.oneOf(['small', 'medium']), }; Table.defaultProps = { component: 'table', padding: 'default', + size: 'medium', }; -export default withStyles(styles, { name: 'MuiTable' })(withForwardedRef(Table)); +export default withStyles(styles, { name: 'MuiTable' })(Table); diff --git a/packages/material-ui/src/Table/Table.test.js b/packages/material-ui/src/Table/Table.test.js index d4ab8702e757bd..802ecf1c01a090 100644 --- a/packages/material-ui/src/Table/Table.test.js +++ b/packages/material-ui/src/Table/Table.test.js @@ -64,7 +64,6 @@ describe('
', () => { {value => { context = value; - return ; }} @@ -72,6 +71,7 @@ describe('
', () => { ); assert.deepStrictEqual(context, { + size: 'medium', padding: 'default', }); }); diff --git a/packages/material-ui/src/Table/TableContext.d.ts b/packages/material-ui/src/Table/TableContext.d.ts index d45ab3a96f01b6..7827b83fb7c8a5 100644 --- a/packages/material-ui/src/Table/TableContext.d.ts +++ b/packages/material-ui/src/Table/TableContext.d.ts @@ -1,8 +1,9 @@ import { Context } from 'react'; -import { Padding } from './Table'; +import { Padding, Size } from './Table'; interface TableContextProps { padding: Padding; + size: Size; } declare const TableContext: Context; diff --git a/packages/material-ui/src/TableBody/TableBody.js b/packages/material-ui/src/TableBody/TableBody.js index cc066c2bd005df..fb4f6c7102c2c8 100644 --- a/packages/material-ui/src/TableBody/TableBody.js +++ b/packages/material-ui/src/TableBody/TableBody.js @@ -11,13 +11,15 @@ export const styles = { }, }; -const contextValue = { variant: 'body' }; +const tablelvl2 = { + variant: 'body', +}; const TableBody = React.forwardRef(function TableBody(props, ref) { const { classes, className, component: Component, ...other } = props; return ( - + ); diff --git a/packages/material-ui/src/TableCell/TableCell.d.ts b/packages/material-ui/src/TableCell/TableCell.d.ts index 3b3797a01e6f7d..e74b19b449c952 100644 --- a/packages/material-ui/src/TableCell/TableCell.d.ts +++ b/packages/material-ui/src/TableCell/TableCell.d.ts @@ -15,6 +15,7 @@ export interface TableCellProps component?: React.ReactType; numeric?: boolean; padding?: Padding; + size?: Size; sortDirection?: SortDirection; variant?: 'head' | 'body' | 'footer'; } @@ -22,7 +23,9 @@ export interface TableCellProps export type TableCellBaseProps = React.ThHTMLAttributes & React.TdHTMLAttributes; -export type Padding = 'default' | 'checkbox' | 'dense' | 'none'; +export type Padding = 'normal' | 'checkbox' | 'none'; + +export type Size = 'small' | 'medium'; export type SortDirection = 'asc' | 'desc' | false; diff --git a/packages/material-ui/src/TableCell/TableCell.js b/packages/material-ui/src/TableCell/TableCell.js index 797701d6ad6295..0b5480e8d876bf 100644 --- a/packages/material-ui/src/TableCell/TableCell.js +++ b/packages/material-ui/src/TableCell/TableCell.js @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import withStyles from '../styles/withStyles'; import { capitalize } from '../utils/helpers'; -import deprecatedPropType from '../utils/deprecatedPropType'; import { darken, fade, lighten } from '../styles/colorManipulator'; import TableContext from '../Table/TableContext'; import Tablelvl2Context from '../Table/Tablelvl2Context'; @@ -11,6 +10,7 @@ import Tablelvl2Context from '../Table/Tablelvl2Context'; export const styles = theme => ({ /* Styles applied to the root element. */ root: { + ...theme.typography.body2, display: 'table-cell', verticalAlign: 'inherit', // Workaround for a rendering bug with spanned columns in Chrome 62.0. @@ -22,43 +22,54 @@ export const styles = theme => ({ : darken(fade(theme.palette.divider, 1), 0.68) }`, textAlign: 'left', - padding: '4px 56px 4px 24px', + padding: '13px 40px 13px 16px', '&:last-child': { - paddingRight: 24, + paddingRight: 16, }, }, /* Styles applied to the root element if `variant="head"` or `context.table.head`. */ head: { color: theme.palette.text.secondary, fontSize: theme.typography.pxToRem(12), + lineHeight: theme.typography.pxToRem(21), fontWeight: theme.typography.fontWeightMedium, }, /* Styles applied to the root element if `variant="body"` or `context.table.body`. */ body: { color: theme.palette.text.primary, - fontSize: theme.typography.pxToRem(13), fontWeight: theme.typography.fontWeightRegular, }, /* Styles applied to the root element if `variant="footer"` or `context.table.footer`. */ footer: { - borderBottom: 0, color: theme.palette.text.secondary, + lineHeight: theme.typography.pxToRem(21), fontSize: theme.typography.pxToRem(12), }, - /* Styles applied to the root element if `numeric={true}`. */ - numeric: { - textAlign: 'right', - flexDirection: 'row-reverse', // can be dynamically inherited at runtime by contents - }, /* Styles applied to the root element if `padding="dense"`. */ - paddingDense: { - paddingRight: 24, + sizeSmall: { + padding: '5px 24px 5px 16px', + '&:last-child': { + paddingRight: 16, + }, + '&$paddingCheckbox': { + width: 24, // prevent the checkbox column from growing + padding: '0px 12px 0 16px', + '&:last-child': { + paddingLeft: 12, + paddingRight: 16, + }, + '& > *': { + padding: 0, + }, + }, }, /* Styles applied to the root element if `padding="checkbox"`. */ paddingCheckbox: { - padding: '0 12px', + width: 48, // prevent the checkbox column from growing + padding: '0 0 0 4px', '&:last-child': { - paddingRight: 12, + paddingLeft: 0, + paddingRight: 4, }, }, /* Styles applied to the root element if `padding="none"`. */ @@ -92,73 +103,61 @@ const TableCell = React.forwardRef(function TableCell(props, ref) { align, children, classes, - className: classNameProp, + className, component, - sortDirection, - numeric = false, padding: paddingProp, scope: scopeProp, + size: sizeProp, + sortDirection, variant, ...other } = props; - return ( - - {table => ( - - {tablelvl2 => { - let Component; - if (component) { - Component = component; - } else { - Component = tablelvl2 && tablelvl2.variant === 'head' ? 'th' : 'td'; - } + const table = React.useContext(TableContext); + const tablelvl2 = React.useContext(Tablelvl2Context); - let scope = scopeProp; - if (!scope && tablelvl2 && tablelvl2.variant === 'head') { - scope = 'col'; - } - const padding = paddingProp || (table && table.padding ? table.padding : 'default'); + let Component; + if (component) { + Component = component; + } else { + Component = tablelvl2 && tablelvl2.variant === 'head' ? 'th' : 'td'; + } - const className = clsx( - classes.root, - { - [classes.head]: variant - ? variant === 'head' - : tablelvl2 && tablelvl2.variant === 'head', - [classes.body]: variant - ? variant === 'body' - : tablelvl2 && tablelvl2.variant === 'body', - [classes.footer]: variant - ? variant === 'footer' - : tablelvl2 && tablelvl2.variant === 'footer', - [classes[`align${capitalize(align)}`]]: align !== 'inherit', - [classes.numeric]: numeric, - [classes[`padding${capitalize(padding)}`]]: padding !== 'default', - }, - classNameProp, - ); + let scope = scopeProp; + if (!scope && tablelvl2 && tablelvl2.variant === 'head') { + scope = 'col'; + } + const padding = paddingProp || (table && table.padding ? table.padding : 'default'); + const size = sizeProp || (table && table.size ? table.size : 'medium'); - let ariaSort = null; - if (sortDirection) { - ariaSort = sortDirection === 'asc' ? 'ascending' : 'descending'; - } + let ariaSort = null; + if (sortDirection) { + ariaSort = sortDirection === 'asc' ? 'ascending' : 'descending'; + } - return ( - - {children} - - ); - }} - + return ( + + aria-sort={ariaSort} + scope={scope} + {...other} + > + {children} + ); }); @@ -188,19 +187,20 @@ TableCell.propTypes = { * Either a string to use a DOM element or a component. */ component: PropTypes.elementType, - /** - * If `true`, content will align to the right. - */ - numeric: deprecatedPropType(PropTypes.bool, 'Instead, use the `align` property.'), /** * Sets the padding applied to the cell. * By default, the Table parent component set the value. */ - padding: PropTypes.oneOf(['default', 'checkbox', 'dense', 'none']), + padding: PropTypes.oneOf(['default', 'checkbox', 'none']), /** * Set scope attribute. */ scope: PropTypes.string, + /** + * Specify the size of the cell. + * By default, the Table parent component set the value (`normal`). + */ + size: PropTypes.oneOf(['small', 'medium']), /** * Set aria-sort direction. */ diff --git a/packages/material-ui/src/TableCell/TableCell.test.js b/packages/material-ui/src/TableCell/TableCell.test.js index 424d9907897413..f8338177a29e53 100644 --- a/packages/material-ui/src/TableCell/TableCell.test.js +++ b/packages/material-ui/src/TableCell/TableCell.test.js @@ -64,11 +64,11 @@ describe('', () => { assert.strictEqual(wrapper.find('td').hasClass(classes.paddingCheckbox), true); }); - it('should render with the user, root, padding, and dense classes', () => { - const wrapper = mountInTable(); + it('should render with the user, root, padding, and small classes', () => { + const wrapper = mountInTable(); assert.strictEqual(wrapper.find('td').hasClass('woofTableCell'), true); assert.strictEqual(wrapper.find('td').hasClass(classes.root), true); - assert.strictEqual(wrapper.find('td').hasClass(classes.paddingDense), true); + assert.strictEqual(wrapper.find('td').hasClass(classes.sizeSmall), true); }); it('should render children', () => { diff --git a/packages/material-ui/src/TableFooter/TableFooter.js b/packages/material-ui/src/TableFooter/TableFooter.js index 6dc713a7f2fcd7..ba9e344a3d7560 100644 --- a/packages/material-ui/src/TableFooter/TableFooter.js +++ b/packages/material-ui/src/TableFooter/TableFooter.js @@ -11,13 +11,15 @@ export const styles = { }, }; -const contextValue = { variant: 'footer' }; +const tablelvl2 = { + variant: 'footer', +}; const TableFooter = React.forwardRef(function TableFooter(props, ref) { const { classes, className, component: Component, ...other } = props; return ( - + ); diff --git a/packages/material-ui/src/TableHead/TableHead.js b/packages/material-ui/src/TableHead/TableHead.js index 565895e91cecff..fda71dced55d36 100644 --- a/packages/material-ui/src/TableHead/TableHead.js +++ b/packages/material-ui/src/TableHead/TableHead.js @@ -11,13 +11,15 @@ export const styles = { }, }; -const contextValue = { variant: 'head' }; +const tablelvl2 = { + variant: 'head', +}; const TableHead = React.forwardRef(function TableHead(props, ref) { const { classes, className, component: Component, ...other } = props; return ( - + ); diff --git a/packages/material-ui/src/TableRow/TableRow.js b/packages/material-ui/src/TableRow/TableRow.js index 2f91404ada0c2c..2d49ac4732ec86 100644 --- a/packages/material-ui/src/TableRow/TableRow.js +++ b/packages/material-ui/src/TableRow/TableRow.js @@ -9,7 +9,6 @@ export const styles = theme => ({ root: { color: 'inherit', display: 'table-row', - height: 48, verticalAlign: 'middle', // We disable the focus ring for mouse, touch and keyboard users. outline: 'none', @@ -30,14 +29,10 @@ export const styles = theme => ({ selected: {}, /* Styles applied to the root element if `hover={true}`. */ hover: {}, - /* Styles applied to the root element if table variant = 'head'. */ - head: { - height: 56, - }, - /* Styles applied to the root element if table variant = 'footer'. */ - footer: { - height: 56, - }, + /* Styles applied to the root element if table variant="head". */ + head: {}, + /* Styles applied to the root element if table variant="footer". */ + footer: {}, }); /** @@ -45,31 +40,24 @@ export const styles = theme => ({ * based on the material table element parent (head, body, etc). */ const TableRow = React.forwardRef(function TableRow(props, ref) { - const { - classes, - className: classNameProp, - component: Component, - hover, - selected, - ...other - } = props; + const { classes, className, component: Component, hover, selected, ...other } = props; + const tablelvl2 = React.useContext(Tablelvl2Context); return ( - - {tablelvl2 => { - const className = clsx( - classes.root, - { - [classes.head]: tablelvl2 && tablelvl2.variant === 'head', - [classes.footer]: tablelvl2 && tablelvl2.variant === 'footer', - [classes.hover]: hover, - [classes.selected]: selected, - }, - classNameProp, - ); - return ; - }} - + ); }); diff --git a/pages/api/table-cell.md b/pages/api/table-cell.md index eedab36e2264d5..e52178027e40d4 100644 --- a/pages/api/table-cell.md +++ b/pages/api/table-cell.md @@ -22,9 +22,9 @@ import TableCell from '@material-ui/core/TableCell'; | children | node |   | The table cell contents. | | classes | object |   | Override or extend the styles applied to the component. See [CSS API](#css) below for more details. | | component | elementType |   | The component used for the root node. Either a string to use a DOM element or a component. | -| ~~numeric~~ | bool |   | *Deprecated*. Instead, use the `align` property.

If `true`, content will align to the right. | -| padding | enum: 'default' |
 'checkbox' |
 'dense' |
 'none'
|   | Sets the padding applied to the cell. By default, the Table parent component set the value. | +| padding | enum: 'default' |
 'checkbox' |
 'none'
|   | Sets the padding applied to the cell. By default, the Table parent component set the value. | | scope | string |   | Set scope attribute. | +| size | enum: 'small' |
 'medium'
|   | Specify the size of the cell. By default, the Table parent component set the value (`normal`). | | sortDirection | enum: 'asc' |
 'desc' |
 false
|   | Set aria-sort direction. | | variant | enum: 'head' |
 'body' |
 'footer'
|   | Specify the cell type. By default, the TableHead, TableBody or TableFooter parent component set the value. | @@ -42,8 +42,7 @@ This property accepts the following keys: | head | Styles applied to the root element if `variant="head"` or `context.table.head`. | body | Styles applied to the root element if `variant="body"` or `context.table.body`. | footer | Styles applied to the root element if `variant="footer"` or `context.table.footer`. -| numeric | Styles applied to the root element if `numeric={true}`. -| paddingDense | Styles applied to the root element if `padding="dense"`. +| sizeSmall | Styles applied to the root element if `padding="dense"`. | paddingCheckbox | Styles applied to the root element if `padding="checkbox"`. | paddingNone | Styles applied to the root element if `padding="none"`. | alignLeft | Styles applied to the root element if `align="left"`. diff --git a/pages/api/table-row.md b/pages/api/table-row.md index 1288dd425ce9a1..3f6d897e34da40 100644 --- a/pages/api/table-row.md +++ b/pages/api/table-row.md @@ -38,8 +38,8 @@ This property accepts the following keys: | root | Styles applied to the root element. | selected | Styles applied to the root element if `selected={true}`. | hover | Styles applied to the root element if `hover={true}`. -| head | Styles applied to the root element if table variant = 'head'. -| footer | Styles applied to the root element if table variant = 'footer'. +| head | Styles applied to the root element if table variant="head". +| footer | Styles applied to the root element if table variant="footer". Have a look at [overriding with classes](/customization/overrides/#overriding-with-classes) section and the [implementation of the component](https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/TableRow/TableRow.js) diff --git a/pages/api/table.md b/pages/api/table.md index d52a12d314cc5b..925786e6d80b0f 100644 --- a/pages/api/table.md +++ b/pages/api/table.md @@ -21,7 +21,8 @@ import Table from '@material-ui/core/Table'; | children * | node |   | The content of the table, normally `TableHead` and `TableBody`. | | classes | object |   | Override or extend the styles applied to the component. See [CSS API](#css) below for more details. | | component | elementType | 'table' | The component used for the root node. Either a string to use a DOM element or a component. | -| padding | enum: 'default' |
 'checkbox' |
 'dense' |
 'none'
| 'default' | Allows TableCells to inherit padding of the Table. | +| padding | enum: 'default' |
 'checkbox' |
 'none'
| 'default' | Allows TableCells to inherit padding of the Table. | +| size | enum: 'small' |
 'medium'
| 'medium' | Allows TableCells to inherit size of the Table. | Any other properties supplied will be spread to the root element (native element). diff --git a/test/regressions/tests/Table/DenseCheckboxTable.js b/test/regressions/tests/Table/DenseCheckboxTable.js new file mode 100644 index 00000000000000..a6e0f8baa82b5d --- /dev/null +++ b/test/regressions/tests/Table/DenseCheckboxTable.js @@ -0,0 +1,86 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import Checkbox from '@material-ui/core/Checkbox'; +import Table from '@material-ui/core/Table'; +import TableBody from '@material-ui/core/TableBody'; +import TableCell from '@material-ui/core/TableCell'; +import TableHead from '@material-ui/core/TableHead'; +import TableRow from '@material-ui/core/TableRow'; +import Paper from '@material-ui/core/Paper'; + +const styles = theme => ({ + root: { + width: '100%', + }, + paper: { + marginTop: theme.spacing(3), + width: '100%', + overflowX: 'auto', + marginBottom: theme.spacing(2), + }, + table: { + minWidth: 650, + }, +}); + +let id = 0; +function createData(name, calories, fat, carbs, protein) { + id += 1; + return { id, name, calories, fat, carbs, protein }; +} + +const rows = [ + createData('Frozen yoghurt', 159, 6.0, 24, 4.0), + createData('Ice cream sandwich', 237, 9.0, 37, 4.3), + createData('Eclair', 262, 16.0, 24, 6.0), + createData('Cupcake', 305, 3.7, 67, 4.3), + createData('Gingerbread', 356, 16.0, 49, 3.9), +]; + +function DenseCheckboxTable(props) { + const { classes } = props; + + return ( +
+ +
+ + + + + + Dessert (100g serving) + Calories + Fat (g) + Carbs (g) + Protein (g) + + + + {rows.map(row => ( + + + + + + {row.name} + + {row.calories} + {row.fat} + {row.carbs} + {row.protein} + + ))} + +
+ + + ); +} + +DenseCheckboxTable.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(DenseCheckboxTable); diff --git a/test/regressions/tests/Table/PaddingTable.js b/test/regressions/tests/Table/PaddingTable.js deleted file mode 100644 index 1493b0561fc3a3..00000000000000 --- a/test/regressions/tests/Table/PaddingTable.js +++ /dev/null @@ -1,62 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import Grid from '@material-ui/core/Grid'; -import Paper from '@material-ui/core/Paper'; -import Table from '@material-ui/core/Table'; -import TableBody from '@material-ui/core/TableBody'; -import TableCell from '@material-ui/core/TableCell'; -import TableHead from '@material-ui/core/TableHead'; -import TableRow from '@material-ui/core/TableRow'; - -function MyTable(props) { - const { padding } = props; - return ( - - - - - Padding: {padding} - - - - - - Dummy Data - Dummy Data - - - Dummy Data - Dummy Data - - -
-
- ); -} - -MyTable.propTypes = { - padding: PropTypes.any, -}; - -function PaddingTable() { - return ( -
- - - - - - - - - - - - - - -
- ); -} - -export default PaddingTable;