Mosmox UI
Current version
GitHubnpmjs.com
Content & Media

List

Flexible lists with content slots, selection, links, and visual variants

List renders collections of related content with consistent spacing and accessible interaction. It supports simple data-driven items, custom row rendering, leading and trailing content, links, selection, headers, footers, and visual variants.

See the live List showcase.

Basic usage

import { List } from '@mosmox/ui';

const items = [
  { key: 'one', title: 'First item', description: 'Supporting information' },
  { key: 'two', title: 'Second item', description: 'More supporting information' },
];

<List items={items} />

Each item needs a stable key and title. description, content, leading, trailing, and meta are optional slots.

Complete data-driven item

Every slot accepts a ReactNode, so an item can contain text, icons, avatars, badges, links, or custom controls:

const projects = [
  {
    key: 'atlas',
    title: 'Project Atlas',
    description: 'Main product workspace',
    content: 'Last updated today at 10:42',
    leading: <Folder size={20} aria-hidden="true" />,
    trailing: <MoreHorizontal size={20} aria-label="More actions" />,
    meta: '12 files',
    href: '/projects/atlas',
    data: { status: 'active', ownerId: 42 },
  },
];

<List items={projects} variant="card" />

data is application data and is not rendered automatically. It is available to callbacks and custom renderers.

Variants and sizes

variant accepts plain, divided, bordered, or card. size accepts sm, default, or lg.

<List items={items} variant="divided" size="sm" />
<List items={items} variant="bordered" />
<List items={items} variant="card" size="lg" />

gap changes the spacing between the list shell sections and can be a number of pixels or a CSS length.

An item with href renders as an anchor. Use onItemClick for application actions. Interactive rows support keyboard activation with Enter and Space.

<List
  items={[
    { key: 'docs', title: 'Documentation', href: '/docs' },
    { key: 'settings', title: 'Settings' },
  ]}
  onItemClick={(item) => console.log(item.key)}
/>

Set disabled: true on an item to prevent interaction and reduce its emphasis.

Selection

selectionMode can be none, single, or multiple. Controlled selection uses selectedKeys; uncontrolled selection starts from defaultSelectedKeys. onSelectionChange receives the next keys and the item that caused the change.

<List
  items={items}
  selectionMode="multiple"
  selectedKeys={selectedKeys}
  onSelectionChange={(keys) => setSelectedKeys(keys)}
  variant="bordered"
/>

Custom row rendering

Use renderItem when the standard slots are not enough. The renderer receives the item and its current state.

<List
  items={items}
  renderItem={(item, state) => (
    <>
      <strong>{state.selected ? 'Selected: ' : ''}{item.title}</strong>
      <span>{item.description}</span>
    </>
  )}
/>

The custom renderer replaces the default row content, but the List still supplies selection state, focus behavior, and row semantics.

Fully custom content

Use children when the rows do not fit the ListItem structure at all. In this mode, children takes precedence over items and you own the markup inside the list container:

<List variant="card">
  <div className="custom-row">
    <strong>Custom heading</strong>
    <span>Any React structure can be placed here.</span>
    <button type="button">Action</button>
  </div>
  <div className="custom-row">
    <img src="/avatar.png" alt="" />
    <span>Avatar, controls, and layout are fully custom.</span>
  </div>
</List>

Use renderItem instead when you want custom markup while keeping built-in row selection, keyboard behavior, links, and disabled states.

<List
  header="Recent activity"
  items={items}
  footer={<button type="button">View all</button>}
/>

ConfigProvider

Configure defaults for a subtree with components.list. Local props override provider values.

<ConfigProvider components={{ list: { variant: 'card', size: 'sm', gap: '12px' } }}>
  <List items={items} />
</ConfigProvider>
SettingTypeDefaultDescription
gapstring8pxSpacing between header, rows, and footer.
sizesm | default | lgdefaultDefault row density.
variantplain | divided | bordered | cardplainDefault list treatment.

Local size, variant, and gap props take precedence over the provider defaults.

Built-in behavior and boundaries

List renders the records supplied to it. It does not provide pagination, an internal scroll area, infinite scroll, sorting, filtering, search, or virtualization. For large collections, paginate or window the data in the parent component and pass the visible records to items.

API Reference

List props

PropTypeDefaultDescription
itemsListItem<T>[][]Data-driven rows.
childrenReactNode—Custom list content; takes precedence over items.
renderItem(item, state) => ReactNode—Replaces default row content while preserving List row behavior. state contains selected, disabled, and index.
headerReactNode—Content above rows.
footerReactNode—Content below rows.
sizesm | default | lgdefaultRow density.
variantplain | divided | bordered | cardplainVisual treatment.
selectionModenone | single | multiplenoneEnables keyboard and pointer selection.
selectedKeysstring[]—Controlled selected keys.
defaultSelectedKeysstring[][]Initial uncontrolled selection.
onSelectionChange(keys, item?) => void—Selection callback.
onItemClick(item, index) => void—Row activation callback.
gapnumber | stringprovider value or 8pxLocal spacing override; numbers are converted to pixels.

ListItem fields

FieldTypeDescription
keystringStable unique row key.
titleReactNodePrimary row content.
descriptionReactNodeSupporting text.
contentReactNodeAdditional body content.
leadingReactNodeIcon, Avatar, or other leading visual.
trailingReactNodeAction or status at the end of the row.
metaReactNodeCompact metadata before trailing content.
hrefstringMakes the row an anchor.
disabledbooleanPrevents interaction.
dataTApplication data associated with the row; not rendered automatically.

All standard HTMLAttributes<HTMLDivElement> are supported on the List root.

Accessibility

Selection mode uses a listbox root and option rows with aria-selected. Interactive rows are keyboard accessible. Links remain native anchors, preserving browser navigation and expected link semantics.