Skip to content

Commit

Permalink
[Table] Padding feature (mui#12415)
Browse files Browse the repository at this point in the history
* Added table padding feature.

Fixed omission of padding as a valid prop of Table.

Fixed read-only problems with padding.

Defined Padding.

* Fixed style errors

* Fixed undefined context padding.

* fix(www): let's merge
  • Loading branch information
aseem191 authored and oliviertassinari committed Aug 7, 2018
1 parent 956e59e commit 5cdc684
Show file tree
Hide file tree
Showing 14 changed files with 63 additions and 48 deletions.
9 changes: 8 additions & 1 deletion packages/material-ui/src/Table/Table.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class Table extends React.Component {
getChildContext() {
// eslint-disable-line class-methods-use-this
return {
table: {},
table: {
padding: this.props.padding,
},
};
}

Expand Down Expand Up @@ -48,10 +50,15 @@ Table.propTypes = {
* Either a string to use a DOM element or a component.
*/
component: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.object]),
/**
* Allows TableCells to inherit padding of the Table.
*/
padding: PropTypes.oneOf(['default', 'checkbox', 'dense', 'none']),
};

Table.defaultProps = {
component: 'table',
padding: 'default',
};

Table.childContextTypes = {
Expand Down
6 changes: 4 additions & 2 deletions packages/material-ui/src/Table/Table.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('<Table />', () => {
it('should spread custom props on the root node', () => {
const wrapper = shallow(<Table data-my-prop="woofTable">foo</Table>);
assert.strictEqual(
wrapper.prop('data-my-prop'),
wrapper.props()['data-my-prop'],
'woofTable',
'custom prop should be woofTable',
);
Expand All @@ -45,6 +45,8 @@ describe('<Table />', () => {

it('should define table in the child context', () => {
const wrapper = shallow(<Table>foo</Table>);
assert.deepStrictEqual(wrapper.instance().getChildContext().table, {});
assert.deepStrictEqual(wrapper.instance().getChildContext().table, {
padding: 'default',
});
});
});
6 changes: 3 additions & 3 deletions packages/material-ui/src/TableBody/TableBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class TableBody extends React.Component {
getChildContext() {
// eslint-disable-line class-methods-use-this
return {
table: {
body: true,
tablelvl2: {
variant: 'body',
},
};
}
Expand Down Expand Up @@ -53,7 +53,7 @@ TableBody.defaultProps = {
};

TableBody.childContextTypes = {
table: PropTypes.object,
tablelvl2: PropTypes.object,
};

export default withStyles(styles, { name: 'MuiTableBody' })(TableBody);
2 changes: 1 addition & 1 deletion packages/material-ui/src/TableBody/TableBody.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ describe('<TableBody />', () => {

it('should define table.body in the child context', () => {
const wrapper = shallow(<TableBody>foo</TableBody>);
assert.strictEqual(wrapper.instance().getChildContext().table.body, true);
assert.strictEqual(wrapper.instance().getChildContext().tablelvl2.variant, 'body');
});
});
23 changes: 14 additions & 9 deletions packages/material-ui/src/TableCell/TableCell.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,30 +75,34 @@ function TableCell(props, context) {
component,
sortDirection,
numeric,
padding,
padding: paddingProp,
scope: scopeProp,
variant,
...other
} = props;
const { table } = context;

const { table, tablelvl2 } = context;
let Component;
if (component) {
Component = component;
} else {
Component = table && table.head ? 'th' : 'td';
Component = tablelvl2 && tablelvl2.variant === 'head' ? 'th' : 'td';
}

let scope = scopeProp;
if (!scope && table && table.head) {
if (!scope && tablelvl2 && tablelvl2.variant === 'head') {
scope = 'col';
}
const padding = paddingProp || (table && table.padding ? table.padding : 'default');

const className = classNames(
classes.root,
{
[classes.head]: variant ? variant === 'head' : table && table.head,
[classes.body]: variant ? variant === 'body' : table && table.body,
[classes.footer]: variant ? variant === 'footer' : table && table.footer,
[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.numeric]: numeric,
[classes[`padding${capitalize(padding)}`]]: padding !== 'default',
},
Expand Down Expand Up @@ -142,6 +146,7 @@ TableCell.propTypes = {
numeric: PropTypes.bool,
/**
* Sets the padding applied to the cell.
* By default, the Table parent component set the value.
*/
padding: PropTypes.oneOf(['default', 'checkbox', 'dense', 'none']),
/**
Expand All @@ -161,11 +166,11 @@ TableCell.propTypes = {

TableCell.defaultProps = {
numeric: false,
padding: 'default',
};

TableCell.contextTypes = {
table: PropTypes.object.isRequired,
table: PropTypes.object,
tablelvl2: PropTypes.object,
};

export default withStyles(styles, { name: 'MuiTableCell' })(TableCell);
16 changes: 8 additions & 8 deletions packages/material-ui/src/TableCell/TableCell.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ describe('<TableCell />', () => {

it('should render a th with the head class when in the context of a table head', () => {
const wrapper = shallow(<TableCell />);
wrapper.setContext({ table: { head: true } });
wrapper.setContext({ tablelvl2: { variant: 'head' } });
assert.strictEqual(wrapper.name(), 'th');
assert.strictEqual(wrapper.hasClass(classes.root), true);
assert.strictEqual(wrapper.hasClass(classes.head), true, 'should have the head class');
Expand All @@ -75,13 +75,13 @@ describe('<TableCell />', () => {

it('should render specified scope attribute even when in the context of a table head', () => {
const wrapper = shallow(<TableCell scope="row" />);
wrapper.setContext({ table: { head: true } });
wrapper.setContext({ tablelvl2: { variant: 'head' } });
assert.strictEqual(wrapper.props().scope, 'row', 'should have the specified scope attribute');
});

it('should render a th with the footer class when in the context of a table footer', () => {
const wrapper = shallow(<TableCell />);
wrapper.setContext({ table: { footer: true } });
wrapper.setContext({ tablelvl2: { variant: 'footer' } });
assert.strictEqual(wrapper.name(), 'td');
assert.strictEqual(wrapper.hasClass(classes.root), true);
assert.strictEqual(wrapper.hasClass(classes.footer), true, 'should have the footer class');
Expand All @@ -95,33 +95,33 @@ describe('<TableCell />', () => {

it('should render with the footer class when in the context of a table footer', () => {
const wrapper = shallow(<TableCell />);
wrapper.setContext({ table: { footer: true } });
wrapper.setContext({ tablelvl2: { variant: 'footer' } });
assert.strictEqual(wrapper.hasClass(classes.root), true);
assert.strictEqual(wrapper.hasClass(classes.footer), true, 'should have the footer class');
});

it('should render with the head class when variant is head, overriding context', () => {
const wrapper = shallow(<TableCell variant="head" />);
wrapper.setContext({ table: { footer: true } });
wrapper.setContext({ tablelvl2: { variant: 'footer' } });
assert.strictEqual(wrapper.hasClass(classes.head), true);
assert.strictEqual(wrapper.props().scope, undefined, 'should have the correct scope attribute');
});

it('should render without head class when variant is body, overriding context', () => {
const wrapper = shallow(<TableCell variant="body" />);
wrapper.setContext({ table: { head: true } });
wrapper.setContext({ tablelvl2: { variant: 'head' } });
assert.strictEqual(wrapper.hasClass(classes.head), false);
});

it('should render without footer class when variant is body, overriding context', () => {
const wrapper = shallow(<TableCell variant="body" />);
wrapper.setContext({ table: { footer: true } });
wrapper.setContext({ tablelvl2: { variant: 'footer' } });
assert.strictEqual(wrapper.hasClass(classes.footer), false);
});

it('should render with the footer class when variant is footer, overriding context', () => {
const wrapper = shallow(<TableCell variant="footer" />);
wrapper.setContext({ table: { head: true } });
wrapper.setContext({ tablelvl2: { variant: 'head' } });
assert.strictEqual(wrapper.hasClass(classes.footer), true);
});

Expand Down
6 changes: 3 additions & 3 deletions packages/material-ui/src/TableFooter/TableFooter.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class TableFooter extends React.Component {
getChildContext() {
// eslint-disable-line class-methods-use-this
return {
table: {
footer: true,
tablelvl2: {
variant: 'footer',
},
};
}
Expand Down Expand Up @@ -53,7 +53,7 @@ TableFooter.defaultProps = {
};

TableFooter.childContextTypes = {
table: PropTypes.object,
tablelvl2: PropTypes.object,
};

export default withStyles(styles, { name: 'MuiTableFooter' })(TableFooter);
6 changes: 3 additions & 3 deletions packages/material-ui/src/TableHead/TableHead.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class TableHead extends React.Component {
getChildContext() {
// eslint-disable-line class-methods-use-this
return {
table: {
head: true,
tablelvl2: {
variant: 'head',
},
};
}
Expand Down Expand Up @@ -53,7 +53,7 @@ TableHead.defaultProps = {
};

TableHead.childContextTypes = {
table: PropTypes.object,
tablelvl2: PropTypes.object,
};

export default withStyles(styles, { name: 'MuiTableHead' })(TableHead);
2 changes: 1 addition & 1 deletion packages/material-ui/src/TableHead/TableHead.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ describe('<TableHead />', () => {

it('should define table.head in the child context', () => {
const wrapper = shallow(<TableHead>foo</TableHead>);
assert.strictEqual(wrapper.instance().getChildContext().table.head, true);
assert.strictEqual(wrapper.instance().getChildContext().tablelvl2.variant, 'head');
});
});
20 changes: 10 additions & 10 deletions packages/material-ui/src/TableRow/TableRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ export const styles = theme => ({
: 'rgba(255, 255, 255, 0.14)',
},
},
/* Styles applied to the root element if `context.table` & `selected={true}`. */
/* Styles applied to the root element if `selected={true}`. */
selected: {},
/* Styles applied to the root element if `context.table` & `hover={true}`. */
/* Styles applied to the root element if `hover={true}`. */
hover: {},
/* Styles applied to the root element if `context.table.head`. */
/* Styles applied to the root element if table variant = 'head'. */
head: {
height: 56,
},
/* Styles applied to the root element if `context.table.footer`. */
/* Styles applied to the root element if table variant = 'footer'. */
footer: {
height: 56,
},
Expand All @@ -52,15 +52,15 @@ function TableRow(props, context) {
selected,
...other
} = props;
const { table } = context;
const { tablelvl2 } = context;

const className = classNames(
classes.root,
{
[classes.head]: table && table.head,
[classes.footer]: table && table.footer,
[classes.hover]: table && hover,
[classes.selected]: table && selected,
[classes.head]: tablelvl2 && tablelvl2.variant === 'head',
[classes.footer]: tablelvl2 && tablelvl2.variant === 'footer',
[classes.hover]: hover,
[classes.selected]: selected,
},
classNameProp,
);
Expand Down Expand Up @@ -104,7 +104,7 @@ TableRow.defaultProps = {
};

TableRow.contextTypes = {
table: PropTypes.object,
tablelvl2: PropTypes.object,
};

export default withStyles(styles, { name: 'MuiTableRow' })(TableRow);
4 changes: 2 additions & 2 deletions packages/material-ui/src/TableRow/TableRow.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ describe('<TableRow />', () => {

it('should render with the head class when in the context of a table head', () => {
const wrapper = shallow(<TableRow />);
wrapper.setContext({ table: { head: true } });
wrapper.setContext({ tablelvl2: { variant: 'head' } });
assert.strictEqual(wrapper.hasClass(classes.root), true);
assert.strictEqual(wrapper.hasClass(classes.head), true, 'should have the head class');
});

it('should render with the footer class when in the context of a table footer', () => {
const wrapper = shallow(<TableRow />);
wrapper.setContext({ table: { footer: true } });
wrapper.setContext({ tablelvl2: { variant: 'footer' } });
assert.strictEqual(wrapper.hasClass(classes.root), true);
assert.strictEqual(wrapper.hasClass(classes.footer), true, 'should have the footer class');
});
Expand Down
2 changes: 1 addition & 1 deletion pages/api/table-cell.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ title: TableCell API
| <span class="prop-name">classes</span> | <span class="prop-type">object |   | Override or extend the styles applied to the component. See [CSS API](#css-api) below for more details. |
| <span class="prop-name">component</span> | <span class="prop-type">union:&nbsp;string&nbsp;&#124;<br>&nbsp;func&nbsp;&#124;<br>&nbsp;object<br> |   | The component used for the root node. Either a string to use a DOM element or a component. |
| <span class="prop-name">numeric</span> | <span class="prop-type">bool | <span class="prop-default">false</span> | If `true`, content will align to the right. |
| <span class="prop-name">padding</span> | <span class="prop-type">enum:&nbsp;'default'&nbsp;&#124;<br>&nbsp;'checkbox'&nbsp;&#124;<br>&nbsp;'dense'&nbsp;&#124;<br>&nbsp;'none'<br> | <span class="prop-default">'default'</span> | Sets the padding applied to the cell. |
| <span class="prop-name">padding</span> | <span class="prop-type">enum:&nbsp;'default'&nbsp;&#124;<br>&nbsp;'checkbox'&nbsp;&#124;<br>&nbsp;'dense'&nbsp;&#124;<br>&nbsp;'none'<br> |   | Sets the padding applied to the cell. By default, the Table parent component set the value. |
| <span class="prop-name">scope</span> | <span class="prop-type">string |   | Set scope attribute. |
| <span class="prop-name">sortDirection</span> | <span class="prop-type">enum:&nbsp;'asc'&nbsp;&#124;<br>&nbsp;'desc'&nbsp;&#124;<br>&nbsp;false<br> |   | Set aria-sort direction. |
| <span class="prop-name">variant</span> | <span class="prop-type">enum:&nbsp;'head'&nbsp;&#124;<br>&nbsp;'body'&nbsp;&#124;<br>&nbsp;'footer'<br> |   | Specify the cell type. By default, the TableHead, TableBody or TableFooter parent component set the value. |
Expand Down
8 changes: 4 additions & 4 deletions pages/api/table-row.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ This property accepts the following keys:
| Name | Description |
|:-----|:------------|
| <span class="prop-name">root</span> | Styles applied to the root element.
| <span class="prop-name">selected</span> | Styles applied to the root element if `context.table` & `selected={true}`.
| <span class="prop-name">hover</span> | Styles applied to the root element if `context.table` & `hover={true}`.
| <span class="prop-name">head</span> | Styles applied to the root element if `context.table.head`.
| <span class="prop-name">footer</span> | Styles applied to the root element if `context.table.footer`.
| <span class="prop-name">selected</span> | Styles applied to the root element if `selected={true}`.
| <span class="prop-name">hover</span> | Styles applied to the root element if `hover={true}`.
| <span class="prop-name">head</span> | Styles applied to the root element if table variant = 'head'.
| <span class="prop-name">footer</span> | 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/tree/master/packages/material-ui/src/TableRow/TableRow.js)
Expand Down
1 change: 1 addition & 0 deletions pages/api/table.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ title: Table API
| <span class="prop-name required">children *</span> | <span class="prop-type">node |   | The content of the table, normally `TableHeader` and `TableBody`. |
| <span class="prop-name">classes</span> | <span class="prop-type">object |   | Override or extend the styles applied to the component. See [CSS API](#css-api) below for more details. |
| <span class="prop-name">component</span> | <span class="prop-type">union:&nbsp;string&nbsp;&#124;<br>&nbsp;func&nbsp;&#124;<br>&nbsp;object<br> | <span class="prop-default">'table'</span> | The component used for the root node. Either a string to use a DOM element or a component. |
| <span class="prop-name">padding</span> | <span class="prop-type">enum:&nbsp;'default'&nbsp;&#124;<br>&nbsp;'checkbox'&nbsp;&#124;<br>&nbsp;'dense'&nbsp;&#124;<br>&nbsp;'none'<br> | <span class="prop-default">'default'</span> | Allows TableCells to inherit padding of the Table. |

Any other properties supplied will be spread to the root element (native element).

Expand Down

0 comments on commit 5cdc684

Please sign in to comment.