diff --git a/public/r/TrueFocus-JS-CSS.json b/public/r/TrueFocus-JS-CSS.json
index 11873834..007f62a0 100644
--- a/public/r/TrueFocus-JS-CSS.json
+++ b/public/r/TrueFocus-JS-CSS.json
@@ -10,7 +10,7 @@
"files": [
{
"path": "public/default/src/content/TextAnimations/TrueFocus/TrueFocus.jsx",
- "content": "import { useEffect, useRef, useState } from 'react';\nimport { motion } from 'motion/react';\nimport './TrueFocus.css';\n\nconst TrueFocus = ({\n sentence = 'True Focus',\n manualMode = false,\n blurAmount = 5,\n borderColor = 'green',\n glowColor = 'rgba(0, 255, 0, 0.6)',\n animationDuration = 0.5,\n pauseBetweenAnimations = 1\n}) => {\n const words = sentence.split(' ');\n const [currentIndex, setCurrentIndex] = useState(0);\n const [lastActiveIndex, setLastActiveIndex] = useState(null);\n const containerRef = useRef(null);\n const wordRefs = useRef([]);\n const [focusRect, setFocusRect] = useState({ x: 0, y: 0, width: 0, height: 0 });\n\n useEffect(() => {\n if (!manualMode) {\n const interval = setInterval(\n () => {\n setCurrentIndex(prev => (prev + 1) % words.length);\n },\n (animationDuration + pauseBetweenAnimations) * 1000\n );\n\n return () => clearInterval(interval);\n }\n }, [manualMode, animationDuration, pauseBetweenAnimations, words.length]);\n\n useEffect(() => {\n if (currentIndex === null || currentIndex === -1) return;\n\n if (!wordRefs.current[currentIndex] || !containerRef.current) return;\n\n const parentRect = containerRef.current.getBoundingClientRect();\n const activeRect = wordRefs.current[currentIndex].getBoundingClientRect();\n\n setFocusRect({\n x: activeRect.left - parentRect.left,\n y: activeRect.top - parentRect.top,\n width: activeRect.width,\n height: activeRect.height\n });\n }, [currentIndex, words.length]);\n\n const handleMouseEnter = index => {\n if (manualMode) {\n setLastActiveIndex(index);\n setCurrentIndex(index);\n }\n };\n\n const handleMouseLeave = () => {\n if (manualMode) {\n setCurrentIndex(lastActiveIndex);\n }\n };\n\n return (\n
\n {words.map((word, index) => {\n const isActive = index === currentIndex;\n return (\n (wordRefs.current[index] = el)}\n className={`focus-word ${manualMode ? 'manual' : ''} ${isActive && !manualMode ? 'active' : ''}`}\n style={{\n filter: manualMode\n ? isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`\n : isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`,\n '--border-color': borderColor,\n '--glow-color': glowColor,\n transition: `filter ${animationDuration}s ease`\n }}\n onMouseEnter={() => handleMouseEnter(index)}\n onMouseLeave={handleMouseLeave}\n >\n {word}\n \n );\n })}\n\n = 0 ? 1 : 0\n }}\n transition={{\n duration: animationDuration\n }}\n style={{\n '--border-color': borderColor,\n '--glow-color': glowColor\n }}\n >\n \n \n \n \n \n
\n );\n};\n\nexport default TrueFocus;\n",
+ "content": "import { useEffect, useRef, useState } from 'react';\nimport { motion } from 'motion/react';\nimport './TrueFocus.css';\n\nconst TrueFocus = ({\n sentence = 'True Focus',\n words,\n manualMode = false,\n blurAmount = 5,\n borderColor = 'green',\n glowColor = 'rgba(0, 255, 0, 0.6)',\n animationDuration = 0.5,\n pauseBetweenAnimations = 1\n}) => {\n const wordList = Array.isArray(words) && words.length > 0 ? words : sentence.split(' ');\n const [currentIndex, setCurrentIndex] = useState(0);\n const [lastActiveIndex, setLastActiveIndex] = useState(null);\n const containerRef = useRef(null);\n const wordRefs = useRef([]);\n const [focusRect, setFocusRect] = useState({ x: 0, y: 0, width: 0, height: 0 });\n\n useEffect(() => {\n if (!manualMode) {\n const interval = setInterval(\n () => {\n setCurrentIndex(prev => (prev + 1) % wordList.length);\n },\n (animationDuration + pauseBetweenAnimations) * 1000\n );\n\n return () => clearInterval(interval);\n }\n }, [manualMode, animationDuration, pauseBetweenAnimations, wordList.length]);\n\n useEffect(() => {\n if (currentIndex === null || currentIndex === -1) return;\n\n if (!wordRefs.current[currentIndex] || !containerRef.current) return;\n\n const parentRect = containerRef.current.getBoundingClientRect();\n const activeRect = wordRefs.current[currentIndex].getBoundingClientRect();\n\n setFocusRect({\n x: activeRect.left - parentRect.left,\n y: activeRect.top - parentRect.top,\n width: activeRect.width,\n height: activeRect.height\n });\n }, [currentIndex, wordList.length]);\n\n const handleMouseEnter = index => {\n if (manualMode) {\n setLastActiveIndex(index);\n setCurrentIndex(index);\n }\n };\n\n const handleMouseLeave = () => {\n if (manualMode) {\n setCurrentIndex(lastActiveIndex);\n }\n };\n\n return (\n \n {wordList.map((word, index) => {\n const isActive = index === currentIndex;\n return (\n (wordRefs.current[index] = el)}\n className={`focus-word ${manualMode ? 'manual' : ''} ${isActive && !manualMode ? 'active' : ''}`}\n style={{\n filter: manualMode\n ? isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`\n : isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`,\n '--border-color': borderColor,\n '--glow-color': glowColor,\n transition: `filter ${animationDuration}s ease`\n }}\n onMouseEnter={() => handleMouseEnter(index)}\n onMouseLeave={handleMouseLeave}\n >\n {word}\n \n );\n })}\n\n = 0 ? 1 : 0\n }}\n transition={{\n duration: animationDuration\n }}\n style={{\n '--border-color': borderColor,\n '--glow-color': glowColor\n }}\n >\n \n \n \n \n \n
\n );\n};\n\nexport default TrueFocus;\n",
"type": "registry:component"
},
{
diff --git a/public/r/TrueFocus-JS-TW.json b/public/r/TrueFocus-JS-TW.json
index 77696c63..d781603c 100644
--- a/public/r/TrueFocus-JS-TW.json
+++ b/public/r/TrueFocus-JS-TW.json
@@ -10,7 +10,7 @@
"files": [
{
"path": "public/tailwind/src/tailwind/TextAnimations/TrueFocus/TrueFocus.jsx",
- "content": "import { useEffect, useRef, useState } from 'react';\nimport { motion } from 'motion/react';\n\nconst TrueFocus = ({\n sentence = 'True Focus',\n manualMode = false,\n blurAmount = 5,\n borderColor = 'green',\n glowColor = 'rgba(0, 255, 0, 0.6)',\n animationDuration = 0.5,\n pauseBetweenAnimations = 1\n}) => {\n const words = sentence.split(' ');\n const [currentIndex, setCurrentIndex] = useState(0);\n const [lastActiveIndex, setLastActiveIndex] = useState(null);\n const containerRef = useRef(null);\n const wordRefs = useRef([]);\n const [focusRect, setFocusRect] = useState({ x: 0, y: 0, width: 0, height: 0 });\n\n useEffect(() => {\n if (!manualMode) {\n const interval = setInterval(\n () => {\n setCurrentIndex(prev => (prev + 1) % words.length);\n },\n (animationDuration + pauseBetweenAnimations) * 1000\n );\n\n return () => clearInterval(interval);\n }\n }, [manualMode, animationDuration, pauseBetweenAnimations, words.length]);\n\n useEffect(() => {\n if (currentIndex === null || currentIndex === -1) return;\n if (!wordRefs.current[currentIndex] || !containerRef.current) return;\n\n const parentRect = containerRef.current.getBoundingClientRect();\n const activeRect = wordRefs.current[currentIndex].getBoundingClientRect();\n\n setFocusRect({\n x: activeRect.left - parentRect.left,\n y: activeRect.top - parentRect.top,\n width: activeRect.width,\n height: activeRect.height\n });\n }, [currentIndex, words.length]);\n\n const handleMouseEnter = index => {\n if (manualMode) {\n setLastActiveIndex(index);\n setCurrentIndex(index);\n }\n };\n\n const handleMouseLeave = () => {\n if (manualMode) {\n setCurrentIndex(lastActiveIndex);\n }\n };\n\n return (\n \n {words.map((word, index) => {\n const isActive = index === currentIndex;\n return (\n (wordRefs.current[index] = el)}\n className=\"relative text-[3rem] font-black cursor-pointer\"\n style={{\n filter: manualMode\n ? isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`\n : isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`,\n '--border-color': borderColor,\n '--glow-color': glowColor,\n transition: `filter ${animationDuration}s ease`\n }}\n onMouseEnter={() => handleMouseEnter(index)}\n onMouseLeave={handleMouseLeave}\n >\n {word}\n \n );\n })}\n\n = 0 ? 1 : 0\n }}\n transition={{\n duration: animationDuration\n }}\n style={{\n '--border-color': borderColor,\n '--glow-color': glowColor\n }}\n >\n \n \n \n \n \n
\n );\n};\n\nexport default TrueFocus;\n",
+ "content": "import { useEffect, useRef, useState } from 'react';\nimport { motion } from 'motion/react';\nimport './TrueFocus.css';\n\nconst TrueFocus = ({\n sentence = 'True Focus',\n words,\n manualMode = false,\n blurAmount = 5,\n borderColor = 'green',\n glowColor = 'rgba(0, 255, 0, 0.6)',\n animationDuration = 0.5,\n pauseBetweenAnimations = 1\n}) => {\n const wordList = Array.isArray(words) && words.length > 0 ? words : sentence.split(' ');\n const [currentIndex, setCurrentIndex] = useState(0);\n const [lastActiveIndex, setLastActiveIndex] = useState(null);\n const containerRef = useRef(null);\n const wordRefs = useRef([]);\n const [focusRect, setFocusRect] = useState({ x: 0, y: 0, width: 0, height: 0 });\n\n useEffect(() => {\n if (!manualMode) {\n const interval = setInterval(\n () => {\n setCurrentIndex(prev => (prev + 1) % wordList.length);\n },\n (animationDuration + pauseBetweenAnimations) * 1000\n );\n\n return () => clearInterval(interval);\n }\n }, [manualMode, animationDuration, pauseBetweenAnimations, wordList.length]);\n\n useEffect(() => {\n if (currentIndex === null || currentIndex === -1) return;\n\n if (!wordRefs.current[currentIndex] || !containerRef.current) return;\n\n const parentRect = containerRef.current.getBoundingClientRect();\n const activeRect = wordRefs.current[currentIndex].getBoundingClientRect();\n\n setFocusRect({\n x: activeRect.left - parentRect.left,\n y: activeRect.top - parentRect.top,\n width: activeRect.width,\n height: activeRect.height\n });\n }, [currentIndex, wordList.length]);\n\n const handleMouseEnter = index => {\n if (manualMode) {\n setLastActiveIndex(index);\n setCurrentIndex(index);\n }\n };\n\n const handleMouseLeave = () => {\n if (manualMode) {\n setCurrentIndex(lastActiveIndex);\n }\n };\n\n return (\n \n {wordList.map((word, index) => {\n const isActive = index === currentIndex;\n return (\n (wordRefs.current[index] = el)}\n className={`focus-word ${manualMode ? 'manual' : ''} ${isActive && !manualMode ? 'active' : ''}`}\n style={{\n filter: manualMode\n ? isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`\n : isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`,\n '--border-color': borderColor,\n '--glow-color': glowColor,\n transition: `filter ${animationDuration}s ease`\n }}\n onMouseEnter={() => handleMouseEnter(index)}\n onMouseLeave={handleMouseLeave}\n >\n {word}\n \n );\n })}\n\n = 0 ? 1 : 0\n }}\n transition={{\n duration: animationDuration\n }}\n style={{\n '--border-color': borderColor,\n '--glow-color': glowColor\n }}\n >\n \n \n \n \n \n
\n );\n};\n\nexport default TrueFocus;\n",
"type": "registry:component"
}
]
diff --git a/public/r/TrueFocus-TS-CSS.json b/public/r/TrueFocus-TS-CSS.json
index 282cc1fe..62c02d4f 100644
--- a/public/r/TrueFocus-TS-CSS.json
+++ b/public/r/TrueFocus-TS-CSS.json
@@ -10,7 +10,7 @@
"files": [
{
"path": "public/ts/default/src/ts-default/TextAnimations/TrueFocus/TrueFocus.tsx",
- "content": "import { useEffect, useRef, useState, RefObject } from 'react';\nimport { motion } from 'motion/react';\nimport './TrueFocus.css';\n\ninterface TrueFocusProps {\n sentence?: string;\n manualMode?: boolean;\n blurAmount?: number;\n borderColor?: string;\n glowColor?: string;\n animationDuration?: number;\n pauseBetweenAnimations?: number;\n}\n\ninterface FocusRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nconst TrueFocus: React.FC = ({\n sentence = 'True Focus',\n manualMode = false,\n blurAmount = 5,\n borderColor = 'green',\n glowColor = 'rgba(0, 255, 0, 0.6)',\n animationDuration = 0.5,\n pauseBetweenAnimations = 1\n}) => {\n const words = sentence.split(' ');\n const [currentIndex, setCurrentIndex] = useState(0);\n const [lastActiveIndex, setLastActiveIndex] = useState(null);\n const containerRef = useRef(null);\n const wordRefs: React.MutableRefObject<(HTMLSpanElement | null)[]> = useRef([]);\n const [focusRect, setFocusRect] = useState({\n x: 0,\n y: 0,\n width: 0,\n height: 0\n });\n\n useEffect(() => {\n if (!manualMode) {\n const interval = setInterval(\n () => {\n setCurrentIndex(prev => (prev + 1) % words.length);\n },\n (animationDuration + pauseBetweenAnimations) * 1000\n );\n\n return () => clearInterval(interval);\n }\n }, [manualMode, animationDuration, pauseBetweenAnimations, words.length]);\n\n useEffect(() => {\n if (currentIndex === null || currentIndex === -1) return;\n\n if (!wordRefs.current[currentIndex] || !containerRef.current) return;\n\n const parentRect = containerRef.current.getBoundingClientRect();\n const activeRect = wordRefs.current[currentIndex]!.getBoundingClientRect();\n\n setFocusRect({\n x: activeRect.left - parentRect.left,\n y: activeRect.top - parentRect.top,\n width: activeRect.width,\n height: activeRect.height\n });\n }, [currentIndex, words.length]);\n\n const handleMouseEnter = (index: number) => {\n if (manualMode) {\n setLastActiveIndex(index);\n setCurrentIndex(index);\n }\n };\n\n const handleMouseLeave = () => {\n if (manualMode) {\n setCurrentIndex(lastActiveIndex ?? 0);\n }\n };\n\n return (\n \n {words.map((word, index) => {\n const isActive = index === currentIndex;\n return (\n {\n if (el) {\n wordRefs.current[index] = el;\n }\n }}\n className={`focus-word ${manualMode ? 'manual' : ''} ${isActive && !manualMode ? 'active' : ''}`}\n style={\n {\n filter: manualMode\n ? isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`\n : isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`,\n transition: `filter ${animationDuration}s ease`,\n '--border-color': borderColor,\n '--glow-color': glowColor\n } as React.CSSProperties\n }\n onMouseEnter={() => handleMouseEnter(index)}\n onMouseLeave={handleMouseLeave}\n >\n {word}\n \n );\n })}\n\n = 0 ? 1 : 0\n }}\n transition={{\n duration: animationDuration\n }}\n style={\n {\n '--border-color': borderColor,\n '--glow-color': glowColor\n } as React.CSSProperties\n }\n >\n \n \n \n \n \n
\n );\n};\n\nexport default TrueFocus;\n",
+ "content": "import { useEffect, useRef, useState, RefObject } from 'react';\nimport { motion } from 'motion/react';\nimport './TrueFocus.css';\n\ninterface TrueFocusProps {\n sentence?: string;\n words?: string[];\n manualMode?: boolean;\n blurAmount?: number;\n borderColor?: string;\n glowColor?: string;\n animationDuration?: number;\n pauseBetweenAnimations?: number;\n}\n\ninterface FocusRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nconst TrueFocus: React.FC = ({\n sentence = 'True Focus',\n words,\n manualMode = false,\n blurAmount = 5,\n borderColor = 'green',\n glowColor = 'rgba(0, 255, 0, 0.6)',\n animationDuration = 0.5,\n pauseBetweenAnimations = 1\n}) => {\n const wordList = Array.isArray(words) && words.length > 0 ? words : sentence.split(' ');\n const [currentIndex, setCurrentIndex] = useState(0);\n const [lastActiveIndex, setLastActiveIndex] = useState(null);\n const containerRef = useRef(null);\n const wordRefs: React.MutableRefObject<(HTMLSpanElement | null)[]> = useRef([]);\n const [focusRect, setFocusRect] = useState({\n x: 0,\n y: 0,\n width: 0,\n height: 0\n });\n\n useEffect(() => {\n if (!manualMode) {\n const interval = setInterval(\n () => {\n setCurrentIndex(prev => (prev + 1) % wordList.length);\n },\n (animationDuration + pauseBetweenAnimations) * 1000\n );\n\n return () => clearInterval(interval);\n }\n }, [manualMode, animationDuration, pauseBetweenAnimations, wordList.length]);\n\n useEffect(() => {\n if (currentIndex === null || currentIndex === -1) return;\n\n if (!wordRefs.current[currentIndex] || !containerRef.current) return;\n\n const parentRect = containerRef.current.getBoundingClientRect();\n const activeRect = wordRefs.current[currentIndex]!.getBoundingClientRect();\n\n setFocusRect({\n x: activeRect.left - parentRect.left,\n y: activeRect.top - parentRect.top,\n width: activeRect.width,\n height: activeRect.height\n });\n }, [currentIndex, wordList.length]);\n\n const handleMouseEnter = (index: number) => {\n if (manualMode) {\n setLastActiveIndex(index);\n setCurrentIndex(index);\n }\n };\n\n const handleMouseLeave = () => {\n if (manualMode) {\n setCurrentIndex(lastActiveIndex ?? 0);\n }\n };\n\n return (\n \n {wordList.map((word, index) => {\n const isActive = index === currentIndex;\n return (\n {\n if (el) {\n wordRefs.current[index] = el;\n }\n }}\n className={`focus-word ${manualMode ? 'manual' : ''} ${isActive && !manualMode ? 'active' : ''}`}\n style={\n {\n filter: manualMode\n ? isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`\n : isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`,\n transition: `filter ${animationDuration}s ease`,\n '--border-color': borderColor,\n '--glow-color': glowColor\n } as React.CSSProperties\n }\n onMouseEnter={() => handleMouseEnter(index)}\n onMouseLeave={handleMouseLeave}\n >\n {word}\n \n );\n })}\n\n = 0 ? 1 : 0\n }}\n transition={{\n duration: animationDuration\n }}\n style={\n {\n '--border-color': borderColor,\n '--glow-color': glowColor\n } as React.CSSProperties\n }\n >\n \n \n \n \n \n
\n );\n};\n\nexport default TrueFocus;\n",
"type": "registry:component"
},
{
diff --git a/public/r/TrueFocus-TS-TW.json b/public/r/TrueFocus-TS-TW.json
index 1367c5c5..146b5ec6 100644
--- a/public/r/TrueFocus-TS-TW.json
+++ b/public/r/TrueFocus-TS-TW.json
@@ -10,7 +10,7 @@
"files": [
{
"path": "public/ts/tailwind/src/ts-tailwind/TextAnimations/TrueFocus/TrueFocus.tsx",
- "content": "import { useEffect, useRef, useState } from 'react';\nimport { motion } from 'motion/react';\n\ninterface TrueFocusProps {\n sentence?: string;\n manualMode?: boolean;\n blurAmount?: number;\n borderColor?: string;\n glowColor?: string;\n animationDuration?: number;\n pauseBetweenAnimations?: number;\n}\n\ninterface FocusRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nconst TrueFocus: React.FC = ({\n sentence = 'True Focus',\n manualMode = false,\n blurAmount = 5,\n borderColor = 'green',\n glowColor = 'rgba(0, 255, 0, 0.6)',\n animationDuration = 0.5,\n pauseBetweenAnimations = 1\n}) => {\n const words = sentence.split(' ');\n const [currentIndex, setCurrentIndex] = useState(0);\n const [lastActiveIndex, setLastActiveIndex] = useState(null);\n const containerRef = useRef(null);\n const wordRefs = useRef<(HTMLSpanElement | null)[]>([]);\n const [focusRect, setFocusRect] = useState({ x: 0, y: 0, width: 0, height: 0 });\n\n useEffect(() => {\n if (!manualMode) {\n const interval = setInterval(\n () => {\n setCurrentIndex(prev => (prev + 1) % words.length);\n },\n (animationDuration + pauseBetweenAnimations) * 1000\n );\n\n return () => clearInterval(interval);\n }\n }, [manualMode, animationDuration, pauseBetweenAnimations, words.length]);\n\n useEffect(() => {\n if (currentIndex === null || currentIndex === -1) return;\n if (!wordRefs.current[currentIndex] || !containerRef.current) return;\n\n const parentRect = containerRef.current.getBoundingClientRect();\n const activeRect = wordRefs.current[currentIndex]!.getBoundingClientRect();\n\n setFocusRect({\n x: activeRect.left - parentRect.left,\n y: activeRect.top - parentRect.top,\n width: activeRect.width,\n height: activeRect.height\n });\n }, [currentIndex, words.length]);\n\n const handleMouseEnter = (index: number) => {\n if (manualMode) {\n setLastActiveIndex(index);\n setCurrentIndex(index);\n }\n };\n\n const handleMouseLeave = () => {\n if (manualMode) {\n setCurrentIndex(lastActiveIndex!);\n }\n };\n\n return (\n \n {words.map((word, index) => {\n const isActive = index === currentIndex;\n return (\n {\n wordRefs.current[index] = el;\n }}\n className=\"relative text-[3rem] font-black cursor-pointer\"\n style={\n {\n filter: manualMode\n ? isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`\n : isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`,\n transition: `filter ${animationDuration}s ease`\n } as React.CSSProperties\n }\n onMouseEnter={() => handleMouseEnter(index)}\n onMouseLeave={handleMouseLeave}\n >\n {word}\n \n );\n })}\n\n = 0 ? 1 : 0\n }}\n transition={{\n duration: animationDuration\n }}\n style={\n {\n '--border-color': borderColor,\n '--glow-color': glowColor\n } as React.CSSProperties\n }\n >\n \n \n \n \n \n
\n );\n};\n\nexport default TrueFocus;\n",
+ "content": "import { useEffect, useRef, useState, RefObject } from 'react';\nimport { motion } from 'motion/react';\nimport './TrueFocus.css';\n\ninterface TrueFocusProps {\n sentence?: string;\n words?: string[];\n manualMode?: boolean;\n blurAmount?: number;\n borderColor?: string;\n glowColor?: string;\n animationDuration?: number;\n pauseBetweenAnimations?: number;\n}\n\ninterface FocusRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\nconst TrueFocus: React.FC = ({\n sentence = 'True Focus',\n words,\n manualMode = false,\n blurAmount = 5,\n borderColor = 'green',\n glowColor = 'rgba(0, 255, 0, 0.6)',\n animationDuration = 0.5,\n pauseBetweenAnimations = 1\n}) => {\n const wordList = Array.isArray(words) && words.length > 0 ? words : sentence.split(' ');\n const [currentIndex, setCurrentIndex] = useState(0);\n const [lastActiveIndex, setLastActiveIndex] = useState(null);\n const containerRef = useRef(null);\n const wordRefs: React.MutableRefObject<(HTMLSpanElement | null)[]> = useRef([]);\n const [focusRect, setFocusRect] = useState({\n x: 0,\n y: 0,\n width: 0,\n height: 0\n });\n\n useEffect(() => {\n if (!manualMode) {\n const interval = setInterval(\n () => {\n setCurrentIndex(prev => (prev + 1) % wordList.length);\n },\n (animationDuration + pauseBetweenAnimations) * 1000\n );\n\n return () => clearInterval(interval);\n }\n }, [manualMode, animationDuration, pauseBetweenAnimations, wordList.length]);\n\n useEffect(() => {\n if (currentIndex === null || currentIndex === -1) return;\n\n if (!wordRefs.current[currentIndex] || !containerRef.current) return;\n\n const parentRect = containerRef.current.getBoundingClientRect();\n const activeRect = wordRefs.current[currentIndex]!.getBoundingClientRect();\n\n setFocusRect({\n x: activeRect.left - parentRect.left,\n y: activeRect.top - parentRect.top,\n width: activeRect.width,\n height: activeRect.height\n });\n }, [currentIndex, wordList.length]);\n\n const handleMouseEnter = (index: number) => {\n if (manualMode) {\n setLastActiveIndex(index);\n setCurrentIndex(index);\n }\n };\n\n const handleMouseLeave = () => {\n if (manualMode) {\n setCurrentIndex(lastActiveIndex ?? 0);\n }\n };\n\n return (\n \n {wordList.map((word, index) => {\n const isActive = index === currentIndex;\n return (\n {\n if (el) {\n wordRefs.current[index] = el;\n }\n }}\n className={`focus-word ${manualMode ? 'manual' : ''} ${isActive && !manualMode ? 'active' : ''}`}\n style={\n {\n filter: manualMode\n ? isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`\n : isActive\n ? `blur(0px)`\n : `blur(${blurAmount}px)`,\n transition: `filter ${animationDuration}s ease`,\n '--border-color': borderColor,\n '--glow-color': glowColor\n } as React.CSSProperties\n }\n onMouseEnter={() => handleMouseEnter(index)}\n onMouseLeave={handleMouseLeave}\n >\n {word}\n \n );\n })}\n\n = 0 ? 1 : 0\n }}\n transition={{\n duration: animationDuration\n }}\n style={\n {\n '--border-color': borderColor,\n '--glow-color': glowColor\n } as React.CSSProperties\n }\n >\n \n \n \n \n \n
\n );\n};\n\nexport default TrueFocus;\n",
"type": "registry:component"
}
]
diff --git a/src/content/TextAnimations/TrueFocus/TrueFocus.jsx b/src/content/TextAnimations/TrueFocus/TrueFocus.jsx
index 578f5526..4e28bc6e 100644
--- a/src/content/TextAnimations/TrueFocus/TrueFocus.jsx
+++ b/src/content/TextAnimations/TrueFocus/TrueFocus.jsx
@@ -4,6 +4,7 @@ import './TrueFocus.css';
const TrueFocus = ({
sentence = 'True Focus',
+ words,
manualMode = false,
blurAmount = 5,
borderColor = 'green',
@@ -11,7 +12,7 @@ const TrueFocus = ({
animationDuration = 0.5,
pauseBetweenAnimations = 1
}) => {
- const words = sentence.split(' ');
+ const wordList = Array.isArray(words) && words.length > 0 ? words : sentence.split(' ');
const [currentIndex, setCurrentIndex] = useState(0);
const [lastActiveIndex, setLastActiveIndex] = useState(null);
const containerRef = useRef(null);
@@ -22,14 +23,14 @@ const TrueFocus = ({
if (!manualMode) {
const interval = setInterval(
() => {
- setCurrentIndex(prev => (prev + 1) % words.length);
+ setCurrentIndex(prev => (prev + 1) % wordList.length);
},
(animationDuration + pauseBetweenAnimations) * 1000
);
return () => clearInterval(interval);
}
- }, [manualMode, animationDuration, pauseBetweenAnimations, words.length]);
+ }, [manualMode, animationDuration, pauseBetweenAnimations, wordList.length]);
useEffect(() => {
if (currentIndex === null || currentIndex === -1) return;
@@ -45,7 +46,7 @@ const TrueFocus = ({
width: activeRect.width,
height: activeRect.height
});
- }, [currentIndex, words.length]);
+ }, [currentIndex, wordList.length]);
const handleMouseEnter = index => {
if (manualMode) {
@@ -62,7 +63,7 @@ const TrueFocus = ({
return (
- {words.map((word, index) => {
+ {wordList.map((word, index) => {
const isActive = index === currentIndex;
return (
{
default: "'True Focus'",
description: 'The text to display with the focus animation.'
},
+ {
+ name: 'words',
+ type: 'string[]',
+ default: 'undefined',
+ description:
+ 'Optional array of words or tokens to display. If provided, it will be used directly instead of splitting the `sentence` by spaces. Useful for precise spacing control.'
+ },
{
name: 'manualMode',
type: 'boolean',
diff --git a/src/tailwind/TextAnimations/TrueFocus/TrueFocus.jsx b/src/tailwind/TextAnimations/TrueFocus/TrueFocus.jsx
index f3dc7366..4e5557c3 100644
--- a/src/tailwind/TextAnimations/TrueFocus/TrueFocus.jsx
+++ b/src/tailwind/TextAnimations/TrueFocus/TrueFocus.jsx
@@ -3,6 +3,7 @@ import { motion } from 'motion/react';
const TrueFocus = ({
sentence = 'True Focus',
+ words,
manualMode = false,
blurAmount = 5,
borderColor = 'green',
@@ -10,7 +11,7 @@ const TrueFocus = ({
animationDuration = 0.5,
pauseBetweenAnimations = 1
}) => {
- const words = sentence.split(' ');
+ const wordList = Array.isArray(words) && words.length > 0 ? words : sentence.split(' ');
const [currentIndex, setCurrentIndex] = useState(0);
const [lastActiveIndex, setLastActiveIndex] = useState(null);
const containerRef = useRef(null);
@@ -21,14 +22,14 @@ const TrueFocus = ({
if (!manualMode) {
const interval = setInterval(
() => {
- setCurrentIndex(prev => (prev + 1) % words.length);
+ setCurrentIndex(prev => (prev + 1) % wordList.length);
},
(animationDuration + pauseBetweenAnimations) * 1000
);
return () => clearInterval(interval);
}
- }, [manualMode, animationDuration, pauseBetweenAnimations, words.length]);
+ }, [manualMode, animationDuration, pauseBetweenAnimations, wordList.length]);
useEffect(() => {
if (currentIndex === null || currentIndex === -1) return;
@@ -43,7 +44,7 @@ const TrueFocus = ({
width: activeRect.width,
height: activeRect.height
});
- }, [currentIndex, words.length]);
+ }, [currentIndex, wordList.length]);
const handleMouseEnter = index => {
if (manualMode) {
@@ -60,7 +61,7 @@ const TrueFocus = ({
return (
- {words.map((word, index) => {
+ {wordList.map((word, index) => {
const isActive = index === currentIndex;
return (
= ({
sentence = 'True Focus',
+ words,
manualMode = false,
blurAmount = 5,
borderColor = 'green',
@@ -28,7 +30,7 @@ const TrueFocus: React.FC = ({
animationDuration = 0.5,
pauseBetweenAnimations = 1
}) => {
- const words = sentence.split(' ');
+ const wordList = Array.isArray(words) && words.length > 0 ? words : sentence.split(' ');
const [currentIndex, setCurrentIndex] = useState(0);
const [lastActiveIndex, setLastActiveIndex] = useState(null);
const containerRef = useRef(null);
@@ -44,14 +46,14 @@ const TrueFocus: React.FC = ({
if (!manualMode) {
const interval = setInterval(
() => {
- setCurrentIndex(prev => (prev + 1) % words.length);
+ setCurrentIndex(prev => (prev + 1) % wordList.length);
},
(animationDuration + pauseBetweenAnimations) * 1000
);
return () => clearInterval(interval);
}
- }, [manualMode, animationDuration, pauseBetweenAnimations, words.length]);
+ }, [manualMode, animationDuration, pauseBetweenAnimations, wordList.length]);
useEffect(() => {
if (currentIndex === null || currentIndex === -1) return;
@@ -67,7 +69,7 @@ const TrueFocus: React.FC = ({
width: activeRect.width,
height: activeRect.height
});
- }, [currentIndex, words.length]);
+ }, [currentIndex, wordList.length]);
const handleMouseEnter = (index: number) => {
if (manualMode) {
@@ -84,7 +86,7 @@ const TrueFocus: React.FC = ({
return (
- {words.map((word, index) => {
+ {wordList.map((word, index) => {
const isActive = index === currentIndex;
return (
= ({
sentence = 'True Focus',
+ words,
manualMode = false,
blurAmount = 5,
borderColor = 'green',
@@ -27,7 +29,7 @@ const TrueFocus: React.FC = ({
animationDuration = 0.5,
pauseBetweenAnimations = 1
}) => {
- const words = sentence.split(' ');
+ const wordList = Array.isArray(words) && words.length > 0 ? words : sentence.split(' ');
const [currentIndex, setCurrentIndex] = useState(0);
const [lastActiveIndex, setLastActiveIndex] = useState(null);
const containerRef = useRef(null);
@@ -38,14 +40,14 @@ const TrueFocus: React.FC = ({
if (!manualMode) {
const interval = setInterval(
() => {
- setCurrentIndex(prev => (prev + 1) % words.length);
+ setCurrentIndex(prev => (prev + 1) % wordList.length);
},
(animationDuration + pauseBetweenAnimations) * 1000
);
return () => clearInterval(interval);
}
- }, [manualMode, animationDuration, pauseBetweenAnimations, words.length]);
+ }, [manualMode, animationDuration, pauseBetweenAnimations, wordList.length]);
useEffect(() => {
if (currentIndex === null || currentIndex === -1) return;
@@ -60,7 +62,7 @@ const TrueFocus: React.FC = ({
width: activeRect.width,
height: activeRect.height
});
- }, [currentIndex, words.length]);
+ }, [currentIndex, wordList.length]);
const handleMouseEnter = (index: number) => {
if (manualMode) {
@@ -77,7 +79,7 @@ const TrueFocus: React.FC = ({
return (
- {words.map((word, index) => {
+ {wordList.map((word, index) => {
const isActive = index === currentIndex;
return (