mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-26 03:24:18 +00:00
Refactor Overlay to not use CSS
This commit is contained in:
parent
4cd0800cc0
commit
86f9abf5dd
3 changed files with 117 additions and 119 deletions
30
src/App.css
30
src/App.css
|
|
@ -133,10 +133,6 @@ button:active {
|
|||
margin-top: 46px; /* This matches the height of #search */
|
||||
}
|
||||
|
||||
body.overlay-open {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#webamp {
|
||||
opacity: 0;
|
||||
transition: opacity 400ms ease-in-out;
|
||||
|
|
@ -163,32 +159,6 @@ body.webamp-loaded #webamp {
|
|||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
z-index: 1000;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
transition: background-color 400ms ease-out;
|
||||
}
|
||||
|
||||
body.overlay-open .overlay {
|
||||
background: rgba(0, 0, 0, 0.95);
|
||||
}
|
||||
|
||||
#close-modal {
|
||||
color: #a7a394;
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
padding: 0;
|
||||
font-size: 50px;
|
||||
line-height: 25px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.metadata {
|
||||
position: absolute;
|
||||
margin: 10px;
|
||||
|
|
|
|||
|
|
@ -1,97 +1,10 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { connect } from "react-redux";
|
||||
import * as ActionCreators from "./redux/actionCreators";
|
||||
|
||||
class Overlay extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
this._node = document.createElement("div");
|
||||
this._node.classList.add("overlay");
|
||||
this._handleKeyDown = this._handleKeyDown.bind(this);
|
||||
this._handleClick = this._handleClick.bind(this);
|
||||
this._handleTouchMove = this._handleTouchMove.bind(this);
|
||||
|
||||
window.document.body.appendChild(this._node);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.document.addEventListener("keydown", this._handleKeyDown);
|
||||
window.document.addEventListener("touchmove", this._handleTouchMove);
|
||||
// TODO: This is technically a race condition, since we could unmount before this fires.
|
||||
if (this.props.shouldAnimate) {
|
||||
setTimeout(() => {
|
||||
// This does not seem to work the first time.
|
||||
// This should _not_ work on page load
|
||||
document.body.classList.add("overlay-open");
|
||||
}, 0);
|
||||
} else {
|
||||
document.body.classList.add("overlay-open");
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.document.body.removeChild(this._node);
|
||||
window.document.removeEventListener("keydown", this._handleKeyDown);
|
||||
window.document.removeEventListener("touchmove", this._handleTouchMove);
|
||||
document.body.classList.remove("overlay-open");
|
||||
}
|
||||
|
||||
_handleTouchMove(e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
_handleKeyDown(e) {
|
||||
// Esc
|
||||
if (e.keyCode === 27) {
|
||||
this.props.closeModal();
|
||||
}
|
||||
}
|
||||
|
||||
_handleClick(e) {
|
||||
if (e.target === e.currentTarget) {
|
||||
this.props.closeModal();
|
||||
}
|
||||
}
|
||||
render() {
|
||||
return ReactDOM.createPortal(
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
// This one werid hack to work around margin collapse which was making
|
||||
// children with top margins cause the top protion of the overlay to
|
||||
// be unclickable: https://stackoverflow.com/a/47351270/1263117
|
||||
display: "flex",
|
||||
flexDirection: "column"
|
||||
}}
|
||||
onClick={this._handleClick}
|
||||
onScroll={e => e.stopPropagation()}
|
||||
>
|
||||
<a
|
||||
id="close-modal"
|
||||
href="/"
|
||||
onClick={e => {
|
||||
this.props.closeModal();
|
||||
e.preventDefault();
|
||||
}}
|
||||
aria-label="Close Modal"
|
||||
>
|
||||
×
|
||||
</a>
|
||||
{this.props.children}
|
||||
</div>,
|
||||
this._node
|
||||
);
|
||||
}
|
||||
}
|
||||
import BaseOverlay from "./components/BaseOverlay";
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
closeModal() {
|
||||
dispatch(ActionCreators.closeModal());
|
||||
}
|
||||
});
|
||||
export default connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
)(Overlay);
|
||||
export default connect(null, mapDispatchToProps)(BaseOverlay);
|
||||
|
|
|
|||
115
src/components/BaseOverlay.js
Normal file
115
src/components/BaseOverlay.js
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
import React, {
|
||||
useEffect,
|
||||
useCallback,
|
||||
useLayoutEffect,
|
||||
useState
|
||||
} from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
function handleTouchMove(e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
function Overlay({ shouldAnimate, closeModal, children }) {
|
||||
const [mounted, setMounted] = useState();
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const timeout = setTimeout(() => {
|
||||
setMounted(true);
|
||||
});
|
||||
const bodyOverflow = document.body.style.overflow;
|
||||
document.body.style.overflow = "hidden";
|
||||
return () => {
|
||||
document.body.style.overflow = bodyOverflow;
|
||||
if (timeout != null) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleClick = useCallback(
|
||||
e => {
|
||||
if (e.target === e.currentTarget) {
|
||||
closeModal();
|
||||
}
|
||||
},
|
||||
[closeModal]
|
||||
);
|
||||
|
||||
const handleKeyDown = useCallback(
|
||||
e => {
|
||||
// Esc
|
||||
if (e.keyCode === 27) {
|
||||
closeModal();
|
||||
}
|
||||
},
|
||||
[closeModal]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
window.document.addEventListener("keydown", handleKeyDown);
|
||||
window.document.addEventListener("touchmove", handleTouchMove);
|
||||
return () => {
|
||||
window.document.removeEventListener("keydown", handleKeyDown);
|
||||
window.document.removeEventListener("touchmove", handleTouchMove);
|
||||
};
|
||||
}, [handleKeyDown]);
|
||||
|
||||
return ReactDOM.createPortal(
|
||||
<div
|
||||
style={{
|
||||
zIndex: 1000,
|
||||
position: "fixed",
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backgroundColor:
|
||||
!shouldAnimate || mounted
|
||||
? "rgba(0, 0, 0, 0.95)"
|
||||
: "rgba(0, 0, 0, 0)",
|
||||
transition: "background-color 400ms ease-out"
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
// This one werid hack to work around margin collapse which was making
|
||||
// children with top margins cause the top protion of the overlay to
|
||||
// be unclickable: https://stackoverflow.com/a/47351270/1263117
|
||||
display: "flex",
|
||||
flexDirection: "column"
|
||||
}}
|
||||
onClick={handleClick}
|
||||
onScroll={handleTouchMove}
|
||||
>
|
||||
<a
|
||||
id="close-modal"
|
||||
href="/"
|
||||
onClick={e => {
|
||||
closeModal();
|
||||
e.preventDefault();
|
||||
}}
|
||||
aria-label="Close Modal"
|
||||
style={{
|
||||
color: "#a7a394",
|
||||
position: "fixed",
|
||||
top: 10,
|
||||
right: 10,
|
||||
padding: 0,
|
||||
fontSize: 50,
|
||||
lineHeight: "25px",
|
||||
textDecoration: "none"
|
||||
}}
|
||||
>
|
||||
×
|
||||
</a>
|
||||
{children}
|
||||
</div>
|
||||
</div>,
|
||||
window.document.body
|
||||
);
|
||||
}
|
||||
|
||||
export default Overlay;
|
||||
Loading…
Add table
Add a link
Reference in a new issue