KQ-1388 · SCROLL/UNFOLD
Scroll Unfold
A scroll-linked media card that grows to fill the frame: the section pins a stage in its nearest scroll container, and the distance scrolled, 1:1 and eased once by the house's symmetric move, opens the card's clip from its inset to full bleed while its corners flatten and the picture zooms out to meet it. The headline is split around the card and each half is pushed by the card's own edge, keeping a fixed gap as the words part and slide off the stage, while the caption rides the frame's bottom edge away and an overlay title rises over the last quarter; scrolling back folds it. Keyboard scrolling of the container (arrows, Page keys, Space) drives it exactly as the wheel does.
Fieldline Journal · Issue 12
Notes from the ridge
Three nights on the Coldbrook ridge with a field camera and a flask. The light goes quickly up there; the plate below was made in the last four minutes of it.
Scroll to open the plate
Above the tree line
We set up below the saddle at five, when the wind dropped and the valley filled with a slow white mist. By half past six the far ridges had gone the colour of slate and the near ones had gone dark.
Next issue: the Basin overlook in snow, and a long exposure from the Waylight hut.
folded · scroll the journal
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/scroll-unfold
Props
- children
- ReactNode
- default —
- The media the card frames (an image, a video, an SVG); it fills the frame, so give it size-full object-cover.
- headline
- string
- default —
- The headline that splits around the card.
- splitAt
- number
- default half the words, rounded up
- How many words go before the card.
- as
- "h1" | "h2" | "h3" | "p"
- default "h2"
- The headline's element.
- caption
- ReactNode
- default —
- A line under the card that slides away as it grows.
- overlay
- ReactNode
- default —
- A title laid over the full-bleed frame, rising in over the last quarter.
- range
- number
- default 400
- How far the reader scrolls to unfold it, px.
- inset
- number
- default 0.26
- The card's starting inset as a share of the stage width (0.05 to 0.45).
- radius
- number
- default 24
- The card's starting corner radius, px; it flattens to 0 at full bleed.
- zoom
- number
- default 0.12
- How much the media zooms out as the frame opens, 0 to 0.4.
- pin
- boolean
- default true
- Hold the stage in place (sticky) while it unfolds.
- height
- number
- default the scroll container's visible height
- The stage's height, px.
- start
- number
- default 0
- Scroll distance before the unfold begins, px.
- smooth
- number
- default 0
- Eases the scroll-linked progress on a spring, from 1:1 with the scroll at 0 to heavy at 1.
- gap
- number
- default 16
- The space between the headline and the card, px.
- onStageChange
- (stage: "folded" | "unfolding" | "unfolded") => void
- default —
- Fires when the piece passes between folded, unfolding and unfolded.
- className
- string
- default —
- Classes for the section.
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | The media the card frames (an image, a video, an SVG); it fills the frame, so give it size-full object-cover. |
| headline | string | — | The headline that splits around the card. |
| splitAt | number | half the words, rounded up | How many words go before the card. |
| as | "h1" | "h2" | "h3" | "p" | "h2" | The headline's element. |
| caption | ReactNode | — | A line under the card that slides away as it grows. |
| overlay | ReactNode | — | A title laid over the full-bleed frame, rising in over the last quarter. |
| range | number | 400 | How far the reader scrolls to unfold it, px. |
| inset | number | 0.26 | The card's starting inset as a share of the stage width (0.05 to 0.45). |
| radius | number | 24 | The card's starting corner radius, px; it flattens to 0 at full bleed. |
| zoom | number | 0.12 | How much the media zooms out as the frame opens, 0 to 0.4. |
| pin | boolean | true | Hold the stage in place (sticky) while it unfolds. |
| height | number | the scroll container's visible height | The stage's height, px. |
| start | number | 0 | Scroll distance before the unfold begins, px. |
| smooth | number | 0 | Eases the scroll-linked progress on a spring, from 1:1 with the scroll at 0 to heavy at 1. |
| gap | number | 16 | The space between the headline and the card, px. |
| onStageChange | (stage: "folded" | "unfolding" | "unfolded") => void | — | Fires when the piece passes between folded, unfolding and unfolded. |
| className | string | — | Classes for the section. |