Styledex
← Index

Shiny Text

superdesignCC0-1.0Prompt onlyLanding · landingGradient · gradientLight · lightMedium · mediumBlue · blueVivid · vividSerif · serifGeneral · generalProfessional · professional

A text component with a customizable shining gradient animation effect that sweeps across the text. Category: Components. Prompt author listed upstream: Jason Zhou.

NNorthwind
Product · Pricing
Specimen
Make the work feel finished

One interface, dressed in this style. Compare type, color, radius, and density.

128
Active
4.8
Score
12ms
Edge

Attribution

"Shiny Text" from https://github.com/superdesigndev/superdesign-prompts (CC0-1.0). © Superdesign. prompts/shiny-text @ 6c6090694520.

https://github.com/superdesigndev/superdesign-prompts · prompts/shiny-text · 6c6090694520 · © Superdesign

Prompt

You are given a task to integrate an existing React component in the codebase
~~~/README.md
# ShinyText
A text component with a customizable shining gradient animation effect that sweeps across the text.
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `text` | string | - | The text to display and animate |
| `disabled` | boolean | false | Whether to disable the animation |
| `speed` | number | 2 | Duration of the animation in seconds |
| `className` | string | '' | Additional CSS classes for styling |
| `color` | string | '#b5b5b5' | The base color of the text |
| `shineColor` | string | '#ffffff' | The color of the shine effect |
| `spread` | number | 120 | The spread angle of the gradient in degrees |
| `yoyo` | boolean | false | Whether the animation should bounce back and forth |
| `pauseOnHover` | boolean | false | Whether to pause the animation on hover |
| `direction` | 'left' \| 'right' | 'left' | The direction of the shine movement |
| `delay` | number | 0 | Delay before animation starts (in seconds) |
## Usage
```tsx
import ShinyText from '@/sd-components/2f78ed51-fbb9-4da5-8537-b528a39fe26f';
// Basic usage
<ShinyText text="Just some shiny text!" />
// Custom speed and colors
<ShinyText
  text="Shiny Text"
  disabled={false}
  speed={3}
  className="custom-class"
  color="#888888"
  shineColor="#3b82f6"
/>
// Interactive usage
<ShinyText
  text="Hover to pause"
  pauseOnHover={true}
  speed={1.5}
/>
```
~~~
~~~/src/App.tsx
import React from 'react';
import ShinyText from './ShinyText';
export default function App() {
  return (
    <div className="min-h-screen w-full flex items-center justify-center bg-[#1A1A1B] p-8 font-sans">
      <div className="relative group rounded-3xl bg-[#222224] p-16 shadow-[0_0_40px_rgba(0,0,0,0.3)] transition-all hover:shadow-[0_0_60px_rgba(0,0,0,0.5)] border border-white/5">
        <div className="text-center space-y-12">
            <div>
              <h2 className="text-sm font-medium text-white/40 mb-8 uppercase tracking-[0.2em]">Default Animation</h2>
              <div className="text-4xl md:text-5xl font-bold tracking-tight">
                  <ShinyText
                      text="✨ Shiny Text Effect"
                      disabled={false}
                      speed={3}
                      className="custom-class"
                  />
              </div>
            </div>
             <div className="pt-12 border-t border-white/5 grid gap-8 justify-items-center">
                <div>
                  <p className="text-xs text-white/30 mb-4 uppercase tracking-widest">Hover to Pause</p>
                  <ShinyText
                      text="Hover over me to pause the shine"
                      speed={2}
                      color="#888888"
                      shineColor="#3b82f6" // Electric blue
                      className="text-xl font-medium"
                      pauseOnHover={true}
                  />
                </div>
                <div>
                  <p className="text-xs text-white/30 mb-4 uppercase tracking-widest">Yoyo Effect</p>
                   <ShinyText
                      text="Bouncing back and forth"
                      speed={1.5}
                      color="#888888"
                      shineColor="#ec4899" // Pink
                      className="text-xl font-medium"
                      yoyo={true}
                  />
                </div>
            </div>
        </div>
      </div>
    </div>
  );
}
~~~
~~~/package.json
{
  "name": "shiny-text-component",
  "version": "1.0.0",
  "description": "A shiny text animation component using Motion",
  "main": "src/ShinyText.tsx",
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "motion": "^12.0.0",
    "lucide-react": "^0.344.0"
  }
}
~~~
~~~/src/ShinyText.tsx
import React, { useState, useCallback, useEffect, useRef } from 'react';
import { motion, useMotionValue, useAnimationFrame, useTransform } from 'motion/react';
interface ShinyTextProps {
  text: string;
  disabled?: boolean;
  speed?: number;
  className?: string;
  color?: string;
  shineColor?: string;
  spread?: number;
  yoyo?: boolean;
  pauseOnHover?: boolean;
  direction?: 'left' | 'right';
  delay?: number;
}
const ShinyText: React.FC<ShinyTextProps> = ({
  text,
  disabled = false,
  speed = 2,
  className = '',
  color = '#b5b5b5',
  shineColor = '#ffffff',
  spread = 120,
  yoyo = false,
  pauseOnHover = false,
  direction = 'left',
  delay = 0
}) => {
  const [isPaused, setIsPaused] = useState(false);
  const progress = useMotionValue(0);
  const elapsedRef = useRef(0);
  const lastTimeRef = useRef<number | null>(null);
  const directionRef = useRef(direction === 'left' ? 1 : -1);
  const animationDuration = speed * 1000;
  const delayDuration = delay * 1000;
  useAnimationFrame(time => {
    if (disabled || isPaused) {
      lastTimeRef.current = null;
      return;
    }
    if (lastTimeRef.current === null) {
      lastTimeRef.current = time;
      return;
    }
    const deltaTime = time - lastTimeRef.current;
    lastTimeRef.current = time;
    elapsedRef.current += deltaTime;
    // Animation goes from 0 to 100
    if (yoyo) {
      const cycleDuration = animationDuration + delayDuration;
      const fullCycle = cycleDuration * 2;
      const cycleTime = elapsedRef.current % fullCycle;
      if (cycleTime < animationDuration) {
        // Forward animation: 0 -> 100
        const p = (cycleTime / animationDuration) * 100;
        progress.set(directionRef.current === 1 ? p : 100 - p);
      } else if (cycleTime < cycleDuration) {
        // Delay at end
        progress.set(directionRef.current === 1 ? 100 : 0);
      } else if (cycleTime < cycleDuration + animationDuration) {
        // Reverse animation: 100 -> 0
        const reverseTime = cycleTime - cycleDuration;
        const p = 100 - (reverseTime / animationDuration) * 100;
        progress.set(directionRef.current === 1 ? p : 100 - p);
      } else {
        // Delay at start
        progress.set(directionRef.current === 1 ? 0 : 100);
      }
    } else {
      const cycleDuration = animationDuration + delayDuration;
      const cycleTime = elapsedRef.current % cycleDuration;
      if (cycleTime < animationDuration) {
        // Animation phase: 0 -> 100
        const p = (cycleTime / animationDuration) * 100;
        progress.set(directionRef.current === 1 ? p : 100 - p);
      } else {
        // Delay phase - hold at end (shine off-screen)
        progress.set(directionRef.current === 1 ? 100 : 0);
      }
    }
  });
  useEffect(() => {
    directionRef.current = direction === 'left' ? 1 : -1;
    elapsedRef.current = 0;
    progress.set(0);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [direction]);
  // Transform: p=0 -> 150% (shine off right), p=100 -> -50% (shine off left)
  const backgroundPosition = useTransform(progress, p => `${150 - p * 2}% center`);
  const handleMouseEnter = useCallback(() => {
    if (pauseOnHover) setIsPaused(true);
  }, [pauseOnHover]);
  const handleMouseLeave = useCallback(() => {
    if (pauseOnHover) setIsPaused(false);
  }, [pauseOnHover]);
  const gradientStyle: React.CSSProperties = {
    backgroundImage: `linear-gradient(${spread}deg, ${color} 0%, ${color} 35%, ${shineColor} 50%, ${color} 65%, ${color} 100%)`,
    backgroundSize: '200% auto',
    WebkitBackgroundClip: 'text',
    backgroundClip: 'text',
    WebkitTextFillColor: 'transparent'
  };
  return (
    <motion.span
      className={`inline-block ${className}`}
      style={{ ...gradientStyle, backgroundPosition }}
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
    >
      {text}
    </motion.span>
  );
};
export default ShinyText;
~~~
Implementation Guidelines
1. Analyze the component structure, styling, animation implementations
2. Review the component's arguments and state
3. Think through what is the best place to adopt this component/style into the design we are doing
4. Then adopt the component/design to our current system
Help me integrate this into my design

---
"Shiny Text" from https://github.com/superdesigndev/superdesign-prompts (CC0-1.0). © Superdesign. prompts/shiny-text @ 6c6090694520.
powered by Styledex — https://styledex.dev

Tokens

DTCG

{
  "$schema": "https://www.designtokens.org/schemas/2025.10/format.json",
  "$description": "Shiny Text. \"Shiny Text\" from https://github.com/superdesigndev/superdesign-prompts (CC0-1.0). © Superdesign. prompts/shiny-text @ 6c6090694520.",
  "$extensions": {
    "dev.styledex": {
      "id": "superdesign-shiny-text",
      "license": "CC0-1.0",
      "attribution": "\"Shiny Text\" from https://github.com/superdesigndev/superdesign-prompts (CC0-1.0). © Superdesign. prompts/shiny-text @ 6c6090694520.",
      "banner": "powered by Styledex — https://styledex.dev"
    }
  },
  "color": {
    "background": {
      "$type": "color",
      "$value": "#ffffff"
    },
    "foreground": {
      "$type": "color",
      "$value": "#1a1a1b"
    },
    "card": {
      "$type": "color",
      "$value": "#ffffff"
    },
    "card-foreground": {
      "$type": "color",
      "$value": "#1a1a1b"
    },
    "primary": {
      "$type": "color",
      "$value": "#3b82f6"
    },
    "primary-foreground": {
      "$type": "color",
      "$value": "#fafaf9"
    },
    "secondary": {
      "$type": "color",
      "$value": "#b5b5b5"
    },
    "secondary-foreground": {
      "$type": "color",
      "$value": "#1a1a1b"
    },
    "accent": {
      "$type": "color",
      "$value": "#ec4899"
    },
    "accent-foreground": {
      "$type": "color",
      "$value": "#fafaf9"
    },
    "muted": {
      "$type": "color",
      "$value": "#f0f0f0"
    },
    "muted-foreground": {
      "$type": "color",
      "$value": "#6a6a6b"
    },
    "border": {
      "$type": "color",
      "$value": "#dbdbdb"
    },
    "destructive": {
      "$type": "color",
      "$value": "#dc2626"
    },
    "ring": {
      "$type": "color",
      "$value": "#3b82f6"
    }
  },
  "font": {
    "sans": {
      "$type": "fontFamily",
      "$value": [
        "ui-sans-serif",
        "system-ui",
        "sans-serif"
      ]
    },
    "serif": {
      "$type": "fontFamily",
      "$value": [
        "ui-serif",
        "Georgia",
        "serif"
      ]
    },
    "mono": {
      "$type": "fontFamily",
      "$value": [
        "ui-monospace",
        "SFMono-Regular",
        "Menlo",
        "monospace"
      ]
    }
  },
  "radius": {
    "base": {
      "$type": "dimension",
      "$value": "0.5rem"
    }
  },
  "spacing": {
    "base": {
      "$type": "dimension",
      "$value": "1rem"
    }
  },
  "shadow": {
    "base": {
      "$type": "shadow",
      "$value": "0 1px 2px rgba(0,0,0,0.06), 0 8px 24px rgba(0,0,0,0.04)"
    }
  }
}

CSS

/* powered by Styledex — https://styledex.dev */
/* "Shiny Text" from https://github.com/superdesigndev/superdesign-prompts (CC0-1.0). © Superdesign. prompts/shiny-text @ 6c6090694520. */
:root {
  --background: #ffffff;
  --foreground: #1a1a1b;
  --card: #ffffff;
  --card-foreground: #1a1a1b;
  --primary: #3b82f6;
  --primary-foreground: #fafaf9;
  --secondary: #b5b5b5;
  --secondary-foreground: #1a1a1b;
  --accent: #ec4899;
  --accent-foreground: #fafaf9;
  --muted: #f0f0f0;
  --muted-foreground: #6a6a6b;
  --border: #dbdbdb;
  --destructive: #dc2626;
  --ring: #3b82f6;
  --radius: 0.5rem;
  --font-sans: ui-sans-serif, system-ui, sans-serif;
  --font-serif: ui-serif, Georgia, serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
  --spacing: 1rem;
  --shadow: 0 1px 2px rgba(0,0,0,0.06), 0 8px 24px rgba(0,0,0,0.04);
}

Tailwind

/* powered by Styledex — https://styledex.dev */
/* "Shiny Text" from https://github.com/superdesigndev/superdesign-prompts (CC0-1.0). © Superdesign. prompts/shiny-text @ 6c6090694520. */
/** Tailwind theme extend for Shiny Text (superdesign-shiny-text) */
module.exports = {
  "theme": {
    "extend": {
      "colors": {
        "background": "#ffffff",
        "foreground": "#1a1a1b",
        "card": "#ffffff",
        "primary": "#3b82f6",
        "primary-foreground": "#fafaf9",
        "secondary": "#b5b5b5",
        "accent": "#ec4899",
        "muted": "#f0f0f0",
        "border": "#dbdbdb",
        "destructive": "#dc2626",
        "ring": "#3b82f6"
      },
      "borderRadius": {
        "lg": "0.5rem"
      },
      "fontFamily": {
        "sans": [
          "ui-sans-serif",
          "system-ui",
          "sans-serif"
        ],
        "serif": [
          "ui-serif",
          "Georgia",
          "serif"
        ],
        "mono": [
          "ui-monospace",
          "SFMono-Regular",
          "Menlo",
          "monospace"
        ]
      },
      "boxShadow": {
        "styledex": "0 1px 2px rgba(0,0,0,0.06), 0 8px 24px rgba(0,0,0,0.04)"
      }
    }
  }
};

shadcn

/* powered by Styledex — https://styledex.dev */
/* "Shiny Text" from https://github.com/superdesigndev/superdesign-prompts (CC0-1.0). © Superdesign. prompts/shiny-text @ 6c6090694520. */
@layer base {
:root {
  --background: #ffffff;
  --foreground: #1a1a1b;
  --card: #ffffff;
  --card-foreground: #1a1a1b;
  --primary: #3b82f6;
  --primary-foreground: #fafaf9;
  --secondary: #b5b5b5;
  --secondary-foreground: #1a1a1b;
  --accent: #ec4899;
  --accent-foreground: #fafaf9;
  --muted: #f0f0f0;
  --muted-foreground: #6a6a6b;
  --border: #dbdbdb;
  --destructive: #dc2626;
  --ring: #3b82f6;
  --radius: 0.5rem;
  --font-sans: ui-sans-serif, system-ui, sans-serif;
  --font-serif: ui-serif, Georgia, serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
  --spacing: 1rem;
  --shadow: 0 1px 2px rgba(0,0,0,0.06), 0 8px 24px rgba(0,0,0,0.04);
}
}