components

Card

Cards are surface-level containers that group related content and actions. They provide a consistent visual boundary and can include headers, body content, and footers. Use the Card component along with CardHeader and CardFooter sub-components to compose structured content sections.

Import
import { Card, CardHeader, CardFooter } from "@skedulo/breeze-ui-react";

Usage Guidance

When to use

  • +Group related content into a visually distinct container.
  • +Create dashboard-style layouts with multiple content sections.
  • +Wrap forms, settings panels, or detail views that need clear boundaries.

When not to use

  • For list items that don't need elevated visual treatment.
  • For full-width page sections — cards imply bounded content.
  • For single-field forms — cards add unnecessary visual weight.

Examples

Code Samples

Basic Card

A simple card with body content.

import { Card } from "@skedulo/breeze-ui-react";

export default function BasicCard() {
  return (
    <Card>
      <div className="p-6">
        <p>This is a basic card with some content inside.</p>
      </div>
    </Card>
  );
}

Card with Header

A card with a CardHeader passed via the header prop for a titled section.

import { Card, CardHeader } from "@skedulo/breeze-ui-react";

export default function CardWithHeader() {
  return (
    <Card header={<CardHeader>Card Title</CardHeader>}>
      <div className="p-6">
        <p>This card has a header section that provides a title for the content below.</p>
      </div>
    </Card>
  );
}

Card with Header and Footer

A card with both a header and a footer containing action buttons.

import { Card, CardHeader, CardFooter, Button } from "@skedulo/breeze-ui-react";

export default function CardWithHeaderAndFooter() {
  return (
    <Card
      header={<CardHeader>Settings</CardHeader>}
      footer={
        <CardFooter>
          <div className="flex justify-end gap-2 w-full">
            <Button buttonType="transparent">Cancel</Button>
            <Button buttonType="primary">Save Changes</Button>
          </div>
        </CardFooter>
      }
    >
      <div className="p-6">
        <p>This card includes both a header and a footer. The footer typically contains action buttons.</p>
      </div>
    </Card>
  );
}

Card Grid

Multiple cards arranged in a responsive grid layout for dashboard-style displays.

import { Card, CardHeader } from "@skedulo/breeze-ui-react";

export default function CardGrid() {
  return (
    <div className="grid grid-cols-12 gap-5">
      <div className="col-span-12 min-[961px]:col-span-4">
        <Card header={<CardHeader>Analytics</CardHeader>}>
          <div className="p-6">
            <p className="text-2xl font-bold">1,234</p>
            <p className="text-sm text-gray-500">Total views</p>
          </div>
        </Card>
      </div>
      <div className="col-span-12 min-[961px]:col-span-4">
        <Card header={<CardHeader>Revenue</CardHeader>}>
          <div className="p-6">
            <p className="text-2xl font-bold">$5,678</p>
            <p className="text-sm text-gray-500">This month</p>
          </div>
        </Card>
      </div>
      <div className="col-span-12 min-[961px]:col-span-4">
        <Card header={<CardHeader>Users</CardHeader>}>
          <div className="p-6">
            <p className="text-2xl font-bold">89</p>
            <p className="text-sm text-gray-500">Active now</p>
          </div>
        </Card>
      </div>
    </div>
  );
}

Guidelines

Do

  • Use CardHeader for a clear title when the card's purpose isn't obvious from content alone.
  • Use CardFooter for action buttons (Save, Cancel) that apply to the card's content.
  • Add padding to the card body using className on a wrapper div (e.g. p-6).
  • Use consistent card sizes in grid layouts for visual harmony.
  • Keep card content focused on a single topic or task.

Don't

  • Don't nest cards inside cards — it creates visual confusion.
  • Don't use cards for purely decorative purposes with no meaningful content.
  • Don't put unrelated actions in the same CardFooter.
  • Don't use cards when a simple border or divider would suffice.

Proposed Modifications

Proposed

Fixed-Height Header & Footer Zones

CardHeader and CardFooter should render at a consistent fixed height (56px / h-14) regardless of whether they contain actions, badges, or only a title. Currently the header and footer heights shift depending on content — a title-only header is ~45px while a header with action buttons is ~57px. This causes visual instability when toggling actions on/off, and creates inconsistent card chrome across a page grid where some cards have actions and others don't. The fix: apply a fixed height with flexbox vertical centering to both zones. This ensures headers and footers are always the same height whether they contain a single title, action buttons, status badges, or a combination. The body section flexes to fill the remaining space. Benefits: • Cards in a grid maintain identical header/footer heights for visual harmony • Toggling header/footer actions doesn't shift the body content • Empty footer guard-rails are the same height as populated footers • Closer alignment with the Breeze CardHeader reference height (64px)

import { Card, CardHeader, CardFooter, Button } from "@skedulo/breeze-ui-react";

// Proposed: CardHeader and CardFooter render at a fixed 56px (h-14)
// with flex centering, regardless of content.

// Header zone — always 56px
// ┌─────────────────────────────────────────────┐
// │ h-14 flex items-center justify-between px-5 │
// │  Title                           [Edit] [⋮] │
// └─────────────────────────────────────────────┘

// Footer zone — always 56px
// ┌─────────────────────────────────────────────┐
// │ h-14 flex items-center justify-end px-5     │
// │                          [Cancel] [Save]    │
// └─────────────────────────────────────────────┘

// Without actions — same height, content vertically centered
// ┌─────────────────────────────────────────────┐
// │ h-14 flex items-center px-5                 │
// │  Card Title                                 │
// └─────────────────────────────────────────────┘

export default function FixedHeightCardZones() {
  return (
    <div className="space-y-4">
      {/* Card WITH header/footer actions */}
      <Card
        header={<CardHeader>Settings</CardHeader>}
        footer={
          <CardFooter>
            <div className="flex justify-end gap-2 w-full">
              <Button buttonType="transparent">Cancel</Button>
              <Button buttonType="primary">Save</Button>
            </div>
          </CardFooter>
        }
      >
        <div className="p-6">
          <p>Header and footer are both 56px tall.</p>
        </div>
      </Card>

      {/* Card WITHOUT actions — identical header/footer heights */}
      <Card header={<CardHeader>Read Only</CardHeader>}>
        <div className="p-6">
          <p>Header is still 56px — same as the card above.</p>
        </div>
      </Card>
    </div>
  );
}

API Reference

PropTypeDefaultDescription
headerReactNodeA CardHeader element to render at the top of the card. Pass a <CardHeader> component to this prop.
footerReactNodeA CardFooter element to render at the bottom of the card. Pass a <CardFooter> component to this prop.
childrenReactNodeThe body content of the card. Typically wrapped in a div with padding.

Related Components