Skip to main content
Glama
Card.tsx3.48 kB
/** * 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;

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/DeamonDev888/Browser-Manager-MCP-Server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server