LogoLoop
logo-loopScrolls a seamless loop of logos with configurable direction and hover pause.
Usage
Basic usage
Pass in the logos list (mixed arrangement of icons or pictures), and the sequence is automatically copied to achieve seamless infinite scrolling; fadeOut adds fade masks to both ends (eat surface token).
const logos = [
{ node: <Hexagon />, ariaLabel: "Hexagon" },
{ node: <Cloud />, ariaLabel: "Cloud" },
{ node: <Database />, ariaLabel: "Database" },
];
<LogoLoop logos={logos} fadeOut />Hover to pause + zoom
direction controls direction; pauseOnHover hovers to stop scrolling, and scaleOnHover hovers to zoom in on the single logo being pointed at.
<LogoLoop
logos={logos}
direction="right"
fadeOut
pauseOnHover
scaleOnHover
/>Speed and spacing
speed adjusts the scroll speed (px/s, negative value reverses), gap adjusts the item spacing, logoHeight adjusts logo height.
<LogoLoop logos={logos} speed={220} gap={56} logoHeight={32} />Vertical scroll
direction="up" / "down" changes to vertical scrolling and needs to be placed in a container with height.
<div className="h-56 overflow-hidden px-8">
<LogoLoop logos={logos} direction="up" fadeOut />
</div>When to use
Use LogoLoop for an infinitely scrolling row or column of partner, integration, or technology logos. Use Table or ProTable for structured data, or PricingTable for a static pricing matrix.
Import
import { LogoLoop } from "@hulianui/ui"Props
| Name | Type | Default | Description |
|---|---|---|---|
| logos * | LogoItem[] | — | Image and node logo entries; the full sequence is duplicated for seamless motion. |
| speed | number | 120 | Pixels per second; negative values reverse direction. |
| direction | "left" | "right" | "up" | "down" | "left" | Scroll direction. |
| width | number | string | "100%" | Container width; numbers are pixels and strings pass through. |
| logoHeight | number | 28 | Logo height in pixels. |
| gap | number | 32 | Gap in pixels. |
| pauseOnHover | boolean | undefined (equivalent to true) | Stops on hover unless hoverSpeed is also provided. |
| hoverSpeed | number | — | Target hover speed, taking precedence over pauseOnHover. |
| fadeOut | boolean | false | Adds token-aware fades at both ends. |
| fadeOutColor | string | var(--color-surface) | Fade color. |
| scaleOnHover | boolean | false | Scales the hovered logo to 1.2. |
| ariaLabel | string | "\u5408\u4f5c\u4f19\u4f34 logo" | Accessible root label. The built-in Chinese copy means “Partner logos.” |
| className | string | — | Root class name. |
| style | CSSProperties | — | Root inline styles. |
LogoItem is either{ src, srcSet?, sizes?, width?, height?, alt?, title?, href? }or{ node, ariaLabel?, title?, href? }. An entry with href is wrapped in a link.
Slots
| Slot | Type | Description |
|---|---|---|
| renderItem | (item: LogoItem, index: number) => ReactNode | Replaces default image or node rendering. |
Example
const logos = [{ node: <HexagonIcon />, ariaLabel: "Hexagon" }, { node: <CloudIcon />, ariaLabel: "Cloud" }];
<LogoLoop logos={logos} fadeOut />
<LogoLoop logos={logos} direction="right" fadeOut pauseOnHover scaleOnHover />Usage guidelines
- Vertical directions need a parent with explicit height.
- Image alt defaults to an empty string; add meaningful alt text when the logo conveys content.
- hoverSpeed takes precedence when supplied with pauseOnHover.
- Reduced-motion mode stops scrolling.
- Linked items without an explicit item label fall back to the built-in Chinese
"logo \u94fe\u63a5", meaning “logo link.”
Related
Table · Book3D · ProTable · PricingTable · JsonViewer · EditableTable
Playground
<LogoLoop
logos={logos}
speed={120}
direction="left"
gap={32}
logoHeight={28}
fadeOut={true}
scaleOnHover={true}
pauseOnHover={true}
/>