Skip to Content
Card

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 { IconArrowRightFromBracket, IconPen } from "@optiaxiom/icons"; import { Card, CardHeader, CardImage, CardLink, CardPreview, EllipsisMenuButton, Menu, MenuContent, MenuTrigger, } from "@optiaxiom/react"; export function App() { return ( <Card maxW="xs"> <CardPreview> <CardImage alt="brown glass bottle beside white book on blue and white textile" src="https://picsum.photos/seed/optiaxiom/640/427" /> </CardPreview> <CardHeader addonAfter={ <Menu options={[ { addon: <IconPen />, label: "Edit" }, { addon: <IconArrowRightFromBracket />, 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.

children

Preview

addonTopLeft
addonTopRight
addonBottomLeft
addonBottomRight

children

description
addonBefore
addonAfter

Header

Footer

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

Unveiling the secrets.
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

On
import { IconArrowRightFromBracket, IconPen } from "@optiaxiom/icons"; import { Badge, Box, Card, CardHeader, EllipsisMenuButton, Menu, MenuContent, MenuTrigger, } from "@optiaxiom/react"; export function App() { return ( <Box maxW="sm" w="full"> <Card> <CardHeader addonAfter={ <> <Badge>On</Badge> <Menu options={[ { addon: <IconPen />, label: "Edit" }, { addon: <IconArrowRightFromBracket />, 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 { IconFolderBlank } from "@optiaxiom/icons"; import { Box, Card, CardHeader } from "@optiaxiom/react"; export function App() { return ( <Box maxW="sm" w="full"> <Card> <CardHeader addonBefore={<IconFolderBlank />}> 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> ); }

Use the CardLink component to render links and make the whole card clickable.

import { IconArrowRightFromBracket, IconPen } from "@optiaxiom/icons"; import { Box, Card, CardHeader, CardLink, EllipsisMenuButton, Menu, MenuContent, MenuTrigger, } from "@optiaxiom/react"; export function App() { return ( <Box maxW="sm" w="full"> <Card> <CardHeader addonAfter={ <Menu options={[ { addon: <IconPen />, label: "Edit" }, { addon: <IconArrowRightFromBracket />, 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 { IconMusic } from "@optiaxiom/icons"; import { Card, CardHeader, CardPreview } from "@optiaxiom/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, Card, CardHeader, CardImage, CardPreview, } from "@optiaxiom/react"; export function App() { return ( <Box maxW="xs" w="full"> <Card> <CardPreview> <CardImage alt="brown glass bottle beside white book on blue and white textile" src="https://picsum.photos/seed/optiaxiom/640/427" /> </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 { IconMusic, IconStar } from "@optiaxiom/icons"; import { Badge, Box, Button, Card, CardCheckbox, CardHeader, CardPreview, Group, } from "@optiaxiom/react"; export function App() { return ( <Group flexDirection={["column", "row"]} gap="16"> <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> </Group> ); }

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 { IconMusic, IconStar } from "@optiaxiom/icons"; import { Badge, Box, Button, Card, CardAction, CardCheckbox, CardHeader, CardPreview, Group, } from "@optiaxiom/react"; export function App() { return ( <Group flexDirection={["column", "row"]} gap="16"> <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> </Group> ); }

#

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 { IconGrip } from "@optiaxiom/icons"; import { Button, Card, CardHeader, CardLink, EllipsisMenuButton, Group, Menu, MenuContent, MenuTrigger, Text, } from "@optiaxiom/react"; import { Sortable, SortableHandle, SortableItem, } from "@optiaxiom/react/unstable"; 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) => ( <Group gap="16" 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={<IconGrip />} /> </SortableHandle> } description={data[item].description} > <CardLink href="data:,">{data[item].title}</CardLink> </CardHeader> </Card> </SortableItem> </Group> )) } </Sortable> ); }

#

Props

#

Card

import { Card } from "@optiaxiom/react"; // or import { Card } from "@optiaxiom/react/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

children

ReactNode

className

string

#

CardAction

import { CardAction } from "@optiaxiom/react"; // or import { CardAction } from "@optiaxiom/react/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

children

ReactNode

className

string

visible

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

"always" | "if-needed"

#

CardCheckbox

import { CardCheckbox } from "@optiaxiom/react"; // or import { CardCheckbox } from "@optiaxiom/react/card";

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

checked

Whether the input is checked. Use with onCheckedChange to control it.

false | true

children

ReactNode

className

string

defaultChecked

Whether the input is checked initially, when uncontrolled.

false | true

disabled

Whether the input is disabled.

false | true

indeterminate

Display a partially checked icon instead of the regular checkmark.

false | true

name

The name of the form control element.

string

onCheckedChange

Handler that is called when the checked state changes.

(checked: boolean) => void

required

Whether selecting this input is required.

false | true

size

Control the size of the checkbox.

"sm" | "md"

value

The value of the form control element.

string | number | readonly string[]

#

CardFooter

import { CardFooter } from "@optiaxiom/react"; // or import { CardFooter } from "@optiaxiom/react/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

children

ReactNode

className

string

#

CardHeader

import { CardHeader } from "@optiaxiom/react"; // or import { CardHeader } from "@optiaxiom/react/card";

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

children

ReactNode

className

string

description

Add secondary text after the primary title.

ReactNode

lineClamp

Truncate the text at specific number of lines.

"2" | "1" | "3" | "4"

truncate

Whether to truncate the text and add an ellipsis at the end.

A flex item doesn’t shrink below its content, so inside a flex row set minW="0" on the item that wraps the Text (or make the Text the flex item).

false | true

#

CardImage

import { CardImage } from "@optiaxiom/react"; // or import { CardImage } from "@optiaxiom/react/card";

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

children

ReactNode

className

string

import { CardLink } from "@optiaxiom/react"; // or import { CardLink } from "@optiaxiom/react/card";

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

children

ReactNode

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

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

false | true

href

The link href.

string

onClick

The link onClick handler. For an action that doesn’t navigate, such as opening a dialog, set asChild and pass the handler to a child <button> instead.

MouseEventHandler<HTMLAnchorElement>

#

CardPreview

import { CardPreview } from "@optiaxiom/react"; // or import { CardPreview } from "@optiaxiom/react/card";

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

children

ReactNode

className

string

#

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 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