an experimental way to build single page applications with Elm!
The goal of this project is to make it easy to add new pages to a single page app, while allowing the pages to be as simple/complex as they need to be.
The idea is asking users for a record that provides their page information (init
, update
, view
, etc).
To be consistent with elm/browser, I stole the same terminology and function signatures.
These are the simplest pages, just like the classic counter example.
type alias SandboxPage model msg appModel appMsg =
{ title : String
, init : model
, update : msg -> model -> model
, view : model -> Html msg
, toMsg : msg -> appMsg
, toModel : model -> appModel
}
Example: Page.About
When you are ready for Cmd
and Sub
, and need to read the global context you can upgrade to an ElementPage
.
type alias ElementPage context model msg appModel appMsg =
{ title : String
, init : context -> ( model, Cmd msg )
, view : model -> Html msg
, update : msg -> model -> ( model, Cmd msg )
, subscriptions : model -> Sub msg
, toMsg : model -> msg -> appMsg
, toModel : model -> appModel
}
Example: Page.Careers
For when you want to control the tab title, you can make an DocumentPage
.
type alias DocumentPage context model msg appModel appMsg =
{ init : context -> ( model, Cmd msg )
, view : model -> Browser.Document msg
, update : msg -> model -> ( model, Cmd msg )
, subscriptions : model -> Sub msg
, toMsg : msg -> appMsg
, toModel : model -> appModel
}
Example: Page.Homepage
If you need to update the Context
with global messages, you can upgrade to a full application page.
type alias ApplicationPage context contextMsg model msg appModel appMsg =
{ init : context -> ( model, Cmd msg, Cmd contextMsg )
, view : context -> model -> Browser.Document msg
, update : context -> msg -> model -> ( model, Cmd msg, Cmd contextMsg )
, subscriptions : context -> model -> Sub msg
, toMsg : msg -> appMsg
, toModel : model -> appModel
}
Example: Page.SignIn
With ryannhg/application
, this diff shows us how to add in a new page:
https://github.com/ryannhg/application/commit/e534ffb56bfc24adbcc153f30e0a13d972ffbfc9
To get a better understanding, pull this repo and play around with the code:
-
npm install
-
npm run dev