The possibilities of the RNN layout API are wide open in terms of what you can construct with it: stacks, tabs and drawers in many combinations.
You can compose arbitrary native layout hierarchies (although some weird edge cases may not be possible or produce errors). In such cases, open an issue so that we either fix it or warn in dev time.
Component layout holds a single react component.
const component = {
id: 'component1', // Optional, Auto generated if empty
name: 'Your registered component name',
options: {},
passProps: {
text: 'This text will be available in your component.props'
}
}
Support children layouts of any kind. A stack can be initialised with more than one screen, in which case the last screen will be presented at the top of the stack.
const stack = {
children: [
{
component: {}
},
{
component: {}
}
],
options: {}
}
const bottomTabs = {
children: [
{
stack: {
children: [],
options: {
bottomTab: {
text: 'Tab 1',
icon: require('../images/one.png')
}
}
}
},
{
component: {
name: 'secondTabScreen',
options: {
bottomTab: {
text: 'Tab 2',
icon: require('../images/two.png')
}
}
}
}
],
options: {}
}
The selected index is a style property which can be updated using the mergeOptions
command. In order to update the BottomTabs options, Pass the BottomTabs componentId
or the componentId
of one of its children.
?>We’ll use the following BottomTabs layout to demonstrate programmatic tab selection.
const bottomTabs = {
id: 'BottomTabsId',
children: [
{
component: {
name: 'FirstScreen',
options: { ... }
}
},
{
component: {
id: 'SecondScreenId',
name: 'SecondScreen',
options: { ... }
}
}
]
}
The following mergeOptions
command will select the second tab. We’re passing the id of our BottomTabs, but we could also use the id of any of the child components, for example SecondScreenId
.
Navigation.mergeOptions('BottomTabsId', {
bottomTabs: {
currentTabIndex: 1
}
});
Tabs can also be selected by componentId. This is particularly useful in cases where you don’t know in which tab a screen is contained.
For example, if invoked from one of the child components;SecondScreen
or FirstScreen
, the following merge command will select the tab containing the child.
Navigation.mergeOptions(this.props.componentId, {
bottomTabs: {
currentTabId: this.props.componentId
}
});
The visible
property can be used to control the BottomTab visibility.
On Android, Visibility can be toggled dynamically using the mergeOptions
command. When hiding BottomTabs, drawBehind: true
should be specified in order for the screen to render behind the area which was previously allocated to the BottomTabs.
Navigation.mergeOptions(componentId, {
bottomTabs: {
visible: false,
...Platform.select({ android: { drawBehind: true } })
},
});
On both platforms visibility can be changed when pushing screens into a stack which is a direct child of a BottomTabs
layout:
Navigation.push(componentId, {
component: {
name: 'pushedScreen',
options: { bottomTabs: visible: false }
}
});
Updating (merging) tab specific options is done using the mergeOptions
command. mergeOptions
expects a componentId
as first argument, therefore in order to update a specific tab we’ll need to pass a componentId
of a child of that specific tab.
For example, Using the layout specified above, To update the badge
property of the second tab we’ll call mergeOptions
with SecondScreenId
.
Navigation.mergeOptions('SecondScreenId', {
bottomTab: {
badge: 'New'
}
});
Expect center, left and right layouts. center: { stack: … } is required to have a topBar in center screen of a sideMenu app.
const sideMenu = {
left: {
component: {}
},
center: {
stack: {
options: {},
children: [{
component: {}
}]
}
},
right: {
component: {}
}
}
Master and Detail based layout.
You can change the it’s options with Navigation.mergeOptions('splitView1', { maxWidth: 400 })
.
const splitView = {
id: 'splitView1', // Required to update options
master: {
// All layout types accepted supported by device, eg. `stack`
},
detail: {
// All layout types accepted supported by device, eg. `stack`
},
options: {
splitView: {
displayMode: 'auto', // Master view display mode: `auto`, `visible`, `hidden` and `overlay`
primaryEdge: 'leading', // Master view side: `leading` or `trailing`
minWidth: 150, // Minimum width of master view
maxWidth: 300, // Maximum width of master view
},
},
}
Navigation.setRoot({
root: {
sideMenu: {
left: {
component: {
name: 'navigation.playground.TextScreen',
passProps: {
text: 'This is a left side menu screen'
}
}
},
center: {
component: {
name: 'navigation.playground.WelcomeScreen'
},
},
right: {
component: {
name: 'navigation.playground.TextScreen',
passProps: {
text: 'This is a right side menu screen'
}
}
}
}
}
});
Navigation.setRoot({
root: {
bottomTabs: {
children: [
{
component: {
name: 'navigation.playground.TextScreen',
passProps: {
text: 'This is tab 1',
myFunction: () => 'Hello from a function!',
},
},
},
{
component: {
name: 'navigation.playground.TextScreen',
passProps: {
text: 'This is tab 2',
},
},
},
],
},
}
});
Navigation.setRoot({
root: {
stack: {
options: {
topBar: {
visible: false
}
},
children: [
{
component: {
name: 'navigation.playground.TextScreen',
passProps: {
text: 'This is tab 1',
myFunction: () => 'Hello from a function!',
}
}
},
{
component: {
name: 'navigation.playground.TextScreen',
passProps: {
text: 'This is tab 2',
}
}
}
]
}
}
});