diff --git a/packages/material-ui/src/ExpansionPanel/ExpansionPanel.js b/packages/material-ui/src/ExpansionPanel/ExpansionPanel.js
index e7d37e11e50471..ce6e550c75301d 100644
--- a/packages/material-ui/src/ExpansionPanel/ExpansionPanel.js
+++ b/packages/material-ui/src/ExpansionPanel/ExpansionPanel.js
@@ -8,6 +8,7 @@ import Collapse from '../Collapse';
import Paper from '../Paper';
import withStyles from '../styles/withStyles';
import { isMuiElement } from '../utils/reactHelpers';
+import { PureProvider } from './ExpansionPanelContext';
export const styles = theme => {
const transition = {
@@ -112,12 +113,15 @@ function ExpansionPanel(props) {
const [expanded, setExpanded] = useMaybeControlled(expandedProp, defaultExpanded);
- function handleChange(event) {
- setExpanded(isExpanded => !isExpanded);
- if (onChange) {
- onChange(event, !expanded);
- }
- }
+ const handleChange = React.useCallback(
+ event => {
+ setExpanded(isExpanded => !isExpanded);
+ if (onChange) {
+ onChange(event, !expanded);
+ }
+ },
+ [expanded, setExpanded, onChange],
+ );
let summary = null;
@@ -135,11 +139,7 @@ function ExpansionPanel(props) {
);
if (isMuiElement(child, ['ExpansionPanelSummary'])) {
- summary = React.cloneElement(child, {
- disabled,
- expanded,
- onChange: handleChange,
- });
+ summary = child;
return null;
}
@@ -147,25 +147,27 @@ function ExpansionPanel(props) {
});
return (
-
- {summary}
-
- {children}
-
-
+
+
+ {summary}
+
+ {children}
+
+
+
);
}
@@ -220,6 +222,7 @@ ExpansionPanel.propTypes = {
ExpansionPanel.defaultProps = {
defaultExpanded: false,
disabled: false,
+ onChange: noop,
square: false,
TransitionComponent: Collapse,
};
diff --git a/packages/material-ui/src/ExpansionPanel/ExpansionPanel.test.js b/packages/material-ui/src/ExpansionPanel/ExpansionPanel.test.js
index bd56ac0c491af3..8f1c6af3a0b9c1 100644
--- a/packages/material-ui/src/ExpansionPanel/ExpansionPanel.test.js
+++ b/packages/material-ui/src/ExpansionPanel/ExpansionPanel.test.js
@@ -2,19 +2,16 @@ import React from 'react';
import PropTypes from 'prop-types';
import { assert } from 'chai';
import { spy } from 'sinon';
-import { createShallow, createMount, getClasses } from '@material-ui/core/test-utils';
-import Collapse from '../Collapse';
+import { createMount, getClasses } from '@material-ui/core/test-utils';
import Paper from '../Paper';
import ExpansionPanel from './ExpansionPanel';
import ExpansionPanelSummary from '../ExpansionPanelSummary';
describe('', () => {
let mount;
- let shallow;
let classes;
before(() => {
- shallow = createShallow({ dive: true });
mount = createMount();
classes = getClasses(foo);
});
@@ -48,23 +45,29 @@ describe('', () => {
});
it('should render the custom className and the root class', () => {
- const wrapper = shallow(foo);
- assert.strictEqual(wrapper.hasClass('test-class-name'), true);
- assert.strictEqual(wrapper.hasClass(classes.root), true);
+ const wrapper = mount(foo);
+ const root = wrapper.find(`.${classes.root}`).first();
+ assert.strictEqual(root.hasClass('test-class-name'), true);
});
it('should render the summary and collapse elements', () => {
- const wrapper = shallow(
-
-
+ const wrapper = mount(
+
+ summary
Hello
,
);
- assert.strictEqual(wrapper.childAt(0).type(), ExpansionPanelSummary);
- const collapse = wrapper.childAt(1);
- assert.strictEqual(collapse.type(), Collapse);
- assert.strictEqual(collapse.children().length, 1, 'collapse should have 1 children div');
+ assert.strictEqual(
+ wrapper
+ .find('[aria-expanded=true]')
+ .first()
+ .text(),
+ 'summary',
+ );
+
+ const collapse = wrapper.find('Collapse');
+ assert.strictEqual(collapse.text(), 'Hello');
});
it('should handle the expanded prop', () => {
@@ -101,21 +104,15 @@ describe('', () => {
assert.strictEqual(handleChange.args[0][1], false);
});
- it('when undefined onChange and controlled should not call the onChange', () => {
- const handleChange = spy();
- const wrapper = mount(
-
-
- ,
- );
- wrapper.setProps({ onChange: undefined });
- wrapper.find(ExpansionPanelSummary).simulate('click');
- assert.strictEqual(handleChange.callCount, 0);
- });
-
it('when disabled should have the disabled class', () => {
- const wrapper = shallow(foo);
- assert.strictEqual(wrapper.hasClass(classes.disabled), true);
+ const wrapper = mount(foo);
+ assert.strictEqual(
+ wrapper
+ .find(`.${classes.root}`)
+ .first()
+ .hasClass(classes.disabled),
+ true,
+ );
});
it('should handle the TransitionComponent prop', () => {
@@ -149,8 +146,8 @@ describe('', () => {
describe('prop: children', () => {
it('should accept an empty child', () => {
- shallow(
-
+ mount(
+
{null}
,
diff --git a/packages/material-ui/src/ExpansionPanel/ExpansionPanelContext.js b/packages/material-ui/src/ExpansionPanel/ExpansionPanelContext.js
index b02367c1d9d484..aaf05b7c1c7d98 100644
--- a/packages/material-ui/src/ExpansionPanel/ExpansionPanelContext.js
+++ b/packages/material-ui/src/ExpansionPanel/ExpansionPanelContext.js
@@ -1,4 +1,5 @@
import React from 'react';
+import PropTypes from 'prop-types';
import warning from 'warning';
const ExpansionPanelContext = React.createContext({
@@ -15,4 +16,14 @@ const ExpansionPanelContext = React.createContext({
},
});
+export const PureProvider = React.memo(props => {
+ const { children, ...value } = props;
+
+ return {children};
+});
+
+PureProvider.propTypes = {
+ children: PropTypes.node,
+};
+
export default ExpansionPanelContext;
diff --git a/packages/material-ui/src/ExpansionPanelSummary/ExpansionPanelSummary.js b/packages/material-ui/src/ExpansionPanelSummary/ExpansionPanelSummary.js
index f5105c3305a97e..efa9f987e4b4d6 100644
--- a/packages/material-ui/src/ExpansionPanelSummary/ExpansionPanelSummary.js
+++ b/packages/material-ui/src/ExpansionPanelSummary/ExpansionPanelSummary.js
@@ -4,6 +4,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import ButtonBase from '../ButtonBase';
+import { useExpansionPanel } from '../ExpansionPanel';
import withStyles from '../styles/withStyles';
export const styles = theme => {
@@ -75,17 +76,15 @@ function ExpansionPanelSummary(props) {
children,
classes,
className,
- disabled,
- expanded,
expandIcon,
IconButtonProps,
onBlur,
- onChange,
onClick,
onFocusVisible,
...other
} = props;
const [focused, setFocused] = React.useState(false);
+ const { disabled, expanded, onChange } = useExpansionPanel();
function handleFocusVisible(event) {
setFocused(true);
@@ -191,7 +190,6 @@ const noop = () => {};
ExpansionPanelSummary.defaultProps = {
disabled: false,
onBlur: noop,
- onChange: noop,
onClick: noop,
onFocusVisible: noop,
};
diff --git a/packages/material-ui/src/ExpansionPanelSummary/ExpansionPanelSummary.test.js b/packages/material-ui/src/ExpansionPanelSummary/ExpansionPanelSummary.test.js
index b33f8e057c1270..1314d9d5941976 100644
--- a/packages/material-ui/src/ExpansionPanelSummary/ExpansionPanelSummary.test.js
+++ b/packages/material-ui/src/ExpansionPanelSummary/ExpansionPanelSummary.test.js
@@ -8,9 +8,10 @@ import {
getClasses,
} from '@material-ui/core/test-utils';
import ButtonBase from '../ButtonBase';
+import ExpansionPanel from '../ExpansionPanel';
import ExpansionPanelSummary from './ExpansionPanelSummary';
-describe('', () => {
+describe.only('', () => {
let mount;
let shallow;
let classes;
@@ -105,11 +106,17 @@ describe('', () => {
return result;
}, {});
- const wrapper = shallow();
+ const wrapper = mount(
+
+
+ ,
+ );
+
+ const summary = wrapper.find('[aria-expanded]').first();
events.forEach(n => {
const event = n.charAt(2).toLowerCase() + n.slice(3);
- wrapper.simulate(event, { persist: () => {} });
+ summary.simulate(event, { persist: () => {} });
assert.strictEqual(handlers[n].callCount, 1, `should have called the ${n} handler`);
});
});
@@ -118,7 +125,11 @@ describe('', () => {
describe('prop: onChange', () => {
it('fires onChange if the summary control is clicked', () => {
const handleChange = spy();
- const wrapper = mount();
+ const wrapper = mount(
+
+
+ ,
+ );
const control = findOutermostIntrinsic(wrapper.find('[aria-expanded]'));
const eventMock = 'woofExpansionPanelSummary';
@@ -132,8 +143,15 @@ describe('', () => {
describe('prop: click', () => {
it('should trigger onClick', () => {
const handleClick = spy();
- const wrapper = shallow();
- wrapper.simulate('click');
+ const wrapper = mount(
+ {}}>
+
+ ,
+ );
+ wrapper
+ .find('[aria-expanded]')
+ .first()
+ .simulate('click');
assert.strictEqual(handleClick.callCount, 1);
});
});