fix(ui): fix modal animations

This commit is contained in:
Łukasz Mierzwa
2020-07-24 09:51:22 +01:00
committed by Łukasz Mierzwa
parent 8bce6d086c
commit 020213b32a
4 changed files with 47 additions and 73 deletions

View File

@@ -1,39 +0,0 @@
import React, { FC, ReactNode } from "react";
import { CSSTransition } from "react-transition-group";
const MountModal: FC<{
children: ReactNode;
in: boolean;
unmountOnExit?: boolean;
}> = ({ children, ...props }) => (
<CSSTransition
classNames="components-animation-modal"
timeout={200}
appear={true}
enter={true}
exit={true}
{...props}
>
{children}
</CSSTransition>
);
const MountModalBackdrop: FC<{
children: ReactNode;
in?: boolean;
unmountOnExit?: boolean;
}> = ({ children, ...props }) => (
<CSSTransition
classNames="components-animation-backdrop"
timeout={200}
appear={true}
enter={true}
exit={true}
{...props}
>
{children}
</CSSTransition>
);
export { MountModal, MountModalBackdrop };

View File

@@ -99,14 +99,14 @@ describe("<ModalInner />", () => {
expect(document.body.className.split(" ")).toContain("modal-open");
});
it("passes extra props down to the MountModal animation component", () => {
it("passes extra props down to the CSSTransition animation component", () => {
const onExited = jest.fn();
const tree = mount(
<Modal isOpen={true} toggleOpen={fakeToggle} onExited={onExited}>
<div />
</Modal>
);
const mountModal = tree.find("MountModal");
const mountModal = tree.find("CSSTransition").at(0);
expect((mountModal.props() as any).onExited).toBe(onExited);
});

View File

@@ -1,15 +1,12 @@
import React, { FC, useEffect } from "react";
import ReactDOM from "react-dom";
import { CSSTransition } from "react-transition-group";
import { disableBodyScroll, enableBodyScroll } from "body-scroll-lock";
import { useHotkeys } from "react-hotkeys-hook";
import {
MountModal,
MountModalBackdrop,
} from "Components/Animations/MountModal";
const ModalInner: FC<{
size: "lg" | "xl";
isUpper: boolean;
@@ -60,19 +57,34 @@ const Modal: FC<{
isOpen,
isUpper = false,
toggleOpen,
onExited,
children,
...props
}) => {
return ReactDOM.createPortal(
<React.Fragment>
<MountModal in={isOpen} unmountOnExit {...props}>
<CSSTransition
in={isOpen}
classNames="components-animation-modal"
timeout={300}
onExited={onExited}
enter
exit
unmountOnExit
>
<ModalInner size={size} isUpper={isUpper} toggleOpen={toggleOpen}>
{children}
</ModalInner>
</MountModal>
<MountModalBackdrop in={isOpen} unmountOnExit>
</CSSTransition>
<CSSTransition
in={isOpen && !isUpper}
classNames="components-animation-backdrop"
timeout={300}
enter
exit
unmountOnExit
>
<div className="modal-backdrop d-block" />
</MountModalBackdrop>
</CSSTransition>
</React.Fragment>,
document.body
);

View File

@@ -1,51 +1,52 @@
$duration: 0.2s;
$duration: 0.3s;
$move: -33%;
$opacity-modal: 0.5;
$opacity-bg: 0.8;
$easing: ease-in-out;
.components-animation-modal {
will-change: opacity, transform;
transform: translateZ(0);
}
.components-animation-modal-appear,
.components-animation-modal-enter {
opacity: 0.01;
transform: translate(0, -25%);
.components-animation-modal-enter > .modal > .modal-dialog {
opacity: $opacity-modal;
transform: translate(0, $move);
}
.components-animation-modal-appear-active,
.components-animation-modal-enter-active {
.components-animation-modal-enter-active > .modal > .modal-dialog {
opacity: 1;
transition: transform $duration ease-out, opacity $duration ease-in;
transition: transform $duration $easing, opacity $duration $easing;
transform: translate(0, 0);
}
.components-animation-modal-exit {
.components-animation-modal-exit > .modal > .modal-dialog {
opacity: 1;
transform: translate(0, 0);
}
.components-animation-modal-exit-active {
opacity: 0.01;
transform: translate(0, -25%);
transition: transform $duration ease-in, opacity $duration ease-out;
.components-animation-modal-exit-active > .modal > .modal-dialog {
opacity: $opacity-modal;
transform: translate(0, $move);
transition: transform $duration $easing, opacity $duration $easing;
}
.components-animation-backdrop-appear,
.components-animation-backdrop-enter {
opacity: 0.01;
opacity: $opacity-modal;
}
.components-animation-backdrop-appear-active,
.components-animation-backdrop-enter-active {
opacity: $modal-backdrop-opacity;
transition: opacity $duration ease-in;
opacity: $opacity-bg;
transition: opacity $duration $easing;
}
.components-animation-backdrop-enter-done {
opacity: $modal-backdrop-opacity;
transition: opacity $duration ease-in;
opacity: $opacity-bg;
transition: opacity $duration $easing;
}
.components-animation-backdrop-exit {
opacity: $modal-backdrop-opacity;
opacity: $opacity-bg;
}
.components-animation-backdrop-exit-active {
opacity: 0.01;
transition: opacity $duration ease-out;
transition: opacity $duration $easing;
}