Animated Navigation

Dropping Breadcrumbs

The Navigation router brings native-like navigation to the web. It builds a stack of the scenes a user visits. You can navigate back to any scene in the stack and animate the scenes as they move through and off the stack. The Navigation router remembers the visited scenes by dropping a breadcrumb at each one, like the fairy-tale characters Hansel and Gretel. You enable the breadcrumb trail by setting trackCrumbTrail to true against each State. In an email application, we set trackCrumbTrail to true on the 'mail' State so that we can animate out the 'inbox' scene and animate in the 'mail' scene when the user opens an email.

var stateNavigator = new Navigation.StateNavigator([
  {key: 'inbox', route: ''},
  {key: 'mail', trackCrumbTrail: true}
]);

Defining Scenes

Instead of defining views, you define scenes and let the Navigation router render them (see the NavigationMotion component below). You define the scenes in functions attached to the renderScene property of each State. When you navigate to a State, the Navigation router creates the scene by calling the corresponding renderScene function, passing in any navigation data. It pops the new scene onto the top of the stack and renders it. We can define the two scenes in the email example using our Inbox and Mail components.

stateNavigator.states.inbox.renderScene = function() {
  return <Inbox />;
};

stateNavigator.states.mail.renderScene = function(data) {
  return <Mail mailId={data.id} />;
};

stateNavigator.start();

Animating

The NavigationMotion component renders the scenes in the stack. It lets you animate the scenes as they progress through the stack. A scene is said to be either unmounted, mounted or a crumb. It's unmounted when it's not on the stack; it's mounted when it's at the top of the stack; and it's a crumb when it's anywhere else in the stack (in the breadcrumb trail).

You assign a style prop to each of these three stages and the NavigationMotion component calls you back with the interpolated values so you can animate the scenes. In our email example, we'll give the unmounted and crumb styles an opacity of 0 and the mounted style an opacity of 1. When the user opens a mail, the 'inbox' scene fades out as it becomes a crumb and the 'mail' scene fades in as it's mounted.

ReactDOM.render(
  <NavigationReact.NavigationHandler stateNavigator={stateNavigator}>
    <NavigationReactMobile.NavigationMotion
      unmountedStyle={{opacity: 0}}
      mountedStyle={{opacity: 1}}
      crumbStyle={{opacity: 0}}>
      {(style, scene, key) => (
        <div
          key={key}
          style={{opacity: style.opacity}}>
          {scene}
        </div>
      )}
    </NavigationReactMobile.NavigationMotion>
  </NavigationReact.NavigationHandler>,
  document.getElementById('app')
);

Navigating Back

The user can navigate back to visited scenes, along the breadcrumb trail, as Hansel and Gretel intended. You navigate back using the NavigationBackLink component specifying the distance you want to travel. In our email example, we add a NavigationBackLink component to the 'mail' scene so the user can return to their inbox. When they click the Hyperlink, the 'mail' scene fades out as it's unmounted and the 'inbox' scene fades back in as it's mounted.

<NavigationReact.NavigationBackLink distance={1}>
  Back to Inbox
</NavigationReact.NavigationBackLink>

You can navigate back programatically by passing the distance into the navigateBack function on the stateNavigator.

<NavigationReact.NavigationContext.Consumer>
  {({ stateNavigator }) => (
    <div onClick={() => >stateNavigator.navigateBack(1)}>Back to Inbox</div>
  )}
</NavigationReact.NavigationContext.Consumer>