refactor(react-dapp-v2): refactor Modal to React hooks

This commit is contained in:
Ben Kremer 2022-02-02 17:04:21 +01:00
parent 2201fed80b
commit b9f59295c8

View File

@ -1,15 +1,12 @@
import * as React from "react"; import React, { useEffect, useRef, useState } from "react";
import * as PropTypes from "prop-types";
import styled from "styled-components"; import styled from "styled-components";
import { colors, transitions } from "../styles"; import { colors, transitions } from "../styles";
interface LightboxStyleProps { const SLightbox = styled.div<{
show: boolean; show: boolean;
offset: number; offset: number;
opacity?: number; opacity?: number;
} }>`
const SLightbox = styled.div<LightboxStyleProps>`
transition: opacity 0.1s ease-in-out; transition: opacity 0.1s ease-in-out;
text-align: center; text-align: center;
position: absolute; position: absolute;
@ -107,75 +104,38 @@ const SModalContent = styled.div`
word-wrap: break-word; word-wrap: break-word;
`; `;
interface ModalState { interface IProps {
offset: number;
}
interface ModalProps {
children: React.ReactNode; children: React.ReactNode;
show: boolean; show: boolean;
closeModal: any; closeModal: () => void;
opacity?: number; opacity?: number;
} }
const INITIAL_STATE: ModalState = { export default function Modal({ children, show, opacity, closeModal }: IProps) {
offset: 0, const [offset, setOffset] = useState(0);
}; const lightboxRef = useRef<HTMLDivElement>(null);
class Modal extends React.Component<ModalProps, ModalState> { useEffect(() => {
public static propTypes = { if (lightboxRef.current) {
children: PropTypes.node.isRequired, const lightboxRect = lightboxRef.current.getBoundingClientRect();
show: PropTypes.bool.isRequired, const nextOffset = lightboxRect.top > 0 ? lightboxRect.top : 0;
closeModal: PropTypes.func.isRequired,
opacity: PropTypes.number,
};
public lightbox?: HTMLDivElement | null; if (nextOffset !== 0 && nextOffset !== offset) {
setOffset(nextOffset);
public state: ModalState = {
...INITIAL_STATE,
};
public componentDidUpdate() {
if (this.lightbox) {
const lightboxRect = this.lightbox.getBoundingClientRect();
const offset = lightboxRect.top > 0 ? lightboxRect.top : 0;
if (offset !== INITIAL_STATE.offset && offset !== this.state.offset) {
this.setState({ offset });
}
} }
} }
}, [offset]);
public closeModal = async () => {
const d = typeof window !== "undefined" ? document : "";
const body = d ? d.body || d.getElementsByTagName("body")[0] : "";
if (body) {
if (this.props.show) {
body.style.position = "";
} else {
body.style.position = "fixed";
}
}
this.props.closeModal();
};
public render() {
const { offset } = this.state;
const { children, show, opacity } = this.props;
return ( return (
<SLightbox show={show} offset={offset} opacity={opacity} ref={c => (this.lightbox = c)}> <SLightbox show={show} offset={offset} opacity={opacity} ref={lightboxRef}>
<SModalContainer> <SModalContainer>
<SHitbox onClick={this.closeModal} /> <SHitbox onClick={closeModal} />
<SCard> <SCard>
<SCloseButton size={25} color={"dark"} onClick={this.closeModal} /> <SCloseButton size={25} color={"dark"} onClick={closeModal} />
<SModalContent>{children}</SModalContent> <SModalContent>{children}</SModalContent>
</SCard> </SCard>
</SModalContainer> </SModalContainer>
</SLightbox> </SLightbox>
); );
} }
}
export default Modal;