Expo UI and Router for iOSExpo SDK 57 and later, iOS only
Components

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.

import { Host, List, Section, Text } from '@expo/ui/swift-ui';

export default function BasicSectionExample() {
  return (
    <Host style={{ flex: 1 }}>
      <List>
        <Section title="Settings">
          <Text>General</Text>
          <Text>Privacy</Text>
          <Text>Notifications</Text>
        </Section>
      </List>
    </Host>
  );
}
A list with a Settings header above General, Privacy, and Notifications rows
A list with a Settings header above General, Privacy, and Notifications rows

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>
  );
}
A section with a location icon in its header, a toggle row, and footer text below
A section with a location icon in its header, a toggle row, and footer text below

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 sidebar style. 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>
  );
}
Two collapsed sections, Favorites and Recents, each with a disclosure chevron
Two collapsed sections, Favorites and Recents, each with a disclosure chevron

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>
  );
}
A form with Appearance, Notifications, and Account sections holding toggles, a picker, and a red Sign out button
A form with Appearance, Notifications, and Account sections holding toggles, a picker, and a red Sign out button

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.

Optional • Type: ReactNode

Sets a custom footer for the section.

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.

Needs care on Section

These modifiers work on Section, but not in the way that you may expect.

ModifierWhat to know
backgroundIt changes the whole section, not one row. For one row, put it on the view in the row.
paddingIt 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.

ModifierWhy nothing happens
layoutPriorityIt has an effect only when the view shares an axis with other views in a stack.
zIndexIt 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.

ModifierWhere it works
activityBackgroundTintWorks only in a Live Activity. It has no effect in the app.
alignmentGuideHas an effect only when the parent, such as a VStack or ZStack, aligns its children by the same guide.
containerBackgroundWorks only in a widget, or in a navigation container when you use a navigation placement.
glassEffectIdWorks 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.
gridCellColumnsWorks only on a view in a Grid.Row. Grid is in @expo/ui/swift-ui, but it has no Expo docs page.
gridCellUnsizedAxesWorks 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.
matchedGeometryEffectWorks only in a Namespace. Give two views the same id and change between them with an animation.
privacySensitiveHas an effect only when a parent view uses redacted with the privacy reason.
unredactedHas an effect only in a parent view that uses redacted.
widgetURLWorks only in a widget. It has no effect in the app.

Sources

The original Expo docs for this page:

On this page