accounts-frontend/packages/app/components/ui/popup/PopupStack.tsx

105 lines
2.9 KiB
TypeScript
Raw Normal View History

import React, { ReactNode } from 'react';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import { browserHistory } from 'app/services/history';
import { connect } from 'react-redux';
import { Location } from 'history';
import { RootState } from 'app/reducers';
2016-06-04 01:08:59 +05:30
2019-12-07 16:58:52 +05:30
import { PopupConfig } from './reducer';
import { destroy } from './actions';
import styles from './popup.scss';
interface Props {
2020-05-24 04:38:24 +05:30
popups: PopupConfig[];
destroy: (popup: PopupConfig) => void;
}
export class PopupStack extends React.Component<Props> {
2020-05-24 04:38:24 +05:30
unlistenTransition: () => void;
componentDidMount(): void {
2020-05-24 04:38:24 +05:30
document.addEventListener('keyup', this.onKeyPress);
this.unlistenTransition = browserHistory.listen(this.onRouteLeave);
}
2016-07-26 10:50:37 +05:30
componentWillUnmount(): void {
2020-05-24 04:38:24 +05:30
document.removeEventListener('keyup', this.onKeyPress);
this.unlistenTransition();
2016-07-26 10:50:37 +05:30
}
render(): ReactNode {
2020-05-24 04:38:24 +05:30
const { popups } = this.props;
return (
<TransitionGroup>
{popups.map((popup, index) => {
const { Popup } = popup;
return (
<CSSTransition
key={index}
classNames={{
enter: styles.trEnter,
enterActive: styles.trEnterActive,
exit: styles.trExit,
exitActive: styles.trExitActive,
}}
timeout={500}
>
<div className={styles.overlay} role="dialog" onClick={this.onOverlayClick(popup)}>
<Popup onClose={this.onClose(popup)} />
</div>
</CSSTransition>
);
})}
</TransitionGroup>
);
}
2020-05-24 04:38:24 +05:30
onClose(popup: PopupConfig) {
return (): void => this.props.destroy(popup);
}
2020-05-24 04:38:24 +05:30
onOverlayClick(popup: PopupConfig) {
return (event: React.MouseEvent<HTMLDivElement>): void => {
2020-05-24 04:38:24 +05:30
if (event.target !== event.currentTarget || popup.disableOverlayClose) {
return;
}
event.preventDefault();
this.props.destroy(popup);
};
}
popStack(): void {
2020-05-24 04:38:24 +05:30
const [popup] = this.props.popups.slice(-1);
if (popup && !popup.disableOverlayClose) {
this.props.destroy(popup);
}
}
onKeyPress = (event: KeyboardEvent): void => {
if (event.code === 'Escape') {
2020-05-24 04:38:24 +05:30
// ESC key
this.popStack();
}
};
onRouteLeave = (nextLocation: Location): void => {
2020-05-24 04:38:24 +05:30
if (nextLocation) {
this.popStack();
}
};
}
export default connect(
2020-05-24 04:38:24 +05:30
(state: RootState) => ({
...state.popup,
}),
{
destroy,
},
)(PopupStack);