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
| Prop | Type | Default | Description |
|---|---|---|---|
items | HoverFeatureCard[] | - | 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)
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | - | Card title displayed inside the illustration area. |
description | string | - | 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.divowns therest/hovervariants, and the panel inherits them automatically. - Cards without an
hrefreceivecursor-not-allowedand reduced opacity, withwhileTapscale disabled. - Use
renderLinkto decouple the component from any specific router — passnext/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.