Reveal Card
A compact, interactive card that expands on hover to reveal additional content, efficiently presenting layered information in a limited space.
John Smith
The Computer Guy
When your computer is slower than your grandma's dial-up, and your code has more bugs than a picnic, who you gonna call? Not Ghostbusters, but close!
- Master of turning it off and on again
- Fluent in Binary, HTML, and Sarcasm
- Can debug your life (results may vary)
- Makes Excel sheets more exciting than Netflix
Installation
Install Dependencies
npm i clsx tailwind-merge framer-motion
Create @/utils/cn.ts file
import clsx, { ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
Reveal Card Component
"use client";
import { cn } from "@/lib/utils";
import { cva, type VariantProps } from "class-variance-authority";
import React, { createContext, useContext } from "react";
type CardSize = "default" | "small" | "large";
const revealCardVariants = cva("relative overflow-hidden rounded-md shadow-md group", {
variants: {
size: {
default: "w-[350px] h-[350px]",
small: "w-[250px] h-[250px]",
large: "w-full sm:w-[450px] h-[450px]"
}
},
defaultVariants: {
size: "default"
}
});
interface RevealCardProps extends React.HTMLAttributes<HTMLDivElement>, Omit<VariantProps<typeof revealCardVariants>, "size"> {
size?: CardSize | null;
}
const RevealCardContext = createContext<{ size: CardSize }>({ size: "default" });
export const RevealCard: React.FC<RevealCardProps> = ({ children, className, size, ...props }) => {
const safeSize: CardSize = size ?? "default";
return (
<RevealCardContext.Provider value={{ size: safeSize }}>
<div className={revealCardVariants({ size: safeSize, className })} {...props}>
{children}
</div>
</RevealCardContext.Provider>
);
};
const revealCardContentVariants = cva("absolute inset-0 rounded-md bg-gray-100", {
variants: {
size: {
default: "",
small: "",
large: ""
}
},
defaultVariants: {
size: "default"
}
});
interface RevealCardContentProps extends React.HTMLAttributes<HTMLDivElement> {}
export const RevealCardContent: React.FC<RevealCardContentProps> = ({ children, className, ...props }) => {
const { size } = useContext(RevealCardContext);
return (
<div className={cn(revealCardContentVariants({ size }), className)} {...props}>
{children}
</div>
);
};
const revealCardHeaderVariants = cva("absolute left-0 right-0 bottom-0 bg-white transition-transform duration-700 ease-in-out z-10", {
variants: {
size: {
default: "h-[90px] group-hover:translate-y-[-260px]",
small: "h-[70px] group-hover:translate-y-[-180px]",
large: "h-[110px] group-hover:translate-y-[-340px]"
}
},
defaultVariants: {
size: "default"
}
});
interface RevealCardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {}
export const RevealCardHeader: React.FC<RevealCardHeaderProps> = ({ children, className, ...props }) => {
const { size } = useContext(RevealCardContext);
return (
<div className={cn(revealCardHeaderVariants({ size }), className)} {...props}>
<div className="p-4">{children}</div>
</div>
);
};
const revealCardBodyVariants = cva(
"absolute inset-x-0 bottom-0 bg-white transition-transform duration-700 ease-in-out transform translate-y-full group-hover:translate-y-0 overflow-y-auto",
{
variants: {
size: {
default: "top-[90px]",
small: "top-[70px]",
large: "top-[110px]"
}
},
defaultVariants: {
size: "default"
}
}
);
interface RevealCardBodyProps extends React.HTMLAttributes<HTMLDivElement> {}
export const RevealCardBody: React.FC<RevealCardBodyProps> = ({ children, className, ...props }) => {
const { size } = useContext(RevealCardContext);
return (
<div className={cn(revealCardBodyVariants({ size }), className)} {...props}>
<div className="h-px w-full bg-gray-200"></div>
<div className="p-6">{children}</div>
</div>
);
};
Examples
Large
Alpine Adventure
Discover the majestic beauty of the mountains
Snowcapped Serenity
A winter wonderland awaits
Embark on an unforgettable journey to our pristine mountain resort. Nestled in the heart of snow-capped peaks, you'll find world-class skiing, cozy lodges, and breathtaking views that will leave you in awe.
- Ski slopes for all levels
- Luxurious mountain-view accommodations
- Gourmet dining with local flavors
- Relaxing spa treatments
Small
React Development
Custom Solutions
Tailored for your needs
- • Scalable architecture
- • Performance optimization
- • API integration