Skip to content

Commit 0854d43

Browse files
committed
Convert Overlay to a function component.
1 parent 9da5535 commit 0854d43

File tree

1 file changed

+56
-87
lines changed

1 file changed

+56
-87
lines changed
Lines changed: 56 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,81 @@
11
import PropTypes from 'prop-types';
2-
import React from 'react';
2+
import React, { useCallback, useRef } from 'react';
3+
import { useSelector } from 'react-redux';
34
import { browserHistory } from 'react-router';
4-
import { withTranslation } from 'react-i18next';
5+
import { useTranslation } from 'react-i18next';
6+
import useModalClose from '../../../common/useModalClose';
57

68
import ExitIcon from '../../../images/exit.svg';
79

8-
class Overlay extends React.Component {
9-
constructor(props) {
10-
super(props);
11-
this.close = this.close.bind(this);
12-
this.handleClick = this.handleClick.bind(this);
13-
this.handleClickOutside = this.handleClickOutside.bind(this);
14-
this.keyPressHandle = this.keyPressHandle.bind(this);
15-
}
10+
const Overlay = ({
11+
actions,
12+
ariaLabel,
13+
children,
14+
closeOverlay,
15+
isFixedHeight,
16+
title
17+
}) => {
18+
const { t } = useTranslation();
1619

17-
componentWillMount() {
18-
document.addEventListener('mousedown', this.handleClick, false);
19-
document.addEventListener('keydown', this.keyPressHandle);
20-
}
20+
const previousPath = useSelector((state) => state.ide.previousPath);
2121

22-
componentDidMount() {
23-
this.node.focus();
24-
}
22+
const ref = useRef(null);
2523

26-
componentWillUnmount() {
27-
document.removeEventListener('mousedown', this.handleClick, false);
28-
document.removeEventListener('keydown', this.keyPressHandle);
29-
}
30-
31-
handleClick(e) {
32-
if (this.node.contains(e.target)) {
33-
return;
34-
}
35-
36-
this.handleClickOutside(e);
37-
}
38-
39-
handleClickOutside() {
40-
this.close();
41-
}
42-
43-
keyPressHandle(e) {
44-
// escape key code = 27.
45-
// So here we are checking if the key pressed was Escape key.
46-
if (e.keyCode === 27) {
47-
this.close();
48-
}
49-
}
50-
51-
close() {
24+
const close = useCallback(() => {
25+
const node = ref.current;
26+
if (!node) return;
5227
// Only close if it is the last (and therefore the topmost overlay)
5328
const overlays = document.getElementsByClassName('overlay');
54-
if (this.node.parentElement.parentElement !== overlays[overlays.length - 1])
29+
if (node.parentElement.parentElement !== overlays[overlays.length - 1])
5530
return;
5631

57-
if (!this.props.closeOverlay) {
58-
browserHistory.push(this.props.previousPath);
32+
if (!closeOverlay) {
33+
browserHistory.push(previousPath);
5934
} else {
60-
this.props.closeOverlay();
35+
closeOverlay();
6136
}
62-
}
37+
}, [previousPath, closeOverlay, ref]);
6338

64-
render() {
65-
const { ariaLabel, title, children, actions, isFixedHeight } = this.props;
66-
return (
67-
<div
68-
className={`overlay ${isFixedHeight ? 'overlay--is-fixed-height' : ''}`}
69-
>
70-
<div className="overlay__content">
71-
<section
72-
role="main"
73-
aria-label={ariaLabel}
74-
ref={(node) => {
75-
this.node = node;
76-
}}
77-
className="overlay__body"
78-
>
79-
<header className="overlay__header">
80-
<h2 className="overlay__title">{title}</h2>
81-
<div className="overlay__actions">
82-
{actions}
83-
<button
84-
className="overlay__close-button"
85-
onClick={this.close}
86-
aria-label={this.props.t('Overlay.AriaLabel', { title })}
87-
>
88-
<ExitIcon focusable="false" aria-hidden="true" />
89-
</button>
90-
</div>
91-
</header>
92-
{children}
93-
</section>
94-
</div>
39+
useModalClose(close, ref);
40+
41+
return (
42+
<div
43+
className={`overlay ${isFixedHeight ? 'overlay--is-fixed-height' : ''}`}
44+
>
45+
<div className="overlay__content">
46+
<section
47+
role="main"
48+
aria-label={ariaLabel}
49+
ref={ref}
50+
className="overlay__body"
51+
>
52+
<header className="overlay__header">
53+
<h2 className="overlay__title">{title}</h2>
54+
<div className="overlay__actions">
55+
{actions}
56+
<button
57+
className="overlay__close-button"
58+
onClick={close}
59+
aria-label={t('Overlay.AriaLabel', { title })}
60+
>
61+
<ExitIcon focusable="false" aria-hidden="true" />
62+
</button>
63+
</div>
64+
</header>
65+
{children}
66+
</section>
9567
</div>
96-
);
97-
}
98-
}
68+
</div>
69+
);
70+
};
9971

10072
Overlay.propTypes = {
10173
children: PropTypes.element,
10274
actions: PropTypes.element,
10375
closeOverlay: PropTypes.func,
10476
title: PropTypes.string,
10577
ariaLabel: PropTypes.string,
106-
previousPath: PropTypes.string,
107-
isFixedHeight: PropTypes.bool,
108-
t: PropTypes.func.isRequired
78+
isFixedHeight: PropTypes.bool
10979
};
11080

11181
Overlay.defaultProps = {
@@ -114,8 +84,7 @@ Overlay.defaultProps = {
11484
title: 'Modal',
11585
closeOverlay: null,
11686
ariaLabel: 'modal',
117-
previousPath: '/',
11887
isFixedHeight: false
11988
};
12089

121-
export default withTranslation()(Overlay);
90+
export default Overlay;

0 commit comments

Comments
 (0)