upsiflu / less-ui / Less

Makes the Url the single source of truth for the state of your user interface, and hides the corresponding messages from your update.

application : { init : ( model, Platform.Cmd.Cmd modelMsg ), update : modelMsg -> model -> Return modelMsg model, view : model -> Document modelMsg } -> Application model modelMsg

Keeps the Ui state in the Url.


type alias Application model modelMsg =
Platform.Program () (ApplicationState model) (Link.Msg modelMsg)

🐌

mapDocument : (html -> List (Html (Link.Msg msg))) -> { body : Ui region html wrapper, layout : Ui.Layout region narrowHtml_ html narrowWrapper_ wrapper, title : String } -> Document msg

Render the document and map it to Html.

reroute : (Link.State -> Link.State) -> Document msg -> { current : Link.State, previous : Maybe Link.State } -> Browser.Document (Link.Msg msg)

If you want to re-route Urls before rendering, compose such functions left of the Document:

import Less.Link

myDocument : Document msg
myDocument =
    { body = ..., layout = ..., title = "..." }
        |> mapDocument identity

myReroute : Less.State -> Less.State
myReroute =
    Less.Link.mapLocation
        (\location -> if location == "/" then "/newHomePage" else location)

myView : () -> Document msg
myView () =
    Less.reroute myReroute >> myDocument

Why?

In the conventional Elm architecture, if you want the view to respect state encoded in the Url such as queries or flags, you need your update to incorporate this state into the in-memory application Model, which is eventually interpreted in the view:

 - - Url ↘               Cmd ⭢ Url' - - -
         Message ↘      ↗
                  update
 - - - - - Model ↗      ↘ Model' - - - - -
                              ↘
                              view

This opens two possible pitfalls:

How?

- - - - - - Url ↘              ↗ Url' - -
             Path, Flags, Fragment
                           ↘
                          view
         Message ↘         ↗
- - - - -  Model ↘    ↗ Model' - - - - -
                 update
                      ↘ Cmd