Reference version

List

A virtualized vertical container of rows, paired with a tappable ListItem primitive.

Android
iOS
Web
Included in Expo Go
Bundled version:
~56.0.8

For the complete documentation index, see llms.txt. Use this file to discover all available pages.

List provides a virtualized vertical container of rows, typically populated with ListItem children. It provides the platform-native chrome (separators, inset styling, pull-to-refresh).ListItem is a tappable row with leading/trailing/supportingText slots.

Installation

Terminal
npx expo install @expo/ui

If you are installing this in an existing React Native app, make sure to install expo in your project.

Usage

Basic list

ListExample.tsx
import { useState } from 'react'; import { Host, List, ListItem, Text } from '@expo/ui'; const ITEMS = [ { id: 1, name: 'Avocado toast' }, { id: 2, name: 'Bagel with cream cheese' }, { id: 3, name: 'Cappuccino' }, ]; export default function ListExample() { const [selected, setSelected] = useState<string | null>(null); return ( <Host style={{ flex: 1 }}> <List> {ITEMS.map(item => ( <ListItem key={item.id} onPress={() => setSelected(item.name)}> {item.name} </ListItem> ))} </List> {selected != null && <Text>Selected: {selected}</Text>} </Host> ); }

Rows with slots

ListItem accepts leading, trailing, and supportingText shorthand props for the common case. Pass a ReactNode for any of them when richer content is needed.

ListItemSlotsExample.tsx
import { Host, Icon, List, ListItem } from '@expo/ui'; const CHEVRON = Icon.select({ ios: 'chevron.right', android: require('@expo/material-symbols/chevron_right.xml'), }); export default function ListItemSlotsExample() { return ( <Host style={{ flex: 1 }}> <List> <ListItem onPress={() => {}} trailing={<Icon name={CHEVRON} size={14} color="gray" />} supportingText="Secondary line below the headline"> Profile </ListItem> <ListItem onPress={() => {}} trailing={<Icon name={CHEVRON} size={14} color="gray" />}> Settings </ListItem> </List> </Host> ); }

Compound slot children

For full control over slot content, use the compound API: <ListItem.Leading>, <ListItem.Trailing>, and <ListItem.Supporting>. Anything not wrapped in a slot becomes the headline.

ListItemCompoundExample.tsx
import { Host, Icon, List, ListItem, Row, Text } from '@expo/ui'; export default function ListItemCompoundExample() { return ( <Host style={{ flex: 1 }}> <List> <ListItem onPress={() => {}}> <ListItem.Leading> <Icon name="star.fill" size={20} color="#FFD60A" /> </ListItem.Leading> <Row spacing={0}> <Text textStyle={{ color: 'gray' }}>{`#42: `}</Text> <Text>Composite headline</Text> </Row> <ListItem.Supporting>Richer slot content</ListItem.Supporting> </ListItem> </List> </Host> ); }

Pull-to-refresh

Pass an async onRefresh handler. The platform-native refresh indicator stays visible until the returned promise settles (resolves or rejects).

ListRefreshExample.tsx
import { useState } from 'react'; import { Host, List, ListItem } from '@expo/ui'; export default function ListRefreshExample() { const [items, setItems] = useState([1, 2, 3]); const handleRefresh = async () => { await new Promise(resolve => setTimeout(resolve, 1500)); setItems(prev => [Math.max(...prev) + 1, ...prev]); }; return ( <Host style={{ flex: 1 }}> <List onRefresh={handleRefresh}> {items.map(id => ( <ListItem key={id}>{`Item #${id}`}</ListItem> ))} </List> </Host> ); }

Pull-to-refresh is not implemented on web yet. The handler is accepted for API parity but the indicator only appears on Android and iOS.

API

import { List, ListItem } from '@expo/ui';

Component

List

Android
iOS
Web

Type: React.Element<ListProps>

A vertical container of rows. Typically populated with ListItem children.

Props for the List component. A virtualized vertical container of rows. Typically populated with ListItem children, though any node is accepted.

ListProps

children

Android
iOS
Web
Optional • Type: ReactNode

The list rows. Usually <ListItem> elements.

onRefresh

Android
iOS
Optional • Type: () => Promise<void>

Optional pull-to-refresh handler. When provided, the list shows the platform-native refresh affordance. The returned promise drives the indicator's visibility.

testID

Android
iOS
Web
Optional • Type: string

Identifier used to locate the component in end-to-end tests.

Components

ListItem

Android
iOS
Web

Type: React.Element<ListItemProps>

A tappable row in a list. Composes with List. Pass row content via the leading / trailing / supportingText shorthand props or the compound <ListItem.Leading> / <ListItem.Trailing> / <ListItem.Supporting> slot children.

Props for the ListItem component. A tappable row in a list.

ListItemProps

children

Android
iOS
Web
Optional • Type: ReactNode

Headline content of the row. The remaining (non-slot) children are rendered in the headline area.

leading

Android
iOS
Web
Optional • Type: ReactNode

Shorthand for the leading slot. Overridden by <ListItem.Leading> if both are provided.

onPress

Android
iOS
Web
Optional • Type: () => void

Tap handler. Activates over the entire row rectangle, including the empty gap between leading/headline/trailing.

supportingText

Android
iOS
Web
Optional • Type: ReactNode

Shorthand for the supporting (sub-)text slot. Strings are rendered with platform-appropriate secondary styling; pass a ReactNode for richer content. Overridden by <ListItem.Supporting> if both are provided.

testID

Android
iOS
Web
Optional • Type: string

Identifier used to locate the component in end-to-end tests.

trailing

Android
iOS
Web
Optional • Type: ReactNode

Shorthand for the trailing slot. Overridden by <ListItem.Trailing> if both are provided.

ListItem.Leading

Android
iOS
Web

Type: React.Element<FC<ListItemLeadingProps>>

Props for the ListItem.Leading slot marker.

ListItemLeadingProps

children

Android
iOS
Web
Optional • Type: ReactNode

Content rendered in the leading (start) slot.

ListItem.Supporting

Android
iOS
Web

Type: React.Element<FC<ListItemSupportingProps>>

Props for the ListItem.Supporting slot marker.

ListItemSupportingProps

children

Android
iOS
Web
Optional • Type: ReactNode

Content rendered below the headline.

ListItem.Trailing

Android
iOS
Web

Type: React.Element<FC<ListItemTrailingProps>>

Props for the ListItem.Trailing slot marker.

ListItemTrailingProps

children

Android
iOS
Web
Optional • Type: ReactNode

Content rendered in the trailing (end) slot.