Hover Scroll Text

Truncated single-line text that scrolls horizontally on hover to reveal the full string.

Examples

Basic

Q3 2025 Portfolio Deep Dive: Industrials, Materials, and Energy Transition
Monthly flash report

Row trigger

Diligence: Project Falcon acquisition financing workstreamJul 22
Apple revenue trend, last eight quartersJul 21
Monday macro briefing: rates, FX, and commodities movesJul 21

Custom speed

20 px/sInstitutional ownership changes across the semiconductor coverage universe
80 px/sSell-side estimate revisions after the Q2 print, by sector and analyst

Overview

HoverScrollText renders a single line of text that truncates with an ellipsis at rest. When the text overflows its container, hovering it slowly scrolls the line to its end, holds, and sweeps back, with fading edges masking whichever side is clipped. Leaving mid-scroll smoothly returns the text to the start and restores the ellipsis. Text that fits does nothing.

tsx
import { HoverScrollText } from "@rogo-technologies/ui/hover-scroll-text";

<HoverScrollText>{project.name}</HoverScrollText>;

Use it for user-generated names in constrained layouts (sidebar items, table cells, panel headers) where a tooltip alone is a poor way to read the full string.

Usage

Row trigger

By default the text scrolls when the pointer is over the text itself. For list rows, spread hoverScrollTextTriggerProps on the row so hovering anywhere in the row drives the scroll:

tsx
import {
  HoverScrollText,
  hoverScrollTextTriggerProps,
} from "@rogo-technologies/ui/hover-scroll-text";

<div {...hoverScrollTextTriggerProps} className="flex items-center gap-1.5">
  <IconFolder1 className="size-4 shrink-0" />
  <HoverScrollText>{project.name}</HoverScrollText>
</div>;

The component finds the nearest ancestor carrying the trigger attribute; without one it falls back to its own hover.

In flex layouts

The root is a block span with min-w-0 baked in, so it shrinks correctly as a flex item. Put text styling on the component itself:

tsx
<HoverScrollText className="text-secondary type-small-strong">{project.name}</HoverScrollText>

Custom speed

speed is the scroll speed in pixels per second (default 40). Duration scales with how far the text overflows, clamped between 0.6s and 6s per sweep.

Accessibility

  • Honors prefers-reduced-motion: the text stays truncated with an ellipsis and never scrolls.
  • The full string is always present in the DOM, so screen readers announce it regardless of truncation or scroll state.

API

HoverScrollText

PropTypeDefaultDescription
childrenReactNodeSingle-line content to truncate and scroll.
speednumber40Scroll speed in pixels per second.
classNamestringAdditional classes: text styles, flex sizing, etc.

Any other <span> attributes pass through to the root element.

hoverScrollTextTriggerProps

Spreadable props object (data-hover-scroll-text-trigger) marking an ancestor as the hover target that drives the scroll.

Guidelines

Do

  • Use for user-generated, unbounded strings in constrained UI (project names, file names)
  • Keep it to one scrolling title per row: the row trigger scrolls every instance inside it

Don't

  • Don't use for multi-line or wrapping text; it's strictly single-line
  • Don't use it as a marquee for decorative or attention-seeking motion; it's a reveal interaction, not an animation effect
  • Don't nest interactive elements inside; children should be plain text or inline content. A block-level child defeats the resting ellipsis (MDX wraps multi-line JSX text in a paragraph, so pass titles from a client component, not inline MDX)
NextInput
Made in NYC© 2026 Rogo Technologies Inc.