KQ-1402 · LOGO/PARADE
Logo Parade
An endless conveyor of marks with edge fades, built in the DOM so every mark stays crisp and real. A row's speed is a spring on springs.drift's constants, so under the pointer it brakes smoothly to a stop and picks back up when the pointer leaves, while the mark under the pointer lifts on springs.snap and takes its colour as the rest stay muted; rows drag 1:1 and a flick hands its velocity to the same spring, so the conveyor spins away, leans into the throw and glides back to cruising speed, with further rows running the other way. Linked or selectable marks sit on a roving tabindex where Left and Right move between them and the row glides on springs.glide to centre the focused one; plain marks make the row the focus stop and the arrows step it.
Field-tested by the crews at
parading · 40 px/s
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/logo-parade
Props
- items
- LogoParadeItem[]
- default —
- The marks, each `{ id, name, mark, color?, href? }`; the mark paints with currentColor and may use var(--mark-color) for an accent that turns to `color` when looked at.
- speed
- number
- default 40
- Cruising speed in px per second.
- gap
- number
- default 48
- Space between marks in px.
- rows
- number
- default 2
- How many rows, 1 to 3; each further row runs the other way, half a set along.
- direction
- "left" | "right"
- default "left"
- Which way the first row travels.
- hoverSpeed
- number
- default 0
- The share of the cruising speed a row keeps under the pointer, 0 to 1; 0 brakes it to a stop.
- lift
- number
- default 4
- How far the looked-at mark lifts, in px.
- muted
- number
- default 0.6
- How grey and faint the marks at rest are, 0 to 1.
- fade
- number
- default 56
- Width of the edge fades in px, never more than a fifth of the row.
- skew
- number
- default 0.5
- How far a fast row leans into its travel, 0 to 1.
- size
- "sm" | "md" | "lg"
- default "md"
- Row height and mark size.
- draggable
- boolean
- default true
- Let rows be dragged and flicked.
- paused
- boolean
- default false
- Stop the conveyor; marks still answer the pointer and keys.
- label
- string
- default "Logos"
- The accessible name of the list of marks.
- onSelect
- (item: LogoParadeItem) => void
- default —
- Called when a mark without an href is pressed or activated with Enter.
- onLook
- (item: LogoParadeItem | null) => void
- default —
- Called when the mark being looked at (hovered or focused) changes, with null when none is.
- className
- string
- default —
- Classes for the wall.
| Prop | Type | Default | Description |
|---|---|---|---|
| items | LogoParadeItem[] | — | The marks, each `{ id, name, mark, color?, href? }`; the mark paints with currentColor and may use var(--mark-color) for an accent that turns to `color` when looked at. |
| speed | number | 40 | Cruising speed in px per second. |
| gap | number | 48 | Space between marks in px. |
| rows | number | 2 | How many rows, 1 to 3; each further row runs the other way, half a set along. |
| direction | "left" | "right" | "left" | Which way the first row travels. |
| hoverSpeed | number | 0 | The share of the cruising speed a row keeps under the pointer, 0 to 1; 0 brakes it to a stop. |
| lift | number | 4 | How far the looked-at mark lifts, in px. |
| muted | number | 0.6 | How grey and faint the marks at rest are, 0 to 1. |
| fade | number | 56 | Width of the edge fades in px, never more than a fifth of the row. |
| skew | number | 0.5 | How far a fast row leans into its travel, 0 to 1. |
| size | "sm" | "md" | "lg" | "md" | Row height and mark size. |
| draggable | boolean | true | Let rows be dragged and flicked. |
| paused | boolean | false | Stop the conveyor; marks still answer the pointer and keys. |
| label | string | "Logos" | The accessible name of the list of marks. |
| onSelect | (item: LogoParadeItem) => void | — | Called when a mark without an href is pressed or activated with Enter. |
| onLook | (item: LogoParadeItem | null) => void | — | Called when the mark being looked at (hovered or focused) changes, with null when none is. |
| className | string | — | Classes for the wall. |