Components
Info Card
Display labeled key-value detail items within a section card. Supports inline, grid, stacked, and wrapped layouts. Each item has a label and a custom-rendered value as children. The value container defaults to text-label-xs and text-sub-600 styling.
Installation
bunx @happlyui/cli@latest add info-card
Dependencies
npm packages
@remixicon/react
Registry dependencies
These are automatically installed when you add this component.
tvhapply-ui-utilsstatus-indicator
Usage
import * as InfoCard from "@/components/ui/info-card"
<InfoCard.Root layout="inline">
<InfoCard.Item>
<InfoCard.Label>Label</InfoCard.Label>
<InfoCard.Value>Value content</InfoCard.Value>
</InfoCard.Item>
</InfoCard.Root>
Examples
Inline
Items displayed side by side, each taking equal width. Uses Avatar for the user image.
Submitted date
Created by
import { RiTimeLine } from '@remixicon/react'
import * as Avatar from '@/components/ui/avatar'
import * as InfoCard from '@/components/ui/info-card'
<InfoCard.Root layout="inline">
<InfoCard.Item>
<InfoCard.Label>Submitted date</InfoCard.Label>
<InfoCard.Value>
<RiTimeLine className="w-4 h-4" />
<span>Jan 3, 2025</span>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Item>
<InfoCard.Label>Created by</InfoCard.Label>
<InfoCard.Value>
<Avatar.Root size="20">
<Avatar.Image src="avatar.jpg" />
</Avatar.Root>
<span>Sean Muir</span>
</InfoCard.Value>
</InfoCard.Item>
</InfoCard.Root>
Inline with Full Width Item
Mix inline and full-width items using the fullWidth prop. Uses StatusBadge for the status value and Avatar for the user image.
Submitted date
Created by
Publication status
import { RiAlertFill, RiTimeLine } from '@remixicon/react'
import * as Avatar from '@/components/ui/avatar'
import * as InfoCard from '@/components/ui/info-card'
import * as StatusBadge from '@/components/ui/status-badge'
<InfoCard.Root layout="inline">
<InfoCard.Item>
<InfoCard.Label>Submitted date</InfoCard.Label>
<InfoCard.Value>
<RiTimeLine className="w-4 h-4" />
<span>Jan 3, 2025</span>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Item>
<InfoCard.Label>Created by</InfoCard.Label>
<InfoCard.Value>
<Avatar.Root size="20">
<Avatar.Image src="avatar.jpg" />
</Avatar.Root>
<span>Sean Muir</span>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Item fullWidth>
<InfoCard.Label>Publication status</InfoCard.Label>
<InfoCard.Value>
<StatusBadge.Root status="pending">
<StatusBadge.Icon as={RiAlertFill} />
Require changes
</StatusBadge.Root>
</InfoCard.Value>
</InfoCard.Item>
</InfoCard.Root>
Grid (2 Columns)
Items arranged in a fixed 2-column grid. Uses Badge for category and priority values.
Start date
End date
Category
Priority
import { RiCalendarLine } from '@remixicon/react'
import * as Badge from '@/components/ui/badge'
import * as InfoCard from '@/components/ui/info-card'
<InfoCard.Root layout="grid" columns={2}>
<InfoCard.Item>
<InfoCard.Label>Start date</InfoCard.Label>
<InfoCard.Value>
<RiCalendarLine className="w-4 h-4" />
<span>Mar 1, 2025</span>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Item>
<InfoCard.Label>End date</InfoCard.Label>
<InfoCard.Value>
<RiCalendarLine className="w-4 h-4" />
<span>Jun 30, 2025</span>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Item>
<InfoCard.Label>Category</InfoCard.Label>
<InfoCard.Value>
<Badge.Root variant="lighter" color="blue">
Technology
</Badge.Root>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Item>
<InfoCard.Label>Priority</InfoCard.Label>
<InfoCard.Value>
<Badge.Root variant="lighter" color="red">
High
</Badge.Root>
</InfoCard.Value>
</InfoCard.Item>
</InfoCard.Root>
Stacked
Items stacked vertically, each taking full width. Uses Avatar and StatusBadge.
Application ID
Applicant
Status
import * as Avatar from '@/components/ui/avatar'
import * as InfoCard from '@/components/ui/info-card'
import * as StatusBadge from '@/components/ui/status-badge'
<InfoCard.Root layout="stack">
<InfoCard.Item>
<InfoCard.Label>Application ID</InfoCard.Label>
<InfoCard.Value>
<span>#APP-2025-0142</span>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Item>
<InfoCard.Label>Applicant</InfoCard.Label>
<InfoCard.Value>
<Avatar.Root size="20">
<Avatar.Image src="avatar.jpg" />
</Avatar.Root>
<span>Jane Cooper</span>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Item>
<InfoCard.Label>Status</InfoCard.Label>
<InfoCard.Value>
<StatusBadge.Root status="completed" variant="light">
<StatusBadge.Dot />
Approved
</StatusBadge.Root>
</InfoCard.Value>
</InfoCard.Item>
</InfoCard.Root>
With Action
Inline layout with a default action button. The action renders as a square button with an arrow icon.
Submitted date
Created by
import { RiTimeLine } from '@remixicon/react'
import * as Avatar from '@/components/ui/avatar'
import * as InfoCard from '@/components/ui/info-card'
<InfoCard.Root layout="inline">
<InfoCard.Item>
<InfoCard.Label>Submitted date</InfoCard.Label>
<InfoCard.Value>
<RiTimeLine className="w-4 h-4" />
<span>Jan 3, 2025</span>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Item>
<InfoCard.Label>Created by</InfoCard.Label>
<InfoCard.Value>
<Avatar.Root size="20">
<Avatar.Image src="avatar.jpg" />
</Avatar.Root>
<span>Sean Muir</span>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Action />
</InfoCard.Root>
Action with Notification
Action button with a notification dot in the top-right corner. Uses the StatusIndicator component internally.
Submitted date
Created by
Created by
Created by
Created by
import { RiTimeLine } from '@remixicon/react'
import * as Avatar from '@/components/ui/avatar'
import * as InfoCard from '@/components/ui/info-card'
<InfoCard.Root layout="inline">
<InfoCard.Item>
<InfoCard.Label>Submitted date</InfoCard.Label>
<InfoCard.Value>
<RiTimeLine className="w-4 h-4" />
<span>Jan 3, 2025</span>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Item>
<InfoCard.Label>Created by</InfoCard.Label>
<InfoCard.Value>
<Avatar.Root size="20">
<Avatar.Image src="avatar.jpg" />
</Avatar.Root>
<span>Sean Muir</span>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Action notification />
</InfoCard.Root>
With Custom Action
Action button with a custom icon. Pass children to override the default arrow icon.
Application ID
Status
import { RiExternalLinkLine } from '@remixicon/react'
import * as InfoCard from '@/components/ui/info-card'
import * as StatusBadge from '@/components/ui/status-badge'
<InfoCard.Root layout="inline">
<InfoCard.Item>
<InfoCard.Label>Application ID</InfoCard.Label>
<InfoCard.Value>
<span>#APP-2025-0142</span>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Item>
<InfoCard.Label>Status</InfoCard.Label>
<InfoCard.Value>
<StatusBadge.Root status="completed" variant="light">
<StatusBadge.Dot />
Approved
</StatusBadge.Root>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Action>
<RiExternalLinkLine className="size-5 text-icon-sub-600" />
</InfoCard.Action>
</InfoCard.Root>
Grid (3 Columns)
Items arranged in a fixed 3-column grid. Uses Badge for the duration value.
Amount
Duration
Deadline
import { RiCalendarLine } from '@remixicon/react'
import * as Badge from '@/components/ui/badge'
import * as InfoCard from '@/components/ui/info-card'
<InfoCard.Root layout="grid" columns={3}>
<InfoCard.Item>
<InfoCard.Label>Amount</InfoCard.Label>
<InfoCard.Value>
<span>$25,000</span>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Item>
<InfoCard.Label>Duration</InfoCard.Label>
<InfoCard.Value>
<Badge.Root variant="stroke">
12 months
</Badge.Root>
</InfoCard.Value>
</InfoCard.Item>
<InfoCard.Item>
<InfoCard.Label>Deadline</InfoCard.Label>
<InfoCard.Value>
<RiCalendarLine className="w-4 h-4" />
<span>Dec 31, 2025</span>
</InfoCard.Value>
</InfoCard.Item>
</InfoCard.Root>
API Reference
InfoCard.Root
The container for info card items. Controls layout and spacing.
| Prop | Type | Default | Description |
|---|---|---|---|
layout | 'inline' | 'grid' | 'stack' | 'wrap' | 'inline' | Controls how items are arranged. |
columns | 1 | 2 | 3 | 4 | - | Number of columns when layout is 'grid'. |
InfoCard.Item
An individual card containing a label and value.
| Prop | Type | Default | Description |
|---|---|---|---|
fullWidth | boolean | false | When true, the item spans the full width of the container. |
InfoCard.Label
The label text for an info card item.
| Prop | Type | Default | Description |
|---|
InfoCard.Value
The value container for custom-rendered content. Defaults to text-label-xs and text-text-sub-600 styling.
| Prop | Type | Default | Description |
|---|
InfoCard.Action
A square action button styled like an info card item. Renders a default RiArrowRightUpLine icon that can be overridden via children. Renders as an anchor tag when href is provided, otherwise a button.
| Prop | Type | Default | Description |
|---|---|---|---|
href | string | - | When provided, renders as an anchor tag instead of a button. |
notification | boolean | false | Show a notification dot in the top-right corner. |