Skip to content
Sign in
VideoLoop cardMenu

Loop cardPro

A gallery card that plays a muted loop on hover or focus and shows its poster otherwise.

ProA gallery of generated clips that loop while pointed at or focused.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/loop-card

Usage

tsx
import { LoopCard } from "@/components/ui/chatcn/pro/loop-card"

<LoopCard
  src="/renders/falls.mp4"
  poster="/renders/falls.webp"
  title="Falls at first light"
  meta="Sora 2 Pro · 6 s"
  href="/clips/falls"
/>

Pass a muted loop file as src, or any ClipSource as clip (a still with a camera move from stillClip, or your own canvas drawing), and it plays only while pointed at, after a 120 ms intent delay, or while focused. The poster fades back the moment you leave. A hairline along the bottom shows the position in the loop and the badge counts while it plays. Touch and reduced motion get a play button instead of autoplay.

Examples

States

ProPlaying, rendering, loading, failed, reduced motion and square with a long title.

Props

PropTypeNotes
srcstringA muted loop file
clipClipSourceOr a clip drawn into a canvas
poster, altstringThe still at rest, and its description
loop"repeat" | "bounce"Bounce plays forward then back. Default repeat
title, metaReactNodeUnder the media
href, onOpenMakes the media a link or a button
playingbooleanPlay from outside
status"ready" | "loading" | "rendering" | "error"With progress, error, onRetry
aspectRationumberDefault 16 / 9
hoverDelaynumberDefault 120 ms

Keyboard

KeyAction
TabFocus the card; the loop plays while it has focus
EnterOpen the card

Accessibility

  • The poster carries alt; the loop itself is hidden from assistive technology.
  • The play button on touch and under reduced motion is a toggle with aria-pressed.
  • Loops only play while someone is pointing at or focused on the card, so nothing moves on its own.

Motion

The poster crossfades in 150 ms. Nothing scales or lifts on hover. The loop position moves by transform. Under reduced motion loops only play when the play button is pressed.