2026-01-13 23:46:43 +01:00

74 lines
1.9 KiB
TypeScript

import type { ReactNode } from 'react'
export type CardVariant = 'default' | 'interactive' | 'selected' | 'compact'
interface CardProps {
children: ReactNode
variant?: CardVariant
className?: string
onClick?: () => void
'aria-label'?: string
}
function getVariantClasses(variant: CardVariant, hasOnClick: boolean): string {
const baseClasses = 'border rounded-lg bg-cyber-dark'
switch (variant) {
case 'default':
return `${baseClasses} border-neon-cyan/30`
case 'interactive':
return `${baseClasses} border-neon-cyan/30 hover:border-neon-cyan/50 hover:shadow-glow-cyan transition-all ${hasOnClick ? 'cursor-pointer' : ''}`
case 'selected':
return `${baseClasses} border-neon-cyan ring-1 ring-neon-cyan/50 shadow-glow-cyan`
case 'compact':
return `${baseClasses} border-neon-cyan/30 p-4`
default:
return `${baseClasses} border-neon-cyan/30`
}
}
function getPaddingClasses(variant: CardVariant): string {
if (variant === 'compact') {
return 'p-4'
}
return 'p-6'
}
export function Card({
children,
variant = 'default',
className = '',
onClick,
'aria-label': ariaLabel,
}: CardProps): React.ReactElement {
const variantClasses = getVariantClasses(variant, onClick !== undefined)
const paddingClasses = getPaddingClasses(variant)
const combinedClasses = `${variantClasses} ${paddingClasses} ${className}`.trim()
if (onClick) {
return (
<div
onClick={onClick}
className={combinedClasses}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault()
onClick()
}
}}
aria-label={ariaLabel}
>
{children}
</div>
)
}
return (
<div className={combinedClasses} aria-label={ariaLabel}>
{children}
</div>
)
}