/**
* Professional Card Component with variants and animations
*/
import React, { forwardRef } from 'react';
import { cn } from '../../utils/cn';
export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
variant?: 'default' | 'outlined' | 'elevated' | 'flat';
padding?: 'none' | 'sm' | 'md' | 'lg';
rounded?: 'none' | 'sm' | 'md' | 'lg' | 'full';
shadow?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
hover?: boolean;
interactive?: boolean;
children: React.ReactNode;
}
export interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
}
export interface CardContentProps extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
}
export interface CardFooterProps extends React.HTMLAttributes<HTMLDivElement> {
children: React.ReactNode;
}
const Card = forwardRef<HTMLDivElement, CardProps>(({
className,
variant = 'default',
padding = 'md',
rounded = 'md',
shadow = 'md',
hover = false,
interactive = false,
children,
...props
}, ref) => {
const baseClasses = [
'bg-white',
'transition-all',
'duration-200',
'ease-in-out'
];
const variantClasses = {
default: ['border', 'border-gray-200'],
outlined: ['border-2', 'border-gray-300'],
elevated: [],
flat: ['border', 'border-gray-100']
};
const paddingClasses = {
none: [],
sm: ['p-4'],
md: ['p-6'],
lg: ['p-8']
};
const roundedClasses = {
none: ['rounded-none'],
sm: ['rounded-sm'],
md: ['rounded-lg'],
lg: ['rounded-xl'],
full: ['rounded-full']
};
const shadowClasses = {
none: ['shadow-none'],
sm: ['shadow-sm'],
md: ['shadow-md'],
lg: ['shadow-lg'],
xl: ['shadow-xl']
};
const interactionClasses = [
hover && 'hover:shadow-lg',
hover && 'hover:-translate-y-0.5',
interactive && 'cursor-pointer',
interactive && 'active:scale-98'
].filter(Boolean);
const classes = cn(
baseClasses,
variantClasses[variant],
paddingClasses[padding],
roundedClasses[rounded],
shadowClasses[shadow],
interactionClasses,
className
);
return (
<div
ref={ref}
className={classes}
{...props}
>
{children}
</div>
);
});
const CardHeader = forwardRef<HTMLDivElement, CardHeaderProps>(({
className,
children,
...props
}, ref) => {
const classes = cn(
'flex',
'flex-col',
'space-y-1.5',
'pb-4',
className
);
return (
<div
ref={ref}
className={classes}
{...props}
>
{children}
</div>
);
});
const CardContent = forwardRef<HTMLDivElement, CardContentProps>(({
className,
children,
...props
}, ref) => {
const classes = cn(
'flex-1',
className
);
return (
<div
ref={ref}
className={classes}
{...props}
>
{children}
</div>
);
});
const CardFooter = forwardRef<HTMLDivElement, CardFooterProps>(({
className,
children,
...props
}, ref) => {
const classes = cn(
'flex',
'items-center',
'pt-4',
'border-t',
'border-gray-100',
className
);
return (
<div
ref={ref}
className={classes}
{...props}
>
{children}
</div>
);
});
Card.displayName = 'Card';
CardHeader.displayName = 'CardHeader';
CardContent.displayName = 'CardContent';
CardFooter.displayName = 'CardFooter';
export { Card, CardHeader, CardContent, CardFooter };
export default Card;