From 4a3c31369cf8dc43e2877e1453df6720d56ccafc Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Wed, 24 Nov 2021 13:09:24 +0300 Subject: [PATCH] Use setTimeout instead of unstable onTransitionEnd Signed-off-by: Alex Andreev --- src/renderer/components/animate/animate.scss | 20 +++++------ src/renderer/components/animate/animate.tsx | 38 ++++++++++---------- src/renderer/components/dialog/dialog.tsx | 2 +- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/renderer/components/animate/animate.scss b/src/renderer/components/animate/animate.scss index 40bcd7c05e..8b6260c2d6 100644 --- a/src/renderer/components/animate/animate.scss +++ b/src/renderer/components/animate/animate.scss @@ -21,43 +21,43 @@ // Animations -@mixin animate-opacity($enterDuration: 100ms, $leaveDuration: 150ms) { +@mixin animate-opacity() { opacity: 0; &.enter { transition-property: opacity; - transition-duration: $enterDuration; + transition-duration: var(--enter-duration); opacity: 1; } &.leave { - transition-duration: $leaveDuration; + transition-duration: var(--leave-duration); transition-timing-function: ease-out; opacity: 0; } } -@mixin animate-slide-right($enterDuration: 100ms, $leaveDuration: 150ms) { +@mixin animate-slide-right() { transform: translateX(100%); will-change: transform; &.enter { transform: translateX(0); - transition: transform $enterDuration; + transition: transform var(--enter-duration); transition-timing-function: ease-in-out; } &.leave { transform: translateX(100%); - transition: transform $leaveDuration; + transition: transform var(--leave-duration); } } -@mixin animate-opacity-scale($enterDuration: 250ms, $leaveDuration: 150ms) { +@mixin animate-opacity-scale() { opacity: 0; &.enter { - transition: opacity $enterDuration; + transition: opacity var(--enter-duration); opacity: 1; } @@ -65,7 +65,7 @@ will-change: opacity, transform; opacity: 0; transform: scale(1.25); - transition: transform $leaveDuration ease-in, opacity $leaveDuration ease-out; + transition: transform var(--leave-duration) ease-in, opacity var(--leave-duration) ease-out; } } @@ -84,6 +84,6 @@ } &.opacity-scale { - @include animate-opacity-scale(100ms); + @include animate-opacity-scale; } } diff --git a/src/renderer/components/animate/animate.tsx b/src/renderer/components/animate/animate.tsx index 7bd2b0a18b..0391ea1e23 100644 --- a/src/renderer/components/animate/animate.tsx +++ b/src/renderer/components/animate/animate.tsx @@ -23,7 +23,7 @@ import "./animate.scss"; import React from "react"; import { observable, reaction, makeObservable } from "mobx"; import { disposeOnUnmount, observer } from "mobx-react"; -import { boundMethod, cssNames, noop } from "../../utils"; +import { cssNames, noop } from "../../utils"; export type AnimateName = "opacity" | "slide-right" | "opacity-scale" | string; @@ -32,17 +32,19 @@ export interface AnimateProps { enter?: boolean; onEnter?: () => void; onLeave?: () => void; + enterDuration?: number; + leaveDuration?: number; } @observer export class Animate extends React.Component { - static VISIBILITY_DELAY_MS = 0; - static defaultProps: AnimateProps = { name: "opacity", enter: true, onEnter: noop, onLeave: noop, + enterDuration: 100, + leaveDuration: 100, }; @observable isVisible = !!this.props.enter; @@ -66,7 +68,6 @@ export class Animate extends React.Component { if (enter) this.enter(); else this.leave(); }, { - delay: Animate.VISIBILITY_DELAY_MS, fireImmediately: true, }), ]); @@ -84,6 +85,11 @@ export class Animate extends React.Component { if (!this.isVisible) return; this.statusClassName.leave = true; this.props.onLeave(); + this.resetAfterLeaveDuration(); + } + + resetAfterLeaveDuration() { + setTimeout(() => this.reset(), this.props.leaveDuration); } reset() { @@ -92,27 +98,21 @@ export class Animate extends React.Component { this.statusClassName.leave = false; } - @boundMethod - onTransitionEnd(evt: React.TransitionEvent) { - const { enter, leave } = this.statusClassName; - const { onTransitionEnd } = this.contentElem.props; - - if (onTransitionEnd) onTransitionEnd(evt); - - // todo: check evt.propertyName and make sure all animating props has finished their transition - if (enter && leave) { - this.reset(); - } - } - render() { - const { name } = this.props; + const { name, enterDuration, leaveDuration } = this.props; const contentElem = this.contentElem; + const durations = { + "--enter-duration": `${enterDuration}ms`, + "--leave-duration": `${leaveDuration}ms`, + } as React.CSSProperties; return React.cloneElement(contentElem, { className: cssNames("Animate", name, contentElem.props.className, this.statusClassName), children: this.isVisible ? contentElem.props.children : null, - onTransitionEnd: this.onTransitionEnd, + style: { + ...contentElem.props.style, + ...durations, + }, }); } } diff --git a/src/renderer/components/dialog/dialog.tsx b/src/renderer/components/dialog/dialog.tsx index be28789eff..6c34c5eb0c 100644 --- a/src/renderer/components/dialog/dialog.tsx +++ b/src/renderer/components/dialog/dialog.tsx @@ -167,7 +167,7 @@ export class Dialog extends React.PureComponent { if (animated) { dialog = ( - + {dialog} );