veza/apps/web/desy/components/ui/card.tsx
2026-01-22 17:23:11 +01:00

141 lines
3 KiB
TypeScript

import * as React from 'react'
import { cva, type VariantProps } from 'class-variance-authority'
import { cn } from '@/lib/utils'
const cardVariants = cva(
'flex flex-col rounded-xl border text-card-foreground transition-all',
{
variants: {
variant: {
default:
'bg-card shadow-sm',
elevated:
'bg-card shadow-lg hover:shadow-xl',
ghost:
'bg-transparent border-transparent',
outline:
'bg-transparent border-border',
muted:
'bg-muted/50 border-transparent',
glass:
'bg-card/80 backdrop-blur-xl border-border/50',
interactive:
'bg-card shadow-sm cursor-pointer hover:shadow-lg hover:border-primary/50 hover:-translate-y-0.5',
glow:
'bg-card shadow-sm hover:shadow-[0_0_30px_oklch(0.75_0.18_195_/_0.15)] hover:border-primary/50',
glowMagenta:
'bg-card shadow-sm hover:shadow-[0_0_30px_oklch(0.65_0.25_330_/_0.15)] hover:border-secondary/50',
},
padding: {
none: '',
sm: 'p-4',
default: 'p-6',
lg: 'p-8',
},
},
defaultVariants: {
variant: 'default',
padding: 'none',
},
},
)
interface CardProps
extends React.ComponentProps<'div'>,
VariantProps<typeof cardVariants> {}
function Card({ className, variant, padding, ...props }: CardProps) {
return (
<div
data-slot="card"
className={cn(cardVariants({ variant, padding }), className)}
{...props}
/>
)
}
function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="card-header"
className={cn(
'flex flex-col gap-1.5 p-6 pb-0',
className,
)}
{...props}
/>
)
}
function CardTitle({ className, ...props }: React.ComponentProps<'h3'>) {
return (
<h3
data-slot="card-title"
className={cn('text-lg font-semibold leading-tight tracking-tight', className)}
{...props}
/>
)
}
function CardDescription({ className, ...props }: React.ComponentProps<'p'>) {
return (
<p
data-slot="card-description"
className={cn('text-sm text-muted-foreground', className)}
{...props}
/>
)
}
function CardAction({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="card-action"
className={cn(
'absolute top-4 right-4',
className,
)}
{...props}
/>
)
}
function CardContent({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="card-content"
className={cn('p-6 pt-4', className)}
{...props}
/>
)
}
function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot="card-footer"
className={cn('flex items-center gap-3 p-6 pt-0', className)}
{...props}
/>
)
}
export {
Card,
CardHeader,
CardFooter,
CardTitle,
CardAction,
CardDescription,
CardContent,
cardVariants,
}