All files / src/components/ui Card.tsx

0% Statements 0/33
0% Branches 0/1
0% Functions 0/1
0% Lines 0/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65                                                                                                                                 
import { motion, HTMLMotionProps } from 'framer-motion';
import { cn } from '../../lib/utils';
import { cardHover } from '../../lib/animations';
 
interface CardProps extends Omit<HTMLMotionProps<'div'>, 'children'> {
  children: React.ReactNode;
  hoverable?: boolean;
}
 
export function Card({ children, className, hoverable = false, ...props }: CardProps) {
  return (
    <motion.div
      className={cn(
        'rounded-xl border border-gray-200 bg-white p-4 shadow-sm',
        'dark:border-gray-700 dark:bg-gray-800',
        hoverable && 'cursor-pointer transition-shadow duration-200',
        className
      )}
      {...(hoverable && { whileHover: cardHover })}
      {...props}
    >
      {children}
    </motion.div>
  );
}
 
interface CardHeaderProps {
  children: React.ReactNode;
  className?: string;
}
 
export function CardHeader({ children, className }: CardHeaderProps) {
  return (
    <div className={cn('mb-3', className)}>
      {children}
    </div>
  );
}
 
interface CardTitleProps {
  children: React.ReactNode;
  className?: string;
}
 
export function CardTitle({ children, className }: CardTitleProps) {
  return (
    <h3 className={cn('text-sm font-semibold text-gray-900 dark:text-gray-100', className)}>
      {children}
    </h3>
  );
}
 
interface CardContentProps {
  children: React.ReactNode;
  className?: string;
}
 
export function CardContent({ children, className }: CardContentProps) {
  return (
    <div className={cn('text-sm text-gray-600 dark:text-gray-300', className)}>
      {children}
    </div>
  );
}