Card
Content container primitive with header/content/footer slots.
npx shadcn@latest add @aavya/ui-card
One-time setup — add the @aavya registry to your components.json so branded dependencies resolve to Aavya (not stock shadcn):
"registries": { "@aavya": "https://registry-dev.aavya.com/r/{name}.json" }Or install by full URL: npx shadcn@latest add https://registry-dev.aavya.com/r/ui-card.json
Card content slot preview.
Card forwards remaining props to all <div> element props.
Do
- Use a Card to group related content; keep one primary idea per card.
- Use CardHeader / CardTitle / CardContent for consistent structure.
- Make the whole card clickable only when it maps to a single destination.
Don’t
- Don't nest cards more than one level — it muddies the hierarchy.
- Don't put multiple competing primary actions in one card.
- Don't rely on the card border alone to convey grouping for AT users.
Role
A plain container (<div>) — no implicit semantics.
Keyboard
Not interactive unless it contains interactive elements.
Screen reader
Give it a heading (CardTitle at an appropriate level) so the section is navigable; the card itself announces nothing. You provide the heading semantics.
Focus
No focus unless made interactive.
Gotcha
A 'clickable card' needs a real control — wrap the primary action in a link or button rather than an onClick on the div.
import { Card } from '@/components/ui/card'
export default function Example() {
return (
<div className="p-6">
<Card />
</div>
)
}
import * as React from 'react'
import { cn } from '@/lib/utils'
function Card({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='card'
className={cn('bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6', className)}
{...props}
/>
)
}
function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='card-header'
className={cn(
'@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6',
className
)}
{...props}
/>
)
}
function CardTitle({ className, ...props }: React.ComponentProps<'div'>) {
return <div data-slot='card-title' className={cn('leading-none font-semibold', className)} {...props} />
}
function CardDescription({ className, ...props }: React.ComponentProps<'div'>) {
return <div data-slot='card-description' className={cn('text-muted-foreground text-sm', className)} {...props} />
}
function CardAction({ className, ...props }: React.ComponentProps<'div'>) {
return (
<div
data-slot='card-action'
className={cn('col-start-2 row-span-2 row-start-1 self-start justify-self-end', className)}
{...props}
/>
)
}
function CardContent({ className, ...props }: React.ComponentProps<'div'>)