diff --git a/src/_pages/LandingPage/components/HeaderView/components/Astronaut/astronauts/AstronautDark.tsx b/src/_pages/LandingPage/components/HeaderView/components/Astronaut/astronauts/AstronautDark.tsx index 15b56b88..cef0ef3a 100644 --- a/src/_pages/LandingPage/components/HeaderView/components/Astronaut/astronauts/AstronautDark.tsx +++ b/src/_pages/LandingPage/components/HeaderView/components/Astronaut/astronauts/AstronautDark.tsx @@ -1,12 +1,13 @@ import React from 'react'; type Props = { - onMouseEnter: (event: React.MouseEvent) => void; + onMouseEnter?: (event: React.MouseEvent) => void; + onMouseLeave?: (event: React.MouseEvent) => void; className?: string; }; const AstronautDark: React.FC = (props) => { - const { onMouseEnter, className } = props; + const { onMouseEnter, onMouseLeave, className } = props; return ( = (props) => { + onMouseEnter={onMouseEnter} + onMouseLeave={onMouseLeave}> ) => void; + onMouseEnter?: (event: React.MouseEvent) => void; + onMouseLeave?: (event: React.MouseEvent) => void; className?: string; }; const AstronautLight: React.FC = (props) => { - const { onMouseEnter, className } = props; + const { onMouseEnter, onMouseLeave, className } = props; return ( = (props) => { + onMouseEnter={onMouseEnter} + onMouseLeave={onMouseLeave}> = (props) => { const { className } = props; const [timing] = useState(200); - const [isRaised, setIsRaised] = React.useState(false); + const [isRaised, setIsRaised] = useState(false); + const [isOnAstronaut, setIsOnAstronaut] = useState(false); const animated_Astronaut = useSpring({ transform: isRaised ? `translateY(-${30}px)` : `translateY(0px)`, config: { @@ -23,10 +24,20 @@ const Astronaut: React.FC = (props) => { }); const dark = useAgile(core.ui.ASTRONAUT_DARK); + const [mounted, setMounted] = useState(false); + // The astronaut theme on SSR is always the default theme but the site theme + // can be in a different mode. React hydration doesn't update DOM styles + // that come from SSR. Hence force a re-render after mounting to apply the + // current relevant styles. There will be a flash seen of the original + // styles seen using this current approach but that's probably ok. Fixing + // the flash will require changing the theming approach and is not worth it + // at this point. useEffect(() => { - if (!isRaised) { - return; - } + setMounted(true); + }, []); + + useEffect(() => { + if (!isRaised) return; const timeoutId = setTimeout(() => { core.ui.toggleAstronautColor(!dark); @@ -36,19 +47,35 @@ const Astronaut: React.FC = (props) => { return () => clearTimeout(timeoutId); }, [isRaised, timing]); - function trigger() { - setIsRaised(true); - } + const onMouseEnter = () => { + if (!isOnAstronaut) { + setIsOnAstronaut(true); + setIsRaised(true); + } + }; + + const onMouseLeave = () => { + // to prevent endless bouncer + setTimeout(() => { + setIsOnAstronaut(false); + }, 1100); + }; return ( -
+
{dark ? ( - + ) : ( - + )}
Poke me 👆 to mutate my color State.