kudzu-forest/elm-page/3.0.0

NOTE: the latest version is 3.0.1

Page

This module allows you to combine multiple apps created with Browser.element or Browser.sandbox into a single application, with or without URL control. The key feature of the Program type is that, unlike other attempts to simplify SPA development, it does not use type variables for inner model and messages (it's Program flag, not Program flag model msg). This allows you to combine all the pages into a single List, Dict, Random.Generator, or any other data structure you like.

Users need to write a bit of boilerplate. For example, if you want to use the digital clock application (discussed in the official guide's subscription section), you'll need to set up a corresponding module like this. (This code is based on the one in the official guide, with first line added and Page substituted for Browser and program for main.)

For usage with multiple pages, see the GitHub repository.

CoreTypes

type Model

A custom type representing internal states of your page. :::note info The Page.Model is distinct from the Model defined in individual page modules. Page.Model provides a level of abstraction that enables consistent handling of all your pages. :::

type Msg

A custom type representing Msgs in your page module. You need to use Page.update to access this value. See the example above.

type Program flag

A custom type representing the main program of a page. Values of this type can be passed to the Page.mapInit function with a flag.

Creation

An empty page. This can be used for initialization. See example above.

{ init : model
, update : msg -> model -> model
, view : model -> Html msg
}
-> Program ()

Functions similarly to Browser.sandbox. You can create a Page.Program () easily by just using Page.sandbox instead of Browser.sandbox.

{ init : flag -> ( model, Cmd msg )
, subscriptions : model -> Sub msg
, update : msg -> model -> ( model, Cmd msg )
, view : model -> Html msg
}
-> Program flag

Functions similarly to Browser.element. The return value is wrapped in Page.Program and can be passed to Page.mapInit along with a flag.

Usage

mapInit : (( Model, Cmd Msg ) -> appMsg) -> Program flag -> flag -> appMsg

The only way you can start new page.

update : Msg -> Model -> ( Model, Cmd Msg )

The only way to handle Page.Msg value from a child component. :::note warn The Page.Msg value is ignored if the page which has emitted the Page.Msg value of first argument and Model value of second argument does not match. For example, some delayed Cmd Page.Msg like Process.sleep 10000 |> Task.perform (\_ -> SomeMsg) is made then Page.mapInit is called before arrival of the returned Page.Msg. :::

mapView : (Msg -> appMsg) -> Model -> Html appMsg

You can use your page with this function. See the example above.

mapSubscriptions : (Msg -> appMsg) -> Model -> Sub appMsg

Don't forget to use this in your subscriptions in the parent module!