d-ui logod-ui
テキスト

Marquee

コンテンツを水平に無限スクロールするマーキーコンポーネント。

インストール

npx shadcn add https://d-ui.daigo-suhara.com/registry/marquee.json

サンプル

React
TypeScript
Next.js
Tailwind CSS
shadcn/ui
Vercel
Radix UI
React
TypeScript
Next.js
Tailwind CSS
shadcn/ui
Vercel
Radix UI

使い方

import { Marquee, MarqueeItem } from "@/components/ui/marquee";

export default function Example() {
  return (
    <Marquee>
      {["React", "TypeScript", "Next.js", "Tailwind"].map((tag) => (
        <MarqueeItem key={tag}>
          <span className="rounded-full border px-3 py-1 text-sm">{tag}</span>
        </MarqueeItem>
      ))}
    </Marquee>
  );
}

プロパティ

speed任意
"slow" | "normal" | "fast"

スクロール速度

デフォルト:"normal"
direction任意
"left" | "right"

スクロール方向

デフォルト:"left"
pauseOnHover任意
boolean

ホバーで一時停止

デフォルト:true
gap任意
number

アイテム間のgap(px)

デフォルト:16

ソースコード

import * as React from "react";
import { cn } from "@/lib/utils";

interface MarqueeProps {
  children: React.ReactNode;
  speed?: "slow" | "normal" | "fast";
  direction?: "left" | "right";
  pauseOnHover?: boolean;
  gap?: number;
  className?: string;
}

const speeds = { slow: "40s", normal: "25s", fast: "12s" };

export function Marquee({
  children,
  speed = "normal",
  direction = "left",
  pauseOnHover = true,
  gap = 16,
  className,
}: MarqueeProps) {
  return (
    <div
      className={cn("overflow-hidden [mask-image:linear-gradient(to_right,transparent,black_10%,black_90%,transparent)]", className)}
    >
      <div
        className={cn(
          "flex w-max",
          direction === "left"
            ? "animate-[marquee_var(--marquee-speed)_linear_infinite]"
            : "animate-[marquee-reverse_var(--marquee-speed)_linear_infinite]",
          pauseOnHover && "hover:[animation-play-state:paused]"
        )}
        style={
          {
            gap: `${gap}px`,
            "--marquee-speed": speeds[speed],
          } as React.CSSProperties
        }
      >
        {children}
        {children}
      </div>
    </div>
  );
}

export function MarqueeItem({
  children,
  className,
}: {
  children: React.ReactNode;
  className?: string;
}) {
  return (
    <div className={cn("flex shrink-0 items-center", className)}>{children}</div>
  );
}