This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 52).
A set of platform components to build native-feeling UIs.
@expo/ui
is a set of native input components that allows you to build fully native interfaces with SwiftUI and Jetpack Compose.
This library is currently in alpha and subject to breaking changes. It is unavailable in the Expo Go app, and you should use development builds.
Installation
-Â
npx expo install @expo/ui
If you are installing this in an existing React Native app, make sure to install expo
in your project.
Examples
BottomSheet component
import { BottomSheet } from '@expo/ui/BottomSheet';
<BottomSheet isOpen={isOpen} onIsOpenedChange={e => setIsOpened(e)}>
<Text>Hello, world!</Text>
</BottomSheet>
Button component
import { Button } from '@expo/ui/Button';
<Button
style={{ flex: 1 }}
onPress={() => {
setEditingProfile(true);
}}>
Edit profile
</Button>
ColorPicker component
import { ColorPicker } from '@expo/ui/ColorPicker';
<ColorPicker
label="Select a color"
selection={color}
onValueChanged={setColor}
style={{ width: 400, height: 200 }}
/>
DateTimePicker component (date variant)
import { DateTimePicker } from '@expo/ui/DateTimePicker';
<DateTimePicker
onDateSelected={date => {
setSelectedDate(date);
}}
displayedComponents='date'
initialDate={selectedDate.toISOString()}
iosVariant='wheel'
androidVariant='picker'
/>
Gauge component
import { Gauge } from "@expo/ui/Gauge";
<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="circular"
/>
LinearProgress component
import { LinearProgress } from '@expo/ui/LinearProgress';
<LinearProgress progress={0.5} style={{ width: 300 }} />
Picker component (segmented variant)
import { Picker } from '@expo/ui/Picker';
<Picker
options={['$', '$$', '$$$', '$$$$']}
selectedIndex={selectedIndex}
onOptionSelected={({ nativeEvent: { index } }) => {
setSelectedIndex(index);
}}
/>
Picker component (wheel variant) (iOS only)
import { Picker } from '@expo/ui/Picker';
<Picker
options={['$', '$$', '$$$', '$$$$']}
selectedIndex={selectedIndex}
onOptionSelected={({ nativeEvent: { index } }) => {
setSelectedIndex(index);
}}
variant="wheel"
style={{
height: 100,
}}
/>
Switch component
import { Switch } from '@expo/ui/Switch';
<Switch
checked={checked}
onValueChange={checked => {
setChecked(checked);
}}
label="Play music"
/>
Switch component (checkbox variant)
import { Switch } from '@expo/ui/Switch';
<Switch
checked={checked}
onValueChange={checked => {
setChecked(checked);
}}
label="Play music"
variant="checkbox"
/>
TextInput component
import { TextInput } from '@expo/ui/TextInput';
<TextInput autocorrection={false} defaultValue="A single line text input" onChangeText={setValue} />
Components
Type: React.Element<BottomSheetProps>
Renders a native BottomSheet
component.
(isOpened: boolean) => void
Callback function that is called when the BottomSheet
is opened.
StyleProp<ViewStyle>
Optional styles to apply to the BottomSheet
component.
Type: React.Element<ButtonProps>
Displays a native button component.
() => void
A callback that is called when the button is pressed.
{
android: MaterialIcon,
ios: string
}
A string describing the system image to display in the button. Uses Material Icons on Android and SF Symbols on iOS.
Type: React.Element<CircularProgressProps>
Renders a CircularProgress
component.
The current progress value of the slider. This is a number between 0
and 1
.
Acceptable values are: number
| null
Type: React.Element<ColorPickerProps>
Renders a ColorPicker
component using SwiftUI.
(value: string) => void
Callback function that is called when a new color is selected.
The currently selected color in the format #RRGGBB
or #RRGGBBAA
.
Acceptable values are: string
| null
StyleProp<ViewStyle>
Optional style to apply to the ColorPicker
component.
Type: React.Element<ContextMenuProps>
ContextMenu
allows you to create a context menu, which can be used to provide additional options to the user.
There are some platform-specific differences in the behavior of the context menu:
- On Android, the expansion of the context menu is controlled by the
expanded
prop. iOS, does not allow for manual control of the expansion state. - On iOS, the context menu can be triggered by a single press or a long press. The
activationMethod
prop allows you to choose between these two options. - Android does not support nesting in the context menu. All the submenus will be flat-mapped into a single level with multiple sections. The
title
prop of theButton
, which opens the submenu on iOS will be used as a section title. - Android does not support showing a
Picker
element in the context menu.
ActivationMethod
Determines how the context menu will be activated.
ReactNode
The contents of the submenu are used as an anchor for the context menu. The children will be wrapped in a pressable element, which triggers opening of the context menu.
StyleProp<ViewStyle>
Optional styles to apply to the ContextMenu
.
Type: React.Element<DateTimePickerProps>
Renders a DateTimePicker
component.
AndroidVariant
 • Default: 'picker'
The variant of the picker, which determines its appearance and behavior.
DisplayedComponents
 • Default: 'date'
The components that the picker should display.
On Android, you can have a picker that selects just the date or just the time.
dateAndTime
is only available on iOS and will result in a date picker on Android.
On iOS, you can have a picker that selects both date and time.
The initial date to display on the picker.
Acceptable values are: string
| null
IOSVariant
 • Default: 'automatic'
The variant of the picker, which determines its appearance and behavior.
boolean
 • Default: true
Determines what format the clock should be displayed in on Android.
(date: Date) => void
Callback function that is called when a date is selected.
boolean
 • Default: true
Show to button to toggle between variants on Android.
Type: React.Element<GaugeProps>
Renders a native Gauge
component.
Color (or array of colors for gradient) of the Gauge
.
Acceptable values are: ColorValue
| ColorValue[]
Type: React.Element<{
children: ReactNode
}>
Items visible inside the context menu. Pass input components as immidiate children of the tag.
Button
, Switch
and Submenu
components are supported on both Android and iOS.
The Picker
component is supported only on iOS. Remember to use components from the @expo/ui
library.
Type: React.Element<LabelProps>
Type: React.Element<LinearProgressProps>
Renders a LinearProgress
component.
The current progress value of the slider. This is a number between 0
and 1
.
Acceptable values are: number
| null
Type: React.Element<ListProps>
A list component that renders its children using a native SwiftUI list.
boolean
 • Default: false
Allows the deletion of list items.
ListStyle
 • Default: 'automatic'
One of the predefined ListStyle types in SwiftUI.
boolean
 • Default: false
Enables reordering of list items.
(index: number) => void
Callback triggered when an item is deleted from the list.
(from: number, to: number) => void
Callback triggered when an item is moved in the list.
(selection: number[]) => void
Callback triggered when the selection changes in a list.
boolean
 • Default: true
Makes the list scrollable.
boolean
 • Default: false
Allows the selection of list items.
StyleProp<ViewStyle>
Custom style for the container wrapping the list.
Type: React.Element<PickerProps>
Displays a native picker component. Depending on the variant it can be a segmented button, an inline picker, a list of choices or a radio button.
string
Picker color. On iOS it only applies to the 'menu'
variant.
string
A label displayed on the picker when in 'menu'
variant inside a form section on iOS.
(event: {
nativeEvent: {
index: number,
label: string
}
}) => void
Callback function that is called when an option is selected.
The index of the currently selected option.
Acceptable values are: number
| null
StyleProp<ViewStyle>
Optional style to apply to the picker component.
string
 • Default: 'segmented'
The variant of the picker, which determines its appearance and behavior.
The 'wheel'
, 'inline'
, 'palette'
and 'menu'
variants are iOS only, the 'radio'
variant is Android only. The 'inline'
variant can only be used inside sections or lists. The 'palette'
variant displays differently inside menus.
Acceptable values are: 'wheel'
| 'segmented'
| 'menu'
| 'radio'
| 'inline'
| 'palette'
Type: React.Element<SectionProps>
Section component uses the native Section component. It has no intrinsic dimensions, so it needs explicit height or flex set to display content (like ScrollView).
StyleProp<ViewStyle>
Type: React.Element<SliderProps>
number
 • Default: 1
The maximum value of the slider. Updating this value does not trigger callbacks if the current value is above max
.
number
 • Default: 0
The minimum value of the slider. Updating this value does not trigger callbacks if the current value is below min
.
(value: number) => void
Callback triggered on dragging along the slider.
number
 • Default: 0
The number of steps between the minimum and maximum values, 0
signifies infinite steps.
Type: React.Element<SubmenuProps>
The Submenu
component is used to create a nested context menu. Submenus can be infinitely nested.
Android does not support nesting in the context menu. All the submenus will be flat-mapped into a single level with multiple titled sections.
ReactElement<ButtonProps>
The button that will be used to expand the submenu. On Android the text
prop of the Button
will be used as a section title.
ReactNode
Children of the submenu. Only Button
, Switch
, Picker
and Submenu
elements should be used.
Type: React.Element<SwitchProps>
string
Picker color. On iOS, it only applies to the menu
variant.
string
Label for the switch.
On Android, the label has an effect only when the
Switch
is used inside aContextMenu
.
(value: boolean) => void
Callback function that is called when the checked state changes.
Type: React.Element<TextInputProps>
Renders a TextInput
component.
boolean
 • Default: true
If true, autocorrection is enabled.
string
Initial value that the TextInput displays when being mounted. As the TextInput is an uncontrolled component, change the key prop if you need to change the text value.
string
 • Default: default
Determines which keyboard to open. For example, 'numeric'
.
Types that work on both platforms:
- default
- numeric
- email-address
- phone-pad
- decimal-pad
- ascii-capable
- url
Types that only work on Android:
- password
- password-numeric
Types that only work on iOS:
- numbers-and-punctuation
- name-phone-pad
- web-search
- ascii-capable-number-pad
Acceptable values are: 'default'
| 'email-address'
| 'numeric'
| 'phone-pad'
| 'ascii-capable'
| 'numbers-and-punctuation'
| 'url'
| 'name-phone-pad'
| 'decimal-pad'
| 'twitter'
| 'web-search'
| 'ascii-capable-number-pad'
boolean
If true, the text input can be multiple lines. While the content will wrap, there's no keyboard button to insert a new line.
number
 • Default: undefined, which means unlimited lines.
The number of lines to display when multiline
is set to true.
If the number of lines in the view is above this number, the view scrolls.
(value: string) => void
A callback triggered when user types in text into the TextInput.
StyleProp<ViewStyle>
Additional styles to apply to the TextInput.
Type: React.Element<{
children: ReactNode
}>
The component visible all the time that triggers the menu when tapped or long-pressed.
Types
Literal Type: string
Activation method of the context menu.
singlePress
: The context menu is opened with a single tap. Does not isolate the content.longPress
: The context menu is opened with a long press. On iOS additionally Highlights the content by blurring the background.
Acceptable values are: 'singlePress'
| 'longPress'
Colors for button's core elements.
Property | Type | Description |
---|---|---|
containerColor(optional) | string | - |
contentColor(optional) | string | - |
disabledContainerColor(optional) | string | - |
disabledContentColor(optional) | string | - |
Literal Type: string
The role of the button.
default
- The default button role.cancel
- A button that cancels the current operation.destructive
- A button that deletes data or performs a destructive action.
Acceptable values are: 'default'
| 'cancel'
| 'destructive'
Literal Type: string
The built-in button styles available on iOS and Android.
Common styles:
default
- The default system button style.bordered
- A button with a light fill. On Android, equivalent toFilledTonalButton
.borderless
- A button with no background or border. On Android, equivalent toTextButton
.
Android-only styles:
outlined
- A button with an outline.elevated
- A filled button with a shadow.
Apple-only styles:
borderedProminent
- A bordered button with a prominent appearance.plain
- A button with no border or background and a less prominent text. macOS-only styles:accessoryBar
- A button style for accessory bars.accessoryBarAction
- A button style for accessory bar actions.card
- A button style for cards.link
- A button style for links.
Acceptable values are: 'default'
| 'bordered'
| 'plain'
| 'borderedProminent'
| 'borderless'
| 'accessoryBar'
| 'accessoryBarAction'
| 'card'
| 'link'
| 'outlined'
| 'elevated'
Literal Type: string
Acceptable values are: 'date'
| 'hourAndMinute'
| 'dateAndTime'
Literal Type: string
The type of Gauge
.
Acceptable values are: 'default'
| 'circular'
| 'circularCapacity'
| 'linear'
| 'linearCapacity'
Literal Type: string
Acceptable values are: 'wheel'
| 'automatic'
| 'graphical'
| 'compact'
Literal Type: string
Acceptable values are: 'automatic'
| 'plain'
| 'inset'
| 'insetGrouped'
| 'grouped'
| 'sidebar'
Colors for picker's core elements.
Property | Type | Description |
---|---|---|
activeBorderColor(optional) | string | - |
activeContainerColor(optional) | string | - |
activeContentColor(optional) | string | - |
disabledActiveBorderColor(optional) | string | - |
disabledActiveContainerColor(optional) | string | - |
disabledActiveContentColor(optional) | string | - |
disabledInactiveBorderColor(optional) | string | - |
disabledInactiveContainerColor(optional) | string | - |
disabledInactiveContentColor(optional) | string | - |
inactiveBorderColor(optional) | string | - |
inactiveContainerColor(optional) | string | - |
inactiveContentColor(optional) | string | - |
Property | Type | Description |
---|---|---|
trackColor(optional) | ColorValue | Only for:  Android Track color. |
Colors for slider's core elements.
Property | Type | Description |
---|---|---|
activeTickColor(optional) | string | - |
activeTrackColor(optional) | string | - |
inactiveTickColor(optional) | string | - |
inactiveTrackColor(optional) | string | - |
thumbColor(optional) | string | - |
Value options for the Gauge
component.
Property | Type | Description |
---|---|---|
color(optional) | ColorValue | Color of the label. |
label(optional) | string | Label of the element. |
value | number | Value of the element. |