-
Notifications
You must be signed in to change notification settings - Fork 5
Tab navigator experiments #19
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
let stack = StackExample.render; | ||
let tab = TabExample.render; | ||
/* let tab = TabExample.render; */ | ||
let drawer = DrawerExample.render; | ||
|
||
let switchNavigator = SwitchExample.render; | ||
|
||
let app = drawer; | ||
let app = stack; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,39 @@ | ||
module Core = { | ||
[@bs.module "@react-navigation/core"] | ||
external stackRouter: ('a, 'b) => ReasonReact.reactElement = "StackRouter"; | ||
external stackRouter: ('a, 'b) => ReasonReact.reactClass = "StackRouter"; | ||
|
||
[@bs.module "@react-navigation/core"] | ||
external switchRouter: ('a, 'b) => ReasonReact.reactElement = "SwitchRouter"; | ||
external switchRouter: ('a, 'b) => ReasonReact.reactClass = "SwitchRouter"; | ||
|
||
[@bs.module "@react-navigation/core"] | ||
external createNavigator: ('a, 'b, 'c) => ReasonReact.reactElement = ""; | ||
external createNavigator: ('a, 'b, 'c) => ReasonReact.reactClass = ""; | ||
}; | ||
|
||
module Native = { | ||
[@bs.module "@react-navigation/native"] | ||
external createAppContainer: 'a => ReasonReact.reactElement = ""; | ||
external createAppContainer: 'a => ReasonReact.reactClass = ""; | ||
}; | ||
|
||
module Stack = { | ||
[@bs.module "react-navigation-stack"] | ||
external stackView: ReasonReact.reactElement = "StackView"; | ||
external stackView: ReasonReact.reactClass = "StackView"; | ||
}; | ||
|
||
module Tab = { | ||
[@bs.module "react-navigation-tabs"] | ||
external createBottomTabNavigator: ('a, 'b) => ReasonReact.reactElement = ""; | ||
external createBottomTabNavigator: ('a, 'b) => ReasonReact.reactClass = ""; | ||
|
||
[@bs.module "react-navigation-tabs"] | ||
external createMaterialTopTabNavigator: 'a => ReasonReact.reactElement = "" | ||
external createMaterialTopTabNavigator: 'a => ReasonReact.reactClass = "" | ||
}; | ||
|
||
module Switch = { | ||
[@bs.module "@react-navigation/core"] | ||
external switchView: ReasonReact.reactElement = "SwitchView"; | ||
external switchView: ReasonReact.reactClass = "SwitchView"; | ||
}; | ||
|
||
module Drawer = { | ||
[@bs.module "react-navigation-drawer"] | ||
external create: ('a, 'b) => ReasonReact.reactElement = | ||
external create: ('a, 'b) => ReasonReact.reactClass = | ||
"createDrawerNavigator"; | ||
}; |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -56,26 +56,39 @@ module type TabConfig = { | |||||||||||||||||||||||||||||||
type tabs; | ||||||||||||||||||||||||||||||||
type order = list(tabs); | ||||||||||||||||||||||||||||||||
let order: order; | ||||||||||||||||||||||||||||||||
let containerName: string; | ||||||||||||||||||||||||||||||||
let tabBarOptions: tabBarOptions; | ||||||||||||||||||||||||||||||||
let getTab: | ||||||||||||||||||||||||||||||||
tabs => (Js.Dict.key, navigation => ReasonReact.reactElement, screenOptions); | ||||||||||||||||||||||||||||||||
(tabs, navigation) => | ||||||||||||||||||||||||||||||||
(Js.Dict.key, unit => ReasonReact.reactElement, screenOptions); | ||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does "screen" has to be a function?
I would unify it with StackNavigator and just make it a React element. It will make the API much easier. If we need a functional form, we can always wrap it later on our side. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't need users to define a string of a route explicitly. I know that TabNavigator's router requires us to use a concept of string to register a route. We can do better. There are two ways of handling that: a) StackNavigator's way - we define only one "route", let's call it Container. Every "route" is a "" element that accepts current screen to render as a prop. For example, "" where "EditUser(5)" could be a ReasonML variant. b) Define a hashing function that can generate a UUID based on a variant it is given. For example, for "EditUser(5)", this could be "Route_EditUser_5". It's representation is not important as long as the function is stable and can generate same string for a given variant. This will be only used internally by the React Navigation. Given that TabNavigator doesn't have StackNavigator's limitations, I propose we go with "b" for the sake of simplicity. We can always change it later, transparently for the end users. |
||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
module Create = (Config: TabConfig) => { | ||||||||||||||||||||||||||||||||
[@bs.deriving abstract] | ||||||||||||||||||||||||||||||||
type navigatorConfig = {initialRouteName: string}; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
[@bs.deriving abstract] | ||||||||||||||||||||||||||||||||
type routeConfig = { | ||||||||||||||||||||||||||||||||
screen: navigation => ReasonReact.reactElement, | ||||||||||||||||||||||||||||||||
screen: unit => ReasonReact.reactElement, | ||||||||||||||||||||||||||||||||
navigationOptions: screenOptions, | ||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
module NavigationProp = { | ||||||||||||||||||||||||||||||||
[@bs.send] external navigate: string => unit = "navigate"; | ||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we pass the Variant to the navigate function, or not? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah in the end we need to pass a variant. We don't want to use string. This is just an experiment. This is not working yet. navigation is WIP. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, would be great to add a comment there to know what's going there There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this case we don't. "NavigationProp" module is a binding to React Navigation's "navigation" that operates on strings and is not aware of ReasonML variant. This is going to be super similar to bs-react-navigation/src/StackNavigator.re Lines 26 to 40 in aaf0f84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should translate variant to string here: https://github.com/callstackincubator/bs-react-navigation/pull/19/files#diff-f5a576ae9729bbd89c5aa8c4a2bf67ffR83 |
||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
[@bs.send] external goBack: unit => unit = "goBack"; | ||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
let makeNavigationProp = () => { | ||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should accept a "navigation" prop so that we can actually talk to a real "navigation". See how StackNavigation handles that. The code will be exactly the same, except for the "routeName" part. Depending on the approach you take, this will be either similar to StackNavigation (passing variant to a Container route) or generating a hash (to be used as a routeName) from a given variant. Either way, "navigate" should accept a "tab" (variant) instead of a "routeName" (string). "NavigationProp.navigate" is good - ReactNavigation operates on "string"s and we should keep it that way. |
||||||||||||||||||||||||||||||||
navigate: routeName => NavigationProp.navigate(routeName), | ||||||||||||||||||||||||||||||||
goBack: () => NavigationProp.goBack(), | ||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
let tabs = | ||||||||||||||||||||||||||||||||
Config.order | ||||||||||||||||||||||||||||||||
|> List.map(tab => { | ||||||||||||||||||||||||||||||||
let (tabname, screen, screenOptionsConfig) = Config.getTab(tab); | ||||||||||||||||||||||||||||||||
let (tabname, screen, screenOptionsConfig) = | ||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As already said, "tabName" could be generated dynamically. "screen" doesn't have to be a function, we can wrap it here if needed. |
||||||||||||||||||||||||||||||||
Config.getTab(tab, makeNavigationProp()); | ||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder that too 😉 We need to discuss that. You, me and @grabbou There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should handle that just like we handle it in StackNavigator -> bs-react-navigation/src/StackNavigator.re Lines 55 to 63 in aaf0f84
|
||||||||||||||||||||||||||||||||
( | ||||||||||||||||||||||||||||||||
tabname, | ||||||||||||||||||||||||||||||||
routeConfig(~screen, ~navigationOptions=screenOptionsConfig), | ||||||||||||||||||||||||||||||||
|
@@ -89,10 +102,8 @@ module Create = (Config: TabConfig) => { | |||||||||||||||||||||||||||||||
"tabBarOptions": Config.tabBarOptions, | ||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
/* navigator */ | ||||||||||||||||||||||||||||||||
let navigator = | ||||||||||||||||||||||||||||||||
ReactNavigation.Tab.createBottomTabNavigator(tabs, tabBarOptions); | ||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||
/* Wrap StackNavigator with the AppContainer - temporary */ | ||||||||||||||||||||||||||||||||
let render = ReactNavigation.Native.createAppContainer(navigator); | ||||||||||||||||||||||||||||||||
let make = ReactNavigation.Native.createAppContainer(navigator); | ||||||||||||||||||||||||||||||||
grabbou marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||
}; |
Uh oh!
There was an error while loading. Please reload this page.