Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Modal] Refactor tests to remove internal accesses #16262

Merged
merged 5 commits into from
Jun 18, 2019

Conversation

oliviertassinari
Copy link
Member

@oliviertassinari oliviertassinari commented Jun 17, 2019

Prepare #16254.

  • Replace some usage of withTheme to useTheme.
  • Move some default props away of .defaultProps.
  • Remove some dead code.
  • Fix a Portal bug with the ref and onRendered inversed call order.
  • Fix a TrapFocus bug when isEnabled is not "stable".
  • Repace packages/material-ui/src/ imports with @material-ui/core/.

@oliviertassinari oliviertassinari added test component: modal This is the name of the generic UI component, not the React module! labels Jun 17, 2019
@mui-pr-bot
Copy link

mui-pr-bot commented Jun 17, 2019

@material-ui/lab: parsed: -0.42% 😍, gzip: -0.31% 😍

Details of bundle changes.

Comparing: 93f5b33...44976a0

bundle parsed diff gzip diff prev parsed current parsed prev gzip current gzip
@material-ui/core -0.09% -0.06% 319,010 318,737 87,576 87,520
@material-ui/core/Paper -0.00% +0.01% 🔺 68,281 68,280 20,353 20,356
@material-ui/core/Paper.esm -0.00% +0.02% 🔺 61,578 61,577 19,133 19,136
@material-ui/core/Popper -0.08% -0.06% 28,968 28,945 10,411 10,405
@material-ui/core/Textarea 0.00% -0.04% 5,513 5,513 2,374 2,373
@material-ui/core/TrapFocus 0.00% 0.00% 3,755 3,755 1,580 1,580
@material-ui/core/styles/createMuiTheme 0.00% +0.05% 🔺 16,012 16,012 5,791 5,794
@material-ui/core/useMediaQuery 0.00% +0.09% 🔺 2,597 2,597 1,102 1,103
@material-ui/lab -0.42% -0.31% 140,580 139,991 43,454 43,319
@material-ui/styles 0.00% +0.03% 🔺 51,703 51,703 15,337 15,342
@material-ui/system 0.00% -0.07% 15,303 15,303 4,342 4,339
Button -0.00% 0.00% 84,279 84,278 25,630 25,631
Modal -0.07% -0.37% 20,345 20,330 6,689 6,664
Slider -0.00% -0.03% 74,681 74,679 23,221 23,213
colorManipulator 0.00% 0.00% 3,904 3,904 1,544 1,544
docs.landing 0.00% 0.00% 55,232 55,232 13,946 13,946
docs.main -0.02% -0.00% 651,051 650,902 205,054 205,053
packages/material-ui/build/umd/material-ui.production.min.js -0.07% +0.03% 🔺 292,254 292,060 83,501 83,522

Generated by 🚫 dangerJS against 44976a0

useEnhancedEffect(() => {
if (onRendered && mountNode) {
onRendered();
}
}, [mountNode, onRendered]);

React.useImperativeHandle(ref, () => mountNode || childRef.current, [mountNode]);
Copy link
Member Author

@oliviertassinari oliviertassinari Jun 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the order so ref triggers before onRendered.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait refs should never trigger before layout effects. Those are two different phases. Do you have a test for that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useImperativeHandle triggers at the same time than synchronous layout effects from what I can log (not layout effects!). I'm adding a test case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, need to play around with this. Did not know that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that reason is the following: you need to have access to the DOM element in the synchronous layout effects. If the ref triggers after, you don't have it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did some experimenting and it is essentially facebook/react#7769 i.e. within a render block useImperativeHandle runs in the same phase as layout effects but any layout effect queued outside (e.g. in a parent) will run after useImperativeHandle of children.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think onRendered is actually an Anti-Pattern. We already have callback refs to handle when a host component is committed. What should happen is

- const portalRef = React.useRef();
- <Portal container={container} onRendered={() => doSomethingWith(portalRef.current)} ref={portalRef} />
+ <Portal container={container} ref={doSomethingWith} />

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, interesting. I have never thought about it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can re-evaluate dropping onRendered for callback refs in v5. For now this fix works.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm in favor of dropping the prop in v5. I will update the Modal implementation to stop using it in the next Modal pull request. Thanks for raising. I agree that it doesn't provide anything since the forwardRef effort was completed. 👌

@@ -1,10 +1,6 @@
import ownerDocument from '../utils/ownerDocument';
import ownerWindow from '../utils/ownerWindow';

export function isBody(node) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code.

packages/material-ui/src/Modal/TrapFocus.js Outdated Show resolved Hide resolved
@@ -94,52 +94,43 @@ describe('<Modal />', () => {
const wrapper = mount(modal);
const onClose = spy();
wrapper.setProps({ onClose });

const handler = wrapper.find('Modal').instance().handleBackdropClick;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove usages of .instance().

}),
);

export default function SimpleModal() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a TypeScript demo 👌

import Dialog from 'packages/material-ui/src/Dialog';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
import Dialog from '@material-ui/core/Dialog';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed all the usages of imports from packages/. Better have fewer ways of doing the same thing!

};

export default withTheme(SwipeableDrawer);
export default SwipeableDrawer;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove most of the usages of withTheme(). It should help with perf, bundle size and debug noise.

@@ -69,10 +69,6 @@ Portal.propTypes = {
onRendered: PropTypes.func,
};

Portal.defaultProps = {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move some of the .defaultProps to prop destructuring. I haven't migrated everything. I have left the complex objects and the one used in the custom prop-types.

packages/material-ui/src/Modal/TrapFocus.js Outdated Show resolved Hide resolved
packages/material-ui/src/Popover/Popover.js Outdated Show resolved Hide resolved
useEnhancedEffect(() => {
if (onRendered && mountNode) {
onRendered();
}
}, [mountNode, onRendered]);

React.useImperativeHandle(ref, () => mountNode || childRef.current, [mountNode]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait refs should never trigger before layout effects. Those are two different phases. Do you have a test for that?

@oliviertassinari oliviertassinari force-pushed the modal-e2e-tests branch 2 times, most recently from cf0664f to 6ebe7f6 Compare June 18, 2019 10:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: modal This is the name of the generic UI component, not the React module! test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants