ProductBrand
Join us
Foundations
  • Introduction
  • Colors
  • Typography
  • Icons
  • Illustrations
  • Logos
  • Shadows
Components
  • Accordion
  • Alert Dialog
  • Avatar
  • Badge
  • Button
  • Calendar
  • Card
  • Chart
  • Checkbox
  • Collapsible
  • Combobox
  • Context Menu
  • Date Picker
  • Dialog
  • Drawer
  • Dropdown Menu
  • Fluid Avatar
  • Hover Scroll Text
  • Input
  • Kbd
  • Popover
  • Progress Bar
  • Radio Group
  • Scroll Area
  • Select
  • Selectors
  • Separator
  • Separator Dot
  • Shimmer Text
  • Skeleton
  • Slider
  • Switch
  • Tabs
  • Textarea
  • Toast
  • Tooltip
Compositions
  • Empty State
  • File Attachment
  • Floating Bar
  • Input Banner
  • Markdown Editor
  • Media Controls
  • Product Feature Banner
  • Panels
  • Sidebar
  • Reasoning Trace
  • Pagination
  • Data Table
  • Breadcrumb
  • Thread Outline
Inline
  • Overview
  • Stat Tile
  • Metric Row
  • Comparison Table
  • Chart Card
  • Trend Tile
  • Cite
  • Custom
  • Agent skill

Hover Scroll Text

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

Examples

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

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

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
childrenReactNode-Single-line content to truncate and scroll.
speednumber40Scroll speed in pixels per second.
classNamestring-Additional 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)
PreviousFluid Avatar
NextInput
Made in NYC© 2026 Rogo Technologies Inc.

Design at Rogo

We’re redesigning an entire industry. Come design it with us.

See open roles

Design at Rogo

  • How we workThe mission of design at Rogo, and the open roles
  • About RogoThe company and the product