orus-io / elm-spa / Spa.PageStack

This module provides the tools to combine multiple pages into a single TEA component.

It can be used separately from Spa, in case it doesn't handle the complexity of your application (and if it's the case I am interested to know about it!).

Another use case is to progressively port a hand-written application to Spa, by embedding a PageStack in the existing application, then port pages to it one by one. Once all the pages are in the stack, the main application can be ported to Spa.


type alias Stack setupError shared sharedMsg route view current previous currentMsg previousMsg =
{ init : shared -> route -> ( Model setupError current previous
, Effect sharedMsg (Msg route currentMsg previousMsg) )
, update : shared -> Msg route currentMsg previousMsg -> Model setupError current previous -> ( Model setupError current previous
, Effect sharedMsg (Msg route currentMsg previousMsg) )
, subscriptions : shared -> Model setupError current previous -> Platform.Sub.Sub (Msg route currentMsg previousMsg)
, view : shared -> Model setupError current previous -> view 
}

A Stack combines pages into a single TEA component

setup : { defaultView : view } -> Stack setupError shared sharedMsg route view () () () ()

Setup a new stack

The defaultView is used when no other view can be applied, which should never happen if the application is properly defined.

add : ( CurrentViewMap route currentMsg previousMsg pageView view, PreviousViewMap route currentMsg previousMsg previousView view ) -> RouteMatcher route flags -> PageSetup setupError flags shared sharedMsg pageView pageModel pageMsg -> Stack setupError shared sharedMsg route previousView previousCurrent previousPrevious previousCurrentMsg previousPreviousMsg -> Stack setupError shared sharedMsg route view pageModel (Model setupError previousCurrent previousPrevious) pageMsg (Msg route previousCurrentMsg previousPreviousMsg)

Add a page to a Stack


type Msg route current previous

The Stack Msg type


type Model setupError current previous

The Stack model

empty : Model setupError a b

An empty model for initialising a stack state

getError : Model setupError current previous -> Maybe setupError

returns the current setup error if any

routeChange : route -> Msg route current previous

Build a message that signal a route change to the page stack


type alias PageSetup setupError flags shared sharedMsg view model msg =
shared -> Result setupError (Spa.Page.Page flags sharedMsg view model msg)

A page setup returns the page definition given the share current state

It can fail with a custom error


type alias RouteMatcher route flags =
route -> Maybe flags

A route matcher is provided for each page. If it matches the route of its page, it returns the flags that will be passed to the page 'init' function


type alias CurrentViewMap route currentMsg previousMsg pageView view =
(currentMsg -> Msg route currentMsg previousMsg) -> pageView -> view

A view mapper, for example Html.map or Element.map depending on your actual view type.


type alias PreviousViewMap route currentMsg previousMsg previousView view =
(previousMsg -> Msg route currentMsg previousMsg) -> previousView -> view

A view mapper, for example Html.map or Element.map depending on your actual view type.