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 (