diff --git a/packages/material-ui/src/Table/Table.js b/packages/material-ui/src/Table/Table.js index 5671bcea9821bb..8b6aee3204160c 100644 --- a/packages/material-ui/src/Table/Table.js +++ b/packages/material-ui/src/Table/Table.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import withStyles from '../styles/withStyles'; +import TableContext from './TableContext'; export const styles = theme => ({ /* Styles applied to the root element. */ @@ -14,21 +15,14 @@ export const styles = theme => ({ }, }); -class Table extends React.Component { - getChildContext() { - // eslint-disable-line class-methods-use-this - return { - table: { - padding: this.props.padding, - }, - }; - } +function Table(props) { + const { classes, className, component: Component, padding, ...other } = props; - render() { - const { classes, className, component: Component, padding, ...other } = this.props; - - return ; - } + return ( + + + + ); } Table.propTypes = { @@ -61,8 +55,4 @@ Table.defaultProps = { padding: 'default', }; -Table.childContextTypes = { - table: PropTypes.object, -}; - 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 911af85f4a7930..2093bf87e0395c 100644 --- a/packages/material-ui/src/Table/Table.test.js +++ b/packages/material-ui/src/Table/Table.test.js @@ -1,29 +1,38 @@ import React from 'react'; import { assert } from 'chai'; -import { createShallow, getClasses } from '../test-utils'; +import { createMount, findOutermostIntrinsic, getClasses } from '../test-utils'; import Table from './Table'; +import TableContext from './TableContext'; describe('', () => { - let shallow; + let mount; let classes; before(() => { - shallow = createShallow({ dive: true }); + mount = createMount(); classes = getClasses(
foo
); }); it('should render a table', () => { - const wrapper = shallow(foo
); - assert.strictEqual(wrapper.name(), 'table'); + const wrapper = mount( + + +
, + ); + assert.strictEqual(wrapper.getDOMNode().nodeName, 'TABLE'); }); it('should render a div', () => { - const wrapper = shallow(foo
); - assert.strictEqual(wrapper.name(), 'div'); + const wrapper = mount(foo
); + assert.strictEqual(wrapper.getDOMNode().nodeName, 'DIV'); }); it('should spread custom props on the root node', () => { - const wrapper = shallow(foo
); + const wrapper = mount( + + +
, + ); assert.strictEqual( wrapper.props()['data-my-prop'], 'woofTable', @@ -32,20 +41,37 @@ describe('', () => { }); it('should render with the user and root classes', () => { - const wrapper = shallow(
foo
); - assert.strictEqual(wrapper.hasClass('woofTable'), true); - assert.strictEqual(wrapper.hasClass(classes.root), true); + const wrapper = mount( + + +
, + ); + assert.strictEqual(findOutermostIntrinsic(wrapper).hasClass('woofTable'), true); + assert.strictEqual(findOutermostIntrinsic(wrapper).hasClass(classes.root), true); }); it('should render children', () => { const children = ; - const wrapper = shallow({children}
); - assert.strictEqual(wrapper.childAt(0).equals(children), true); + const wrapper = mount({children}
); + assert.strictEqual(wrapper.contains(children), true); }); it('should define table in the child context', () => { - const wrapper = shallow(foo
); - assert.deepStrictEqual(wrapper.instance().getChildContext().table, { + let context; + + mount( + + + {value => { + context = value; + + return ; + }} + +
, + ); + + assert.deepStrictEqual(context, { padding: 'default', }); }); diff --git a/packages/material-ui/src/Table/TableContext.d.ts b/packages/material-ui/src/Table/TableContext.d.ts new file mode 100644 index 00000000000000..d45ab3a96f01b6 --- /dev/null +++ b/packages/material-ui/src/Table/TableContext.d.ts @@ -0,0 +1,10 @@ +import { Context } from 'react'; +import { Padding } from './Table'; + +interface TableContextProps { + padding: Padding; +} + +declare const TableContext: Context; + +export default TableContext; diff --git a/packages/material-ui/src/Table/TableContext.js b/packages/material-ui/src/Table/TableContext.js new file mode 100644 index 00000000000000..70fd54205d7c0b --- /dev/null +++ b/packages/material-ui/src/Table/TableContext.js @@ -0,0 +1,8 @@ +import React from 'react'; + +/** + * @ignore - internal component. + */ +const TableContext = React.createContext(); + +export default TableContext; diff --git a/packages/material-ui/src/Table/Tablelvl2Context.d.ts b/packages/material-ui/src/Table/Tablelvl2Context.d.ts new file mode 100644 index 00000000000000..cd87dfda3a8a18 --- /dev/null +++ b/packages/material-ui/src/Table/Tablelvl2Context.d.ts @@ -0,0 +1,9 @@ +import { Context } from 'react'; + +interface Tablelvl2ContextProps { + variant: 'head' | 'body' | 'footer'; +} + +declare const Tablelvl2Context: Context; + +export default Tablelvl2Context; diff --git a/packages/material-ui/src/Table/Tablelvl2Context.js b/packages/material-ui/src/Table/Tablelvl2Context.js new file mode 100644 index 00000000000000..695f797292e689 --- /dev/null +++ b/packages/material-ui/src/Table/Tablelvl2Context.js @@ -0,0 +1,8 @@ +import React from 'react'; + +/** + * @ignore - internal component. + */ +const Tablelvl2Context = React.createContext(); + +export default Tablelvl2Context; diff --git a/packages/material-ui/src/TableBody/TableBody.js b/packages/material-ui/src/TableBody/TableBody.js index 1a7c08d885d374..a3d5e3bad1763c 100644 --- a/packages/material-ui/src/TableBody/TableBody.js +++ b/packages/material-ui/src/TableBody/TableBody.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import withStyles from '../styles/withStyles'; +import Tablelvl2Context from '../Table/Tablelvl2Context'; export const styles = { /* Styles applied to the root element. */ @@ -10,28 +11,21 @@ export const styles = { }, }; -class TableBody extends React.Component { - getChildContext() { - // eslint-disable-line class-methods-use-this - return { - tablelvl2: { - variant: 'body', - }, - }; - } +function TableBody(props) { + const { classes, className, component: Component, ...other } = props; - render() { - const { classes, className, component: Component, ...other } = this.props; - - return ; - } + return ( + + + + ); } TableBody.propTypes = { /** * The content of the component, normally `TableRow`. */ - children: PropTypes.node.isRequired, + children: PropTypes.node, /** * Override or extend the styles applied to the component. * See [CSS API](#css-api) below for more details. @@ -52,8 +46,4 @@ TableBody.defaultProps = { component: 'tbody', }; -TableBody.childContextTypes = { - tablelvl2: PropTypes.object, -}; - export default withStyles(styles, { name: 'MuiTableBody' })(TableBody); diff --git a/packages/material-ui/src/TableBody/TableBody.test.js b/packages/material-ui/src/TableBody/TableBody.test.js index cac6ab3583f7c0..4f241d71b92f3f 100644 --- a/packages/material-ui/src/TableBody/TableBody.test.js +++ b/packages/material-ui/src/TableBody/TableBody.test.js @@ -1,41 +1,61 @@ import React from 'react'; import { assert } from 'chai'; -import { createShallow, getClasses } from '../test-utils'; +import { createMount, findOutermostIntrinsic, getClasses } from '../test-utils'; import TableBody from './TableBody'; +import Tablelvl2Context from '../Table/Tablelvl2Context'; describe('', () => { - let shallow; + let mount; let classes; + function mountInTable(node) { + const wrapper = mount({node}
); + return wrapper.childAt(0); + } + before(() => { - shallow = createShallow({ dive: true }); - classes = getClasses(foo); + mount = createMount(); + + classes = getClasses(); + }); + + after(() => { + mount.cleanUp(); }); it('should render a tbody', () => { - const wrapper = shallow(foo); - assert.strictEqual(wrapper.name(), 'tbody'); + const wrapper = mountInTable(); + assert.strictEqual(wrapper.getDOMNode().nodeName, 'TBODY'); }); it('should render a div', () => { - const wrapper = shallow(foo); - assert.strictEqual(wrapper.name(), 'div'); + const wrapper = mount(foo); + assert.strictEqual(wrapper.getDOMNode().nodeName, 'DIV'); }); it('should render with the user and root class', () => { - const wrapper = shallow(foo); - assert.strictEqual(wrapper.hasClass('woofTableBody'), true); - assert.strictEqual(wrapper.hasClass(classes.root), true); + const wrapper = mountInTable(); + assert.strictEqual(findOutermostIntrinsic(wrapper).hasClass('woofTableBody'), true); + assert.strictEqual(findOutermostIntrinsic(wrapper).hasClass(classes.root), true); }); it('should render children', () => { const children = ; - const wrapper = shallow({children}); - assert.strictEqual(wrapper.childAt(0).equals(children), true); + const wrapper = mountInTable({children}); + assert.strictEqual(wrapper.contains(children), true); }); it('should define table.body in the child context', () => { - const wrapper = shallow(foo); - assert.strictEqual(wrapper.instance().getChildContext().tablelvl2.variant, 'body'); + let context; + mountInTable( + + + {value => { + context = value; + }} + + , + ); + assert.strictEqual(context.variant, 'body'); }); }); diff --git a/packages/material-ui/src/TableCell/TableCell.js b/packages/material-ui/src/TableCell/TableCell.js index d7a8cb678e2add..b34c201ccda35f 100644 --- a/packages/material-ui/src/TableCell/TableCell.js +++ b/packages/material-ui/src/TableCell/TableCell.js @@ -4,6 +4,8 @@ import classNames from 'classnames'; import withStyles from '../styles/withStyles'; import { capitalize } from '../utils/helpers'; import { darken, fade, lighten } from '../styles/colorManipulator'; +import TableContext from '../Table/TableContext'; +import Tablelvl2Context from '../Table/Tablelvl2Context'; export const styles = theme => ({ /* Styles applied to the root element. */ @@ -67,7 +69,7 @@ export const styles = theme => ({ }, }); -function TableCell(props, context) { +function TableCell(props) { const { children, classes, @@ -81,43 +83,56 @@ function TableCell(props, context) { ...other } = props; - const { table, tablelvl2 } = context; - let Component; - if (component) { - Component = component; - } else { - Component = tablelvl2 && tablelvl2.variant === 'head' ? 'th' : 'td'; - } + return ( + + {table => ( + + {tablelvl2 => { + let Component; + if (component) { + Component = component; + } else { + Component = tablelvl2 && tablelvl2.variant === 'head' ? 'th' : 'td'; + } - let scope = scopeProp; - if (!scope && tablelvl2 && tablelvl2.variant === 'head') { - scope = 'col'; - } - const padding = paddingProp || (table && table.padding ? table.padding : 'default'); + let scope = scopeProp; + 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' : 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', - }, - classNameProp, - ); + const className = classNames( + 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.numeric]: numeric, + [classes[`padding${capitalize(padding)}`]]: padding !== 'default', + }, + classNameProp, + ); - let ariaSort = null; - if (sortDirection) { - ariaSort = sortDirection === 'asc' ? 'ascending' : 'descending'; - } + let ariaSort = null; + if (sortDirection) { + ariaSort = sortDirection === 'asc' ? 'ascending' : 'descending'; + } - return ( - - {children} - + return ( + + {children} + + ); + }} + + )} + ); } @@ -171,9 +186,4 @@ TableCell.defaultProps = { numeric: false, }; -TableCell.contextTypes = { - table: PropTypes.object, - tablelvl2: PropTypes.object, -}; - export default withStyles(styles, { name: 'MuiTableCell' })(TableCell); diff --git a/packages/material-ui/src/TableCell/TableCell.test.js b/packages/material-ui/src/TableCell/TableCell.test.js index 586d0ad3e5d577..81f7394acfe72f 100644 --- a/packages/material-ui/src/TableCell/TableCell.test.js +++ b/packages/material-ui/src/TableCell/TableCell.test.js @@ -1,143 +1,101 @@ import React from 'react'; import { assert } from 'chai'; -import { createShallow, getClasses } from '../test-utils'; +import { createMount, getClasses } from '../test-utils'; import TableCell from './TableCell'; describe('', () => { - let shallow; + let mount; let classes; + function mountInTable(node) { + const wrapper = mount( + + + {node} + +
, + ); + return wrapper + .childAt(0) + .childAt(0) + .childAt(0); + } before(() => { - shallow = createShallow({ untilSelector: TableCell, context: { table: { footer: true } } }); + mount = createMount(); classes = getClasses(); }); it('should render a td', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.name(), 'td'); + const wrapper = mountInTable(); + assert.strictEqual(wrapper.getDOMNode().nodeName, 'TD'); }); it('should spread custom props on the root node', () => { - const wrapper = shallow(); + const wrapper = mountInTable(); assert.strictEqual( - wrapper.props()['data-my-prop'], + wrapper.find('td').props()['data-my-prop'], 'woofTableCell', 'custom prop should be woofTableCell', ); }); it('should render with the user, root and padding classes', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.hasClass('woofTableCell'), true); - assert.strictEqual(wrapper.hasClass(classes.root), true); - assert.strictEqual(wrapper.hasClass(classes.paddingDefault), false); + 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.paddingDefault), false); }); it('should render with the user, root and without the padding classes', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.hasClass('woofTableCell'), true); - assert.strictEqual(wrapper.hasClass(classes.root), true); + const wrapper = mountInTable(); + assert.strictEqual(wrapper.find('td').hasClass('woofTableCell'), true); + assert.strictEqual(wrapper.find('td').hasClass(classes.root), true); assert.strictEqual( - wrapper.hasClass(classes.paddingDefault), + wrapper.find('td').hasClass(classes.paddingDefault), false, 'should not have the padding class', ); }); it('should render with the user, root, padding, and checkbox classes', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.hasClass('woofTableCell'), true); - assert.strictEqual(wrapper.hasClass(classes.root), true); - assert.strictEqual(wrapper.hasClass(classes.paddingCheckbox), true); + 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.paddingCheckbox), true); }); it('should render with the user, root, padding, and dense classes', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.hasClass('woofTableCell'), true); - assert.strictEqual(wrapper.hasClass(classes.root), true); - assert.strictEqual(wrapper.hasClass(classes.paddingDense), true); + 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); }); it('should render children', () => { const children =

Hello

; - const wrapper = shallow({children}); - assert.strictEqual(wrapper.childAt(0).equals(children), true); - }); - - it('should render a th with the head class when in the context of a table head', () => { - const wrapper = shallow(); - wrapper.setContext({ tablelvl2: { variant: 'head' } }); - assert.strictEqual(wrapper.name(), 'th'); - assert.strictEqual(wrapper.hasClass(classes.root), true); - assert.strictEqual(wrapper.hasClass(classes.head), true); - assert.strictEqual(wrapper.props().scope, 'col'); - }); - - it('should render specified scope attribute even when in the context of a table head', () => { - const wrapper = shallow(); - wrapper.setContext({ tablelvl2: { variant: 'head' } }); - assert.strictEqual(wrapper.props().scope, 'row'); - }); - - it('should render a th with the footer class when in the context of a table footer', () => { - const wrapper = shallow(); - wrapper.setContext({ tablelvl2: { variant: 'footer' } }); - assert.strictEqual(wrapper.name(), 'td'); - assert.strictEqual(wrapper.hasClass(classes.root), true); - assert.strictEqual(wrapper.hasClass(classes.footer), true); + const wrapper = mountInTable({children}); + assert.strictEqual(wrapper.contains(children), true); }); it('should render a div when custom component prop is used', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.name(), 'div', 'should be a div element'); - assert.strictEqual(wrapper.hasClass(classes.root), true); - }); - - it('should render with the footer class when in the context of a table footer', () => { - const wrapper = shallow(); - wrapper.setContext({ tablelvl2: { variant: 'footer' } }); - assert.strictEqual(wrapper.hasClass(classes.root), true); - assert.strictEqual(wrapper.hasClass(classes.footer), true); - }); - - it('should render with the head class when variant is head, overriding context', () => { - const wrapper = shallow(); - wrapper.setContext({ tablelvl2: { variant: 'footer' } }); - assert.strictEqual(wrapper.hasClass(classes.head), true); - assert.strictEqual(wrapper.props().scope, undefined); - }); - - it('should render without head class when variant is body, overriding context', () => { - const wrapper = shallow(); - 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(); - 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(); - wrapper.setContext({ tablelvl2: { variant: 'head' } }); - assert.strictEqual(wrapper.hasClass(classes.footer), true); + const wrapper = mount(); + assert.strictEqual(wrapper.getDOMNode().nodeName, 'DIV'); + assert.strictEqual(wrapper.find('div').hasClass(classes.root), true); }); it('should render with the numeric class', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.hasClass(classes.root), true); - assert.strictEqual(wrapper.hasClass(classes.numeric), true); + const wrapper = mountInTable(); + assert.strictEqual(wrapper.find('td').hasClass(classes.root), true); + assert.strictEqual(wrapper.find('td').hasClass(classes.numeric), true); }); it('should render aria-sort="ascending" when prop sortDirection="asc" provided', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.props()['aria-sort'], 'ascending'); + const wrapper = mountInTable(); + assert.strictEqual(wrapper.find('td').props()['aria-sort'], 'ascending'); }); it('should render aria-sort="descending" when prop sortDirection="desc" provided', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.props()['aria-sort'], 'descending'); + const wrapper = mountInTable(); + assert.strictEqual(wrapper.find('td').props()['aria-sort'], 'descending'); }); }); diff --git a/packages/material-ui/src/TableFooter/TableFooter.js b/packages/material-ui/src/TableFooter/TableFooter.js index 739157cbdbbe84..3774a233e5ec78 100644 --- a/packages/material-ui/src/TableFooter/TableFooter.js +++ b/packages/material-ui/src/TableFooter/TableFooter.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import withStyles from '../styles/withStyles'; +import Tablelvl2Context from '../Table/Tablelvl2Context'; export const styles = { /* Styles applied to the root element. */ @@ -10,21 +11,14 @@ export const styles = { }, }; -class TableFooter extends React.Component { - getChildContext() { - // eslint-disable-line class-methods-use-this - return { - tablelvl2: { - variant: 'footer', - }, - }; - } +function TableFooter(props) { + const { classes, className, component: Component, ...other } = props; - render() { - const { classes, className, component: Component, ...other } = this.props; - - return ; - } + return ( + + + + ); } TableFooter.propTypes = { @@ -52,8 +46,4 @@ TableFooter.defaultProps = { component: 'tfoot', }; -TableFooter.childContextTypes = { - tablelvl2: PropTypes.object, -}; - export default withStyles(styles, { name: 'MuiTableFooter' })(TableFooter); diff --git a/packages/material-ui/src/TableFooter/TableFooter.test.js b/packages/material-ui/src/TableFooter/TableFooter.test.js index 5622f91c1b362f..7a0de78f905e5a 100644 --- a/packages/material-ui/src/TableFooter/TableFooter.test.js +++ b/packages/material-ui/src/TableFooter/TableFooter.test.js @@ -1,36 +1,60 @@ import React from 'react'; import { assert } from 'chai'; -import { createShallow, getClasses } from '../test-utils'; +import { createMount, findOutermostIntrinsic, getClasses } from '../test-utils'; import TableFooter from './TableFooter'; +import Tablelvl2Context from '../Table/Tablelvl2Context'; describe('', () => { - let shallow; + let mount; let classes; + function mountInTable(node) { + const wrapper = mount({node}
); + return wrapper.childAt(0); + } + before(() => { - shallow = createShallow({ dive: true }); + mount = createMount(); classes = getClasses(); }); + after(() => { + mount.cleanUp(); + }); + it('should render a tfoot', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.name(), 'tfoot'); + const wrapper = mountInTable(); + assert.strictEqual(wrapper.getDOMNode().nodeName, 'TFOOT'); }); it('should render a div', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.name(), 'div'); + const wrapper = mount(); + assert.strictEqual(wrapper.getDOMNode().nodeName, 'DIV'); }); it('should render with the user and root class', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.hasClass('woofTableHead'), true); - assert.strictEqual(wrapper.hasClass(classes.root), true); + const wrapper = mountInTable(); + assert.strictEqual(findOutermostIntrinsic(wrapper).hasClass('woofTableHead'), true); + assert.strictEqual(findOutermostIntrinsic(wrapper).hasClass(classes.root), true); }); it('should render children', () => { const children = ; - const wrapper = shallow({children}); - assert.strictEqual(wrapper.childAt(0).equals(children), true); + const wrapper = mountInTable({children}); + assert.strictEqual(wrapper.contains(children), true); + }); + + it('should define table.footer in the child context', () => { + let context; + mountInTable( + + + {value => { + context = value; + }} + + , + ); + assert.strictEqual(context.variant, 'footer'); }); }); diff --git a/packages/material-ui/src/TableHead/TableHead.js b/packages/material-ui/src/TableHead/TableHead.js index 772faf8f58c33f..16c85c1b051e0e 100644 --- a/packages/material-ui/src/TableHead/TableHead.js +++ b/packages/material-ui/src/TableHead/TableHead.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import withStyles from '../styles/withStyles'; +import Tablelvl2Context from '../Table/Tablelvl2Context'; export const styles = { /* Styles applied to the root element. */ @@ -10,28 +11,21 @@ export const styles = { }, }; -class TableHead extends React.Component { - getChildContext() { - // eslint-disable-line class-methods-use-this - return { - tablelvl2: { - variant: 'head', - }, - }; - } +function TableHead(props) { + const { classes, className, component: Component, ...other } = props; - render() { - const { classes, className, component: Component, ...other } = this.props; - - return ; - } + return ( + + + + ); } TableHead.propTypes = { /** * The content of the component, normally `TableRow`. */ - children: PropTypes.node.isRequired, + children: PropTypes.node, /** * Override or extend the styles applied to the component. * See [CSS API](#css-api) below for more details. @@ -52,8 +46,4 @@ TableHead.defaultProps = { component: 'thead', }; -TableHead.childContextTypes = { - tablelvl2: PropTypes.object, -}; - export default withStyles(styles, { name: 'MuiTableHead' })(TableHead); diff --git a/packages/material-ui/src/TableHead/TableHead.test.js b/packages/material-ui/src/TableHead/TableHead.test.js index a96ba5a09627d2..47e2838fce0c25 100644 --- a/packages/material-ui/src/TableHead/TableHead.test.js +++ b/packages/material-ui/src/TableHead/TableHead.test.js @@ -1,41 +1,59 @@ import React from 'react'; import { assert } from 'chai'; -import { createShallow, getClasses } from '../test-utils'; +import { createMount, getClasses } from '../test-utils'; import TableHead from './TableHead'; +import Tablelvl2Context from '../Table/Tablelvl2Context'; describe('', () => { - let shallow; + let mount; let classes; + function mountInTable(node) { + const wrapper = mount({node}
); + return wrapper.childAt(0); + } before(() => { - shallow = createShallow({ dive: true }); + mount = createMount(); classes = getClasses(foo); }); + after(() => { + mount.cleanUp(); + }); + it('should render a thead', () => { - const wrapper = shallow(foo); - assert.strictEqual(wrapper.name(), 'thead'); + const wrapper = mountInTable(); + assert.strictEqual(wrapper.getDOMNode().nodeName, 'THEAD'); }); it('should render a div', () => { - const wrapper = shallow(foo); - assert.strictEqual(wrapper.name(), 'div'); + const wrapper = mount(foo); + assert.strictEqual(wrapper.getDOMNode().nodeName, 'DIV'); }); it('should render with the user and root class', () => { - const wrapper = shallow(foo); - assert.strictEqual(wrapper.hasClass('woofTableHead'), true); - assert.strictEqual(wrapper.hasClass(classes.root), true); + const wrapper = mountInTable(); + assert.strictEqual(wrapper.find('thead').hasClass('woofTableHead'), true); + assert.strictEqual(wrapper.find('thead').hasClass(classes.root), true); }); it('should render children', () => { const children = ; - const wrapper = shallow({children}); - assert.strictEqual(wrapper.childAt(0).equals(children), true); + const wrapper = mountInTable({children}); + assert.strictEqual(wrapper.contains(children), true); }); it('should define table.head in the child context', () => { - const wrapper = shallow(foo); - assert.strictEqual(wrapper.instance().getChildContext().tablelvl2.variant, 'head'); + let context; + mountInTable( + + + {value => { + context = value; + }} + + , + ); + assert.strictEqual(context.variant, 'head'); }); }); diff --git a/packages/material-ui/src/TableRow/TableRow.js b/packages/material-ui/src/TableRow/TableRow.js index d147daf5f719e7..6e0c0a9c0d66da 100644 --- a/packages/material-ui/src/TableRow/TableRow.js +++ b/packages/material-ui/src/TableRow/TableRow.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import withStyles from '../styles/withStyles'; +import Tablelvl2Context from '../Table/Tablelvl2Context'; export const styles = theme => ({ /* Styles applied to the root element. */ @@ -43,7 +44,7 @@ export const styles = theme => ({ * Will automatically set dynamic row height * based on the material table element parent (head, body, etc). */ -function TableRow(props, context) { +function TableRow(props) { const { classes, className: classNameProp, @@ -52,20 +53,24 @@ function TableRow(props, context) { selected, ...other } = props; - const { tablelvl2 } = context; - const className = classNames( - classes.root, - { - [classes.head]: tablelvl2 && tablelvl2.variant === 'head', - [classes.footer]: tablelvl2 && tablelvl2.variant === 'footer', - [classes.hover]: hover, - [classes.selected]: selected, - }, - classNameProp, + return ( + + {tablelvl2 => { + const className = classNames( + classes.root, + { + [classes.head]: tablelvl2 && tablelvl2.variant === 'head', + [classes.footer]: tablelvl2 && tablelvl2.variant === 'footer', + [classes.hover]: hover, + [classes.selected]: selected, + }, + classNameProp, + ); + return ; + }} + ); - - return ; } TableRow.propTypes = { @@ -103,8 +108,4 @@ TableRow.defaultProps = { selected: false, }; -TableRow.contextTypes = { - tablelvl2: PropTypes.object, -}; - export default withStyles(styles, { name: 'MuiTableRow' })(TableRow); diff --git a/packages/material-ui/src/TableRow/TableRow.test.js b/packages/material-ui/src/TableRow/TableRow.test.js index 2024701031d0e0..ad67efbae3a1ab 100644 --- a/packages/material-ui/src/TableRow/TableRow.test.js +++ b/packages/material-ui/src/TableRow/TableRow.test.js @@ -1,55 +1,53 @@ import React from 'react'; import { assert } from 'chai'; -import { createShallow, getClasses } from '../test-utils'; +import { createMount, findOutermostIntrinsic, getClasses } from '../test-utils'; import TableRow from './TableRow'; describe('', () => { - let shallow; + let mount; let classes; + function mountInTable(node) { + const wrapper = mount( + + {node} +
, + ); + return wrapper.childAt(0).childAt(0); + } before(() => { - shallow = createShallow({ dive: true }); + mount = createMount(); classes = getClasses(); }); + after(() => { + mount.cleanUp(); + }); + it('should render a tr', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.name(), 'tr'); + const wrapper = mountInTable(); + assert.strictEqual(wrapper.getDOMNode().nodeName, 'TR'); }); it('should render a div', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.name(), 'div'); + const wrapper = mount(); + assert.strictEqual(wrapper.getDOMNode().nodeName, 'DIV'); }); it('should spread custom props on the root node', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.props()['data-my-prop'], 'woofTableRow'); + const wrapper = mountInTable(); + assert.strictEqual(findOutermostIntrinsic(wrapper).props()['data-my-prop'], 'woofTableRow'); }); it('should render with the user and root classes', () => { - const wrapper = shallow(); - assert.strictEqual(wrapper.hasClass('woofTableRow'), true); - assert.strictEqual(wrapper.hasClass(classes.root), true); + const wrapper = mountInTable(); + assert.strictEqual(findOutermostIntrinsic(wrapper).hasClass('woofTableRow'), true); + assert.strictEqual(findOutermostIntrinsic(wrapper).hasClass(classes.root), true); }); it('should render children', () => { const children = ; - const wrapper = shallow({children}); - assert.strictEqual(wrapper.childAt(0).equals(children), true); - }); - - it('should render with the head class when in the context of a table head', () => { - const wrapper = shallow(); - wrapper.setContext({ tablelvl2: { variant: 'head' } }); - assert.strictEqual(wrapper.hasClass(classes.root), true); - assert.strictEqual(wrapper.hasClass(classes.head), true); - }); - - it('should render with the footer class when in the context of a table footer', () => { - const wrapper = shallow(); - wrapper.setContext({ tablelvl2: { variant: 'footer' } }); - assert.strictEqual(wrapper.hasClass(classes.root), true); - assert.strictEqual(wrapper.hasClass(classes.footer), true); + const wrapper = mountInTable({children}); + assert.strictEqual(wrapper.contains(children), true); }); }); diff --git a/packages/material-ui/test/integration/TableCell.test.js b/packages/material-ui/test/integration/TableCell.test.js new file mode 100644 index 00000000000000..443c92ff615d97 --- /dev/null +++ b/packages/material-ui/test/integration/TableCell.test.js @@ -0,0 +1,77 @@ +import React from 'react'; +import { assert } from 'chai'; +import { createMount, getClasses } from 'packages/material-ui/src/test-utils'; +import TableCell from 'packages/material-ui/src/TableCell'; +import TableFooter from 'packages/material-ui/src/TableFooter'; +import TableHead from 'packages/material-ui/src/TableHead'; + +describe(' integration', () => { + let classes; + let mount; + function mountInTable(node, Variant) { + const wrapper = mount( + + + {node} + +
, + ); + return wrapper.find('tr').childAt(0); + } + + before(() => { + classes = getClasses(); + mount = createMount(); + }); + + after(() => { + mount.cleanUp(); + }); + + it('should render a th with the head class when in the context of a table head', () => { + const wrapper = mountInTable(, TableHead); + assert.strictEqual(wrapper.getDOMNode().nodeName, 'TH'); + assert.strictEqual(wrapper.find('th').hasClass(classes.root), true); + assert.strictEqual(wrapper.find('th').hasClass(classes.head), true); + assert.strictEqual(wrapper.find('th').props().scope, 'col'); + }); + + it('should render specified scope attribute even when in the context of a table head', () => { + const wrapper = mountInTable(, TableHead); + assert.strictEqual(wrapper.props().scope, 'row'); + }); + + it('should render a th with the footer class when in the context of a table footer', () => { + const wrapper = mountInTable(, TableFooter); + assert.strictEqual(wrapper.getDOMNode().nodeName, 'TD'); + assert.strictEqual(wrapper.find('td').hasClass(classes.root), true); + assert.strictEqual(wrapper.find('td').hasClass(classes.footer), true); + }); + + it('should render with the footer class when in the context of a table footer', () => { + const wrapper = mountInTable(, TableFooter); + assert.strictEqual(wrapper.find('td').hasClass(classes.root), true); + assert.strictEqual(wrapper.find('td').hasClass(classes.footer), true); + }); + + it('should render with the head class when variant is head, overriding context', () => { + const wrapper = mountInTable(, TableFooter); + assert.strictEqual(wrapper.find('td').hasClass(classes.head), true); + assert.strictEqual(wrapper.find('td').props().scope, undefined); + }); + + it('should render without head class when variant is body, overriding context', () => { + const wrapper = mountInTable(, TableFooter); + assert.strictEqual(wrapper.find('td').hasClass(classes.head), false); + }); + + it('should render without footer class when variant is body, overriding context', () => { + const wrapper = mountInTable(, TableFooter); + assert.strictEqual(wrapper.find('td').hasClass(classes.footer), false); + }); + + it('should render with the footer class when variant is footer, overriding context', () => { + const wrapper = mountInTable(, TableHead); + assert.strictEqual(wrapper.find('th').hasClass(classes.footer), true); + }); +}); diff --git a/packages/material-ui/test/integration/TableRow.test.js b/packages/material-ui/test/integration/TableRow.test.js new file mode 100644 index 00000000000000..8a4d0b650ed158 --- /dev/null +++ b/packages/material-ui/test/integration/TableRow.test.js @@ -0,0 +1,44 @@ +import React from 'react'; +import { assert } from 'chai'; +import { createMount, getClasses } from 'packages/material-ui/src/test-utils'; +import TableFooter from 'packages/material-ui/src/TableFooter'; +import TableHead from 'packages/material-ui/src/TableHead'; +import TableRow from 'packages/material-ui/src/TableRow'; + +describe(' integration', () => { + let classes; + let mount; + + before(() => { + classes = getClasses(); + mount = createMount(); + }); + + after(() => { + mount.cleanUp(); + }); + + it('should render with the head class when in the context of a table head', () => { + const wrapper = mount( + + + + +
, + ); + assert.strictEqual(wrapper.find('tr').hasClass(classes.root), true); + assert.strictEqual(wrapper.find('tr').hasClass(classes.head), true); + }); + + it('should render with the footer class when in the context of a table footer', () => { + const wrapper = mount( + + + + +
, + ); + assert.strictEqual(wrapper.find('tr').hasClass(classes.root), true); + assert.strictEqual(wrapper.find('tr').hasClass(classes.footer), true); + }); +}); diff --git a/pages/api/table-body.md b/pages/api/table-body.md index 54fd6e004bbe78..5d4461b4537cfd 100644 --- a/pages/api/table-body.md +++ b/pages/api/table-body.md @@ -19,7 +19,7 @@ import TableBody from '@material-ui/core/TableBody'; | Name | Type | Default | Description | |:-----|:-----|:--------|:------------| -| children * | node |   | The content of the component, normally `TableRow`. | +| children | node |   | The content of the component, normally `TableRow`. | | classes | object |   | Override or extend the styles applied to the component. See [CSS API](#css-api) below for more details. | | component | union: string |
 func |
 object
| 'tbody' | The component used for the root node. Either a string to use a DOM element or a component. | diff --git a/pages/api/table-head.md b/pages/api/table-head.md index c6eded11c55c0f..bcbfb5fc6f6ae7 100644 --- a/pages/api/table-head.md +++ b/pages/api/table-head.md @@ -19,7 +19,7 @@ import TableHead from '@material-ui/core/TableHead'; | Name | Type | Default | Description | |:-----|:-----|:--------|:------------| -| children * | node |   | The content of the component, normally `TableRow`. | +| children | node |   | The content of the component, normally `TableRow`. | | classes | object |   | Override or extend the styles applied to the component. See [CSS API](#css-api) below for more details. | | component | union: string |
 func |
 object
| 'thead' | The component used for the root node. Either a string to use a DOM element or a component. |