MC Card

A flexible container for grouping related content.

Overview

The mc-card is a layout component of the MicroClub UI library. Built with class-variance-authority, it provides a flexible card container that supports both vertical and horizontal layouts with configurable footer alignment.

As a part of the MicroClub library, this component is designed for instant deployment into your codebase, giving you full ownership of its look and behavior.

Preview

Loading...
import { McButton } from '../ui/mc-button';import { McCard, McCardContent, McCardHeader, McCardFooter } from '../ui/mc-card';export default function McCardDemo() {  return (    <McCard className="max-w-sm">      <McCardHeader        title="Card Title"        description="This is a brief description of the card content."      />      <McCardContent>        <p className="text-sm text-muted-foreground">          This is the card content area. You can place any content here.        </p>      </McCardContent>      <McCardFooter align="end">        <McButton variant="secondary">Cancel</McButton>        <McButton>Confirm</McButton>      </McCardFooter>    </McCard>  );}

Add to Your Project

Deploy the mc-card directly to your components/ui directory:

npx mcoli-ui@latest add mc-card
pnpm dlx mcoli-ui@latest add mc-card
yarn dlx mcoli-ui@latest add mc-card
bunx mcoli-ui@latest add mc-card

Manual Setup

If you prefer manual control:

Copy the source code
'use client';import * as React from 'react';import { cva, type VariantProps } from 'class-variance-authority';import { cn } from '@/lib/utils';const McCardDirectionContext = React.createContext<{ direction: 'row' | 'column' } | null>(null);const cardVariants = cva(  'flex gap-4 rounded-lg border border-border bg-card p-4 text-card-foreground shadow-sm w-full',  {    variants: {      direction: {        row: 'flex-row',        column: 'flex-col',      },    },    defaultVariants: {      direction: 'column',    },  });function McCard({  className,  direction = 'column',  children,  ...props}: React.ComponentProps<'div'> & { direction?: 'row' | 'column' }) {  return (    <McCardDirectionContext.Provider value={{ direction }}>      <div data-slot="card" className={cn(cardVariants({ direction }), className)} {...props}>        {children}      </div>    </McCardDirectionContext.Provider>  );}export interface McCardHeaderProps extends React.ComponentProps<'div'> {  title: string;  description?: string;}function McCardHeader({ className, title, description, ...props }: McCardHeaderProps) {  return (    <div data-slot="card-header" className={cn('flex flex-col gap-1', className)} {...props}>      <h3 className="text-xl font-bold leading-normal tracking-normal">{title}</h3>      {description && <p className="text-xs font-normal">{description}</p>}    </div>  );}const footerVariants = cva('flex gap-2', {  variants: {    cardDirection: {      row: 'self-stretch ms-auto',      column: '',    },    direction: {      row: 'flex-row',      column: 'flex-col',    },    align: {      start: '',      end: '',      center: '',      stretch: '',    },  },  compoundVariants: [    // cardDirection: column — matches previous footer-only (direction × align) behavior    {      cardDirection: 'column',      direction: 'row',      align: 'start',      className: 'items-center justify-start [&>*]:shrink-0 [&>*]:grow-0',    },    {      cardDirection: 'column',      direction: 'row',      align: 'end',      className: 'items-center justify-end [&>*]:shrink-0 [&>*]:grow-0',    },    {      cardDirection: 'column',      direction: 'row',      align: 'center',      className: 'items-center justify-center [&>*]:shrink-0 [&>*]:grow-0',    },    {      cardDirection: 'column',      direction: 'row',      align: 'stretch',      className: 'items-center justify-stretch *:min-w-0 *:flex-1',    },    {      cardDirection: 'column',      direction: 'column',      align: 'start',      className: 'items-start justify-start [&>*]:shrink-0 [&>*]:grow-0',    },    {      cardDirection: 'column',      direction: 'column',      align: 'end',      className: 'items-end justify-start [&>*]:shrink-0 [&>*]:grow-0',    },    {      cardDirection: 'column',      direction: 'column',      align: 'center',      className: 'items-center justify-start [&>*]:shrink-0 [&>*]:grow-0',    },    {      cardDirection: 'column',      direction: 'column',      align: 'stretch',      className: 'items-stretch justify-start *:min-h-0 *:flex-1',    },    // cardDirection: row — horizontal card; footer sits beside header/body, align controls vertical position    // footer direction: row → children horizontal, align maps to cross-axis (items-*)    {      cardDirection: 'row',      direction: 'row',      align: 'start',      className: 'items-start [&>*]:shrink-0 [&>*]:grow-0',    },    {      cardDirection: 'row',      direction: 'row',      align: 'end',      className: 'items-end [&>*]:shrink-0 [&>*]:grow-0',    },    {      cardDirection: 'row',      direction: 'row',      align: 'center',      className: 'items-center [&>*]:shrink-0 [&>*]:grow-0',    },    {      cardDirection: 'row',      direction: 'row',      align: 'stretch',      className: 'items-stretch *:min-w-0 *:flex-1',    },    // footer direction: column → children vertical, align maps to main-axis (justify-*)    {      cardDirection: 'row',      direction: 'column',      align: 'start',      className: 'justify-start [&>*]:shrink-0 [&>*]:grow-0',    },    {      cardDirection: 'row',      direction: 'column',      align: 'end',      className: 'justify-end [&>*]:shrink-0 [&>*]:grow-0',    },    {      cardDirection: 'row',      direction: 'column',      align: 'center',      className: 'justify-center [&>*]:shrink-0 [&>*]:grow-0',    },    {      cardDirection: 'row',      direction: 'column',      align: 'stretch',      className: 'items-stretch justify-start *:min-h-0 *:flex-1',    },  ],  defaultVariants: {    cardDirection: 'column',    direction: 'row',    align: 'stretch',  },});export interface McCardFooterProps  extends React.ComponentProps<'div'>, VariantProps<typeof footerVariants> {}function McCardFooter({  className,  direction,  align,  cardDirection: cardDirectionProp,  ...props}: McCardFooterProps) {  const ctx = React.useContext(McCardDirectionContext);  const cardDirection = cardDirectionProp ?? ctx?.direction ?? 'column';  return (    <div      data-slot="card-footer"      className={cn(footerVariants({ cardDirection, direction, align }), className)}      {...props}    />  );}export type McCardContentProps = React.ComponentProps<'div'>;function McCardContent({ className, ...props }: McCardContentProps) {  return <div data-slot="card-content" className={cn(className)} {...props} />;}export { McCard, McCardHeader, McCardFooter, McCardContent };
Adjust import paths

Ensure your @/lib/utils or equivalent classname helper is correctly imported.

Usage

import { McCard, McCardContent, McCardHeader, McCardFooter } from '@/components/ui/mc-card';

export default function Example() {
  return (
    <McCard>
      <McCardHeader title="Card Title" description="A short description." />
      <McCardContent>
        <p>Card content goes here.</p>
      </McCardContent>
      <McCardFooter>
        <button>Action</button>
      </McCardFooter>
    </McCard>
  );
}

Examples

Column Direction (Default)

<McCard>
  <McCardHeader title="Notifications" description="Manage your notification preferences." />
  <McCardContent>
    <p>Your notification settings and preferences go here.</p>
  </McCardContent>
  <McCardFooter align="end">
    <McButton variant="secondary">Cancel</McButton>
    <McButton>Save</McButton>
  </McCardFooter>
</McCard>

Row Direction

<McCard direction="row">
  <McCardHeader title="Horizontal Card" description="Content flows left to right." />
  <McCardContent>
    <p>Additional content here.</p>
  </McCardContent>
  <McCardFooter align="center">
    <McButton>Action</McButton>
  </McCardFooter>
</McCard>

Control how footer children are positioned with the align prop.

<McCard>
  <McCardHeader title="Start Aligned" />
  <McCardFooter align="start">
    <McButton>Left</McButton>
  </McCardFooter>
</McCard>

<McCard>
  <McCardHeader title="Stretch" />
  <McCardFooter align="stretch">
    <McButton variant="secondary">Cancel</McButton>
    <McButton>Confirm</McButton>
  </McCardFooter>
</McCard>

The footer can independently control its children layout direction.

<McCard>
  <McCardHeader title="Stacked Footer" />
  <McCardFooter direction="column" align="stretch">
    <McButton>Primary Action</McButton>
    <McButton variant="secondary">Secondary Action</McButton>
  </McCardFooter>
</McCard>

API Reference

McCard

PropTypeDefaultDescription
direction"row" | "column""column"The layout direction of the card
classNamestringundefinedAdditional CSS classes

All standard div props are supported.

McCardHeader

PropTypeDefaultDescription
titlestringThe heading text (required)
descriptionstringundefinedOptional description below the title
classNamestringundefinedAdditional CSS classes

All standard div props are supported.

McCardFooter

PropTypeDefaultDescription
direction"row" | "column""row"Layout direction of footer children
align"start" | "end" | "center" | "stretch""stretch"Alignment of footer children
cardDirection"row" | "column"from contextOverrides the card direction read from context
classNamestringundefinedAdditional CSS classes

All standard div props are supported.

McCardContent

PropTypeDefaultDescription
classNamestringundefinedAdditional CSS classes

All standard div props are supported.

On this page