Skip to content

Commit 3a5d0b1

Browse files
authored
Merge pull request #15783 from ethereum/fix-morpher-fade
feat: add fade transition for reduced motion
2 parents c4664aa + ac26c93 commit 3a5d0b1

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

src/components/Morpher/index.tsx

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import { useEffect, useRef, useState } from "react"
44

5+
import { cn } from "@/lib/utils/cn"
6+
57
import { usePrefersReducedMotion } from "@/hooks/usePrefersReducedMotion"
68

79
type MorpherProps = {
@@ -15,11 +17,12 @@ const Morpher = ({
1517
}: MorpherProps) => {
1618
const [currentText, setCurrentText] = useState(words[0])
1719
const [isAnimating, setIsAnimating] = useState(false)
20+
const [isFading, setIsFading] = useState(false)
1821
const { prefersReducedMotion } = usePrefersReducedMotion()
1922

2023
const morphTimeoutRef = useRef<NodeJS.Timeout | null>(null)
2124
const morphIntervalRef = useRef<NodeJS.Timeout | null>(null)
22-
const counterRef = useRef(1)
25+
const counterRef = useRef(0)
2326
const wordsRef = useRef(words)
2427
const currentTextRef = useRef(currentText)
2528
const isAnimatingRef = useRef(false)
@@ -114,13 +117,18 @@ const Morpher = ({
114117
}
115118

116119
useEffect(() => {
117-
// If reduced motion is preferred, show static text cycling
120+
// If reduced motion is preferred, show static text cycling with fade
118121
if (prefersReducedMotion) {
119122
morphIntervalRef.current = setInterval(() => {
120-
const nextWord = wordsRef.current[counterRef.current]
121-
setCurrentText(nextWord)
122-
currentTextRef.current = nextWord
123-
counterRef.current = (counterRef.current + 1) % wordsRef.current.length
123+
setIsFading(true)
124+
setTimeout(() => {
125+
counterRef.current =
126+
(counterRef.current + 1) % wordsRef.current.length
127+
const nextWord = wordsRef.current[counterRef.current]
128+
setCurrentText(nextWord)
129+
currentTextRef.current = nextWord
130+
setIsFading(false)
131+
}, 150) // Half of the fade duration
124132
}, 3000)
125133
} else {
126134
// Defer animation start by 2 seconds to improve initial page load
@@ -159,7 +167,16 @@ const Morpher = ({
159167
// eslint-disable-next-line react-hooks/exhaustive-deps
160168
}, [prefersReducedMotion, charSet])
161169

162-
return currentText
170+
return (
171+
<span
172+
className={cn(
173+
"transition-opacity duration-300 ease-in-out",
174+
prefersReducedMotion && isFading && "opacity-0"
175+
)}
176+
>
177+
{currentText}
178+
</span>
179+
)
163180
}
164181

165182
export default Morpher

0 commit comments

Comments
 (0)