Hover Feature Cards

A responsive grid of feature cards where a description panel slides in from below on hover, with spring animation and optional image support.

Installation

File Structure

hover-feature-cards.tsx

Usage

import {
  HoverFeatureCards,
  type HoverFeatureCard,
} from "@/components/unlumen-ui/hover-feature-cards";
import Link from "next/link";

const items: HoverFeatureCard[] = [
  {
    name: "Components",
    description:
      "Real components, not just primitives. Ready to use and customize.",
    href: "/components",
    img: "/blocks.png",
    imgLight: "/blocks-light.png",
    imgClassName: "absolute -bottom-10 left-1/2 -translate-x-1/2",
    imgWidth: 320,
    containerClassName: "h-full rounded-3xl",
    fadeBottom: true,
  },
  {
    name: "primitives",
    description: "Polished UI system, focused on aesthetics and smooth UX.",
    href: "/docs/ui",
    img: "/refined-ui.png",
    imgWidth: 200,
    containerClassName: "h-full rounded-3xl",
  },
];

export default function Example() {
  return (
    <HoverFeatureCards
      items={items}
      renderLink={(href, children) => <Link href={href}>{children}</Link>}
    />
  );
}

API Reference

HoverFeatureCards

PropTypeDefaultDescription
itemsHoverFeatureCard[]-Array of feature card data objects.
renderLink?(href: string, children: React.ReactNode) => React.ReactNode-Optional render prop to wrap linked cards. Receives the href and card children. Use this to inject Next.js Link or any router link.
className?string-Extra classes applied to the grid wrapper.

HoverFeatureCard (item shape)

PropTypeDefaultDescription
namestring-Card title displayed inside the illustration area.
descriptionstring-Text shown in the slide-in panel on hover.
href?string-Optional link target. When omitted the card is non-interactive.
img?string-Image URL shown in dark mode (or always when imgLight is not set).
imgLight?string-Image URL shown in light mode.
imgClassName?string-Extra classes applied to the image element.
imgWidth?number-Intrinsic width of the image in pixels.
containerClassName?string-Extra classes applied to the illustration container.
fadeBottom?boolean-When true, a gradient fades the bottom of the illustration area into the card background.
soon?boolean-When true, renders a 'Coming soon' badge and disables hover interaction.

Notes

  • The description panel slides up via Motion variant propagation: the parent motion.div owns the rest/hover variants, and the panel inherits them automatically.
  • Cards without an href receive cursor-not-allowed and reduced opacity, with whileTap scale disabled.
  • Use renderLink to decouple the component from any specific router — pass next/link, react-router, or a plain <a> tag.

Credits

Built by leo.

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.