Skip to Content
Components
Card ALPHA

Card

Generic container for grouping related components together.

Documentation

Usage

brown glass bottle beside white book on blue and white textile

The majestic world of turtles

Unveiling the secrets.
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, EllipsisMenuButton, } from "@optiaxiom/react"; import { Card, CardHeader, CardImage, CardLink, CardPreview, } from "@optiaxiom/react/unstable"; 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={ <DropdownMenu> <DropdownMenuTrigger asChild> <EllipsisMenuButton appearance="subtle" aria-label="actions" size="sm" /> </DropdownMenuTrigger> <DropdownMenuContent align="end"> <DropdownMenuItem icon={<IconPencil />}>Edit</DropdownMenuItem> <DropdownMenuItem icon={<IconLogout />} intent="danger"> Delete </DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> } 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/unstable"; 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.

children
addonTopLeft
addonTopRight
addonBottomLeft
addonBottomRight

children

description
addonBefore
addonAfter
Footer

Header

Use the CardHeader component to add a title to cards.

The majestic world of turtles

import { Box } from "@optiaxiom/react"; import { Card, CardHeader } from "@optiaxiom/react/unstable"; 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

Unveiling the secrets.
import { Box } from "@optiaxiom/react"; import { Card, CardHeader } from "@optiaxiom/react/unstable"; 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

On
import { Badge, Box, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, EllipsisMenuButton, } from "@optiaxiom/react"; import { Card, CardHeader } from "@optiaxiom/react/unstable"; import { IconLogout, IconPencil } from "@tabler/icons-react"; export function App() { return ( <Box maxW="sm" w="full"> <Card> <CardHeader addonAfter={ <> <Badge>On</Badge> <DropdownMenu> <DropdownMenuTrigger asChild> <EllipsisMenuButton appearance="subtle" aria-label="actions" size="sm" /> </DropdownMenuTrigger> <DropdownMenuContent align="end"> <DropdownMenuItem icon={<IconPencil />}> Edit </DropdownMenuItem> <DropdownMenuItem icon={<IconLogout />} intent="danger"> Delete </DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> </> } > 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 } from "@optiaxiom/react"; import { Card, CardHeader } from "@optiaxiom/react/unstable"; 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, Text } from "@optiaxiom/react"; import { Card, CardHeader } from "@optiaxiom/react/unstable"; 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, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, EllipsisMenuButton, } from "@optiaxiom/react"; import { Card, CardHeader, CardLink } from "@optiaxiom/react/unstable"; import { IconLogout, IconPencil } from "@tabler/icons-react"; export function App() { return ( <Box maxW="sm" w="full"> <Card> <CardHeader addonAfter={ <DropdownMenu> <DropdownMenuTrigger asChild> <EllipsisMenuButton appearance="subtle" aria-label="actions" size="sm" /> </DropdownMenuTrigger> <DropdownMenuContent align="end"> <DropdownMenuItem icon={<IconPencil />}>Edit</DropdownMenuItem> <DropdownMenuItem icon={<IconLogout />} intent="danger"> Delete </DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> } > <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, Text, Tooltip } from "@optiaxiom/react"; import { Card, CardHeader, CardLink } from "@optiaxiom/react/unstable"; 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/unstable"; 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.

brown glass bottle beside white book on blue and white textile

The majestic world of turtles

import { Box } from "@optiaxiom/react"; import { Card, CardHeader, CardImage, CardPreview, } from "@optiaxiom/react/unstable"; 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.

Check to select

Checkbox

Check to select
Duplicate

Checkbox and star button

import { Badge, Box, Button, Flex } from "@optiaxiom/react"; import { Card, CardCheckbox, CardHeader, CardPreview, } from "@optiaxiom/react/unstable"; 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.

Check to select

Checkbox

Check to select
Duplicate

Checkbox and star button

import { Badge, Box, Button, Flex } from "@optiaxiom/react"; import { Card, CardAction, CardCheckbox, CardHeader, CardPreview, } from "@optiaxiom/react/unstable"; 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

A/B Test - United Kingdom or Canada or Germany

2

Age Experiment

A/B Test - Everyone: 14, 16, 18

3

Multi-Armed Bandit for Images

Multi-armed bandit - Everyone: Off, Image 1
"use client"; import { Button, EllipsisMenuButton, Flex, Text } from "@optiaxiom/react"; import { Card, CardHeader, CardLink, Menu, MenuContent, MenuTrigger, 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

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

CardAction

Supports all Box props in addition to its own. Renders a <div> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

visible

Control whether to always show the contents or only when user is hovering or interacting with them.

"always" | "if-needed"

CardCheckbox

Supports all Checkbox props in addition to its own. Renders a <div> element but forwards all props to a hidden <input> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

indeterminate

Display a partially checked icon instead of the regular checkmark.

false | true

onCheckedChange

Handler that is called when the checked state changes.

(checked: boolean) => void

CardFooter

Supports all Box props in addition to its own. Renders a <div> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

CardHeader

Supports all Box props in addition to its own. Renders a <div> element.

Prop

addonAfter

Display content inside the header after children.

ReactNode

addonBefore

Display content inside the header before children.

ReactNode

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

description

Add secondary text after the primary title.

ReactNode

CardImage

Supports all Box props in addition to its own. Renders an <img> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

CardLink

Supports all Link props in addition to its own. Renders an <a> element.

Prop

appearance

Control the appearance by selecting between the different link types.

"default" | "subtle" | "inverse"

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

cover

Whether to expand and fill up the whole area of the parent which has position: relative.

false | true | "inset"

disabled

Whether to show disabled state and disable interactions.

false | true

external

Show an external link icon and sets the correct rel/target attributes.

false | true

CardPreview

Supports all Box props in addition to its own. Renders a <div> element.

Prop

addonBottomLeft

Display content in the bottom-left corner of the preview panel.

ReactNode

addonBottomRight

Display content in the bottom-right corner of the preview panel.

ReactNode

addonTopLeft

Display content in the top-left corner of the preview panel.

ReactNode

addonTopRight

Display content in the top-right corner of the preview panel.

ReactNode

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

Changelog

1.5.0

  • Renamed CardOverflow component to CardPreview:

    // Before <Card> <CardOverflow /> </Card> // After <Card> <CardPreview /> </Card>
  • Removed CardContent component

  • Combined CardTitle and CardDescription into one CardHeader component:

    // 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
Last updated on