feature: add closeOnBackdropClick and closeOnEsc props in modal

This commit is contained in:
George Lima 2018-12-19 15:35:39 -03:00
parent bdb4680057
commit 17a254ee5e
1 changed files with 26 additions and 7 deletions

View File

@ -22,7 +22,9 @@ const ChildrenWrapper = styled.div`
type Props = { type Props = {
renderTrigger: (() => void) => Element<*>, renderTrigger: (() => void) => Element<*>,
children: Element<*>, children: (() => void) => Element<*>,
closeOnBackdropClick?: boolean,
closeOnEsc?: boolean,
}; };
type State = { type State = {
@ -34,16 +36,29 @@ const modalRoot = document.getElementById('modal-root');
export class ModalComponent extends PureComponent<Props, State> { export class ModalComponent extends PureComponent<Props, State> {
element = document.createElement('div'); element = document.createElement('div');
static defaultProps = {
closeOnBackdropClick: true,
closeOnEsc: true,
};
state = { state = {
isVisible: false, isVisible: false,
}; };
componentDidMount() { componentDidMount() {
window.addEventListener('keydown', this.handleEscPress); const { closeOnEsc } = this.props;
if (closeOnEsc) {
window.addEventListener('keydown', this.handleEscPress);
}
} }
componentWillUnmount() { componentWillUnmount() {
window.removeEventListener('keydown', this.handleEscPress); const { closeOnEsc } = this.props;
if (closeOnEsc) {
window.removeEventListener('keydown', this.handleEscPress);
}
} }
handleEscPress = (event: Object) => { handleEscPress = (event: Object) => {
@ -73,21 +88,25 @@ export class ModalComponent extends PureComponent<Props, State> {
}; };
render() { render() {
const { renderTrigger, children } = this.props; const { renderTrigger, children, closeOnBackdropClick } = this.props;
const { isVisible } = this.state; const { isVisible } = this.state;
const toggleVisibility = isVisible ? this.close : this.open;
return ( return (
<Fragment> <Fragment>
{renderTrigger(isVisible ? this.close : this.open)} {renderTrigger(toggleVisibility)}
{isVisible {isVisible
? createPortal( ? createPortal(
<ModalWrapper <ModalWrapper
id='modal-portal-wrapper' id='modal-portal-wrapper'
onClick={(event) => { onClick={(event) => {
if (event.target.id === 'modal-portal-wrapper') this.close(); if (
closeOnBackdropClick
&& event.target.id === 'modal-portal-wrapper'
) this.close();
}} }}
> >
<ChildrenWrapper>{children}</ChildrenWrapper> <ChildrenWrapper>{children(toggleVisibility)}</ChildrenWrapper>
</ModalWrapper>, </ModalWrapper>,
this.element, this.element,
) )