Scroll Text
kokonut-ui/scroll-textFreeComponent
Animated on scroll texts.
Live preview
live · rendered by the registry
Rendered by kokonut-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://kokonutui.com/r/scroll-text.jsonSource
1"use client";23/**4 * @author: @dorianbaffier5 * @description: Scroll Text6 * @version: 1.0.07 * @date: 2025-06-268 * @license: MIT9 * @website: https://kokonutui.com10 * @github: https://github.com/kokonut-labs/kokonutui11 */1213import { motion, type Variants } from "motion/react";14import { useEffect, useRef, useState } from "react";15import { cn } from "@/lib/utils";1617interface ScrollTextProps {18 texts?: string[];19 className?: string;20}2122export default function ScrollText({23 texts = [24 "TailwindCSS",25 "Kokonut UI",26 "shadcn/ui",27 "Next.js",28 "Vercel",29 "Motion",30 "React",31 "Resend",32 "TypeScript",33 "Fumadocs",34 "Supabase",35 "Vercel",36 ],37 className,38}: ScrollTextProps) {39 const [activeIndex, setActiveIndex] = useState(0);40 const observerRef = useRef<IntersectionObserver | null>(null);41 const itemsRef = useRef<(HTMLDivElement | null)[]>([]);42 const containerRef = useRef<HTMLDivElement>(null);4344 // Scroll to top on mount45 useEffect(() => {46 if (containerRef.current) {47 containerRef.current.scrollTop = 0;48 }49 }, []);5051 const handleIntersection = (entries: IntersectionObserverEntry[]) => {52 entries.forEach((entry) => {53 if (entry.isIntersecting) {54 const index = itemsRef.current.findIndex(55 (item) => item === entry.target56 );57 setActiveIndex(index);58 }59 });60 };6162 // Setup intersection observer63 const setupObserver = (element: HTMLDivElement | null, index: number) => {64 if (element && !itemsRef.current[index]) {65 itemsRef.current[index] = element;6667 if (!observerRef.current) {68 observerRef.current = new IntersectionObserver(handleIntersection, {69 threshold: 0.7,70 root: containerRef.current,71 rootMargin: "-45% 0px -45% 0px",72 });73 }7475 observerRef.current.observe(element);76 }77 };7879 // Animation variants for the reveal effect80 const containerVariants: Variants = {81 hidden: { opacity: 0 },82 visible: {83 opacity: 1,84 transition: {85 staggerChildren: 0.1,86 },87 },88 };8990 const itemVariants: Variants = {91 hidden: (index: number) => ({92 opacity: 0,93 x: index % 2 === 0 ? -100 : 100,94 rotate: index % 2 === 0 ? -10 : 10,95 }),96 visible: {97 opacity: 1,98 x: 0,99 rotate: 0,100 transition: {101 type: "spring",102 stiffness: 100,103 damping: 15,104 duration: 0.5,105 },106 },107 };108109 return (110// … truncated
What it pulls in
npm packages
Files it writes
More from kokonut-ui
All 40 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Action Search Baraction-search-bar | kokonut-ui | Components | Free | 2 deps · 2 files | |
| AI Input Searchai-input-search | kokonut-ui | Components | Free | 1 dep · 2 files | |
| AI State Loadingai-loading | kokonut-ui | Components | Free | 1 dep | |
| AI Input Selectorai-prompt | kokonut-ui | Components | Free | 2 deps · 4 files | |
| AI Text Loadingai-text-loading | kokonut-ui | Components | Free | 1 dep | |
| AI Voiceai-voice | kokonut-ui | Components | Free | 2 deps | |
| Apple Activity Cardapple-activity-card | kokonut-ui | Components | Free | 1 dep | |
| Magnet Buttonattract-button | kokonut-ui | Components | Free | 2 deps |
