KQ-1408 · EDGE/HAZE
Edge Haze
A scroll area whose edges dissolve instead of cutting off: stacks of backdrop blurs, each twice the last and masked to begin a step further toward the edge, ramp the content smoothly from sharp to the full blur while a wash of the surface's own colour deepens toward the edge. Each edge's haze measures what it hides — the distance hidden beyond it over reach, followed on springs.glide — so the bottom haze recedes as the end comes near and lifts away on arrival while the top one gathers, and with nothing to scroll nothing is drawn. The viewport is a focusable region while it overflows, so arrow keys, Page Up and Down, Home and End scroll it natively.
Waylight 4.2 · release notes
What changed this spring
Apr 18
Offline reading lists
Save a list before the tunnel and it opens without a signal.
Apr 15
Quieter night theme
Lower contrast after ten, with the accent pulled back to amber.
Apr 11
Faster search
Results arrive as you type, ranked by what you last opened.
Apr 08
Shared highlights
Send a passage to a friend with your note pinned beside it.
Apr 04
Reading time on every story
Measured from your own pace, not an average reader's.
Mar 30
Gentler notifications
One digest at the hour you choose instead of a ping per story.
Mar 26
Larger type on small phones
Body text scales with the screen so lines stay a comfortable length.
Mar 21
Resume where you left off
Open a story on another device and it lands on your last line.
Mar 17
Waylight 4.2 begins
The spring release, built from your notes over the winter.
hazed below · 9 notes, newest first
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/edge-haze
Props
- children
- ReactNode
- default —
- The scrolling content.
- strength
- number
- default 10
- The blur at the very edge, in CSS pixels; it halves at each step inward.
- height
- number
- default 64
- How deep the haze reaches into the area at its fullest, in CSS pixels.
- edges
- "both" | "top" | "bottom"
- default "both"
- Which edges haze over when content is hidden beyond them.
- steps
- number
- default 6
- How many blur layers build the ramp, 3 to 8.
- fade
- number
- default 0.5
- How far the content fades into the surface at the very edge as well as blurring, 0 (not at all) to 1 (gone at the edge).
- reach
- number
- default height × 1.5
- How many pixels of hidden content give the full haze.
- tint
- string
- default the first solid background behind the area
- The colour the content fades into at the edge, any CSS colour; read on the element and again when the theme changes.
- maxHeight
- number | string
- default —
- The scroll area's maximum height (a number is CSS pixels); or size the box with className.
- label
- string
- default "Scrollable content"
- The scroll area's accessible name.
- scrollPadding
- boolean
- default true
- Keep keyboard-focused content and page steps clear of the haze.
- onEdgesChange
- (edges: { top: boolean; bottom: boolean }) => void
- default —
- Fires when content starts or stops being hidden beyond either edge, and once on the first measure.
- viewportRef
- Ref<HTMLDivElement>
- default —
- A ref to the scrolling element, for hosts that scroll it themselves.
- viewportClassName
- string
- default —
- Classes for the scrolling element.
- className
- string
- default —
- Classes for the box.
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | The scrolling content. |
| strength | number | 10 | The blur at the very edge, in CSS pixels; it halves at each step inward. |
| height | number | 64 | How deep the haze reaches into the area at its fullest, in CSS pixels. |
| edges | "both" | "top" | "bottom" | "both" | Which edges haze over when content is hidden beyond them. |
| steps | number | 6 | How many blur layers build the ramp, 3 to 8. |
| fade | number | 0.5 | How far the content fades into the surface at the very edge as well as blurring, 0 (not at all) to 1 (gone at the edge). |
| reach | number | height × 1.5 | How many pixels of hidden content give the full haze. |
| tint | string | the first solid background behind the area | The colour the content fades into at the edge, any CSS colour; read on the element and again when the theme changes. |
| maxHeight | number | string | — | The scroll area's maximum height (a number is CSS pixels); or size the box with className. |
| label | string | "Scrollable content" | The scroll area's accessible name. |
| scrollPadding | boolean | true | Keep keyboard-focused content and page steps clear of the haze. |
| onEdgesChange | (edges: { top: boolean; bottom: boolean }) => void | — | Fires when content starts or stops being hidden beyond either edge, and once on the first measure. |
| viewportRef | Ref<HTMLDivElement> | — | A ref to the scrolling element, for hosts that scroll it themselves. |
| viewportClassName | string | — | Classes for the scrolling element. |
| className | string | — | Classes for the box. |