Infinite auto-scrolling content strip with hold-to-pause, direction control and SVG edge fades.
$ npx lumioui add marquee
import { Marquee } from "@/components/ui/marquee/marquee";
Files installed into your repo
components/ui/marquee/marquee.tsx
Native packages required
@lumioui/core@latestreact-native-reanimated@*react-native-svg@*
Props12
| children | React.ReactNode | |
| direction? | "left" | "right" | Scroll direction. Default "left". |
| speed? | number | Scroll speed in px/sec. Default 48. |
| spacing? | number | Gap between loop copies in px. Default 32. |
| pauseOnPress? | boolean | Hold the strip to pause; release resumes from where it stopped. Default true. |
| playing? | boolean | Run the loop. Default true. |
| fadeEdges? | boolean | Gradient fades on both edges. Default true. |
| fadeWidth? | number | Fade width in px. Default 24. |
| fadeColor? | string | Fade tint — defaults to the theme background color. |
| contentClassName? | string | Classes for each content copy's row. |
| accessibilityLabel? | string | Label announced for the whole strip (role "text"). Tiled loop copies after the first stay hidden, so the content is never read twice. |
| className? | string | |
Marquee — Reversereverse.tsx
Live preview offline the relay is unreachable — check back shortly
marquee/variants/reverse.tsx open Infinite auto-scrolling content strip with hold-to-pause, direction control and SVG edge fades.
import { MarqueeReverse } from "@/components/ui/marquee/variants/reverse";
export function Example() {
return (
<MarqueeReverse />
);
}
import * as React from "react";
import { View } from "react-native";
import { Marquee } from "../marquee";
import { Badge } from "../../badge/badge";
import { Glass } from "../../glass/glass";
const ROW_A = ["Free shipping", "60-day returns", "Carbon neutral", "Members save 10%"];
const ROW_B = ["Lisbon", "Kyoto", "Oaxaca", "Reykjavík", "Portland"];
/** MarqueeReverse — two strips scrolling in opposite directions. */
export function MarqueeReverse() {
return (
<View className="w-full gap-3">
<Glass interactive curvature="edge" className="w-full gap-2 rounded-2xl py-4">
<Marquee speed={40}>
{ROW_A.map((t) => (
<Badge key={t} variant="secondary" className="mr-2">
{t}
</Badge>
))}
</Marquee>
<Marquee direction="right" speed={30} fadeWidth={32}>
{ROW_B.map((t) => (
<Badge key={t} variant="outline" className="mr-2">
{t}
</Badge>
))}
</Marquee>
</Glass>
</View>
);
}
Marquee — Tickerticker.tsx
Live preview offline the relay is unreachable — check back shortly
marquee/variants/ticker.tsx open Infinite auto-scrolling content strip with hold-to-pause, direction control and SVG edge fades.
import { MarqueeTicker } from "@/components/ui/marquee/variants/ticker";
export function Example() {
return (
<MarqueeTicker />
);
}
import * as React from "react";
import { View } from "react-native";
import { Marquee } from "../marquee";
import { Badge } from "../../badge/badge";
import { Icon } from "../../icon/icon";
import { Text } from "../../text/text";
import { Glass } from "../../glass/glass";
const HEADLINES = [
"Aurora Drop 04 goes live Friday",
"Members save an extra 10% this week",
"Free returns extended to 60 days",
"New: same-day delivery in Lisbon",
];
/** MarqueeTicker — news-ticker strip staged as a store card header. */
export function MarqueeTicker() {
return (
<View className="w-full gap-3">
<Glass interactive curvature="edge" className="w-full gap-3 rounded-2xl p-4">
<View className="flex-row items-center justify-between">
<View className="flex-row items-center gap-2">
<Icon name="zap" size="sm" color="primary" />
<Text variant="small" className="font-semibold">Aurora Store</Text>
</View>
<Text variant="muted" className="text-xs">Open now</Text>
</View>
<Glass interactive curvature="edge" className="flex-row items-center gap-2 rounded-xl px-3 py-2.5">
<Badge variant="destructive" icon={null} pulse>Live</Badge>
<Marquee speed={56} spacing={0} fadeWidth={20} className="flex-1">
{HEADLINES.map((h) => (
<View key={h} className="flex-row items-center">
<Text className="text-sm font-medium text-foreground">{h}</Text>
<View className="mx-4 h-1 w-1 rounded-full bg-muted-foreground" />
</View>
))}
</Marquee>
</Glass>
<View className="flex-row gap-2">
{["New", "Deals", "Members"].map((t) => (
<Glass interactive key={t} curvature="edge" className="rounded-full px-3 py-1.5">
<Text className="text-xs font-medium text-foreground">{t}</Text>
</Glass>
))}
</View>
</Glass>
</View>
);
}