Text Shimmer
nexus-ui/text-shimmerFreeComponent
Animated shimmer text for loading, tool runs, and other in-progress UI
Live preview
live · rendered by the registry
Rendered by nexus-ui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://nexus-ui.dev/r/text-shimmer.jsonSource
1import * as React from "react";23import { cn } from "@/lib/utils";45export type TextShimmerProps = Omit<6 React.HTMLAttributes<HTMLElement>,7 "color"8> & {9 as?: React.ElementType;10 /**11 * Duration in seconds.12 * @default 113 */14 duration?: number;15 /**16 * Spread around center in percent points.17 * @default 2018 */19 spread?: number;20 /**21 * Beam angle in degrees.22 * @default 023 */24 angle?: number;25 /**26 * Override highlight color.27 */28 color?: string;29 /**30 * Invert shimmer contrast.31 * @default false32 */33 invert?: boolean;34 /**35 * Invert shimmer contrast in light theme only.36 * @default false37 */38 invertLight?: boolean;39 /**40 * Invert shimmer contrast in dark theme only.41 * @default false42 */43 invertDark?: boolean;44 /**45 * Delay before the next shimmer pass in seconds.46 * @default 047 */48 repeatDelay?: number;49 /**50 * Disable shimmer animation and render plain text.51 * @default false52 */53 disableShimmer?: boolean;54};5556export function TextShimmer({57 as: Comp = "span",58 className,59 style,60 duration = 1,61 repeatDelay = 0,62 spread = 20,63 angle = 0,64 color,65 invert = false,66 invertLight = false,67 invertDark = false,68 disableShimmer = false,69 children,70 ...props71}: TextShimmerProps) {72 const id = React.useId();73 const boundedSpread = Math.min(Math.max(spread, 5), 45);74 const activeDuration = Math.max(duration, 0);75 const pauseDuration = Math.max(repeatDelay, 0);76 const totalDuration = Math.max(activeDuration + pauseDuration, 0.001);77 const movePercent = (activeDuration / totalDuration) * 100;78 const keyframeName = React.useMemo(79 () => `nx-text-shimmer-${id.replace(/[^a-zA-Z0-9_-]/g, "")}`,80 [id],81 );82 const start = 50 - boundedSpread;83 const end = 50 + boundedSpread;84 const edge = "currentColor";85 const brightBeam =86 color ??87 "oklch(from currentColor max(0.8, calc(l + 0.4)) c h / calc(alpha + 0.35))";88 const dimBeam =89 color ??90 "oklch(from currentColor min(calc(l - 0.4), 0.2) c h / calc(alpha + 0.4))";91 const lightBeam = invert || invertLight ? dimBeam : brightBeam;92 const darkBeam = invert || invertDark ? dimBeam : brightBeam;93 const keyframes = `@keyframes ${keyframeName} {94 0% { background-position: 100% 50%; }95 ${movePercent}% { background-position: -60% 50%; }96 100% { background-position: -100% 50%; }97 }98 [data-nx-text-shimmer="${keyframeName}"] {99 --nx-text-shimmer-beam: var(--nx-text-shimmer-beam-light);100 }101// … truncated
Files it writes
More from nexus-ui
All 15 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Attachmentsattachments | nexus-ui | Components | Free | 4 deps · 2 files | |
| Chain of Thoughtchain-of-thought | nexus-ui | Components | Free | 2 deps · 2 files | |
| Citationcitation | nexus-ui | Components | Free | 4 deps | |
| Feedback Barfeedback-bar | nexus-ui | Components | Free | 1 dep | |
| Imageimage | nexus-ui | Components | Free | 2 deps | |
| Messagemessage | nexus-ui | Components | Free | 9 deps · 2 files | |
| Model Selectormodel-selector | nexus-ui | Components | Free | 3 deps | |
| Prompt Inputprompt-input | nexus-ui | Components | Free | 1 dep |
