Skip to content

Logo Carousel

DisplayMIT
View in Storybook

Auto-scrolling logo strip for marketing social-proof sections.

bun add @otfdashkit/ui

Preview

Logo Carousel
Loading Storybook preview…

Code

import { LogoCarousel } from '@otfdashkit/ui'

const LOGO_LABELS = ['Acme', 'Globex', 'Initech', 'Umbrella', 'Massive Dynamic', 'Stark Industries', 'Wayne Enterprises', 'Hooli'] as const

export function Example() {
  return (
    <div className="space-y-8">
      <div className="space-y-3">
        <p className="text-xs font-mono uppercase tracking-widest text-[hsl(var(--muted-foreground))]">Default · 30s · pause on hover</p>
        <LogoCarousel
          logos={LOGO_LABELS.map((l) => (
            <span key={l} className="text-base font-semibold tracking-tight whitespace-nowrap">
              {l}
            </span>
          ))}
        />
      </div>

      <div className="space-y-3">
        <p className="text-xs font-mono uppercase tracking-widest text-[hsl(var(--muted-foreground))]">Reverse · faster · no fade</p>
        <LogoCarousel
          duration={20}
          direction="right"
          fadeEdges={false}
          gap="2.5rem"
          logos={LOGO_LABELS.map((l) => (
            <span key={l} className="text-sm font-medium uppercase tracking-[0.2em] text-[hsl(var(--muted-foreground))] whitespace-nowrap">
              {l}
            </span>
          ))}
        />
      </div>

      <div className="space-y-3">
        <p className="text-xs font-mono uppercase tracking-widest text-[hsl(var(--muted-foreground))]">SVG marks · slow drift</p>
        <LogoCarousel
          duration={45}
          gap="4rem"
          logos={[
            <svg key="a" width="80" height="20" viewBox="0 0 80 20" className="text-[hsl(var(--muted-foreground))]">
              <text x="0" y="15" fontFamily="monospace" fontSize="14" fontWeight="700" fill="currentColor">{'<acme/>'}</text>
            </svg>,
            <svg key="b" width="60" height="20" viewBox="0 0 60 20" className="text-[hsl(var(--muted-foreground))]">
              <circle cx="10" cy="10" r="6" fill="currentColor" />
              <text x="22" y="15" fontSize="13" fontWeight="600" fill="currentColor">Orbit</text>
            </svg>,
            <svg key="c" width="80" height="20" viewBox="0 0 80 20" className="text-[hsl(var(--muted-foreground))]">
              <text x="0" y="15" fontFamily="serif" fontSize="15" fontStyle="italic" fill="currentColor">Lumen.</text>
            </svg>,
            <svg key="d" width="80" height="20" viewBox="0 0 80 20" className="text-[hsl(var(--muted-foreground))]">
              <rect x="0" y="3" width="14" height="14" fill="currentColor" />
              <text x="20" y="15" fontSize="13" fontWeight="700" fill="currentColor">CUBIT</text>
            </svg>,
            <svg key="e" width="70" height="20" viewBox="0 0 70 20" className="text-[hsl(var(--muted-foreground))]">
              <text x="0" y="15" fontFamily="sans-serif" fontSize="14" fontWeight="800" letterSpacing="2" fill="currentColor">PRISM</text>
            </svg>,
            <svg key="f" width="90" height="20" viewBox="0 0 90 20" className="text-[hsl(var(--muted-foreground))]">
              <path d="M0 10 L10 0 L20 10 L10 20 Z" fill="currentColor" />
              <text x="26" y="15" fontSize="13" fontWeight="600" fill="currentColor">Vertex</text>
            </svg>,
          ]}
        />
      </div>
    </div>
  )
}

Free with the SDK. This component ships in @otfdashkit/ui under the MIT license.

Props

Props declared in the LogoCarousel source. Inherited HTML attributes are not listed.

PropTypeDefaultDescription
logosrequiredReactNode[]Logo nodes (text, <img>, <svg>, or any React element).
direction'left' | 'right''left'Direction of travel. Default 'left'.
durationnumber30Travel duration in seconds. Lower = faster. Default 30.
fadeEdgesbooleantrueFaded edges so logos enter/exit smoothly. Default true.
gapstring | number'3rem'Gap between logos (any valid CSS length). Default '3rem'.
pauseOnHoverbooleantruePause the marquee when hovering. Default true.