Components / Data display
ImageCompare
Drag a divider across two images to see what changed.
Install
npx shadcn@latest add https://irisui.dev/r/image-compare.jsonimport { ImageCompare } from "@/components/iris/image-compare/image-compare";Preview
ImageCompare
Two images stacked in one frame with a draggable divider, so people can wipe between a before and an after.
When to use
- Showing what changed: a revised floor plan, a redesign, a photo edit.
- When the two images share the same framing and the difference is spatial.
- Use Carousel for several unrelated images, and side-by-side images (two Card media) when people need to see both whole at once.
Usage
import { ImageCompare } from "@/components/iris/image-compare/image-compare";
h(ImageCompare, {
before: h("img", { src: "/plans/kypseli-current.svg", alt: "Current floor plan" }),
after: h("img", { src: "/plans/kypseli-revised.svg", alt: "Revised floor plan" }),
labels: ["Current", "Revised"],
label: "Reveal the revised floor plan",
aspectRatio: "16 / 9",
});
Props
| Prop | Type | Default | Description |
|---|---|---|---|
before |
ReactNode |
— (required) | Original, on the left (or top). Pass an element with its own alt text; it is sized to cover the frame. |
after |
ReactNode |
— (required) | Result, on the right (or bottom). |
position / defaultPosition / onPositionChange |
number / number / (p) => void |
— / 50 |
Divider position in percent, controlled or uncontrolled. |
orientation |
"horizontal" | "vertical" |
"horizontal" |
Vertical stacks top and bottom; switching swings the divider a quarter turn. |
labels |
[string, string] | false |
["Before", "After"] |
Captions over each side; they fade as the divider reaches them. false hides them. |
label |
string |
"Before and after" |
Accessible name of the divider. |
aspectRatio |
string |
"3 / 2" |
Frame proportions as a CSS aspect-ratio. |
className |
string |
— | Extra class on the root. |
Notes
- The divider is a focusable slider: arrow keys step 1% (Shift for 10%), Home/End reveal one side fully, double-clicking the handle springs it back to the middle.
- Dragging follows 1:1 with a rubber-band past the edges; a press on the image springs the divider there. On touch it waits for a sideways drag so the page still scrolls.
- Any element works for each side (
img,picture,video, inline SVG).