diff --git a/stylesheets/components/CompositionInput.scss b/stylesheets/components/CompositionInput.scss index e1c6fc9fec74..ac427c4992ad 100644 --- a/stylesheets/components/CompositionInput.scss +++ b/stylesheets/components/CompositionInput.scss @@ -194,6 +194,9 @@ border-radius: 4px; margin-bottom: 8px; + opacity: 0; + transition: opacity 120ms ease-out; + @include light-theme { background-color: $color-black; color: $color-gray-05; diff --git a/ts/quill/formatting/menu.tsx b/ts/quill/formatting/menu.tsx index c6b8adfa2e41..d7d5bc1512a6 100644 --- a/ts/quill/formatting/menu.tsx +++ b/ts/quill/formatting/menu.tsx @@ -15,10 +15,10 @@ import * as log from '../../logging/log'; import * as Errors from '../../types/errors'; import type { LocalizerType } from '../../types/Util'; import { handleOutsideClick } from '../../util/handleOutsideClick'; -import { SECOND } from '../../util/durations/constants'; -const FADE_OUT_MS = 200; -const BUTTON_HOVER_TIMEOUT = 2 * SECOND; +const MENU_FADE_OUT_MS = 200; +const POPUP_GUIDE_FADE_MS = 120; +const BUTTON_HOVER_TIMEOUT_MS = 900; const MENU_TEXT_BUFFER = 12; // pixels // Note: Keyboard shortcuts are defined in the constructor below, and when using @@ -160,7 +160,7 @@ export class FormattingMenu { this.lastRect = undefined; this.fadingOutTimeout = undefined; this.render(); - }, FADE_OUT_MS); + }, MENU_FADE_OUT_MS); this.render(); } @@ -452,34 +452,47 @@ function FormattingButton({ toggleForStyle: (style: QuillFormattingStyle) => unknown; }): JSX.Element { const buttonRef = React.useRef(null); - const timerRef = React.useRef(); + const [isHovered, setIsHovered] = React.useState(false); + const hoverTimerRef = React.useRef(); + + const [isFadingOut, setIsFadingOut] = React.useState(false); + const fadeOutTimerRef = React.useRef(); React.useEffect(() => { return () => { - if (timerRef.current) { - clearTimeout(timerRef.current); - timerRef.current = undefined; + if (hoverTimerRef.current) { + clearTimeout(hoverTimerRef.current); + hoverTimerRef.current = undefined; + } + + if (fadeOutTimerRef.current) { + clearTimeout(fadeOutTimerRef.current); + fadeOutTimerRef.current = undefined; } }; }, []); return ( <> - {hasLongHovered && isHovered && buttonRef.current ? ( + {(isFadingOut || (hasLongHovered && isHovered)) && buttonRef.current ? ( - {({ ref, style: popperStyles }) => ( -
- {popupGuideText} -
- {popupGuideShortcut} + {({ ref, style: popperStyles }) => { + const opacity = !popperStyles.transform || isFadingOut ? 0 : 1; + + return ( +
+ {popupGuideText} +
+ {popupGuideShortcut} +
-
- )} + ); + }} ) : null}