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
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:
Manual Setup
If you prefer manual control:
'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 };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>Footer Alignment
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>Footer Direction
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
| Prop | Type | Default | Description |
|---|---|---|---|
direction | "row" | "column" | "column" | The layout direction of the card |
className | string | undefined | Additional CSS classes |
All standard div props are supported.
McCardHeader
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | — | The heading text (required) |
description | string | undefined | Optional description below the title |
className | string | undefined | Additional CSS classes |
All standard div props are supported.
McCardFooter
| Prop | Type | Default | Description |
|---|---|---|---|
direction | "row" | "column" | "row" | Layout direction of footer children |
align | "start" | "end" | "center" | "stretch" | "stretch" | Alignment of footer children |
cardDirection | "row" | "column" | from context | Overrides the card direction read from context |
className | string | undefined | Additional CSS classes |
All standard div props are supported.
McCardContent
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | undefined | Additional CSS classes |
All standard div props are supported.