KQ-1290 · COLLAPSE/HEADER
Collapse Header
A scroll container with a large header whose title is one heading floating over the page: as you scroll it moves 1:1 with the page toward the toolbar, easing across to its docked place beside the back button (or centred) and down to toolbar size, while the cover parallaxes and fades behind it and the actions fold into the overflow button as they slide up to meet the bar. Past the threshold the title lets go of the scroll and docks by itself on the snap spring; docked, the header stays compact however you scroll until you come back to the very top, where it re-expands on glide. The scroll area is a focusable region, so arrow, Page, Home and End keys reach the same states, and the overflow button is a menu button whose menu holds the folded actions.
Basin Road survey
expanded · 3 actions
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/collapse-header
Props
- title
- string
- default "Basin Road survey"
- The heading that docks in the toolbar. Large it may wrap to two lines; docked it is always one clean line.
- subtitle
- string
- default —
- The line under the title; it scrolls away with the page.
- eyebrow
- string
- default —
- A small label above the title.
- cover
- React.ReactNode
- default a procedural ridge drawing
- Fills the cover; the default is drawn in the accent and mixed toward the page, so it reads in both themes.
- actions
- CollapseHeaderAction[]
- default defaultHeaderActions
- The row of actions under the title (id, label, icon); they fold into the overflow menu as they reach the toolbar.
- onAction
- (id: string) => void
- default —
- An action pressed, inline or from the overflow menu.
- onBack
- () => void
- default —
- The back button. Without it the button is still drawn, for the docked title to sit beside.
- backLabel
- string
- default "Back"
- The back button's accessible name.
- overflowLabel
- string
- default "More actions"
- The overflow button's and its menu's accessible name.
- onDockChange
- (docked: boolean) => void
- default —
- Fires from the scroll that docked the title (true) or re-expanded the header at the top (false).
- parallax
- number
- default 0.5
- How much slower than the page the cover moves, 0 to 1: 0 scrolls with the page, 1 stays put behind it.
- dock
- "start" | "center"
- default "start"
- Where the title docks in the toolbar: beside the back button, or centred.
- threshold
- number
- default 0.6
- How far through its travel (0.3 to 1) the title lets go of the scroll and docks by itself on the snap spring; 1 never lets go early.
- coverHeight
- number
- default 168
- The cover's height in px; a fifth taller when the header is 560px wide or more.
- height
- number | string
- default 520
- The container's height, px or any CSS length. It scrolls inside itself.
- size
- "sm" | "md" | "lg"
- default "md"
- The large title: 24, 28 or 34 px. It docks at 17 px.
- accent
- string
- default "var(--accent-bright)"
- The cover drawing and the docked toolbar's rule. Any CSS colour.
- children
- React.ReactNode
- default —
- The page under the header.
- sound
- boolean
- default false
- A swish as the visitor's scroll docks the title (higher) and as it re-expands the header at the top (lower). Nothing else plays.
- className
- string
- default —
- Merged onto the root (a rounded, clipped container-query box that carries data-state="expanded" or "docked").
| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | "Basin Road survey" | The heading that docks in the toolbar. Large it may wrap to two lines; docked it is always one clean line. |
| subtitle | string | — | The line under the title; it scrolls away with the page. |
| eyebrow | string | — | A small label above the title. |
| cover | React.ReactNode | a procedural ridge drawing | Fills the cover; the default is drawn in the accent and mixed toward the page, so it reads in both themes. |
| actions | CollapseHeaderAction[] | defaultHeaderActions | The row of actions under the title (id, label, icon); they fold into the overflow menu as they reach the toolbar. |
| onAction | (id: string) => void | — | An action pressed, inline or from the overflow menu. |
| onBack | () => void | — | The back button. Without it the button is still drawn, for the docked title to sit beside. |
| backLabel | string | "Back" | The back button's accessible name. |
| overflowLabel | string | "More actions" | The overflow button's and its menu's accessible name. |
| onDockChange | (docked: boolean) => void | — | Fires from the scroll that docked the title (true) or re-expanded the header at the top (false). |
| parallax | number | 0.5 | How much slower than the page the cover moves, 0 to 1: 0 scrolls with the page, 1 stays put behind it. |
| dock | "start" | "center" | "start" | Where the title docks in the toolbar: beside the back button, or centred. |
| threshold | number | 0.6 | How far through its travel (0.3 to 1) the title lets go of the scroll and docks by itself on the snap spring; 1 never lets go early. |
| coverHeight | number | 168 | The cover's height in px; a fifth taller when the header is 560px wide or more. |
| height | number | string | 520 | The container's height, px or any CSS length. It scrolls inside itself. |
| size | "sm" | "md" | "lg" | "md" | The large title: 24, 28 or 34 px. It docks at 17 px. |
| accent | string | "var(--accent-bright)" | The cover drawing and the docked toolbar's rule. Any CSS colour. |
| children | React.ReactNode | — | The page under the header. |
| sound | boolean | false | A swish as the visitor's scroll docks the title (higher) and as it re-expands the header at the top (lower). Nothing else plays. |
| className | string | — | Merged onto the root (a rounded, clipped container-query box that carries data-state="expanded" or "docked"). |