Confidenceman02 / elm-animate-height / AnimateHeight.Variant.Switch

A slick variant that animates height when switching between your views.

Set up


type Msg


type Config msg


type State view


type Identifier


type Transition view
    = TransitionStart view
    | TransitionEnd view

Transitions that are dispatched in sync with the animation lifecycle.

TransitionStart - Dispatched when an animation starts.

TransitionEnd - Dispatched when an animation ends.

The parameter on each type represents the target view.

TransitionStart view1 -> The transition has started and will switch from the current view to the view1 view.

TransitionEnd view1 -> The transition has ended and the view1 view is rendered.

type YourViews
  = View1
  | View2

yourUpdate msg yourModel =
  case msg of
    SwitchMsg msg ->
      let
          (maybeTransition, updatedState, cmds) =
              update msg yourModel.switchState

          handleTransition =
            case maybeTransition of
              Just ( TransitionStart View1 ) ->
                -- Do something

              Just (TransitionEnd View2) ->
                -- Do something
      in
      ({model | switchState = updatedState}, Cmd.map SwitchMsg cmds)

init : Identifier -> State view

Initialize a Switch State

NOTE: Ensure you store the State structure in your model.

type YourView
    = View1
    | View2

type alias Model =
    { switchState : State YourView
    }

yourInit =
    { switchState = init (identifier "some-unique-string") }

subscriptions : State view -> Platform.Sub.Sub Msg

Subcriptions for the switch.

type alias Model =
    { switchState : State }

type Msg
    = SwitchMsg Switch.Msg

yourSubs : Model -> Sub Msg
yourSubs model =
    Sub.map SwitchMsg <|
        subscriptions model.switchState

update : Msg -> State view -> ( Maybe (Transition view), State view, Platform.Cmd.Cmd Msg )

Add a branch in your update to handle the Switch Msg's.

type alias Model =
    { switchState : State }

type Msg
    = SwitchMsg

yourUpdate : Msg -> Model -> ( Model, Cmd Msg )
yourUpdate msg model =
    case msg of
        SwitchMsg switchMsg ->
            let
                ( transition, newState, cmds ) =
                    update switchMsg model.switchState
            in
            ( { model | switchState = newState }
            , Cmd.map SwitchMsg cmds
            )

make : (Msg -> msg) -> Config msg

A default Config

Argument is a msg that handles Msg's

switchConfig : Config YourViews
switchConfig =
    make SwitchMsg

cubicBezier : Basics.Float -> Basics.Float -> Basics.Float -> Basics.Float -> Config msg -> Config msg

Cubic bezier timing

make SwitchView
    |> cubicBezier 0.1 0.7 1 0.1

ease : Config msg -> Config msg

Ease timing

 make SwitchView
      |> ease

easeIn : Config msg -> Config msg

Ease-in timing

make SwitchView
    |> easeIn

easeInOut : Config msg -> Config msg

Ease-in-out timing

make SwitchView
    |> easeInOut

easeOut : Config msg -> Config msg

Ease-out timing

  make SwitchView
      |> easeOut

linear : Config msg -> Config msg

Linear timing

make SwitchView
    |> linear

fixView : view -> State view -> State view

Set the view without transitions.

Useful for when you want to set an initial view without animating to it.

type YourView
    = View1
    | View2

yourInit : Model
yourInit =
    init (identifier "unique-id")
        |> fixView View1

toView : Maybe view -> State view -> State view

Switch from a current view to a new view.

If no current view exists the incoming view will still transition in.

type alias Model =
    { switchState : State }

type YourMsg
    = ChangeView

yourUpdate model msg =
    case msg of
        ChangeView ->
            let
                newState =
                    toView (Just View2) model.switchState
            in
            ( { model | switchState = newState }, Cmd.none )

view : (view -> List (Html msg)) -> Config msg -> State view -> Html msg

Render the switch view

type YourView
    = View1
    | View2
    | View3

viewResolver : YourView -> List (Html msg)
viewResolver v =
    case v of
        View1 ->
            [ text "View 1" ]

        View2 ->
            [ text "View 2" ]

        View3 ->
            [ text "View 3" ]

yourView : Model -> Html Msg
yourView model =
    view viewResolver (make SwitchView) model.switchView

identifier : String -> Identifier

A unique indentifier that Switch uses internally.

NOTE: The String passed must be unique.