Hello World

The Navigation router helps you build web applications with native-like navigation. You can animate scenes as they enter and leave and the user can step back through a stack of visited scenes. Let's build an example to see what native-like navigation on the web looks like. The example will have two scenes. The first scene will display a Hyperlink that says 'Hello'. Clicking the Hyperlink will animate the first scene off screen to the left and animate the second in from the right. The second scene will display a Hyperlink that says 'World'. Clicking this Hyperlink will run the animations in reverse and return you to the first scene.

After following the Setup instructions, we'll begin by adding two States to the StateNavigator - one per scene. Our first step to achieve native-like navigation is to enable the 'breadcrumb trail'. Named after the trail of breadcrumbs Hansel and Gretel dropped in the woods so they could safely retrace their steps, the breadcrumb trail keeps track of the scenes a user visits. When we click the 'Hello' Hyperlink, the Navigation router drops a breadcrumb so that we can return to the 'hello' Scene later on. We'll enable the breadcrumb trail by setting trackCrumbTrail to true on the 'world' State.

const stateNavigator = new StateNavigator([
  {key: 'hello', route: ''},
  {key: 'world', trackCrumbTrail: true}
]);

We'll create the two scenes, one for each State. The 'hello' scene consists of a Hyperlink that navigates to the 'world' State. For now, we'll populate the 'world' scene with a placeholder. Later on, we'll use the breadcrumb trail to replace this div with a Hyperlink that navigates back to the 'hello' Scene.

import {NavigationLink} from 'navigation-react';

const Hello = () => (
  <NavigationLink stateKey="world">
    Hello
  </NavigationLink>
);

const World = () => <div>World</div>;

We'll wrap each scene inside a Scene component and assign the matching State to the stateKey prop. The NavigationMotion component renders each scene when the associated State becomes active. When we visit the 'world' scene the 'hello' scene doesn't unmount. It stays in the stack like in a native app.

import {Scene} from 'navigation-react-mobile';

<NavigationMotion>
  <Scene stateKey="hello"><Hello /></Scene>
  <Scene stateKey="world"><World /></Scene>
</NavigationMotion>

Animation

We'll use the NavigationMotion component to animate the scenes as they come and go. Each scene can exist in one of three stages - unmounted, mounted or crumb. At the start, the 'home' scene is mounted and the 'world' scene is unmounted. When we click the 'home' Hyperlink the 'home' scene becomes a crumb (in the breadcrumb trail) and the 'world' scene is mounted.

We'll assign each of these stages a different translation style prop. The NavigationMotion component provides a renderMotion callback prop that lets us animate between these styles as a scene moves from one stage to another. We'll use the callback's parameters to style the scene with the interpolated translation value. A value of 100% for the unmountedStyle, for example, means the 'world' scene will slide in from the right.

<NavigationMotion
  unmountedStyle={{translate: 100}}
  mountedStyle={{translate: 0}}
  crumbStyle={{translate: -10}}
  renderMotion={(style, scene, key) => (
    <div
      key={key}
      style={{
        ...sceneStyle,
        transform: `translate(${style.translate}%)`
      }}>
      {scene}
    </div>
  )}>

Breadcrumbs

You'll remember that the Navigation router drops a breadcrumb when we click the 'hello' Hyperlink. We can use this crumb to build a Hyperlink that returns us to the 'hello' scene. We'll replace the div in the 'world' scene with a NavigationBackLink component that navigates back a distance of 1 breadcrumb along the trail. When we click this Hyperlink, the NavigationMotion component plays the animations in reverse as the 'home' scene mounts and the 'world' scene unmounts.

import {NavigationBackLink} from 'navigation-react';

const World = () => (
  <NavigationBackLink distance={1}>
    World
  </NavigationBackLink>
);

Try It Out