Last active
May 17, 2018 22:01
-
-
Save dotfold/b44df0280a6b7c04ff70b06cd7948023 to your computer and use it in GitHub Desktop.
ReasonML Link and Router components that integrate with the built in router
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
open Css; | |
let link = selected => | |
style([ | |
color(selected ? red : green), | |
textDecoration(selected ? none : underline), | |
cursor(selected ? `default : `pointer) | |
]); | |
type action = | |
| UpdateRoute(ReasonReact.Router.url); | |
type state = {selected: bool}; | |
let component = ReasonReact.reducerComponent("Link"); | |
let make = (~href, ~path, ~className="", children) => { | |
...component, | |
initialState: () => {selected: false}, | |
didMount: (self) => { | |
/* let a = ReasonReact.Router.dangerouslyGetInitialUrl(); | |
let selected = switch (List.hd(a.path)) { | |
| url => url == path | |
| exception Failure(hd) => false | |
}; */ | |
self.send(UpdateRoute(ReasonReact.Router.dangerouslyGetInitialUrl())); | |
}, | |
reducer: (action, state) => | |
switch action { | |
| UpdateRoute(url) => | |
switch url.path { | |
| [] => ReasonReact.NoUpdate | |
| [base, ..._] => ReasonReact.Update({...state, selected: base == path}) | |
} | |
}, | |
subscriptions: ({send}) => [ | |
Sub( | |
() => ReasonReact.Router.watchUrl(url => send(UpdateRoute(url))), | |
ReasonReact.Router.unwatchUrl | |
) | |
], | |
render: ({state, handle}) => | |
ReasonReact.createDomElement( | |
"a", | |
~props={ | |
"className": link(state.selected), | |
"href": href, | |
"selected": state.selected, | |
"onClick": | |
handle((event, _self) => { | |
ReactEventRe.Mouse.preventDefault(event); | |
ReasonReact.Router.push(href); | |
}) | |
}, | |
children | |
) | |
}; |
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
/* this doesn't work because of the null renderer */ | |
module Redirect { | |
let component = ReasonReact.statelessComponent("Redirect"); | |
let make = (~_to, _children) => { | |
...component, | |
didMount: _self => { | |
ReasonReact.Router.push(_to) | |
}, | |
render: _self => ReasonReact.null | |
} | |
}; |
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
/* taken from the razzle examples repo */ | |
type action = | |
| UpdateRoute(ReasonReact.Router.url); | |
type state = ReasonReact.Router.url; | |
/* copied from ReasonReact */ | |
let urlToUrlList = url => | |
switch url { | |
| "" | |
| "/" => [] | |
| _ => | |
/* remove the preceeding /, which every pathname seems to have */ | |
let raw = Js.String.sliceToEnd(~from=1, url); | |
/* remove the trailing /, which some pathnames might have. Ugh */ | |
let raw = | |
switch (Js.String.get(raw, Js.String.length(raw) - 1)) { | |
| "/" => Js.String.slice(~from=0, ~to_=-1, raw) | |
| _ => raw | |
}; | |
raw |> Js.String.split("/") |> Array.to_list; | |
}; | |
let component = ReasonReact.reducerComponent("Router"); | |
let make: | |
(~initialUrl: option(string), 'a) => ReasonReact.component(state, _, action) = | |
(~initialUrl, children) => { | |
...component, | |
initialState: () => | |
switch initialUrl { | |
| Some(url) => {path: urlToUrlList(url), hash: "", search: ""} | |
| None => ReasonReact.Router.dangerouslyGetInitialUrl() | |
}, | |
reducer: (action, _state) => | |
switch action { | |
| UpdateRoute(url) => ReasonReact.Update(url) | |
}, | |
subscriptions: ({send}) => [ | |
Sub( | |
() => ReasonReact.Router.watchUrl(url => send(UpdateRoute(url))), | |
ReasonReact.Router.unwatchUrl | |
) | |
], | |
render: ({state}) => children(state) | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment