Marble UI
← Components

List View (GridList)

Preview: Selectable

Interactive list row (React Aria GridList): selection, row actions and nested buttons with grid keyboard navigation.

Import

import { ListView, ListViewItem } from '@marbleui/ui'

Props

<ListView>

No props of its own.

Also accepts React Aria props (101).

<ListViewItem>

PropTypeDefaultDescription
children *requiredReactNode—
actionsReactNode—Buttons / menus on the right. They stay keyboard-reachable with arrow keys.
descriptionReactNode—
leadingReactNode—

Also accepts React Aria props (96).

Accessibility

Keyboard interaction, focus management and ARIA semantics come from the underlying primitives: React Aria GridList · React Aria GridListItem. Follow the primitive's docs for the full keyboard map.

Usage notes

Interactive list rows with selection, row actions and nested buttons. For a plain pick-from-list use ListBox; for tabular columns use Table.

<ListView aria-label="Members" selectionMode="multiple" items={members}>
  {(m) => (
    <ListViewItem id={m.id} textValue={m.name} description={m.email} actions={<Badge>{m.role}</Badge>}>
      {m.name}
    </ListViewItem>
  )}
</ListView>
  • Built on React Aria GridList: selectionMode, selectedKeys, onSelectionChange and onAction are supported, so selection is controlled or uncontrolled as in React Aria.
  • Provide aria-label. Set textValue when row children aren’t a plain string.
  • leading (avatar or icon) and actions (buttons, menus) slots stay keyboard reachable with the arrow keys.
  • Multiple selection shows a checkbox in each row automatically.
Example source · show
import { Avatar } from '../avatar'
import { Badge } from '../badge'
import { Button } from '../button'
import { ListView, ListViewItem } from './list-view'

const members = [
  { id: 'maya', name: 'Maya Chen', email: 'maya@acme.com', role: 'Owner' },
  { id: 'charles', name: 'Charles Webb', email: 'charles@acme.com', role: 'Admin' },
  { id: 'ada', name: 'Ada Lovelace', email: 'ada@acme.com', role: 'Member' },
  { id: 'grace', name: 'Grace Hopper', email: 'grace@acme.com', role: 'Member' },
]

export const styles = {
  Selectable: () => (
    <ListView aria-label="Members" selectionMode="multiple" items={members} className="w-[26rem]">
      {(m) => (
        <ListViewItem id={m.id} textValue={m.name} description={m.email} leading={<Avatar size="sm" name={m.name} />} actions={<Badge>{m.role}</Badge>}>
          {m.name}
        </ListViewItem>
      )}
    </ListView>
  ),
  Actions: () => (
    <ListView aria-label="Integrations" items={members.slice(0, 3)} className="w-[26rem]" onAction={() => {}}>
      {(m) => (
        <ListViewItem id={m.id} textValue={m.name} description="Connected 2 days ago" actions={<Button size="sm" variant="outline">Manage</Button>}>
          {m.name.split(' ')[0]}'s workspace
        </ListViewItem>
      )}
    </ListView>
  ),
}

Source: packages/ui/src/list-view/list-view.tsx

Catalog

Category
collections
Priority
Core
Primitive
react-aria
React Aria
GridList