Compare Slider
InteractiveA before/after reveal with a draggable vertical divider, click-to-jump track, and a full-keyboard ARIA slider grip; panels accept image descriptors or arbitrary nodes.
v2
v1
Left of the divider shows Draft; right shows Final.
Installation
npx shadcn@latest add https://parable-three.vercel.app/r/compare-slider.jsonRuns the shadcn CLI — the component source is copied intocomponents/parable/compare-slider.tsx. You own it from there.
Usage
The exact code rendering the preview above.
<div className="flex w-full items-center justify-center p-6">
<CompareSlider
className="h-[320px] w-full max-w-md"
labels={{ before: "Draft", after: "Final" }}
before={
<div className="flex h-full w-full items-center justify-center bg-gradient-to-br from-[#151517] via-[#1b1220] to-[#241428]">
<span className="text-4xl font-semibold tracking-tight text-white/35">v1</span>
</div>
}
after={
<div className="flex h-full w-full items-center justify-center bg-gradient-to-br from-[#8b5cf6] via-[#ec4899] to-[#f5a623]">
<span className="text-4xl font-semibold tracking-tight text-white">v2</span>
</div>
}
/>
</div>Props
CompareSliderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children">
| Prop | Type | Default | Description |
|---|---|---|---|
| before* | ComparePanel | — | Left / top-of-stack panel, revealed by the divider. Image descriptor or node. |
| after* | ComparePanel | — | Right / base panel that fills the frame. Image descriptor or node. |
| defaultPosition | number | 50 | Uncontrolled starting divider position, 0–100. Defaults to `50`. |
| position | number | — | Controlled divider position, 0–100. Pair with `onPositionChange`. |
| onPositionChange | (position: number) => void | — | Fires with the next clamped position whenever the divider moves. |
| labels | { before: React.ReactNode; after: React.ReactNode } | — | Corner captions for each panel. |
| accent | string | "#8b5cf6" | Accent for the focus ring and idle hint. Mirrors the site `--pb-violet` token. |
npm dependencies
- lucide-react