Basic
Title + description + body — the most common layout.
Cards are surface-level containers that host related content. Everything in this library uses them to scope a demo.
Installation
$Terminal
npx shadcn@latest add https://sdk-components.thesqd.com/r/card.jsonUsage
Pass `title`, `description`, `action`, `footer` as props. Children render inside `<CardContent>` automatically.
TSImport
import { Card } from "@/components/ui/card";TSExample
import { Card } from "@/components/ui/card";
export function Example() {
return (
<Card
title="Heads up"
description="You can add components to your app using the squad-ui CLI."
>
Card content goes here.
</Card>
);
}Composition
Anatomy of the Card primitive.
Card (single component — pass content as props)
├── icon={LucideIcon} (optional — FeaturedIcon above the title)
│ ├── iconColor="brand" (color token; default "brand")
│ ├── iconVariant="gradient" (gradient | flat; default "gradient")
│ └── iconSize="lg" (sm | md | lg | xl | 2xl; default "lg")
├── title={<ReactNode>} (renders into the header title slot)
├── description={<ReactNode>} (multi-line / JSX is fine)
├── action={<Button … />} (optional — top-right of the header)
├── footer={<ReactNode>} (optional — bordered footer strip)
├── type="default" | "comment" | "image-card"
├── image={url | <Image/>} (type="image-card" — full-bleed media at the top)
├── imageAlt="…" (alt text when image is a URL)
├── ratio="W:H" | "W/H" (type="image-card" — aspect ratio of the WHOLE card; image fills the remaining space)
├── imageRatio="W:H" | "W/H" (type="image-card" — aspect ratio of just the image; default "16:9"; ignored when ratio is set)
├── href="…" (type="image-card" — makes the whole card a clickable <a>; pair with target / rel)
├── onClick={fn} (makes the whole card interactive — cursor-pointer, hover shadow, focus ring, keyboard activation)
├── tag={"New" | <Badge …/>} (type="image-card" — overlay badge in the top-left of the image)
├── showCornerTab (pins a corner tab tinted to match the card outline)
├── cornerTabContent={text | <Comp/>} (tab contents — string or any ReactNode)
├── cornerTabPosition="top-right" (top-right | top-left | bottom-right | bottom-left)
├── cornerTabClassName="…" (override the tab's padding / text / background)
├── children (auto-wrapped in <CardContent> unless contentWrapper="none")
├── size="default" | "sm"
└── contentWrapper="card-content" | "none"
Need a non-standard layout (e.g. an image-only card, custom header grid, or
two stacked content sections)? The slot exports — CardHeader, CardTitle,
CardDescription, CardAction, CardContent, CardFooter — are still exported
from the same file as an escape hatch. Drop the prop API for that one card
and compose the slots directly.Basic
Title + description + body — the most common layout.
Basic
Title + description + body — the most common layout.
Cards are surface-level containers that host related content. Everything in this library uses them to scope a demo.
Content only
Pass just `children` — no `title` or `description`. The body fills the whole padded surface.
Cards are surface-level containers that host related content. With no title or description, the body fills the whole padded surface.
With icon
Pass any lucide icon to `icon` to render a `FeaturedIcon` above the title. Tune it with `iconColor`, `iconVariant`, and `iconSize`.
Brand
`onClick` makes the whole card interactive. Click me for a toast.
Amber
`iconColor` tints the FeaturedIcon — mirrors the Badge palette.
Flat indigo
`iconVariant="flat"` swaps the gradient chip for a soft flat tint.
With action
`action` slots a secondary control into the top-right of the header.
With action
action slots a secondary control into the top-right of the header.Use this for links that jump to a fuller view or toggles that affect the card's contents.
With footer
Pin primary/secondary actions to the bottom.
With footer
Pin primary/secondary actions to the bottom.
Great for forms, confirmations, or any card whose actions belong alongside a submit/cancel pair.
Small size
size="sm" tightens the paddings and shrinks the title — useful for dense grids.
Small size
size="sm" tightens the paddings and shrinks the title.Useful for dense grids of cards where a lot of surfaces share the viewport.
Image card
Pass `type="image-card"` plus `image`, `title`, and `description` for a full-bleed media tile. Use `imageRatio` to shape the image alone (default `"16:9"`); use `ratio` to lock the **whole card** to a target aspect — the image then fills the remaining space above the caption.
New
Linked card
`href` makes the whole card clickable. `tag` overlays a Badge in the top-left.
Square card
`ratio="1:1"` — whole card is square; image fills the remaining space.
Portrait card
`ratio="4:5"` — portrait card; image fills above the caption.
Corner tab
Set `showCornerTab` and `cornerTabContent` to pin a little tab to a corner of the card — its background matches the card's outline. The content can be plain text or any component. Move it with `cornerTabPosition` and restyle it with `cornerTabClassName`.
New
Text tab
`cornerTabContent` takes a plain string for the default styled tab.
The tab background matches the card's outline.
Pro
Component tab
Pass any ReactNode — here an icon + label.
Render whatever you like inside the tab.
Component tab
Drop any component into the tab — here a tiny `CircularProgress`.
The tab concavely flows into the card's top-right corner.
Pricing grid
Two cards laid out in a responsive two-column grid with per-card footers.
Plan — Team
For growing squads that need more room.
$29/mo
Plan — Business
For larger orgs with advanced needs.
$79/mo
API Reference
Props exposed by the Card component.
| Prop | Type | Default | Description |
|---|---|---|---|
title | ReactNode | — | Heading rendered inside the auto-emitted CardHeader. |
description | ReactNode | — | Subheading. Accepts strings or JSX (multi-line, links, code). |
icon | ComponentType<{ className?: string }> | — | Lucide icon (or any `({ className }) => JSX`) rendered as a `FeaturedIcon` above the title. |
iconColor | FeaturedIconColor | "brand" | Color token for the `icon`'s FeaturedIcon. |
iconVariant | "gradient" | "flat" | "gradient" | Surface treatment for the `icon`'s FeaturedIcon. |
iconSize | "sm" | "md" | "lg" | "xl" | "2xl" | "lg" | Size of the `icon`'s FeaturedIcon. |
action | ReactNode | — | Top-right slot inside the header — typically a small button or link. |
footer | ReactNode | — | Footer strip. Wrap multiple buttons in a flex row to align them. |
size | "default" | "sm" | "default" | `sm` tightens paddings and shrinks the title — good for dense grids. |
contentWrapper | "card-content" | "none" | "card-content" | When the prop API is in use, children are wrapped in `<CardContent>` by default. Set to `"none"` to render them inline (no padding). |
type | "default" | "comment" | "image-card" | "default" | `image-card` swaps the layout for a full-bleed image at the top with a controllable aspect ratio, then title + description below. `comment` renders an avatar + name + time header. |
image | string | ReactNode | — | `type="image-card"` — image URL (rendered as `<img>` with `object-cover`) or any ReactNode (e.g. `<Image>` from next/image). |
imageAlt | string | — | Alt text used when `image` is a URL. |
ratio | string | — | `type="image-card"` — aspect ratio for the **whole card** (image + caption). Accepts `"W:H"` / `"W/H"`. When set, the image fills the remaining space above the caption. Leave undefined for auto-height. |
imageRatio | string | "16:9" | `type="image-card"` — aspect ratio for the **image** only. Accepts `"W:H"` / `"W/H"` (e.g. `"4:3"`, `"1:1"`). Ignored when `ratio` is set. |
href | string | — | `type="image-card"` — makes the entire card a clickable link (renders as `<a>`). Pair with `target` / `rel` as needed. Adds a hover shadow + subtle image zoom. |
target | HTMLAttributeAnchorTarget | — | Anchor target when `href` is set. |
rel | string | — | Anchor rel when `href` is set. |
tag | ReactNode | — | `type="image-card"` — overlay badge in the top-left corner of the image. Pass a string for a default `<Badge>` or any ReactNode (e.g. `<Badge variant="secondary">…</Badge>`) for full control. |
showCornerTab | boolean | false | Render a small corner tab clipped to one corner of the card, tinted to match the card's outline (`ring-foreground/10`). Requires `cornerTabContent`. |
cornerTabContent | ReactNode | — | Content shown inside the corner tab. Pass a string/number for the default styled tab, or any ReactNode (including your own component). |
cornerTabPosition | "top-right" | "top-left" | "bottom-right" | "bottom-left" | "top-right" | Which corner the tab sits in. |
cornerTabClassName | string | — | Extra classes for the tab element — override its padding, text, or background. |
onClick | (e) => void | — | Click handler. On any card it makes the whole surface interactive — adds `cursor-pointer`, a hover shadow, a focus ring, and keyboard activation (Enter/Space) with `role="button"`. |
className | string | — | Override or extend the resolved Card classes. |