pastetaste
Index Reel
A looping word index with a fixed arrow: the list creeps, snaps and settles one row at a time, the entry under the arrow steps in and darkens, the rest fade with distance. Clickable, keyboard-driven.
Paste it into Claude Code: it installs the component, asks for your brand and content, and places it on the page you name.
Live demo. Move the mouse and scroll inside it.
Install
Or by hand, in a Next.js project with shadcn set up. It writes components/pastetaste/index-reel.tsx.
npx shadcn@latest add https://pastetaste.com/r/index-reel.jsonPrompt
Install the pastetaste component "Index Reel" (index-reel) into this Next.js project and use it.
What it is: A looping word index with a fixed arrow: the list creeps, snaps and settles one row at a time, the entry under the arrow steps in and darkens, the rest fade with distance. Clickable, keyboard-driven.
Before you place it, ask me (one short message, in my language; "skip" = sensible default): which page and section it goes in, my brand colour (hex), the text, labels or images it should show, and whether I want my logo or my own copy in the demo content. Then:
Steps:
1. If the project has no components.json, run: npx shadcn@latest init -y -d. Then run: npx shadcn@latest add https://pastetaste.com/r/index-reel.json
(it writes components/pastetaste/index-reel.tsx; install any npm packages it reports).
2. Import it: import { IndexReel } from "@/components/pastetaste/index-reel" (check the file for the exact named export).
3. Put it where it fits on the page I name, keep the rest of the page untouched, and pass props for my colours instead of editing the installed file.
4. It does not depend on Tailwind; colours come from CSS variables (--pt-*) or props.
5. It supports prefers-reduced-motion with a still state; do not remove it.
Props (all optional unless the type has no default):
- items: Array<string | { label: ReactNode; href?: string; key?: string }> — Entries on the reel, in order. The list loops; short lists are repeated so no row ever jumps across.
- index / defaultIndex: number / number = — / 0 — Controlled or starting entry.
- onIndexChange: (index: number) => void — Fires when the reel starts rolling to a new entry (autoplay, click or key). Use it to swap a photo or caption in step with the reel.
- onSelect: (index: number) => void — Fires when the current entry is clicked or Enter is pressed on it. Items with href follow their link as well.
- autoplay / interval: boolean / number = true / 1.5 — Step on its own every interval seconds. Pauses on mouse hover, keyboard focus, off-screen and in a hidden tab; off with reduced motion.
- paused: boolean = false — Stop autoplay from outside, e.g. a Pause button next to the reel.
- duration: number = 0.62 — Seconds one step takes. Jumps of several rows take up to 2.2× as long.
- direction: 'up' | 'down' = 'up' — Autoplay travel: 'up' brings the next entry up from below.
- rows: number = 3 — Rows shown on each side of the arrow (1 to 6). The reel is (2 × rows + 1) × leading em tall.
- size: string = 'clamp(2.25rem, 6vw, 4.5rem)' — CSS font-size of the reel; arrow, indent and pitch scale with it.
- marker: ReactNode | null = arrow — What sits at the middle row. null removes it (and the indent).
- indent / leading: number / number = 1.08 / 1.04 — How far the current entry steps in, and the row pitch, both in em.
- interactive: boolean = true — Rows are buttons (or links). Off renders plain text for a pure display reel.
- label: string = 'Index' — Accessible name of the list.
Live preview: https://pastetaste.com/c/index-reel
Then run the dev server, check it in the browser at desktop and mobile width, and tell me the page URL.Props 14
| Prop | Type | Default | Description |
|---|---|---|---|
| items | Array<string | { label: ReactNode; href?: string; key?: string }> | - | Entries on the reel, in order. The list loops; short lists are repeated so no row ever jumps across. |
| index / defaultIndex | number / number | — / 0 | Controlled or starting entry. |
| onIndexChange | (index: number) => void | - | Fires when the reel starts rolling to a new entry (autoplay, click or key). Use it to swap a photo or caption in step with the reel. |
| onSelect | (index: number) => void | - | Fires when the current entry is clicked or Enter is pressed on it. Items with href follow their link as well. |
| autoplay / interval | boolean / number | true / 1.5 | Step on its own every interval seconds. Pauses on mouse hover, keyboard focus, off-screen and in a hidden tab; off with reduced motion. |
| paused | boolean | false | Stop autoplay from outside, e.g. a Pause button next to the reel. |
| duration | number | 0.62 | Seconds one step takes. Jumps of several rows take up to 2.2× as long. |
| direction | 'up' | 'down' | 'up' | Autoplay travel: 'up' brings the next entry up from below. |
| rows | number | 3 | Rows shown on each side of the arrow (1 to 6). The reel is (2 × rows + 1) × leading em tall. |
| size | string | 'clamp(2.25rem, 6vw, 4.5rem)' | CSS font-size of the reel; arrow, indent and pitch scale with it. |
| marker | ReactNode | null | arrow | What sits at the middle row. null removes it (and the indent). |
| indent / leading | number / number | 1.08 / 1.04 | How far the current entry steps in, and the row pitch, both in em. |
| interactive | boolean | true | Rows are buttons (or links). Off renders plain text for a pure display reel. |
| label | string | 'Index' | Accessible name of the list. |