Skip to content

Simplified navigation for React Native with improved Typescript support, based on react-navigation

Notifications You must be signed in to change notification settings

pothos-dev/magellan

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@bearbytes/magellan

This is a wrapper around react-navigation, the popular navigation library for React Native.

It adds improved Typescript support and a simplified API for basic navigation needs.

Getting started

Install the dependency: npm i @bearbytes/magellan

Define the available screens and their corresponding navigation parameters:

export interface AppScreens {
  Home: {}
  UserProfile: { userId: string }
  Chat: { partnerUserId: string; isPrivate?: boolean }
}

Initialize the navigation system. It will create a StackNavigator which can be pre-configured with the usual configuration:

import { createNavigation } from './lib/Magellan/createNavigationRoot'
import { AppScreens } from './AppScreens'

export const {
  NavigationRoot,
  navigate,
  navigateBack,
  dispatchNavigationAction,
} = createNavigation<AppScreens>({
  // Pass configuration for the main StackNavigator here
  headerMode: 'none',
  transparentCard: true,
})

The NavigationRoot is a React Component that will contain the currently visible screen(s). Put it into the root of your app. You will need to pass it a component for each screen in the AppScreens interface.

export default function MyApp() {
  return (
    <SomeContextProvider>
      <MaybeReduxContainerOrSomething>
        {/* Should be the main component */}
        <NavigationRoot
          Home={HomeScreen}
          UserProfile={UserProfileScreen}
          Chat={props => {
            // You could also create adhoc components in here.
            // The props passed to the component are equivalent to
            // navigation parameters in react-navigation.
            if (props.isPrivate) {
              return <PrivateChatScreen {...props} />
            } else {
              return <PublicChatScreen {...props} />
            }
          }}
        />
      </MaybeReduxContainerOrSomething>
    </SomeContextProvider>
  )
}

To avoid having to maintain duplicate props definitions, I would advise to use the AppScreens interface to define the screen props:

export function UserProfileScreen(props: AppScreens['UserProfile']) {
  return <Text>Profile of {props.userId}.</Text>
}

Navigating

As you may have noticed, the navigation prop that is usually used in react-nativation is nowhere to be found here. Instead, magellan opts to use top level functions to navigate between screens:

// The navigate function knows about which screens exist and
// what parameters can or must be passed to them. Typescript
// will enforce that we never forget something here.

navigate('UserProfile', { userId: 'bob' })

// Navigation params must always be passed, even when empty.
navigate('Home', {})

// Go back to the previous screen.
// Does nothing when there is only one screen on the stack.
navigateBack()

// The above actions should be enough for most usecases.
// If you need to use a more complex action, you can dispatch
// it directly. Note that unlike the other functions, no
// typesafeness is guaranteed here.
dispatchNavigationAction({ type: 'Navigation/OPEN_DRAWER' })

dispatchNavigationAction({
  type: 'Navigation/POP_TO_TOP',
  immediate: true,
})

About

Simplified navigation for React Native with improved Typescript support, based on react-navigation

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published