Card
The Card component is a composite layout element that groups related content within a bordered, rounded container. It uses a compound component pattern with CardHeader, CardContent, and CardFooter sub-components for structured content areas.
Import
import { Card, CardHeader, CardContent, CardFooter } from '@nim-ui/components';Basic Usage
Basic Card
This is a basic card with content only.
View Code
<Card> <CardContent> <p>This is a basic card with content only.</p> </CardContent></Card>Full Card Structure
Use all three sub-components for a complete card layout with header, content, and footer.
Full Card with Header, Content, and Footer
Card Title
Card description goes here
This is the main content area of the card. It can contain any type of content including text, images, forms, or other components.
View Code
<Card> <CardHeader> <h3 className="text-lg font-semibold">Card Title</h3> <p className="text-sm text-neutral-500">Card description goes here</p> </CardHeader> <CardContent> <p>This is the main content area of the card.</p> </CardContent> <CardFooter> <Button variant="primary" size="sm">Save</Button> <Button variant="outline" size="sm">Cancel</Button> </CardFooter></Card>Header and Content Only
Card Without Footer
Notifications
You have 3 unread notifications.
View Code
<Card> <CardHeader> <h3 className="text-lg font-semibold">Notifications</h3> </CardHeader> <CardContent> <p>You have 3 unread notifications.</p> </CardContent></Card>Custom Styling
Cards accept a className prop for custom styling including width constraints, shadows, and border customization.
Custom Styled Cards
Elevated card with shadow-lg
Card with custom border color
Card with custom background
View Code
<Card className="shadow-lg"> <CardContent>Elevated card with shadow-lg</CardContent></Card>
<Card className="border-primary-500 border-2"> <CardContent>Card with custom border color</CardContent></Card>
<Card className="bg-primary-50 dark:bg-primary-900/20"> <CardContent>Card with custom background</CardContent></Card>Props
Card
| Name | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes for custom styling (width, shadow, border, etc.) |
children * | ReactNode | - | Card content, typically CardHeader, CardContent, and/or CardFooter |
CardHeader
| Name | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes to apply to the header area |
children * | ReactNode | - | Header content (title, description, etc.) |
CardContent
| Name | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes to apply to the content area |
children * | ReactNode | - | Main card content |
CardFooter
| Name | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes to apply to the footer area |
children * | ReactNode | - | Footer content (actions, links, metadata) |
Usage Examples
User Profile Card
function UserProfileCard({ user }) { return ( <Card className="max-w-sm"> <CardHeader> <Flex align="center" gap="md"> <Avatar src={user.avatar} initials={user.initials} /> <div> <h3 className="font-semibold">{user.name}</h3> <p className="text-sm text-neutral-500">{user.role}</p> </div> </Flex> </CardHeader> <CardContent> <p className="text-sm">{user.bio}</p> </CardContent> <CardFooter> <Button variant="primary" size="sm">Follow</Button> <Button variant="outline" size="sm">Message</Button> </CardFooter> </Card> );}Settings Card
function SettingsCard() { return ( <Card> <CardHeader> <h3 className="text-lg font-semibold">Account Settings</h3> <p className="text-sm text-neutral-500"> Manage your account preferences </p> </CardHeader> <CardContent> <Stack spacing="md"> <Input label="Display Name" defaultValue="John Doe" /> <Textarea label="Bio" rows={3} /> </Stack> </CardContent> <CardFooter className="justify-end"> <Button variant="outline">Cancel</Button> <Button variant="primary">Save Changes</Button> </CardFooter> </Card> );}Card Grid
function CardGrid({ items }) { return ( <Grid cols={3} gap="lg"> {items.map((item) => ( <Card key={item.id}> <CardHeader> <h3 className="font-semibold">{item.title}</h3> </CardHeader> <CardContent> <p className="text-sm">{item.description}</p> </CardContent> <CardFooter> <Button variant="ghost" size="sm">Learn more</Button> </CardFooter> </Card> ))} </Grid> );}Accessibility
The Card component renders semantic <div> elements. For better accessibility:
- Use heading elements (
h2,h3, etc.) in CardHeader for proper document structure - When cards are interactive (clickable), add
role="button"andtabIndex={0}with keyboard handlers - For card lists, consider wrapping in a
<section>with a label
{/* Interactive card */}<Card role="button" tabIndex={0} onClick={handleClick} onKeyDown={(e) => e.key === 'Enter' && handleClick()} className="cursor-pointer hover:shadow-md transition-shadow"> <CardContent>Click to view details</CardContent></Card>
{/* Card section with heading */}<section aria-labelledby="team-heading"> <h2 id="team-heading">Team Members</h2> <Grid cols={3} gap="md"> <Card>...</Card> <Card>...</Card> </Grid></section>