Hover Image List

A list of large headings that reveal an image on the left and shift right on hover, animated with Motion.

Installation

Pro components require registry authentication. Add your Unlumen UI Pro key as UNLUMEN_LICENSE_KEY in your .env.local file and follow the setup guide.

File Structure

hover-image-list.tsx

Usage

import { HoverImageList } from "@/components/unlumen-ui/hover-image-list";

const items = [
  { label: "Design systems", image: "/images/design.jpg" },
  { label: "Prototyping", image: "/images/proto.jpg" },
  { label: "Motion & animation", image: "/images/motion.jpg" },
];

<HoverImageList items={items} />;

API Reference

HoverImageList

items
HoverImageListItem[]

Array of items to display.

imageWidth?
number
220

Width of the image panel in pixels.

imageGap?
number
40

Gap between the image panel and the text list in pixels.

className?
string

Additional CSS classes.

HoverImageListItem

label
string

Large heading text.

image
string

Image URL shown when this item is hovered.

imageAlt?
string
""

Alt text for the image.

Notes

  • The image panel tracks the hovered item's vertical center using a Motion spring (stiffness: 200, damping: 18, mass: 0.6) — the image slides smoothly between items.
  • Images are aspect-square and object-cover by default. Provide square or close-to-square images for the best result.
  • The hovered item shifts 16px to the right, non-hovered items fade to opacity: 0.18 — both animated with a stiff spring (stiffness: 380, damping: 30).
  • Image transitions use AnimatePresence with mode="popLayout" — the outgoing image fades out while the incoming one fades in, with no layout jump.
  • Images use loading="lazy" and decoding="async" — but since they appear on hover, consider preloading critical images if the list is short.
  • The component uses onHoverStart / onHoverEnd from Motion — these fire on pointer enter/leave, not on focus. For keyboard accessibility, you may want to add onFocus handlers.
  • Set imageWidth and imageGap to control the layout. The image panel is flex-shrink-0 so it never collapses.

Credits

Inspired by @raul_dronca's original Design. Thanks to Raul for the initial idea!

Keep in mind

Most components on this site are inspired by or recreated from existing work across the web. I'm not here to take credit; just to learn, experiment, and sometimes push things a bit further. If something looks familiar and I forgot to mention you, reach out and I'll fix that right away.