VideoMarquee
Scroll a looping, draggable row of portrait video, embed, or image cards with optional controls.
VideoMarquee scrolls a looping, draggable row of portrait video, embed or image cards, with optional previous/next controls, dots and a Play/Pause toggle. It renders two copies of the card sequence in a motion track and advances it every animation frame. Cards are 18rem wide with a 9/16 aspect ratio.
Import#
import { VideoMarquee } from "@reactberry/system/blocks";
Usage#
import { VideoMarquee } from "@reactberry/system/blocks";
const items = [
{ id: "reel", src: "/videos/reel.mp4", title: "Product reel", handle: "@studio" },
{ id: "tour", imageSrc: "/images/tour.jpg", title: "Studio tour", handle: "@studio", description: "Behind the scenes." },
{ id: "tiktok", embedUrl: "https://www.tiktok.com/embed/v2/1234567890", sourceUrl: "https://www.tiktok.com/@studio/video/1234567890", title: "Launch clip", handle: "@studio" },
];
export default function Showcase() {
return <VideoMarquee items={items} speed={30} />;
}
Examples#
Without controls#
Hide the arrows, dots and toggle with showControls, showDots and showPlayPause. Here the row also scrolls to the right at a lower speed.
API#
VideoMarquee#
| Prop | Type | Default | Description |
|---|---|---|---|
items* | VideoMarqueeItem[] | — | Cards to render. The component returns |
speed | number | 42 | Auto-scroll speed in pixels per second (minimum 1). |
direction | "left""right" | "left" | Auto-scroll direction. |
pauseOnHover | boolean | true | Pauses auto-scroll while the pointer is over a card. |
gap | string | number | 1rem | Space between cards. |
showControls | boolean | true | Shows previous and next controls over the track (only with more than one item). |
showDots | boolean | true | Shows one dot per item; the active dot follows the scroll position. |
showPlayPause | boolean | true | Shows a Play/Pause toggle for auto-scroll. |
No other props are accepted and nothing is spread.
VideoMarqueeItem#
The type is exported from src/blocks/VideoMarquee but not re-exported from @reactberry/system/blocks.
| Prop | Type | Default | Description |
|---|---|---|---|
id* | string | — | Unique key for the card. |
title* | string | — | Shown in bold in the caption; also used as image |
handle* | string | — | Shown below the title. |
src | string | — | Video URL, played muted, looping and inline with |
embedUrl | string | — | Iframe URL. Takes priority over all other media fields. |
imageSrc | string | — | Static image URL. |
poster | string | — | Image URL, used as a static image (see Notes). |
description | string | — | Optional caption text. |
sourceUrl | string | — | Renders an "Open on TikTok" link that opens in a new tab. |
Accessibility#
- The duplicated sequence is
aria-hidden. - Dots are
buttonelements labelled "Go to demo N", and the toggle is abuttonwitharia-pressed. - The previous and next controls are
divelements without a button role or label, so they cannot be reached with the keyboard. - Auto-scroll runs on
useAnimationFrameand does not check for reduced-motion preferences; the Play/Pause toggle is the only way to stop it.
Notes#
- Media priority per card:
embedUrlrenders an iframe; otherwiseimageSrcorposterrenders animg; otherwisesrcrenders avideo. Settingpostertogether withsrc(withoutembedUrl) therefore shows the poster image and the video is not rendered. - The corner badge reads "TikTok" for embed and image cards and "Demo reel" for video cards. These labels and the "Open on TikTok" link text are fixed.
- Auto-scroll stops when toggled off, and pauses while hovered (if
pauseOnHover), while dragging, and during the 0.35 second settle animation after a control, dot, or drag. - The track can be dragged horizontally; on release it snaps to the nearest card. The previous and next controls move by one card width, and dots take the shortest path to their card.
- The dots are black and the toggle is white, so the footer is meant for a light background.
- The footer is hidden when there is only one item.