Display

Card.

A panel with header, content and footer slots, plus the grid-patterned art banner from the Lantern directory.

Sign in to the Hub
Publish sites that stay up while your server sleeps.

Installation#

With the CLI

$npx lanterncn add card

This also installs the Lantern theme and any Lantern UI components it depends on. The shadcn CLI works directly too: npx shadcn@latest add httptim/lantern-ui/card. See Installation if your project is not set up yet.

Manually

  1. Copy the source into your project

    components/ui/card.tsx
    import * as React from "react";
    
    import { cn } from "@/lib/utils";
    
    function Card({ className, ...props }: React.ComponentProps<"div">) {
      return (
        <div
          data-slot="card"
          className={cn("flex flex-col gap-6 overflow-hidden rounded-lg border bg-card py-6 text-card-foreground", className)}
          {...props}
        />
      );
    }
    
    /** Grid-patterned banner for the top of a card, as on the Lantern directory. */
    function CardArt({ className, ...props }: React.ComponentProps<"div">) {
      return (
        <div
          data-slot="card-art"
          className={cn(
            "relative -mt-6 flex h-40 items-center justify-center border-b bg-accent bg-grid text-[#b7ca9e] [&_svg:not([class*='size-'])]:size-14 [&_svg]:stroke-[1.25]",
            className,
          )}
          {...props}
        />
      );
    }
    
    function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
      return (
        <div
          data-slot="card-header"
          className={cn(
            "grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto]",
            className,
          )}
          {...props}
        />
      );
    }
    
    function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
      return <div data-slot="card-title" className={cn("font-display text-xl leading-tight font-medium tracking-tight", className)} {...props} />;
    }
    
    function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
      return <div data-slot="card-description" className={cn("text-sm text-muted-foreground", className)} {...props} />;
    }
    
    function CardAction({ className, ...props }: React.ComponentProps<"div">) {
      return (
        <div
          data-slot="card-action"
          className={cn("col-start-2 row-span-2 row-start-1 self-start justify-self-end", className)}
          {...props}
        />
      );
    }
    
    function CardContent({ className, ...props }: React.ComponentProps<"div">) {
      return <div data-slot="card-content" className={cn("px-6", className)} {...props} />;
    }
    
    function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
      return <div data-slot="card-footer" className={cn("flex items-center px-6 [.border-t]:pt-6", className)} {...props} />;
    }
    
    export { Card, CardArt, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent };
  2. Update the import paths to match your project

    The source imports cn from @/lib/utils.

Usage#

import {
  Card,
  CardArt,
  CardHeader,
  CardFooter,
  CardTitle,
  CardAction,
  CardDescription,
  CardContent,
} from "@/components/ui/card";
<Card>
  <CardHeader>
    <CardTitle>Title</CardTitle>
    <CardDescription>Description</CardDescription>
  </CardHeader>
  <CardContent>Content</CardContent>
</Card>

Examples#

Directory card with art

hub://guestbook/
Community
Lantern Guestbook
Leave a little warmth for the next traveler.
LuaHub