Section
A SwiftUI Section component for grouping content within lists and forms.
Expo UI Section matches the official SwiftUI Section API and is used to group related content within List, Form or Picker components.
Usage
Basic section with title
Use the title prop for simple sections with a text header.

Section with custom header and footer
Use the header and footer props for custom views. These props are only used when title is not provided.
import {
Host,
List,
Section,
Toggle,
Text,
HStack,
Image,
} from '@expo/ui/swift-ui';
import { useState } from 'react';
export default function CustomHeaderFooterExample() {
const [locationEnabled, setLocationEnabled] = useState(false);
return (
<Host style={{ flex: 1 }}>
<List>
<Section
header={
<HStack>
<Image
systemName="location.fill"
color="blue"
size={16}
/>
<Text>Location Services</Text>
</HStack>
}
footer={
<Text>
Enabling location services allows the app to provide
personalized recommendations.
</Text>
}>
<Toggle
label="Enable location"
isOn={locationEnabled}
onIsOnChange={setLocationEnabled}
/>
</Section>
</List>
</Host>
);
}
Collapsible section
Use the isExpanded prop to control whether the section is expanded or collapsed. When provided, the section becomes collapsible. Use onIsExpandedChange to handle state changes.
Note: Collapsible sections require iOS 17+ and tvOS 17+, and the list must use the
sidebarstyle. Footer is not supported for collapsible sections.
import { useState } from 'react';
import { Host, List, Section, Text } from '@expo/ui/swift-ui';
import { listStyle } from '@expo/ui/swift-ui/modifiers';
export default function CollapsibleSectionExample() {
const [favoritesExpanded, setFavoritesExpanded] = useState(false);
const [recentsExpanded, setRecentsExpanded] = useState(false);
return (
<Host style={{ flex: 1 }}>
<List modifiers={[listStyle('sidebar')]}>
<Section
title="Favorites"
isExpanded={favoritesExpanded}
onIsExpandedChange={setFavoritesExpanded}>
<Text>Home</Text>
<Text>Work</Text>
<Text>Gym</Text>
</Section>
<Section
title="Recents"
isExpanded={recentsExpanded}
onIsExpandedChange={setRecentsExpanded}>
<Text>Coffee Shop</Text>
<Text>Library</Text>
<Text>Park</Text>
</Section>
</List>
</Host>
);
}
Multiple sections in a form
Sections work within Form components to organize form controls into logical groups.
import { useState } from 'react';
import {
Host,
Form,
Section,
Toggle,
Picker,
Text,
Button,
} from '@expo/ui/swift-ui';
import { pickerStyle, tag } from '@expo/ui/swift-ui/modifiers';
export default function FormSectionsExample() {
const [darkMode, setDarkMode] = useState(false);
const [notifications, setNotifications] = useState(true);
const [language, setLanguage] = useState(0);
const languages = ['English', 'Spanish', 'French', 'German'];
return (
<Host style={{ flex: 1 }}>
<Form>
<Section title="Appearance">
<Toggle
label="Dark Mode"
isOn={darkMode}
onIsOnChange={setDarkMode}
/>
<Picker
label="Language"
selection={language}
onSelectionChange={setLanguage}
modifiers={[pickerStyle('menu')]}>
{languages.map((lang, index) => (
<Text key={index} modifiers={[tag(index)]}>
{lang}
</Text>
))}
</Picker>
</Section>
<Section title="Notifications">
<Toggle
label="Push Notifications"
isOn={notifications}
onIsOnChange={setNotifications}
/>
</Section>
<Section title="Account">
<Button
label="Sign out"
role="destructive"
onPress={() => alert('Signed out')}
/>
</Section>
</Form>
</Host>
);
}
API
import { Section } from '@expo/ui/swift-ui';Component
Section
Type: React.Element<SectionProps>
Section component uses the native Section component.
SectionProps
children
Type: ReactNode
The content of the section.
footer
Optional • Type: ReactNode
Sets a custom footer for the section.
header
Optional • Type: ReactNode
Sets a custom header for the section.
isExpanded
iOS 17+Optional • Type: boolean
Controls whether the section is expanded or collapsed. When provided, the section becomes collapsible.
Note: Available only when the list style is set to
sidebar.
onIsExpandedChange
iOS 17+Optional • Type: (isExpanded: boolean) => void
Callback triggered when the section's expanded state changes.
title
Optional • Type: string
The title of the section.
Inherited props
Modifiers
Use these modifiers in the modifiers prop of the SwiftUI version.
Expo UI lets you put any of the 89 modifiers for any view on Section, but not all of them do something here.
- 74 change what you see on Section.
- 2 work, but not in the way that you may expect.
- 2 have no visible effect on Section.
- 13 work only in one place, such as a widget or a
Grid.
Where the modifiers go
modifiers apply to the whole section. To change one row, put the modifiers on the view in that row.
Best modifiers for Section
These modifiers are made for Section, or they are the ones that you use most with it.
Also works on Section
Section takes these modifiers too, and each one works in the usual way.
accessibilityAddTraitsaccessibilityElementaccessibilityHiddenaccessibilityHintaccessibilityIdentifieraccessibilityInputLabelsaccessibilityLabelaccessibilityRemoveTraitsaccessibilityValueallowsTighteninganimationaspectRatiobackgroundOverlayblurboldborderbrightnessclippedclipShapecolorInvertcontainerRelativeFrameiOS 17+containerShapecontentShapecontentTransitioniOS 16+contrastcornerRadiusdisableddynamicTypeSizeenvironmentfixedSizeforegroundColorframegeometryGroupiOS 17+glassEffectgrayscalehiddenhueRotationidignoreSafeAreaimageScaleitalickerninglineHeightiOS 26+lineLimitlineSpacingluminanceToAlphamaskminimumScaleFactormonospacedDigitmultilineTextAlignmentoffsetonAppearonDisappearonGeometryChangeonLongPressGestureonTapGestureopacityoverlayredactedrotation3DEffectrotationEffectsaturationscaleEffectshadowstrikethroughstrokeBordertextCasetinttruncationModeunderline
Needs care on Section
These modifiers work on Section, but not in the way that you may expect.
| Modifier | What to know |
|---|---|
background | It changes the whole section, not one row. For one row, put it on the view in the row. |
padding | It changes the whole section, not one row. For one row, put it on the view in the row. |
No visible effect on Section
Section accepts these modifiers, but you see no change. They do not give an error.
| Modifier | Why nothing happens |
|---|---|
layoutPriority | It has an effect only when the view shares an axis with other views in a stack. |
zIndex | It changes the order of views that cover each other in the same parent, and Section does not stack its children. |
Only in some places
These modifiers work only in a widget, in a Grid, in a Namespace or in a parent that asks for them.
| Modifier | Where it works |
|---|---|
activityBackgroundTint | Works only in a Live Activity. It has no effect in the app. |
alignmentGuide | Has an effect only when the parent, such as a VStack or ZStack, aligns its children by the same guide. |
containerBackground | Works only in a widget, or in a navigation container when you use a navigation placement. |
glassEffectId | Works only on a view that also has glassEffect, in a GlassEffectContainer and a Namespace. |
gridCellAnchor iOS 16+ | Works only on a cell of a Grid. Grid is in @expo/ui/swift-ui, but it has no Expo docs page. |
gridCellColumns | Works only on a view in a Grid.Row. Grid is in @expo/ui/swift-ui, but it has no Expo docs page. |
gridCellUnsizedAxes | Works only on a view in a Grid. Grid is in @expo/ui/swift-ui, but it has no Expo docs page. |
gridColumnAlignment iOS 16+ | Works only on a view in a Grid.Row. Grid is in @expo/ui/swift-ui, but it has no Expo docs page. |
invalidatableContent iOS 17+ | Has an effect only when a parent view uses redacted with the invalidated reason. |
matchedGeometryEffect | Works only in a Namespace. Give two views the same id and change between them with an animation. |
privacySensitive | Has an effect only when a parent view uses redacted with the privacy reason. |
unredacted | Has an effect only in a parent view that uses redacted. |
widgetURL | Works only in a widget. It has no effect in the app. |
Sources
The original Expo docs for this page:
- Section (SwiftUI) (
source-of-truth/versions/v57.0.0/sdk/ui/swift-ui/section.md)



