This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.
1.0.0
Drop-in router with animated transitions for single page apps
version 1.0.1
license BSD3
native-modules False
elm-version 0.16.0 <= v < 0.17.0
Tag 1.0.1
Committed At 2016-01-03 07:57:49 UTC
evancz/elm-effects 2.0.1 <= v < 3.0.0 2.0.1
etaque/elm-transit 5.0.0 <= v < 6.0.0 5.0.0
etaque/elm-response 1.0.0 <= v < 2.0.0 1.0.0
elm-lang/core 3.0.0 <= v < 4.0.0 3.0.0
elm-community/elm-history 1.0.1 <= v < 2.0.0 1.2.0

Modules

README

Elm Transit Router

elm package install etaque/elm-transit-router

Drop-in router with animated route transitions for single page apps in Elm.

Features

  • Takes care of the history interaction and actions plumbing
  • Enables animated transition on route changes, thanks to elm-transit
  • Provides a simple Signal.Address String for navigation

Usage

To be able to provide animated route transitions, TransitRouter (and Transit underneath) works by action delegation: it will be able to emit (Action, Effects Action) by knowing how to wrap his own TransitRouter.Action type into your app's Action type. This is why the actionWrapper is needed in config below.

Model

Say you have an Action type wrapping TransitRouter.Action:

type Action = Foo | ... | RouterAction TransitRouter.Action | NoOp

Also a Route type to describe all routes in your apps:

type Route = Home | ... | NotFound | EmptyRoute

You must then extend your model with WithRoute on Route type:

type alias Model = TransitRouter.WithRoute Route 
  { foo: String }

Your Model is now enabled to work with TransitRouter. Initialize it with the EmptyRoute that should render nothing in your view, to avoid content flashing on app init.

initialModel : Model
initialModel =
  { transitRouter = TransitRouter.empty EmptyRoute
  , foo: ""
  }

Update

A config should be prepared:

routerConfig : TransitRouter.Config Route Action Model
routerConfig :
  { mountRoute : Route -> Route -> Model -> (Model, Effects Action)
  , getDurations : Route -> Route -> Model -> (Float, Float)
  , actionWrapper : TransitRouter.Action -> Action
  , routeDecoder : String -> Route
  }
  • In mountRoute, you'll provide what should be done in your update when a new route is mounted. The Route params are previous and new routes.

  • In getDurations, you'll return the transition durations, given previous/new route and current model. Write \_ _ _ -> (50, 200) if you always want an exit of 50ms then an enter of 200ms. You mountRoute will happend at the end of exit.

  • actionWrapper will be used to transform internal TransitAction.Action to your own Action.

  • routeDecoder takes the current path as input and should return the associated route. See my elm-route-parser package for help on this.

It's now time to wire init and update functions:

init : String -> (Model, Effects Action)
init path =
  TransitRouter.init routerConfig path initialModel

This will parse and mount initial route on app init. You can get initial path value by setting up a port in main and provide current path from JS side.

In update, the lib will take care of routes updates and transition control.

update : Action -> Model -> (Model, Effects Action)
update action model =
  case action of

    NoOp ->
      (model, Effects.none)

    RouterAction routeAction ->
      TransitRouter.update routerConfig routeAction model

    Foo ->
      (doFoo model, Effects.none)

View

This is where visible part of routing happens. You just have to match current route to render the current route's view, using getRoute:

contentView : Address Action -> Model -> Html
contentView address model =
  case (TransitRouter.getRoute model) of

    Home ->
      homeView address model
    
    --- and so on

Now for animations, there is getTransition, to be used with elm-transit-style (or directly with Transit.getStatus and Transit.getValue from elm-transit).

contentView : Address Action -> Model -> Html
contentView address model =
  div
    [ style (TransitStyle.fadeSlideLeft 100 (getTransition model)) ]
    [ contentView address model ]

Links: use pushPathAddress for clink handling, for instance within that kind of helper:

clickTo : String -> List Attribute
clickTo path =
  [ href path
  , onWithOptions
      "click"
      { stopPropagation = True, preventDefault = True }
      Json.value
      (\_ -> message TransitRouter.pushPathAddress path)
  ]