Card
A flexible surface container for grouping related content. Four variants (elevated/outlined/filled/ghost), five intents, six rounded options, five sizes, horizontal layout, interactive states, and LTR/RTL support.
Installation
pnpm add @tessinaui/uiUsage
import {
Card,
CardMedia,
CardHeader,
CardTitle,
CardDescription,
CardContent,
CardFooter,
CardDivider,
} from "@tessinaui/ui";{/* Basic card */}
<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
<CardDescription>Description</CardDescription>
</CardHeader>
<CardContent>Content</CardContent>
<CardFooter>
<Button variant="primary">Action</Button>
</CardFooter>
</Card>
{/* Outlined with intent */}
<Card variant="outlined" intent="success">
<CardHeader>
<CardTitle>Success</CardTitle>
</CardHeader>
</Card>
{/* Card with media */}
<Card rounded="lg" className="overflow-hidden w-72">
<CardMedia src="/image.jpg" alt="Cover" aspectRatio="video" position="top" />
<CardHeader>
<CardTitle>Article title</CardTitle>
</CardHeader>
</Card>
{/* Interactive card */}
<Card interactive onClick={() => navigate('/details')}>
<CardContent>Click me</CardContent>
</Card>
{/* Horizontal layout */}
<Card horizontal className="max-w-lg overflow-hidden">
<CardMedia position="start" className="w-32 bg-secondary" />
<div className="flex flex-col flex-1">
<CardHeader>
<CardTitle>Horizontal card</CardTitle>
</CardHeader>
<CardContent>Content beside media</CardContent>
</div>
</Card>
{/* RTL */}
<Card dir="rtl" variant="outlined">
<CardHeader>
<CardTitle>عنوان البطاقة</CardTitle>
</CardHeader>
</Card>Playground
Preview
Showcase
Preview
API Reference
Card Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "elevated" | "outlined" | "filled" | "ghost" | "elevated" | Visual surface style |
intent | "none" | "error" | "warning" | "success" | "info" | "none" | Semantic intent color applied to the card surface |
size | "xs" | "sm" | "md" | "lg" | "xl" | "md" | Controls padding of all inner sections |
rounded | "none" | "sm" | "md" | "lg" | "xl" | "full" | "md" | Corner radius |
width | "narrow" | "default" | "wide" | "full" | "default" | Max-width constraint |
shadow | "none" | "sm" | "md" | "lg" | "md" for elevated, "none" otherwise | Drop shadow depth |
interactive | boolean | false | Adds hover / active / focus-ring states |
disabled | boolean | false | Dims the card and disables pointer events |
horizontal | boolean | false | Switches internal flex direction to row |
dir | "ltr" | "rtl" | "ltr" | Text direction |
className | string | — | Additional class on the root element |
CardMedia Props
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | — | Image source URL |
alt | string | "" | Image alt text |
aspectRatio | "auto" | "video" | "4/3" | "1/1" | "2/1" | "3/4" | "video" | Aspect ratio of the media container |
position | "top" | "bottom" | "start" | "end" | "fill" | "top" | Edge the media abuts — determines which corners are rounded |
children | ReactNode | — | Custom media content (video, iframe, etc.) replaces the default <img> |
CardHeader Props
| Prop | Type | Default | Description |
|---|---|---|---|
icon | ReactNode | — | Icon / illustration rendered above (or inline with) the title |
inlineIcon | boolean | false | Lays out icon and title text in a horizontal row |
CardFooter Props
| Prop | Type | Default | Description |
|---|---|---|---|
vertical | boolean | false | Stacks footer items vertically |
align | "start" | "center" | "end" | "between" | "start" | Alignment of footer items |
Variants
| Value | Style |
|---|---|
"elevated" | bg-card with drop shadow (default shadow-md) |
"outlined" | bg-background with border-border — flat with visible border |
"filled" | bg-secondary (or intent-light color) — tinted surface |
"ghost" | Transparent — no border, no shadow |
Notes
- Section padding —
CardHeader,CardContent, andCardFooterall readsizefrom context and apply consistent padding. Override per-section withclassName. - CardMedia rounding — use
positionto control which corners are rounded on the media figure. Setposition="start"for the left edge of horizontal cards; it uses logical CSS properties so it flips automatically in RTL. - Interactive cards — when
interactiveis set and the card contains nested buttons or links, prefer the stretched-link pattern (absolute-positioned<a>) rather thanonClickon the card root to avoid nested interactive element accessibility issues. - Horizontal layout — set
horizontalon theCardroot, then useCardMediawithposition="start"(or"end") and wrap remaining sections in a<div className="flex flex-col flex-1">. - RTL —
dir="rtl"is applied to the root and propagates to all children. Logical CSS properties (rounded-s-*,rounded-e-*) ensure media rounding flips correctly.
Dropdown Menu
A contextual menu that opens from a trigger, built on Radix UI. Supports grouped items, leading/trailing icons, keyboard shortcuts, descriptions, submenus, checkboxes, radio groups, and full RTL layout.
Modal
An accessible dialog overlay built on Base UI. Compound component pattern with Header, Body, Footer, Title, Description, and Close. Five sizes. Five corner-rounding options. LTR and RTL support.