Item list

A card-per-row list with a leading icon, auto-derived columns, inline actions, and click-through navigation.

Name
Team member
Date
Amount
Chrome
Web Browser
Ann Wong
10 Apr 2017
$88,904.92
Slack
Communication
Georgie Bryant
09 Apr 2017
$61,636.03
Spotify
Music
Todd Murphy
07 Jun 2017
$15,970.97
Instagram
Social Media
Ollie Lambert
15 Sep 2017
$46,926.03
Installation
$Terminal
npx shadcn@latest add https://sdk-components.thesqd.com/r/item-list.json
Usage
Pass a `data` array of dicts. Columns are derived from the keys (minus reserved keys like `icon`, `title`, `actions`, `href`); pass `columns` to reorder, relabel, align, or custom-render.
TSImport
import { ItemList, type ItemListRow } from "@/components/ui/item-list";
TSExample
import { ItemList, type ItemListRow } from "@/components/ui/item-list";
import { GlobeIcon } from "lucide-react";

const data: ItemListRow[] = [
  {
    icon: GlobeIcon,
    title: "Chrome",
    subtitle: "Web Browser",
    member: "Ann Wong",
    amount: "$88,904.92",
    href: "/apps/chrome",
  },
];

export function Example() {
  // Columns auto-derive from the keys (member, amount); pass `columns` to
  // reorder / relabel / align / custom-render.
  return <ItemList data={data} />;
}
Composition
Anatomy of the ItemList primitive.
ItemList (props)                              // flat, card-per-row list
├── data: ItemListRow[]                       // each row is a dict
│   ├── icon? | image?                        // leading visual
│   ├── title / subtitle?                     // leading text
│   ├── [key]: ReactNode                      // any other key → a data column (auto)
│   ├── actions?: { icon, label, onClick }[]  // animate-ui icon buttons
│   └── href? | onNavigate?                   // trailing chevron navigation
├── columns?: ItemListColumn[]                // optional: reorder / relabel / align / render
├── nameHeader?  (default "Name")
└── hideHeader? / emptyState? / getRowId?

Row = <Card> surface
├── Leading cell — icon|image + title + subtitle
├── Data columns — value rendered as-is (drop in Badge / Select / Input to edit inline)
├── Action cluster — animated Lucide icons, animate on hover
└── Chevron — navigates via href (<a>) or onNavigate
Default
App-directory style: a leading icon + title/subtitle, data columns, a status indicator, animate-ui icon actions, and a chevron that navigates. Columns are reordered/aligned via `columns`.
Name
Team member
Date
Amount
Chrome
Web Browser
Ann Wong
10 Apr 2017
$88,904.92
Slack
Communication
Georgie Bryant
09 Apr 2017
$61,636.03
Spotify
Music
Todd Murphy
07 Jun 2017
$15,970.97
Instagram
Social Media
Ollie Lambert
15 Sep 2017
$46,926.03
Inline editing
A cell value can be any node — drop a `Badge`, `Select`, or `Input` into a column and wire its `onChange` to your own state. The list stays uncontrolled.
Name
Tier
Plan
Seats
Northpoint
Atlanta, GA
scale
Redeemer
New York, NY
growth
Cornerstone
Austin, TX
starter
Auto columns
Pass just `data` — columns are inferred from the dict keys (minus reserved keys). No actions or navigation.
Name
Region
Uptime
Marketing site
Production
us-east-1
99.98%
Docs
Production
eu-west-2
99.95%
Status page
Edge
global
100%
API Reference
Props for the flat `<ItemList>` component plus the row, column, and action shapes.

ItemList

PropTypeDefaultDescription
dataItemListRow[]Rows to render. Each is a dict; non-reserved keys become data columns automatically.
columnsItemListColumn[]Optional override — reorder, relabel, align, set width, or custom-render columns. Omit to auto-derive from keys.
nameHeaderReactNode"Name"Header label for the leading (icon + title) column.
hideHeaderbooleanfalseHide the uppercase column-label header row.
getRowId(row, index) => stringStable row key. Falls back to `row.id` then the index.
emptyStateReactNodeRendered in place of the list when `data` is empty.
aria-labelstringAccessibility label for the list.
classNamestringExtra wrapper classes.

ItemListRow

PropTypeDefaultDescription
idstring | numberStable id (else `getRowId`, else the index).
iconComponentType<{ className?: string }>Leading icon (use this OR `image`).
imagestringLeading image URL (use this OR `icon`).
imageAltstringAlt text for `image`.
titleReactNodePrimary label in the leading cell.
subtitleReactNodeSecondary muted label under the title.
actionsItemListAction[]Animated icon-action buttons rendered before the chevron.
hrefstringNavigate here when the chevron is clicked (renders an `<a>`).
targetHTMLAttributeAnchorTargetAnchor target for `href`.
onNavigate(row) => voidAlternative to `href` — called when the chevron is clicked.
[key]ReactNodeAny other key becomes a data column. The value may be any node — text, a Badge, a Select, an Input, etc.

ItemListColumn

PropTypeDefaultDescription
keystringRow key this column reads.
headerReactNodeHeader label. Defaults to a humanized version of `key`.
align"start" | "center" | "end""start"Text alignment for the column.
widthstring | numberTrack width (number = px). Defaults to a flexible `1fr`.
render(value, row) => ReactNodeCustom cell renderer. Without it the raw value renders as-is.
classNamestringExtra classes on the cell.

ItemListAction

PropTypeDefaultDescription
iconAnimatedIconComponentAnimated (motion) Lucide icon — e.g. `FoldersIcon` from `@/components/ui/folders`. Plays its animation on hover.
labelstringAccessible label + tooltip.
onClick(e) => voidFires when the action is clicked.
disabledbooleanDisables the action.