Reference version

This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 53).

Expo UI

GitHub

npm

A set of components that allow you to build UIs directly with SwiftUI and Jetpack Compose from React.

Android
iOS

This library is currently in alpha and will frequently experience breaking changes. It is not available in the Expo Go app – use development builds to try it out.

@expo/ui is a set of native input components that allows you to build fully native interfaces with SwiftUI and Jetpack Compose. It aims to provide the commonly used features and components that a typical app will need.

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.

Swift UI examples

BottomSheet

import { BottomSheet } from '@expo/ui/swift-ui';

<BottomSheet isOpened={isOpened} onIsOpenedChange={e => setIsOpened(e)}>
  <Text>Hello, world!</Text>
</BottomSheet>

See also: official SwiftUI documentation

Button

import { Button } from '@expo/ui/swift-ui';

<Button
  style={{ flex: 1 }}
  variant="default"
  onPress={() => {
    setEditingProfile(true);
  }}>
  Edit profile
</Button>

See also: official SwiftUI documentation

CircularProgress

import { CircularProgress } from '@expo/ui/swift-ui';

<CircularProgress progress={0.5} style={{ width: 300 }} color="blue" />

See also: official SwiftUI documentation

ColorPicker

import { ColorPicker } from '@expo/ui/swift-ui';

<ColorPicker
  label="Select a color"
  selection={color}
  onValueChanged={setColor}
  style={{ width: 400, height: 200 }}
/>

See also: official SwiftUI documentation

ContextMenu

Note: Also known as DropdownMenu.

import { ContextMenu } from '@expo/ui/swift-ui';

<ContextMenu style={{ width: 150, height: 50 }}>
  <ContextMenu.Items>
    <Button
      systemImage="person.crop.circle.badge.xmark"
      onPress={() => console.log('Pressed1')}>
      Hello
    </Button>
    <Button
      variant="bordered"
      systemImage="heart"
      onPress={() => console.log('Pressed2')}>
      Love it
    </Button>
    <Picker
      label="Doggos"
      options={['very', 'veery', 'veeery', 'much']}
      variant="menu"
      selectedIndex={selectedIndex}
      onOptionSelected={({ nativeEvent: { index } }) => setSelectedIndex(index)}
    />
  </ContextMenu.Items>
  <ContextMenu.Trigger>
    <Button variant="bordered" style={{ width: 150, height: 50 }}>
      Show Menu
    </Button>
  </ContextMenu.Trigger>
</ContextMenu>

See also: official SwiftUI documentation

DateTimePicker (date)

import { DateTimePicker } from '@expo/ui/swift-ui';

<DateTimePicker
  onDateSelected={date => {
    setSelectedDate(date);
  }}
  displayedComponents='date'
  initialDate={selectedDate.toISOString()}
  variant='wheel'
/>

See also: official SwiftUI documentation

DateTimePicker (time)

import { DateTimePicker } from '@expo/ui/swift-ui';

<DateTimePicker
  onDateSelected={date => {
    setSelectedDate(date);
  }}
  displayedComponents='hourAndMinute'
  initialDate={selectedDate.toISOString()}
  variant='wheel'
/>

See also: official SwiftUI documentation

Gauge

import { Gauge } from "@expo/ui/swift-ui";

<Gauge
  max={{ value: 1, label: '1' }}
  min={{ value: 0, label: '0' }}
  current={{ value: 0.5 }}
  color={[
    PlatformColor('systemRed'),
    PlatformColor('systemOrange'),
    PlatformColor('systemYellow'),
    PlatformColor('systemGreen'),
  ]}
  type="circularCapacity"
/>

See also: official SwiftUI documentation

LinearProgress

import { LinearProgress } from '@expo/ui/swift-ui';

<LinearProgress progress={0.5} style={{ width: 300 }} color="red" />

See also: official SwiftUI documentation

List

import { List } from '@expo/ui/swift-ui';

<List
  scrollEnabled={false}
  editModeEnabled={editModeEnabled}
  onSelectionChange={(items) => alert(`indexes of selected items: ${items.join(', ')}`)}
  moveEnabled={moveEnabled}
  onMoveItem={(from, to) => alert(`moved item at index ${from} to index ${to}`)}
  onDeleteItem={(item) => alert(`deleted item at index: ${item}`)}
  style={{ flex: 1 }}
  listStyle='automatic'
  deleteEnabled={deleteEnabled}
  selectEnabled={selectEnabled}>
  {data.map((item, index) => (
    <LabelPrimitive key={index} title={item.text} systemImage={item.systemImage} color={color} />
  ))}
</List>

See also: official SwiftUI documentation

Picker (segmented)

import { Picker } from '@expo/ui/swift-ui';

<Picker
  options={['$', '$$', '$$$', '$$$$']}
  selectedIndex={selectedIndex}
  onOptionSelected={({ nativeEvent: { index } }) => {
    setSelectedIndex(index);
  }}
  variant="segmented"
/>

See also: official SwiftUI documentation

Picker (wheel)

import { Picker } from '@expo/ui/swift-ui';

<Picker
  options={['$', '$$', '$$$', '$$$$']}
  selectedIndex={selectedIndex}
  onOptionSelected={({ nativeEvent: { index } }) => {
    setSelectedIndex(index);
  }}
  variant="wheel"
  style={{
    height: 100,
  }}
/>

See also: official SwiftUI documentation

Slider

import { Slider } from '@expo/ui/swift-ui';

<Slider
  style={{ minHeight: 60 }}
  value={value}
  onValueChange={(value) => {
    setValue(value);
  }}
/>

See also: official SwiftUI documentation

Switch (toggle)

Note: Also known as Toggle.

import { Switch } from '@expo/ui/swift-ui';

<Switch
  checked={checked}
  onValueChange={checked => {
    setChecked(checked);
  }}
  color="#ff0000"
  label="Play music"
  variant="switch"
/>

See also: official SwiftUI documentation

Switch (checkbox)

import { Switch } from '@expo/ui/swift-ui';

<Switch
  checked={checked}
  onValueChange={checked => {
    setChecked(checked);
  }}
  label="Play music"
  variant="checkbox"
/>

See also: official SwiftUI documentation

TextInput

import { TextInput } from '@expo/ui/swift-ui';

<TextInput autocorrection={false} defaultValue="A single line text input" onChangeText={setValue} />

See also: official SwiftUI documentation

Jetpack Compose examples

Button

import { Button } from '@expo/ui/jetpack-compose';

<Button
  style={{ flex: 1 }}
  variant="default"
  onPress={() => {
    setEditingProfile(true);
  }}>
  Edit profile
</Button>

See also: official Jetpack Compose documentation

CircularProgress

import { CircularProgress } from '@expo/ui/jetpack-compose';

<CircularProgress progress={0.5} style={{ width: 300 }} color="blue" elementColors={{ trackColor: '#cccccc' }} />

See also: official Jetpack Compose documentation

ContextMenu

Note: Also known as DropdownMenu.

import { ContextMenu } from '@expo/ui/jetpack-compose';

<ContextMenu style={{ width: 150, height: 50 }}>
  <ContextMenu.Items>
    <Button
      elementColors={{ containerColor: '#0000ff', contentColor: '#00ff00' }}
      onPress={() => console.log('Pressed1')}>
      Hello
    </Button>
    <Button
      variant="bordered"
      color="#ff0000"
      onPress={() => console.log('Pressed2')}>
      Love it
    </Button>
    <Picker
      label="Doggos"
      options={['very', 'veery', 'veeery', 'much']}
      variant="menu"
      selectedIndex={selectedIndex}
      onOptionSelected={({ nativeEvent: { index } }) => setSelectedIndex(index)}
    />
  </ContextMenu.Items>
  <ContextMenu.Trigger>
    <Button variant="bordered" style={{ width: 150, height: 50 }}>
      Show Menu
    </Button>
  </ContextMenu.Trigger>
</ContextMenu>

See also: official Jetpack Compose documentation

DateTimePicker (date)

import { DateTimePicker } from '@expo/ui/jetpack-compose';

<DateTimePicker
  onDateSelected={date => {
    setSelectedDate(date);
  }}
  displayedComponents='date'
  initialDate={selectedDate.toISOString()}
  variant='picker'
/>

See also: official Jetpack Compose documentation

DateTimePicker (time)

import { DateTimePicker } from '@expo/ui/jetpack-compose';

<DateTimePicker
  onDateSelected={date => {
    setSelectedDate(date);
  }}
  displayedComponents='hourAndMinute'
  initialDate={selectedDate.toISOString()}
  variant='picker'
/>

See also: official Jetpack Compose documentation

LinearProgress

import { LinearProgress } from '@expo/ui/jetpack-compose';

<LinearProgress progress={0.5} style={{ width: 300 }} color="red" />

See also: official Jetpack Compose documentation

Picker (radio)

import { Picker } from '@expo/ui/jetpack-compose';

<Picker
  options={['$', '$$', '$$$', '$$$$']}
  selectedIndex={selectedIndex}
  onOptionSelected={({ nativeEvent: { index } }) => {
    setSelectedIndex(index);
  }}
  variant="radio"
/>

See also: official Jetpack Compose documentation

Picker (segmented)

import { Picker } from '@expo/ui/jetpack-compose';

<Picker
  options={['$', '$$', '$$$', '$$$$']}
  selectedIndex={selectedIndex}
  onOptionSelected={({ nativeEvent: { index } }) => {
    setSelectedIndex(index);
  }}
  variant="segmented"
/>

See also: official Jetpack Compose documentation

Slider

import { Slider } from '@expo/ui/jetpack-compose';

<Slider
  style={{ minHeight: 60 }}
  value={value}
  onValueChange={(value) => {
    setValue(value);
  }}
/>

See also: official Jetpack Compose documentation

Switch (toggle)

Note: also known as Toggle.

import { Switch } from '@expo/ui/jetpack-compose';

<Switch
  value={checked}
  onValueChange={checked => {
    setChecked(checked);
  }}
  color="#ff0000"
  label="Play music"
  variant="switch"
/>

See also: official Jetpack Compose documentation

Switch (checkbox)

import { Switch } from '@expo/ui/jetpack-compose';

<Switch
  value={checked}
  onValueChange={checked => {
    setChecked(checked);
  }}
  label="Play music"
  color="#ff0000"
  variant="checkbox"
/>

See also: official Jetpack Compose documentation

TextInput

import { TextInput } from '@expo/ui/jetpack-compose';

<TextInput autocorrection={false} defaultValue="A single line text input" onChangeText={setValue} />

See also: official Jetpack Compose documentation

API

Full documentation is not yet available. Use TypeScript types to explore the API.

// Import from the SwiftUI package
import { BottomSheet } from '@expo/ui/swift-ui';
// Import from the Jetpack Compose package
import { Button } from '@expo/ui/jetpack-compose';