-
Notifications
You must be signed in to change notification settings - Fork 842
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
update EuiOverlayMask to use react portal #254
Conversation
888c511
to
138694a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sweet!! I'm stoked that we're using the new portals. I had a few suggestions. Can we also add a note to the top of the component file about why there are no tests?
/**
* NOTE: We can't test this component because Enzyme doesn't support rendering
* into portals.
*/
import React, {
Component,
} from 'react';
@@ -2,6 +2,8 @@ import React, { | |||
Component, | |||
} from 'react'; | |||
import PropTypes from 'prop-types'; | |||
import { createPortal } from 'react-dom'; | |||
import classnames from 'classnames'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nit but we've been aliasing this as classNames
elsewhere.
className="euiOverlayMask" | ||
{...rest} | ||
/> | ||
if (!this.overlayMaskNode) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the docs recommend creating the node in the constructor and the using componentDidMount
to attach it to the DOM. I think we can also do away with this check when we remove it, unless you found a case in which it didn't already exist?
import React, {
Component,
} from 'react';
import PropTypes from 'prop-types';
import { createPortal } from 'react-dom';
import classNames from 'classnames';
export class EuiOverlayMask extends Component {
constructor(props) {
super(props);
const {
className,
children,
...rest
} = props;
this.overlayMaskNode = document.createElement('div');
this.overlayMaskNode.className = classNames(
'euiOverlayMask',
className
);
Object.keys(rest).forEach((key) => {
this.overlayMaskNode.setAttribute(key, rest[key]);
});
}
componentDidMount() {
document.body.classList.add('euiBody-hasOverlayMask');
document.body.appendChild(this.overlayMaskNode);
}
componentWillUnmount() {
document.body.classList.remove('euiBody-hasOverlayMask');
document.body.removeChild(this.overlayMaskNode);
this.overlayMaskNode = null;
}
render() {
return createPortal(
this.props.children,
this.overlayMaskNode
);
}
}
EuiOverlayMask.propTypes = {
className: PropTypes.string,
children: PropTypes.node,
};
@@ -34,7 +34,7 @@ export class ConfirmModal extends Component { | |||
|
|||
if (this.state.isModalVisible) { | |||
modal = ( | |||
<EuiOverlayMask> | |||
<EuiOverlayMask data-test-subj="exampleOverlayMask" className="test1"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need these attributes for the example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Use react portal to mount the euiOverlayMask div directly to the body element to avoid situations where EuiOverlayMask does not cover entire screen. Below the kibana nav is on top of the euiOverlayMask div despite proper z-index settings.
Unfortunately, enzyme does not support Portals so there is no way to test snapshots