Getting started
Foundations
Integrations
Form19
Display5
Layout4
Navigation4
Overlay8
Feedback4
Motion19
#Installation
npx @dinachi/cli@latest add marquee#Usage
tsx
import { Marquee } from "@/components/ui/marquee"tsx
<Marquee>
{logos.map((logo) => (
<img key={logo.name} src={logo.src} alt={logo.name} className="h-8" />
))}
</Marquee>#Examples
#When it moves
The loop only runs when it has something to say.
- Content narrower than the container sits still. Sliding a gap past the reader adds nothing they could not already see. The strip measures itself, so this needs no prop.
- It stops while scrolled out of view, and while hovered or focused.
- Pausing brakes rather than stops, over 160ms. Stopping dead reads as a dropped frame. Resuming takes 240ms, since it answers nothing the reader is waiting on.
- Touch does not count as hover. A tap fires
pointerenterwith no matchingpointerleave, which would strand the strip until the next tap elsewhere.
#Accessibility
- The duplicate track is
aria-hiddenandinert. A seamless loop needs a second copy, and its links are neither announced twice nor reachable by tab. - Focus pauses the strip regardless of
pauseOnHover, so a keyboard user never loses the element they are on. - Reduced motion turns the strip into an ordinary horizontal scroller. The container becomes focusable, since nothing carries the overflow into view on its own.
#API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| duration | number | 24 | Seconds for one full pass of the content |
| direction | "left" | "right" | "left" | Travel direction |
| pauseOnHover | boolean | true | Brake while hovered. Focus pauses the strip regardless |
| fade | boolean | true | Fade the leading and trailing edges. Applies only while the strip is moving |