GitHub

Card

A card component for displaying content in a contained format, ready for CMS integration.

CMSPayload CMS Integration

Cards can be configured as CMS blocks, allowing content editors to customize titles, descriptions, and content without code changes.

CMS Demo

See how content editors configure cards in a CMS:

Loading...
CMS ConfigurationSimulates Payload CMS card fields with localization

Payload Block Example

// In your Payload CMS block config
export const CardBlock = {
  slug: "card-block",
  fields: [
    { name: "title", type: "text", localized: true, required: true },
    { name: "description", type: "text", localized: true },
    { name: "content", type: "richText", localized: true },
    { name: "showFooter", type: "checkbox", defaultValue: true },
    { name: "buttonLabel", type: "text", localized: true },
    { name: "buttonHref", type: "text" },
  ],
}

Rendering the Block

import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  CardFooter,
  Button,
} from "@mordecai-design-system/ui"
import Link from "next/link"

export function CardBlock({ data }) {
  return (
    <Card>
      <CardHeader>
        <CardTitle>{data.title}</CardTitle>
        <CardDescription>{data.description}</CardDescription>
      </CardHeader>
      <CardContent>{data.content}</CardContent>
      {data.showFooter && (
        <CardFooter>
          <Button render={<Link href={data.buttonHref} />}>
            {data.buttonLabel}
          </Button>
        </CardFooter>
      )}
    </Card>
  )
}

Basic Usage

Loading...
CardA card with header, content, and footer

Installation

pnpm add @corew500/ui

Usage

import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  CardFooter,
} from "@mordecai-design-system/ui"
<Card>
  <CardHeader>
    <CardTitle>Card Title</CardTitle>
    <CardDescription>Card description</CardDescription>
  </CardHeader>
  <CardContent>
    <p>Card content goes here.</p>
  </CardContent>
  <CardFooter>
    <p>Card footer</p>
  </CardFooter>
</Card>

Sub-components

| Component | Description | |-----------|-------------| | Card | The main container | | CardHeader | Contains the title and description | | CardTitle | The card's heading | | CardDescription | Secondary text below the title | | CardContent | Main content area | | CardFooter | Bottom section, typically for actions |

Examples

Simple Card

<Card className="w-[350px]">
  <CardHeader>
    <CardTitle>Notifications</CardTitle>
    <CardDescription>You have 3 unread messages.</CardDescription>
  </CardHeader>
  <CardContent>
    <p>Check your inbox for updates.</p>
  </CardContent>
</Card>

Card with Form

<Card className="w-[350px]">
  <CardHeader>
    <CardTitle>Create account</CardTitle>
    <CardDescription>Enter your email below to create your account.</CardDescription>
  </CardHeader>
  <CardContent>
    <Input placeholder="Email" />
  </CardContent>
  <CardFooter className="flex justify-between">
    <Button variant="outline">Cancel</Button>
    <Button>Submit</Button>
  </CardFooter>
</Card>

Props

Card

PropTypeDefaultDescription
interactiveenumfalseEnables hover effects (shadow elevation, ring color transition, cursor pointer). Adds `group` class for child elements to use `group-hover:*` utilities.
hoverIntentenumdefaultColor intent for hover ring. Only applies when `interactive` is true.
render(props: CardRenderProps) => ReactNode—Render function for custom element types (e.g., `<a>`, `<button>`). Receives props that must be spread onto the rendered element. @example ```tsx <Card interactive render={(props) => <a href="/details" {...props}>Content</a>} /> ```
variantenumdefault—
sizeenumdefault—

All sub-components accept className and standard HTML attributes.