File
Blob: src/client/components/ui/card.tsx
| 1 | import { forwardRef, type HTMLAttributes } from "react"; |
| 2 | |
| 3 | const variantClasses = { |
| 4 | default: "rounded-xl border border-zinc-800/60 bg-zinc-900 p-5 sm:p-6", |
| 5 | accent: "rounded-xl border border-accent-500/20 bg-zinc-900 p-5 sm:p-6", |
| 6 | } as const; |
| 7 | |
| 8 | export type CardVariant = keyof typeof variantClasses; |
| 9 | |
| 10 | interface CardProps extends HTMLAttributes<HTMLDivElement> { |
| 11 | variant?: CardVariant; |
| 12 | interactive?: boolean; |
| 13 | } |
| 14 | |
| 15 | export const Card = forwardRef<HTMLDivElement, CardProps>( |
| 16 | ({ variant = "default", interactive, children, className, ...rest }, ref) => { |
| 17 | return ( |
| 18 | <div |
| 19 | ref={ref} |
| 20 | className={[ |
| 21 | variantClasses[variant], |
| 22 | interactive && |
| 23 | "cursor-pointer hover:-translate-y-0.5 transition-transform focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-500/50 focus-visible:ring-offset-2 focus-visible:ring-offset-canvas", |
| 24 | className, |
| 25 | ] |
| 26 | .filter(Boolean) |
| 27 | .join(" ")} |
| 28 | {...rest} |
| 29 | > |
| 30 | {children} |
| 31 | </div> |
| 32 | ); |
| 33 | }, |
| 34 | ); |
| 35 | |
| 36 | Card.displayName = "Card"; |