This library is my attempt to unify all cljs
react-navigation
libraries under a shared code base. Right now it only includes Reagent/Re-Frame
libraries, but I'm hoping other people will help me add om-next
and rum
libraries.
Clojurescript
[org.clojure/clojurescript "1.9.854"] ;; using cljs.spec.alpha namespace
[reagent "0.7.0"] ;; Import the cljs-react-navigation.reagent namespace
[re-frame "0.9.3"] ;; Import the cljs-react-navigation.re-frame namespace
Javascript
"react": "16.0.0-alpha.12",
"react-native": "0.44.0",
"react-navigation": "^1.0.0-beta.9"
Add react-navigation
to your project.
npm install react-navigation --save
If you're using re-natal, also add it to re-natal
re-natal use-component react-navigation
re-natal use-figwheel
If you're using my cljs expo template, make sure to require react-navigation somewhere in your code.
; react-navigation
(defonce ReactNavigation (js/require "react-navigation"))
Anything react-navigation
related is documented on their site. The idea for this library isn't to re-invent the wheel, but make it cljs friendly.
Specifically:
- Conforming whatever cljs wrapper components into the correct react components/elements
- Converting props to cljs data structures to avoid
clj->js
&js->clj
ing everything.
Yeah, you really don't use this directly. Try extending this set of specs and and functions. See the reagent
version.
That being said, I'm literally just spec'ing out the javascript API, with some minor tweaks:
screen
function isn't overloaded (there's astack-screen
and atab-screen
)screen
functions accepts thenavigationOptions
as a second param (god knows why they insist on doing ES6 style initializations)
First import the reagent version of the library library:
(ns uiexplorer.routing
(:require [cljs-react-navigation.reagent :refer [stack-navigator tab-navigator stack-screen tab-screen router]]))
Then create reagent-components that accept props like this:
(defn home
"Each Screen will receive two props:
- screenProps - Extra props passed down from the router (rarely used)
- navigation - The main navigation functions in a map as follows:
{:state - routing state for this screen
:dispatch - generic dispatch fn
:goBack - pop's the current screen off the stack
:navigate - most common way to navigate to the next screen
:setParams - used to change the params for the current screen}"
[props]
(fn [{:keys [screenProps navigation] :as props}]
(let [{:keys [navigate goBack]} navigation]
[:> View {:style {:flex 1
:alignItems "center"
:justifyContent "center"}}
[:> Button {:style {:fontSize 17}
:onPress #(navigate "Modal")
:title "Modal Me!"}]
[:> Button {:style {:fontSize 17}
:onPress #(goBack)
:title "Go Back!"}]
[:> Button {:style {:fontSize 17}
:onPress #(navigate "Placeholder")}]])))
And then you can create stacks and screens for them like this:
(def HomeStack (stack-navigator {:Home {:screen (stack-screen home {:title "Home"})}}))
And then you can just render that Stack like a normal reagent component:
(defn app-root []
(fn []
[:> HomeStack {}]))
(defn init []
(.registerComponent AppRegistry "UIExplorer" #(r/reactify-component app-root)))
TODO: Create an example
Pretty much the same as the Reagent version, but you can store the routing state in re-frame's app-db (which is great for serializing state to AsyncStorage). Also, dispatch routing changes from anywhere.
See the examples folder.
- Finish spec'ing all functions and parameters (I think I've got most of them)
- Reagent example
- Rum example
- Om-Next example
Copyright © 2017 Sean Tempesta
Distributed under the MIT license.