List
A SwiftUI List component for displaying scrollable lists of items.
For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.
Expo UI List matches the official SwiftUI List API and supports styling via the listStyle modifier, various row/section modifiers, as well as selection, reordering, and editing capabilities.
Installation
- npx expo install @expo/uiIf you are installing this in an existing React Native app, make sure to install expo in your project.
Usage
Basic list
import { Host, List, Text, Section } from '@expo/ui/swift-ui'; export default function BasicListExample() { return ( <Host style={{ flex: 1 }}> <List> <Section title="Fruits"> <Text>Apple</Text> <Text>Banana</Text> <Text>Orange</Text> </Section> <Section title="Vegetables"> <Text>Carrot</Text> <Text>Broccoli</Text> <Text>Spinach</Text> </Section> </List> </Host> ); }
List with labels and icons
import { Host, List, Label, Section } from '@expo/ui/swift-ui'; export default function ListWithLabelsExample() { return ( <Host style={{ flex: 1 }}> <List> <Section title="Settings"> <Label title="Wi-Fi" systemImage="wifi" /> <Label title="Bluetooth" systemImage="antenna.radiowaves.left.and.right" /> <Label title="Cellular" systemImage="antenna.radiowaves.left.and.right.circle" /> </Section> </List> </Host> ); }
List styles
Use the listStyle modifier to change the list's appearance.
Note: The
inset,insetGrouped, andsidebarstyles are not available on tvOS.
import { useState } from 'react'; import { Host, List, Text, Section, Picker } from '@expo/ui/swift-ui'; import { listStyle, pickerStyle, tag } from '@expo/ui/swift-ui/modifiers'; const styles = ['automatic', 'plain', 'inset', 'insetGrouped', 'grouped', 'sidebar'] as const; export default function ListStylesExample() { const [styleIndex, setStyleIndex] = useState(0); return ( <Host style={{ flex: 1 }}> <List modifiers={[listStyle(styles[styleIndex])]}> <Section title="Style Picker"> <Picker label="List Style" selection={styleIndex} onSelectionChange={setStyleIndex} modifiers={[pickerStyle('menu')]}> {styles.map((style, index) => ( <Text key={style} modifiers={[tag(index)]}> {style} </Text> ))} </Picker> </Section> <Section title="Sample Items"> <Text>Item 1</Text> <Text>Item 2</Text> <Text>Item 3</Text> </Section> </List> </Host> ); }
Selection and edit mode
Enable selection, deletion, and reordering of list items using the List.ForEach compound component with onDelete and onMove props.
- Use the
environmentmodifier to enable edit mode - Use the
tagmodifier to identify items - Use the
selectionprop to control selected items - Use
moveDisabledanddeleteDisabledmodifiers to disable these actions on individual items
import { useState } from 'react'; import { Host, List, Label, Section, Button, Toggle } from '@expo/ui/swift-ui'; import { environment, tag } from '@expo/ui/swift-ui/modifiers'; type Task = { id: string; title: string }; const INITIAL_TASKS: Task[] = [ { id: '1', title: 'Task 1' }, { id: '2', title: 'Task 2' }, { id: '3', title: 'Task 3' }, { id: '4', title: 'Task 4' }, ]; export default function EditableListExample() { const [tasks, setTasks] = useState<Task[]>(INITIAL_TASKS); const [selectedIds, setSelectedIds] = useState<string[]>([]); const [editMode, setEditMode] = useState(false); const handleDelete = (indices: number[]) => { setTasks(prev => prev.filter((_, i) => !indices.includes(i))); }; const handleMove = (sourceIndices: number[], destination: number) => { setTasks(prev => { const newTasks = [...prev]; const [removed] = newTasks.splice(sourceIndices[0], 1); const adjustedDest = sourceIndices[0] < destination ? destination - 1 : destination; newTasks.splice(adjustedDest, 0, removed); return newTasks; }); }; return ( <Host style={{ flex: 1 }}> <List selection={selectedIds} onSelectionChange={ids => setSelectedIds(ids.map(String))} modifiers={[environment('editMode', editMode ? 'active' : 'inactive')]}> <Section title="Settings"> <Toggle label="Edit Mode" isOn={editMode} onIsOnChange={setEditMode} /> </Section> <Section title="Tasks"> <List.ForEach onDelete={handleDelete} onMove={handleMove}> {tasks.map(task => ( <Label key={task.id} title={task.title} modifiers={[tag(task.id)]} /> ))} </List.ForEach> </Section> </List> </Host> ); }
Pull to refresh
Use the refreshable modifier to enable pull-to-refresh functionality.
import { useState } from 'react'; import { Host, List, Text, Section } from '@expo/ui/swift-ui'; import { refreshable } from '@expo/ui/swift-ui/modifiers'; export default function RefreshableListExample() { const [lastRefresh, setLastRefresh] = useState<Date | null>(null); const handleRefresh = async () => { // Simulate async data fetching await new Promise(resolve => setTimeout(resolve, 1500)); setLastRefresh(new Date()); }; return ( <Host style={{ flex: 1 }}> <List modifiers={[refreshable(handleRefresh)]}> <Section title="Data"> <Text>Pull down to refresh</Text> {lastRefresh && <Text>Last refresh: {lastRefresh.toLocaleTimeString()}</Text>} </Section> </List> </Host> ); }
Row styling
Use listRowBackground, listRowSeparator, and listRowInsets modifiers to customize individual rows.
import { Host, List, Text, Section } from '@expo/ui/swift-ui'; import { listRowBackground, listRowSeparator, listRowInsets } from '@expo/ui/swift-ui/modifiers'; export default function RowStylingExample() { return ( <Host style={{ flex: 1 }}> <List> <Section title="Styled Rows"> <Text modifiers={[listRowBackground('blue')]}>Blue background</Text> <Text modifiers={[listRowSeparator('hidden')]}>Hidden separator</Text> <Text modifiers={[listRowInsets({ leading: 40 })]}>Extra leading inset</Text> <Text modifiers={[listRowInsets({ leading: 0, trailing: 0 })]}>No horizontal insets</Text> </Section> </List> </Host> ); }
Keyboard dismiss behavior
Use the scrollDismissesKeyboard modifier to control how the keyboard is dismissed when scrolling.
import { Host, List, Section, TextField } from '@expo/ui/swift-ui'; import { scrollDismissesKeyboard } from '@expo/ui/swift-ui/modifiers'; export default function KeyboardDismissExample() { return ( <Host style={{ flex: 1 }}> <List modifiers={[scrollDismissesKeyboard('interactively')]}> <Section title="Form"> <TextField placeholder="Name" /> <TextField placeholder="Email" /> <TextField placeholder="Phone" /> </Section> </List> </Host> ); }
Header prominence
Use the headerProminence modifier to adjust the visual prominence of section headers.
import { Host, List, Text, Section } from '@expo/ui/swift-ui'; import { headerProminence } from '@expo/ui/swift-ui/modifiers'; export default function HeaderProminenceExample() { return ( <Host style={{ flex: 1 }}> <List modifiers={[headerProminence('increased')]}> <Section title="Important Section"> <Text>This section has increased header prominence</Text> </Section> <Section title="Another Section"> <Text>Headers are more prominent</Text> </Section> </List> </Host> ); }
API
import { List } from '@expo/ui/swift-ui';
Components
Type: React.Element<ListProps>
A list component that renders its children using a native SwiftUI List.
Type: React.Element<ListForEachProps>
A compound component of List that enables item deletion and reordering.
This component must be used as a child of List (as List.ForEach).
(indices: number[]) => voidCallback triggered when items are deleted. Receives an array of indices that were deleted.
See: Official SwiftUI documentation.
(sourceIndices: number[], destination: number) => voidCallback triggered when items are moved. Receives the source indices and destination index.
See: Official SwiftUI documentation.