ComponentsCard
Card
Group related content and actions in a single panel.
On this page
Install component source from the public registry, or use the local workspace package. Follow the setup guide first. The npm package is not published yet.
View registry filesImplemented with React and browser APIs, without an additional behavior or rendering library.
Shared foundation: React, clsx for conditional classes, tailwind-merge for resolving utility-class conflicts. Styles use Tailwind CSS and Dethink CSS variables.
Based on this component’s source and registry composition. Libraries used only in showcase examples are excluded.
Import 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" |