bs-react-navigation web interface for WEB (hooks api)
Instantly share code, notes, and snippets.
Last active
November 30, 2020 16:17
-
Save hew/d99e7354cd40581d0e9a34e34f253af9 to your computer and use it in GitHub Desktop.
bs-react-navigation interface types for WEB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type navigation('a) = { | |
push: 'a => unit, | |
pop: 'a => unit, | |
}; | |
[@bs.deriving abstract] | |
type screenOptions = { | |
[@bs.optional] | |
title: string, | |
}; | |
module type StackConfig = { | |
type route; | |
let initialRoute: route; | |
let getScreen: | |
(route, navigation(route)) => (React.element, screenOptions); | |
}; | |
module Create = (Config: StackConfig) => { | |
[@bs.deriving abstract] | |
type navigatorConfig = {initialRouteName: string}; | |
[@bs.deriving abstract] | |
type routeProps = {route: Config.route}; | |
module NavigationProp = { | |
type t; | |
module State = { | |
type t; | |
[@bs.get] external getParams: t => option(routeProps) = "params"; | |
}; | |
[@bs.send] external push: (t, string, routeProps) => unit = "push"; | |
[@bs.get "state"] external getState: t => State.t = ""; | |
let getParams = t => getState(t) |> State.getParams; | |
}; | |
module ScreenOptions = { | |
type t = {. "navigation": NavigationProp.t}; | |
}; | |
[@bs.deriving abstract] | |
type routeConfig = { | |
params: routeProps, | |
screen: ScreenOptions.t => React.element, | |
navigationOptions: ScreenOptions.t => screenOptions, | |
}; | |
let containerDisplayName = "#"; | |
let makeNavigationProp = (navigation: NavigationProp.t) => { | |
push: route => | |
NavigationProp.push( | |
navigation, | |
containerDisplayName, | |
routeProps(~route), | |
), | |
pop: _route => (), | |
}; | |
let getCurrentScreen = (navigation: NavigationProp.t) => { | |
/** Params can be `null` in React Navigation, but we are always declaring them */ | |
let params = NavigationProp.getParams(navigation) |> Js.Option.getExn; | |
let nav = makeNavigationProp(navigation); | |
Config.getScreen(routeGet(params), nav); | |
}; | |
module Container = { | |
[@react.component] | |
let make = (~navigation: NavigationProp.t) => { | |
getCurrentScreen(navigation) |> fst | |
}; | |
}; | |
let route = | |
routeConfig( | |
~params=routeProps(~route=Config.initialRoute), | |
~screen= | |
(options: ScreenOptions.t) => | |
<Container navigation=options##navigation />, | |
~navigationOptions= | |
(options: ScreenOptions.t) => | |
getCurrentScreen(options##navigation) |> snd, | |
); | |
/* StackNavigator route */ | |
let routes = Js.Dict.empty(); | |
Js.Dict.set(routes, containerDisplayName, route); | |
/* StackNavigator config */ | |
let config = navigatorConfig(~initialRouteName=containerDisplayName); | |
/* Router */ | |
let router = ReactNavigation.Core.stackRouter(routes, config); | |
/* navigator */ | |
let navigator = | |
ReactNavigation.Core.createNavigator( | |
ReactNavigation.Stack.stackView, | |
router, | |
config, | |
); | |
/* Wrap StackNavigator with the AppContainer - temporary */ | |
let render = ReactNavigation.Web.createBrowserApp(navigator); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type navigation('a) = { | |
navigate: 'a => unit, | |
goBack: 'a => unit, | |
}; | |
[@bs.deriving abstract] | |
type screenOptions = { | |
[@bs.optional] | |
title: string, | |
}; | |
module type SwitchConfig = { | |
type route; | |
let initialRoute: route; | |
let getScreen: | |
(route, navigation(route)) => (React.element, screenOptions); | |
}; | |
module Create = (Config: SwitchConfig) => { | |
[@bs.deriving abstract] | |
type navigatorConfig = {initialRouteName: string}; | |
[@bs.deriving abstract] | |
type routeProps = {route: Config.route}; | |
module NavigationProp = { | |
type t; | |
module State = { | |
type t; | |
[@bs.get] external getParams: t => option(routeProps) = "params"; | |
}; | |
[@bs.send] external navigate: (t, string, routeProps) => unit = "navigate"; | |
[@bs.send] external goBack: unit => unit = "goBack"; | |
[@bs.get "state"] external getState: t => State.t = ""; | |
let getParams = t => getState(t) |> State.getParams; | |
}; | |
module ScreenOptions = { | |
type t = {. "navigation": NavigationProp.t}; | |
}; | |
[@bs.deriving abstract] | |
type routeConfig = { | |
params: routeProps, | |
screen: ScreenOptions.t => React.element, | |
navigationOptions: ScreenOptions.t => screenOptions, | |
}; | |
let containerDisplayName = "#router"; | |
let makeNavigationProp = (navigation: NavigationProp.t) => { | |
navigate: route => | |
NavigationProp.navigate( | |
navigation, | |
containerDisplayName, | |
routeProps(~route), | |
), | |
goBack: _ => NavigationProp.goBack(), | |
}; | |
let getCurrentScreen = (navigation: NavigationProp.t) => { | |
/** Params can be `null` in React Navigation, but we are always declaring them */ | |
let params = NavigationProp.getParams(navigation) |> Js.Option.getExn; | |
let nav = makeNavigationProp(navigation); | |
Config.getScreen(routeGet(params), nav); | |
}; | |
module Container = { | |
[@react.component] | |
let make = (~navigation: NavigationProp.t) => { | |
getCurrentScreen(navigation) |> fst; | |
}; | |
}; | |
let route = | |
routeConfig( | |
~params=routeProps(~route=Config.initialRoute), | |
~screen= | |
(options: ScreenOptions.t) => | |
<Container navigation=options##navigation />, | |
~navigationOptions= | |
(options: ScreenOptions.t) => | |
getCurrentScreen(options##navigation) |> snd, | |
); | |
/* SwitchNavigator route */ | |
let routes = Js.Dict.empty(); | |
Js.Dict.set(routes, containerDisplayName, route); | |
/* SwitchNavigator config */ | |
let config = navigatorConfig(~initialRouteName=containerDisplayName); | |
/* Router */ | |
let router = ReactNavigation.Core.switchRouter(routes, config); | |
/* navigator */ | |
let navigator = | |
ReactNavigation.Core.createNavigator( | |
ReactNavigation.Switch.switchView, | |
router, | |
config, | |
); | |
/* Wrap SwitchNavigator with the AppContainer - temporary */ | |
let render = ReactNavigation.Web.createBrowserApp(navigator); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment