ComponentsCard
Card
Group related content and actions in a single panel.
On this page
Use this component from the local workspace package. Follow the setup guide first. A public npm package and registry are not available yet.
View registry filesImport the component into your page or component file.
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@dethink/components";
export function Example() {
return (
<Card>
<CardHeader>
<CardTitle>Team plan</CardTitle>
<CardDescription>Everything your team needs.</CardDescription>
</CardHeader>
<CardContent>Invite members and work on projects together.</CardContent>
<CardFooter>Includes up to 10 members.</CardFooter>
</Card>
);
}Try the examples, then open the code to use them in your app.
Anatomy
Header, title, description, content, and a footer with justified actions.
Show sourceexamples/card/basic.tsx
"use client";
import {
Button,
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@dethink/components";
export function CardBasic() {
return (
<Card className="w-full max-w-sm">
<CardHeader>
<CardTitle>Usage this month</CardTitle>
<CardDescription>
Track how your workspace is consuming its plan.
</CardDescription>
</CardHeader>
<CardContent>
<p className="font-heading text-3xl font-semibold">
12,480{" "}
<span className="text-muted-foreground text-sm font-normal">
/ 20,000 requests
</span>
</p>
</CardContent>
<CardFooter justify="end">
<Button variant="ghost">Dismiss</Button>
<Button variant="soft">Upgrade plan</Button>
</CardFooter>
</Card>
);
}Header action
CardAction pins controls to the end of the header โ icon buttons, menus, or badges โ while the title and description keep their column.
Show sourceexamples/card/action.tsx
"use client";
import {
Button,
Card,
CardAction,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@dethink/components";
import { Settings2 } from "lucide-react";
const members = [
{ name: "Amara Osei", role: "Owner" },
{ name: "Jonas Weber", role: "Editor" },
{ name: "Priya Nair", role: "Viewer" },
];
export function CardWithAction() {
return (
<Card className="w-full max-w-sm">
<CardHeader>
<CardTitle>Team members</CardTitle>
<CardDescription>People with access to this project.</CardDescription>
<CardAction>
<Button size="icon" variant="ghost" aria-label="Manage team settings">
<Settings2 className="size-4" />
</Button>
</CardAction>
</CardHeader>
<CardContent>
<ul className="divide-border divide-y">
{members.map((member) => (
<li
key={member.name}
className="flex items-center justify-between py-2.5 text-sm"
>
<span className="font-medium">{member.name}</span>
<span className="text-muted-foreground">{member.role}</span>
</li>
))}
</ul>
</CardContent>
</Card>
);
}Surfaces, borders, and spacing
Mix surface, border, shadow, radius, and spacing to move between elevated cards, quiet sections, and dense dashboard tiles.
Show sourceexamples/card/options.tsx
"use client";
import { Card, CardContent } from "@dethink/components";
export function CardOptions() {
return (
<div className="grid w-full gap-4 sm:grid-cols-2">
<Card surface="default" shadow="md">
<CardContent className="text-sm">
<code className="text-primary font-mono text-xs">
shadow="md"
</code>
<p className="text-muted-foreground mt-1">Elevated surface.</p>
</CardContent>
</Card>
<Card surface="muted" border="muted" shadow="none">
<CardContent className="text-sm">
<code className="text-primary font-mono text-xs">
surface="muted"
</code>
<p className="text-muted-foreground mt-1">Quiet, recessed section.</p>
</CardContent>
</Card>
<Card radius="md" spacing="sm">
<CardContent className="text-sm">
<code className="text-primary font-mono text-xs">
spacing="sm"
</code>
<p className="text-muted-foreground mt-1">Dense dashboards.</p>
</CardContent>
</Card>
<Card surface="transparent" border="none" shadow="none">
<CardContent className="text-sm">
<code className="text-primary font-mono text-xs">
surface="transparent"
</code>
<p className="text-muted-foreground mt-1">
Structure without chrome.
</p>
</CardContent>
</Card>
</div>
);
}Composition
Cards compose naturally with other Dethink components โ here a sign-in form built from Input and Button.
Show sourceexamples/card/form.tsx
"use client";
import {
Button,
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
Input,
} from "@dethink/components";
export function CardSignInForm() {
return (
<Card className="w-full max-w-sm" shadow="md">
<CardHeader>
<CardTitle>Sign in</CardTitle>
<CardDescription>Use your work email to continue.</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-1.5">
<label htmlFor="signin-email" className="text-sm font-medium">
Email
</label>
<Input
id="signin-email"
type="email"
placeholder="you@company.com"
autoComplete="email"
/>
</div>
<div className="space-y-1.5">
<label htmlFor="signin-password" className="text-sm font-medium">
Password
</label>
<Input
id="signin-password"
type="password"
autoComplete="current-password"
/>
</div>
</CardContent>
<CardFooter>
<Button className="w-full">Continue</Button>
</CardFooter>
</Card>
);
}Card and its section components accept all native attributes of the element they render.
| Prop | What it does | Default |
|---|---|---|
surface"default" | "muted" | "transparent" | Sets the card background. | "default" |
border"default" | "muted" | "none" | Sets the card border style. | "default" |
radius"md" | "lg" | Sets how rounded the corners are. | "lg" |
shadow"none" | "sm" | "md" | Sets the shadow below the card. | "sm" |
spacing"sm" | "md" | "lg" | Sets the padding and gaps inside each card section. Follows the app density setting. | "md" |
as"div" | "article" | "section" | "aside" | "li" | The HTML element to render. | "div" |
asChildboolean | Applies the card styles to its single child instead of adding a wrapper. | false |
Section components
| Prop | What it does | Default |
|---|---|---|
CardHeaderas: "div" | "header" | "section" | Groups the title, description, and optional action. | "div" |
CardTitleas: "div" | "h2"โ"h6" | Heading of the card. Pick the level that fits the page outline. | "h3" |
CardDescriptionas: "p" | "div" | "span" | Adds supporting text below the title. | "p" |
CardActionas: "div" | "span" | Places a button, menu, or badge beside the title. | "div" |
CardContentas: "div" | "section" | Main body of the card. | "div" |
CardFooteras + justify: "start" | "between" | "end" | Places actions at the bottom. Use justify to align them. | "div", "start" |