React Before / After Slider

Some things are only legible as a comparison. A thermal map means little in isolation but everything beside the same board with a heatsink; two floorplans; this quarter's yield map against last. The slider does one job — clip the top layer to a handle — and asks only that the two layers be the same size and registered to each other.

Stock — 94 °C peakWith heatsink — 61 °C

Drag the handle, or focus it and use ← →. Same board, same thermal load — the right layer adds a heatsink over the hot quadrant.

Installation

npx shadcn@latest add "https://kelvinui.com/registry/before-after-slider.json"

Props

PropTypeDescription
beforeReact.ReactNodeRevealed-on-the-left layer
afterReact.ReactNodeRevealed-on-the-right layer, clipped to handle
beforeLabelstringCorner label for the before layer
afterLabelstringCorner label for the after layer
defaultPositionnumberInitial divider position, 0–100 (default 50)
aspectstringFrame aspect ratio, e.g. "16 / 10"

It has to be operable without a mouse

The handle is a real role="slider": focus it and ← → nudge by 2%, Shift+← → by 10%, Home/End jump to the ends. That is not a nicety — a comparison a keyboard or switch user cannot move is a comparison they cannot see, and the whole component exists to be seen.

Two smaller decisions. The labels fade out as the handle passes their side, so the divider never sits on top of the word describing it. And the frame is touch-none, because on a phone the gesture you want is "drag the handle", not "scroll the page" — letting the browser interpret it as a scroll makes the control feel broken.

Pass anything for the two layers — an <img>, an inline SVG, a canvas. The demo uses two SVG thermal fields computed from the same analytic function so both sides render identically on the server and after hydration.

New components every week

Get the week's new Kelvin UI components and templates in one short email. No spam, unsubscribe anytime.