Card
Generic container for grouping related components together.
#
Documentation
#
#
Usage
#

The majestic world of turtles
import {
Card,
CardHeader,
CardImage,
CardLink,
CardPreview,
EllipsisMenuButton,
Menu,
MenuContent,
MenuTrigger,
} from "@optiaxiom/react";
import { IconLogout, IconPencil } from "@tabler/icons-react";
import Image from "next/image";
import beach from "@/demos/beach.jpg";
export function App() {
return (
<Card maxW="xs">
<CardPreview>
<CardImage asChild>
<Image
alt="brown glass bottle beside white book on blue and white textile"
priority
src={beach}
/>
</CardImage>
</CardPreview>
<CardHeader
addonAfter={
<Menu
options={[
{ addon: <IconPencil />, label: "Edit" },
{ addon: <IconLogout />, intent: "danger", label: "Delete" },
]}
>
<MenuTrigger asChild>
<EllipsisMenuButton
appearance="subtle"
aria-label="actions"
size="sm"
/>
</MenuTrigger>
<MenuContent align="end" />
</Menu>
}
description="Unveiling the secrets."
>
<CardLink href="../">The majestic world of turtles</CardLink>
</CardHeader>
</Card>
);
}#
Anatomy
#
import {
Card,
CardAction,
CardCheckbox,
CardFooter,
CardHeader,
CardImage,
CardLink,
CardPreview,
} from "@optiaxiom/react";
export default () => (
<Card>
<CardPreview>
<CardImage />
<CardCheckbox />
<CardAction />
</CardPreview>
<CardHeader>
<CardLink />
</CardHeader>
<CardFooter />
</Card>
);#
Structure
#
Card has a basic structure containing the following parts:
CardPreview: An optional media/thumbnail preview.CardHeader: Contains the title and an optional short description along with slots for icons, actions, etc. on left/right side of the title.CardFooter: Contains secondary information and sticks to the bottom of the card.
CardHeader is the only required element - and all other elements are optional.
Preview
children
Header
#
Header
#
Use the CardHeader component to add a title to cards.
The majestic world of turtles
import { Box, Card, CardHeader } from "@optiaxiom/react";
export function App() {
return (
<Box maxW="sm" w="full">
<Card>
<CardHeader>The majestic world of turtles</CardHeader>
</Card>
</Box>
);
}#
Description
#
Use the description prop on CardHeader to add short descriptions to cards.
The majestic world of turtles
import { Box, Card, CardHeader } from "@optiaxiom/react";
export function App() {
return (
<Box maxW="sm" w="full">
<Card>
<CardHeader description="Unveiling the secrets.">
The majestic world of turtles
</CardHeader>
</Card>
</Box>
);
}#
Addons
#
Use the addonAfter prop on CardHeader to add menus and other secondary actions after the title.
The majestic world of turtles
import {
Badge,
Box,
Card,
CardHeader,
EllipsisMenuButton,
Menu,
MenuContent,
MenuTrigger,
} from "@optiaxiom/react";
import { IconLogout, IconPencil } from "@tabler/icons-react";
export function App() {
return (
<Box maxW="sm" w="full">
<Card>
<CardHeader
addonAfter={
<>
<Badge>On</Badge>
<Menu
options={[
{ addon: <IconPencil />, label: "Edit" },
{ addon: <IconLogout />, intent: "danger", label: "Delete" },
]}
>
<MenuTrigger asChild>
<EllipsisMenuButton
appearance="subtle"
aria-label="actions"
size="sm"
/>
</MenuTrigger>
<MenuContent align="end" />
</Menu>
</>
}
>
The majestic world of turtles
</CardHeader>
</Card>
</Box>
);
}Use the addonBefore prop on CardHeader to add icons or other visuals before the title.
The majestic world of turtles
import { Box, Card, CardHeader } from "@optiaxiom/react";
import { IconFolder } from "@tabler/icons-react";
export function App() {
return (
<Box maxW="sm" w="full">
<Card>
<CardHeader addonBefore={<IconFolder />}>
The majestic world of turtles
</CardHeader>
</Card>
</Box>
);
}#
Truncate
#
We can use the Text component to truncate header titles.
Step by step: How to brainstorm a creative marketing campaign (+ free template)
import { Box, Card, CardHeader, Text } from "@optiaxiom/react";
export function App() {
return (
<Box maxW="xs" w="full">
<Card>
<CardHeader>
<Text lineClamp="1">
Step by step: How to brainstorm a creative marketing campaign (+
free template)
</Text>
</CardHeader>
</Card>
</Box>
);
}#
Links
#
Use the CardLink component to render links and make the whole card clickable.
import {
Box,
Card,
CardHeader,
CardLink,
EllipsisMenuButton,
Menu,
MenuContent,
MenuTrigger,
} from "@optiaxiom/react";
import { IconLogout, IconPencil } from "@tabler/icons-react";
export function App() {
return (
<Box maxW="sm" w="full">
<Card>
<CardHeader
addonAfter={
<Menu
options={[
{ addon: <IconPencil />, label: "Edit" },
{ addon: <IconLogout />, intent: "danger", label: "Delete" },
]}
>
<MenuTrigger asChild>
<EllipsisMenuButton
appearance="subtle"
aria-label="actions"
size="sm"
/>
</MenuTrigger>
<MenuContent align="end" />
</Menu>
}
>
<CardLink href="../">The majestic world of turtles</CardLink>
</CardHeader>
</Card>
</Box>
);
}#
Tooltip
#
We can combine this with the Text and Tooltip component to truncate header titles while also showing the full title in a tooltip.
Use the auto prop on Tooltip to only show a tooltip if the text is actually clipped.
import {
Box,
Card,
CardHeader,
CardLink,
Text,
Tooltip,
} from "@optiaxiom/react";
export function App() {
return (
<Box maxW="xs" w="full">
<Card>
<CardHeader>
<Tooltip
auto
content="Step by step: How to brainstorm a creative marketing campaign (+ free template)"
>
<CardLink href="../">
<Text lineClamp="1">
Step by step: How to brainstorm a creative marketing campaign (+
free template)
</Text>
</CardLink>
</Tooltip>
</CardHeader>
</Card>
</Box>
);
}#
Preview
#
Use the CardPreview component to add a preview section for cards.
The majestic world of turtles
import { Card, CardHeader, CardPreview } from "@optiaxiom/react";
import { IconMusic } from "@tabler/icons-react";
export function App() {
return (
<Card size="224">
<CardPreview bg="bg.success" color="fg.default.inverse" flex="1">
<IconMusic size="32" />
</CardPreview>
<CardHeader>The majestic world of turtles</CardHeader>
</Card>
);
}We can also use the CardImage component to add thumbnail images for cards.

The majestic world of turtles
import {
Box,
Card,
CardHeader,
CardImage,
CardPreview,
} from "@optiaxiom/react";
import Image from "next/image";
import beach from "@/demos/beach.jpg";
export function App() {
return (
<Box maxW="xs" w="full">
<Card>
<CardPreview>
<CardImage asChild>
<Image
alt="brown glass bottle beside white book on blue and white textile"
priority
src={beach}
/>
</CardImage>
</CardPreview>
<CardHeader>The majestic world of turtles</CardHeader>
</Card>
</Box>
);
}#
Overlay
#
Use the addonTopLeft/addonTopRight/addonBottomRight/addonBottomLeft props on CardPreview to add checkbox and other tertiary actions to cards.
Checkbox
Checkbox and star button
import {
Badge,
Box,
Button,
Card,
CardCheckbox,
CardHeader,
CardPreview,
Flex,
} from "@optiaxiom/react";
import { IconMusic, IconStar } from "@tabler/icons-react";
export function App() {
return (
<Flex flexDirection={["column", "row"]}>
<Card size="224">
<CardPreview addonTopLeft={<CardCheckbox />} bg="bg.page" flex="1">
<Box
bg="bg.default"
color="fg.success"
p="16"
rounded="md"
shadow="sm"
>
<IconMusic size="32" />
</Box>
</CardPreview>
<CardHeader>Checkbox</CardHeader>
</Card>
<Card size="224">
<CardPreview
addonBottomLeft={<Badge intent="warning">Duplicate</Badge>}
addonTopLeft={<CardCheckbox />}
addonTopRight={
<Button aria-label="Add to favorites" icon={<IconStar />} />
}
bg="bg.page"
flex="1"
>
<Box
bg="bg.default"
color="fg.success"
p="16"
rounded="md"
shadow="sm"
>
<IconMusic size="32" />
</Box>
</CardPreview>
<CardHeader>Checkbox and star button</CardHeader>
</Card>
</Flex>
);
}Include the CardAction component if you’d like the checkbox to be hidden until hovered or interacted with.
Hover over the card to see the checkbox:
Checkbox
Checkbox and star button
import {
Badge,
Box,
Button,
Card,
CardAction,
CardCheckbox,
CardHeader,
CardPreview,
Flex,
} from "@optiaxiom/react";
import { IconMusic, IconStar } from "@tabler/icons-react";
export function App() {
return (
<Flex flexDirection={["column", "row"]}>
<Card size="224">
<CardPreview
addonTopLeft={
<CardAction>
<CardCheckbox />
</CardAction>
}
bg="bg.page"
flex="1"
>
<Box
bg="bg.default"
color="fg.success"
p="16"
rounded="md"
shadow="sm"
>
<IconMusic size="32" />
</Box>
</CardPreview>
<CardHeader>Checkbox</CardHeader>
</Card>
<Card size="224">
<CardPreview
addonBottomLeft={<Badge intent="warning">Duplicate</Badge>}
addonTopLeft={
<CardAction>
<CardCheckbox />
</CardAction>
}
addonTopRight={
<CardAction>
<Button aria-label="Add to favorites" icon={<IconStar />} />
</CardAction>
}
bg="bg.page"
flex="1"
>
<Box
bg="bg.default"
color="fg.success"
p="16"
rounded="md"
shadow="sm"
>
<IconMusic size="32" />
</Box>
</CardPreview>
<CardHeader>Checkbox and star button</CardHeader>
</Card>
</Flex>
);
}#
Sortable
#
We can combine cards with the Sortable component to build a sortable list of cards.
1
Launch Scooter Beta Sign Up
2
Age Experiment
3
Multi-Armed Bandit for Images
App.tsx
"use client";
import {
Button,
Card,
CardHeader,
CardLink,
EllipsisMenuButton,
Flex,
Menu,
MenuContent,
MenuTrigger,
Text,
} from "@optiaxiom/react";
import {
Sortable,
SortableHandle,
SortableItem,
} from "@optiaxiom/react/unstable";
import { IconGripVertical } from "@tabler/icons-react";
import { useState } from "react";
import { data } from "./data";
export function App() {
const [items, setItems] = useState(() => Object.keys(data));
return (
<Sortable items={items} onItemsChange={setItems}>
{(items) =>
items.map((item, index) => (
<Flex flexDirection="row" key={item}>
<Text color="fg.secondary" fontSize="md" w="20">
{index + 1}
</Text>
<SortableItem asChild index={index} item={item}>
<Card flex="1">
<CardHeader
addonAfter={
<Menu options={[{ label: "Edit" }]}>
<MenuTrigger asChild>
<EllipsisMenuButton
appearance="subtle"
aria-label="actions"
ml="auto"
/>
</MenuTrigger>
<MenuContent />
</Menu>
}
addonBefore={
<SortableHandle
asChild
color="fg.tertiary"
transition="colors"
>
<Button appearance="subtle" icon={<IconGripVertical />} />
</SortableHandle>
}
description={data[item].description}
>
<CardLink href="data:,">{data[item].title}</CardLink>
</CardHeader>
</Card>
</SortableItem>
</Flex>
))
}
</Sortable>
);
}#
Props
#
#
Card
#
Supports all Box props in addition to its own. Renders a <div> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
#
CardAction
#
Supports all Box props in addition to its own. Renders a <div> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
visibleControl whether to always show the contents or only when user is hovering or interacting with them.
|
#
CardCheckbox
#
Supports all Checkbox props in addition to its own. Renders a <div> element but forwards all props to a hidden <input> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
indeterminateDisplay a partially checked icon instead of the regular checkmark.
|
onCheckedChangeHandler that is called when the checked state changes.
|
#
CardFooter
#
Supports all Box props in addition to its own. Renders a <div> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
#
CardHeader
#
Supports all Box props in addition to its own. Renders a <div> element.
Prop |
|---|
addonAfterDisplay content inside the header after
|
addonBeforeDisplay content inside the header before
|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
descriptionAdd secondary text after the primary title.
|
#
CardImage
#
Supports all Box props in addition to its own. Renders an <img> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
#
CardLink
#
Supports all Link props in addition to its own. Renders an <a> element.
Prop |
|---|
appearanceControl the appearance by selecting between the different link types.
|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
coverWhether to expand and fill up the whole area of the parent which has
|
disabledWhether to show disabled state and disable interactions.
|
externalShows an external link icon and sets the correct rel/target attributes.
|
#
CardPreview
#
Supports all Box props in addition to its own. Renders a <div> element.
Prop |
|---|
addonBottomLeftDisplay content in the bottom-left corner of the preview panel.
|
addonBottomRightDisplay content in the bottom-right corner of the preview panel.
|
addonTopLeftDisplay content in the top-left corner of the preview panel.
|
addonTopRightDisplay content in the top-right corner of the preview panel.
|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
#
Changelog
#
#
1.6.0
#
-
Moved component out of Alpha.
// Before import { Card } from "@optiaxiom/react/unstable"; // After import { Card } from "@optiaxiom/react";
#
1.5.0
#
-
Renamed
CardOverflowcomponent toCardPreview:// Before <Card> <CardOverflow /> </Card> // After <Card> <CardPreview /> </Card> -
Removed
CardContentcomponent -
Combined
CardTitleandCardDescriptioninto oneCardHeadercomponent:// Before <Card> <CardTitle>Sample Title</CardTitle> <CardDescription>Sample Description</CardDescription> </Card> // After <Card> <CardHeader description="Sample Description"> Sample Title </CardHeader> </Card>
#
0.12.1
#
- Added component