2019-10-05 01:16:02 +03:00
|
|
|
# ryannhg/elm-app
|
|
|
|
> a way to build single page apps with Elm.
|
|
|
|
|
|
|
|
## try it out
|
|
|
|
|
|
|
|
```
|
|
|
|
elm install ryannhg/elm-app
|
|
|
|
```
|
|
|
|
|
|
|
|
## quick overview
|
|
|
|
|
|
|
|
this package is a wrapper around Elm's `Browser.application`, adding in page transitions and utilities for adding in new pages and routes.
|
|
|
|
|
|
|
|
here's what it looks like to use it:
|
|
|
|
|
|
|
|
|
|
|
|
### src/Main.elm
|
2019-10-05 01:18:12 +03:00
|
|
|
> Uses `Application.create`
|
2019-10-05 01:16:02 +03:00
|
|
|
|
2019-10-05 01:18:12 +03:00
|
|
|
This is the entrypoint to the app, it imports a few things:
|
2019-10-05 01:16:02 +03:00
|
|
|
|
2019-10-05 01:18:12 +03:00
|
|
|
- `Application` - (this package)
|
2019-10-05 01:16:02 +03:00
|
|
|
- `App` - the top level `Model`, `Msg`, `init`, `update`, `subscriptions`, and `view`
|
2019-10-05 01:18:12 +03:00
|
|
|
- `Context` - the shared state between pages.
|
|
|
|
- `Route` - the routes for your application
|
|
|
|
- `Flags` - the initial JSON sent into the app
|
|
|
|
|
2019-10-05 01:16:02 +03:00
|
|
|
|
|
|
|
```elm
|
|
|
|
module Main exposing (main)
|
|
|
|
|
|
|
|
import Application exposing (Application)
|
|
|
|
|
|
|
|
import App
|
|
|
|
import Context
|
|
|
|
import Route
|
|
|
|
import Flags exposing (Flags)
|
|
|
|
|
|
|
|
|
|
|
|
main : Application Flags Context.Model Context.Msg App.Model App.Msg
|
|
|
|
main =
|
|
|
|
Application.create
|
|
|
|
{ transition = 300
|
|
|
|
, toRoute = Route.fromUrl
|
|
|
|
, title = Route.title
|
|
|
|
, context =
|
|
|
|
{ init = Context.init
|
|
|
|
, update = Context.update
|
|
|
|
, view = Context.view
|
|
|
|
, subscriptions = Context.subscriptions
|
|
|
|
}
|
|
|
|
, page =
|
|
|
|
{ init = App.init
|
|
|
|
, update = App.update
|
|
|
|
, view = App.view
|
|
|
|
, subscriptions = App.subscriptions
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### src/Pages/Homepage.elm
|
2019-10-05 01:18:12 +03:00
|
|
|
> uses `Application.Page.static`
|
2019-10-05 01:16:02 +03:00
|
|
|
|
|
|
|
The homepage is static, so it's just a `view`:
|
|
|
|
|
|
|
|
```elm
|
|
|
|
module Pages.Homepage exposing (view)
|
|
|
|
|
|
|
|
import Html exposing (Html)
|
|
|
|
|
|
|
|
|
|
|
|
view : Html Never
|
|
|
|
view =
|
|
|
|
Html.text "Homepage!"
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### src/Pages/Counter.elm
|
2019-10-05 01:18:12 +03:00
|
|
|
> uses `Application.Page.Sandbox`
|
2019-10-05 01:16:02 +03:00
|
|
|
|
|
|
|
The counter page doesn't have any side effects:
|
|
|
|
|
|
|
|
```elm
|
|
|
|
module Pages.Counter exposing (Model, Msg, init, update, view)
|
|
|
|
|
|
|
|
import Html exposing (..)
|
|
|
|
import Html.Events as Events
|
|
|
|
|
|
|
|
|
|
|
|
type alias Model =
|
|
|
|
{ counter : Int
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type Msg
|
|
|
|
= Increment
|
|
|
|
| Decrement
|
|
|
|
|
|
|
|
|
|
|
|
init : Model
|
|
|
|
init =
|
|
|
|
{ counter = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
update : Msg -> Model -> Model
|
|
|
|
update msg model =
|
|
|
|
case msg of
|
|
|
|
Decrement ->
|
|
|
|
{ model | counter = model.counter - 1 }
|
|
|
|
|
|
|
|
Increment ->
|
|
|
|
{ model | counter = model.counter + 1 }
|
|
|
|
|
|
|
|
|
|
|
|
view : Model -> Html Msg
|
|
|
|
view model =
|
|
|
|
div []
|
|
|
|
[ button [ Events.onClick Decrement ] [ text "-" ]
|
|
|
|
, text (String.fromInt model.counter)
|
|
|
|
, button [ Events.onClick Increment ] [ text "+" ]
|
|
|
|
]
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### src/Pages/Random.elm
|
2019-10-05 01:18:12 +03:00
|
|
|
> uses `Application.Page.element`
|
2019-10-05 01:16:02 +03:00
|
|
|
|
|
|
|
The random page doesn't need to update the context of the application:
|
|
|
|
|
|
|
|
```elm
|
|
|
|
module Pages.Random exposing
|
|
|
|
( Model
|
|
|
|
, Msg
|
|
|
|
, init
|
|
|
|
, subscriptions
|
|
|
|
, update
|
|
|
|
, view
|
|
|
|
)
|
|
|
|
|
|
|
|
import Flags exposing (Flags)
|
|
|
|
import Html exposing (..)
|
|
|
|
import Html.Events as Events
|
|
|
|
import Random
|
|
|
|
|
|
|
|
|
|
|
|
type alias Model =
|
2019-10-05 01:18:12 +03:00
|
|
|
{ roll : Maybe Int
|
|
|
|
}
|
2019-10-05 01:16:02 +03:00
|
|
|
|
|
|
|
type Msg
|
2019-10-05 01:18:12 +03:00
|
|
|
= Roll
|
|
|
|
| GotOutcome Int
|
2019-10-05 01:16:02 +03:00
|
|
|
|
|
|
|
|
|
|
|
init : Flags -> ( Model, Cmd Msg )
|
|
|
|
init _ =
|
|
|
|
( { roll = Nothing }
|
|
|
|
, Cmd.none
|
|
|
|
)
|
|
|
|
|
|
|
|
rollDice : Model -> ( Model, Cmd Msg )
|
|
|
|
rollDice model =
|
|
|
|
( model
|
|
|
|
, Random.generate GotOutcome (Random.int 1 6)
|
|
|
|
)
|
|
|
|
|
|
|
|
update : Msg -> Model -> ( Model, Cmd Msg )
|
|
|
|
update msg model =
|
|
|
|
case msg of
|
|
|
|
Roll ->
|
|
|
|
rollDice model
|
|
|
|
|
|
|
|
GotOutcome value ->
|
|
|
|
( { model | roll = Just value }
|
|
|
|
, Cmd.none
|
|
|
|
)
|
|
|
|
|
|
|
|
view : Model -> Html Msg
|
|
|
|
view model =
|
|
|
|
div []
|
|
|
|
[ button [ Events.onClick Roll ] [ text "Roll" ]
|
|
|
|
, p []
|
2019-10-05 01:18:12 +03:00
|
|
|
( case model.roll of
|
2019-10-05 01:16:02 +03:00
|
|
|
Just roll ->
|
2019-10-05 01:18:12 +03:00
|
|
|
[ text (String.fromInt roll) ]
|
2019-10-05 01:16:02 +03:00
|
|
|
Nothing ->
|
2019-10-05 01:18:12 +03:00
|
|
|
[]
|
|
|
|
)
|
2019-10-05 01:16:02 +03:00
|
|
|
]
|
|
|
|
|
|
|
|
subscriptions : Model -> Sub Msg
|
|
|
|
subscriptions model =
|
2019-10-05 01:18:12 +03:00
|
|
|
Sub.none
|
2019-10-05 01:16:02 +03:00
|
|
|
```
|