Skip to content
← Components

Card

Card with thoughtful defaults, semantic styling, and editable source.

Open ↗

Make it yours.

Install the editable source and its dependencies into your React + Tailwind project.

Scroll horizontally for long lines
pnpm dlx shadcn@4.0.8 add http://localhost:3000/r/card.json

Use it

Scroll horizontally for long lines
"use client";
import { useState } from "react";
import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardAction,
  CardContent,
  CardFooter,
} from "@/components/jez-ui/ui/card";
import { Badge } from "@/components/jez-ui/ui/badge";
import { FormField } from "@/components/jez-ui/ui/form-field";
import { Input } from "@/components/jez-ui/ui/input";
import { Button } from "@/components/jez-ui/ui/button";

export default function Example() {
  const [notice, setNotice] = useState("");
  return (
    <>
      <Card>
        <CardHeader>
          <CardTitle>A little room to think.</CardTitle>
          <CardDescription>
            A considered surface for whatever comes next.
          </CardDescription>
          <CardAction>
            <Badge>Draft</Badge>
          </CardAction>
        </CardHeader>
        <CardContent>
          <FormField label="Project name">
            <Input placeholder="Field notes" />
          </FormField>
        </CardContent>
        <CardFooter>
          <Button onClick={() => setNotice("Project created.")}>
            Create project
          </Button>
          <Button variant="outline">Cancel</Button>
        </CardFooter>
      </Card>
      <p role="status">{notice}</p>
    </>
  );
}

Compose your own

These styled parts are included in the same install. Use children to build your layout; add className only when you want an override.

Scroll horizontally for long lines
import { Card, CardHeader, CardTitle, CardDescription, CardAction, CardContent, CardFooter } from "@/components/jez-ui/ui/card";
Read the composition guide →

Props & types

Scroll horizontally for long lines
React.ComponentProps<"div">

Source

View 2 source files

registry/ui/card.tsx

Scroll horizontally for long lines
"use client";
import * as React from "react";
import { cn } from "./utils";
export function Card({ className, ...props }: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="card"
      className={cn(
        "rounded-xl border border-border bg-background p-6 text-foreground",
        className,
      )}
      {...props}
    />
  );
}
export function CardHeader({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="card-header"
      className={cn(
        "grid grid-cols-[1fr_auto] gap-x-4 gap-y-2 pb-5",
        className,
      )}
      {...props}
    />
  );
}
export function CardTitle({ className, ...props }: React.ComponentProps<"h3">) {
  return (
    <h3
      data-slot="card-title"
      className={cn(
        "col-start-1 font-display text-lg font-semibold leading-tight tracking-tight",
        className,
      )}
      {...props}
    />
  );
}
export function CardDescription({
  className,
  ...props
}: React.ComponentProps<"p">) {
  return (
    <p
      data-slot="card-description"
      className={cn(
        "col-start-1 text-sm leading-relaxed text-muted-foreground",
        className,
      )}
      {...props}
    />
  );
}
export function CardAction({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="card-action"
      className={cn("col-start-2 row-start-1 row-span-2 self-start", className)}
      {...props}
    />
  );
}
export function CardContent({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="card-content"
      className={cn("grid gap-4 text-sm leading-relaxed", className)}
      {...props}
    />
  );
}
export function CardFooter({
  className,
  ...props
}: React.ComponentProps<"div">) {
  return (
    <div
      data-slot="card-footer"
      className={cn("flex flex-wrap items-center gap-3 pt-6", className)}
      {...props}
    />
  );
}

registry/ui/utils.ts

Scroll horizontally for long lines
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...values: ClassValue[]) {
  return twMerge(clsx(values));
}

Dependencies

clsx@2.1.1 · tailwind-merge@3.5.0

Accessibility & behaviour

Provide meaningful labels and preserve keyboard focus styles. Check contrast when customising theme colours.

Read the accessibility and performance guide →