Card
Cards collect and divide content into designated areas. Cards can be actionable themselves or have actionable elements within.
Loading...
Overview
Resources
Install
yarn add @camp/card
Upgrading to Next Gen
🎨 Updated Color Palette & Style Refresh: Aligned styling with our refreshed brand standards, delivering a modernized and cohesive look and feel.
Migration steps
- Update import path: Replace the old Card imports with Card from
@camp/card
. - Update prop values:
disabled
: used to disable anactionable
card and prevent any interactions with it. Note: you will need to manually set any buttons to be disabled within it.dismissLabel
: used to pass a translated string to the dismiss icononDismiss
: whenactionable
is false, this can be used to pass a function when the dismiss button is clicked.selected
:actionable
cards can be shown with aselected
state
- New
<CardContent>
component: The<CardContent>
is a preformatted component that handles the layout of the card content. It accepts props fortitle
,paragraph
, and render functions for various types of content. Card may still be used as a container for other custom styled children, but the<CardContent>
component is recommended for most use cases. For full prop details, see the CardContent tab in the Overview section above.
Variations
Default card
Use the default card in most cases when looking to group related content together. Card
is the outer container that defines outer styling including padding/border, and CardContent
is the inner container which handles the layout of the inner content.
Loading...
import { Card, CardContent } from '@camp/card';
import { Chip } from '@camp/chip';
import { Button } from '@camp/button';
<Card>
<CardContent
title="Title"
paragraph="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labe et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
renderChips={() => (
<div style={{ display: 'flex', gap: Space[2] }}>
<Chip type="default" color="ac-blue">
Chip
</Chip>
<Chip type="default" color="moss">
Chip
</Chip>
</div>
)}
renderActions={() => (
<div style={{ display: 'flex', gap: Space[3] }}>
<Button size="small" appearance="secondary">
Card action
</Button>
<Button size="small" appearance="secondary">
Card action
</Button>
</div>
)}
/>
</Card>;
Card with Image
<CardContent>
also accepts a render function for an image. This is useful for cards that have a visual element, such as a product image or a photo.
Loading...
import { Card, CardContent } from '@camp/card';
import { Chip } from '@camp/chip';
import { Button } from '@camp/button';
<Card>
<CardContent
title="Title"
paragraph="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labe et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
renderImage={() => <img src="https://picsum.photos/id/76/180/250" alt="Bicycle" />}
renderChips={() => (
<div style={{ display: 'flex', gap: Space[2] }}>
<Chip type="default" color="ac-blue">
Chip
</Chip>
<Chip type="default" color="moss">
Chip
</Chip>
</div>
)}
renderActions={() => (
<div style={{ display: 'flex', gap: Space[3] }}>
<Button size="small" appearance="secondary">
Card action
</Button>
<Button size="small" appearance="secondary">
Card action
</Button>
</div>
)}
/>
</Card>;
Actionable card
An actionable
card can be interacted with. Hover/click on the card below to see. <Card>
also accepts all HTML div attributes, so you can pass event handlers such as onClick
to the card itself. Dismiss props are not supported on actionable cards.
Loading...
import { Card, CardContent } from '@camp/card';
<Card actionable>
<CardContent
title="Title"
paragraph="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labe et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
/>
</Card>;
Disabled Card
You can make an actionable card disabled, preventing interaction.
Note: you will need to manually set any buttons to be disabled within it.
Loading...
import { Card, CardContent } from '@camp/card';
<Card actionable disabled>
<CardContent
title="Title"
paragraph="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labe et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
/>
</Card>;
Selected Card
You can add a selected state to an actionable card.
Loading...
import { Card, CardContent } from '@camp/card';
<Card actionable selected>
<CardContent
title="Title"
paragraph="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labe et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
/>
</Card>;
With Dismiss
You can also add a dismiss button to the card with the onDismiss
prop. This is useful for cards that are not actionable, but you want to give the user the option to dismiss them. The dismissLabel
prop is required when using onDismiss
to add a label to the button for accessibility.
Loading...
import { Card, CardContent } from '@camp/card';
<Card onDismiss={() => alert('Card dismissed')} dismissLabel="Dismiss">
<CardContent
title="Title"
paragraph="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labe et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
/>
</Card>;
AI Card
The ai
prop is used to create an AI card. When using the ai
prop, the dismiss props are not allowed, since AI cards are not dismissable.
Static
<CardContent>
can also be used within an ai
card to render the content. The renderMenu
prop is available for use on <CardContent>
to render a menu, which is a common pattern for AI cards.
Loading...
import { Card, CardContent } from '@camp/card';
<Card ai>
<CardContent
title="Title"
paragraph="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labe et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
renderActions={renderActions}
renderMenu={renderMenu}
/>
</Card>;
Actionable
Actionable AI cards have hover, focus, and active states. They also have a selected
state. Dismiss props are not supported on actionable AI cards.
Loading...
Loading...
Loading...
import { Card, CardContent } from '@camp/card';
<Card ai actionable>
<CardContent title="Card 1" paragraph="Some descriptive text." />
</Card>
<Card ai actionable>
<CardContent title="Card 2" paragraph="Some descriptive text." />
</Card>
<Card ai actionable selected>
<CardContent title="Card 3" paragraph="This card is selected." />
</Card>
Loading
The Loading AI card can be used by itself in place of content that is loading, or the loading state can be toggled on and off for the card itself. The size of the loading card will expand to fill the parent container (this differs from the static card, which is sized based on the inner content; size your parent container accordingly).
Title and medium loading indicator
Loading...
No title and small loading indicator
Loading...
Custom loading background color and custom content
Loading...
Any content passed as children
to the Card will not be visible when the card is loading. It is replaced by any content passed as loadingContent
.
You can also update the loading background color by passing a value for loadingBackgroundColor
. The available colors are: bg-default
, bg-educational
, bg-disabled
.
The helper component <CardLoadingContent>
may be used to optionally render a text and/or loading indicator. Full prop descriptions for <CardLoadingContent>
can be found in the Overview section above.
import { Card, CardContent } from '@camp/card';
<Card
ai
loading
loadingContent={<CardLoadingContent title="Loading..." loadingIndicatorSize="medium" />}
>
<CardContent title="Card 1" paragraph="Some descriptive text." />
</Card>;
Usage
Best practices
✅ DO
- Do use to visually separate content that is meant to draw focus. Use cards with dropshadows for the most important information on the page.
Accessibility
Keyboard support
- You can tab into an actionable card and then into its content.
- You can tab into the dismiss in the card (last).
Labels
- The developer should set
dismissLabel
to provide a translated aria-label for the dismiss “X” button.