write docs for new api

This commit is contained in:
Ryan Haskell-Glatz 2019-11-21 18:45:31 -06:00
parent 89e3b99966
commit d54a2711b1
21 changed files with 3336 additions and 153 deletions

2
.gitignore vendored
View File

@ -1,4 +1,4 @@
.DS_Store
./dist
elm-stuff
./node_modules
node_modules

View File

@ -7,7 +7,9 @@
"exposed-modules": [
"Spa",
"Spa.Page",
"Spa.Types"
"Spa.Types",
"Spa.Transition",
"Spa.Path"
],
"elm-version": "0.19.0 <= v < 0.20.0",
"dependencies": {

View File

@ -1,6 +1,6 @@
module Components.Button exposing (view)
import Components.Styles as Styles
import Utils.Styles as Styles
import Element exposing (..)
import Element.Background as Background
import Element.Border as Border

View File

@ -1,6 +1,6 @@
module Components.Hero exposing (Action(..), view)
import Components.Styles as Styles
import Utils.Styles as Styles
import Element exposing (..)
import Element.Input as Input

View File

@ -1,6 +1,6 @@
module Components.Section exposing (view)
import Components.Styles as Styles
import Utils.Styles as Styles
import Element exposing (..)
import Html.Attributes as Attr
import Markdown

View File

@ -1,7 +1,7 @@
module Layout exposing (view)
import Components.Button
import Components.Styles as Styles
import Utils.Styles as Styles
import Element exposing (..)
import Element.Background as Background
import Element.Border as Border
@ -48,7 +48,7 @@ viewNavbar user_ =
, Font.color Styles.colors.coral
, Styles.transition
{ property = "opacity"
, speed = 150
, duration = 150
}
, mouseOver [ alpha 0.6 ]
]

View File

@ -1,6 +1,6 @@
module Layouts.Docs exposing (view)
import Components.Styles as Styles
import Utils.Styles as Styles
import Element exposing (..)
import Element.Font as Font
import Generated.Routes as Routes exposing (Route, routes)

View File

@ -1,6 +1,6 @@
module Layouts.Guide exposing (view)
import Components.Styles as Styles
import Utils.Styles as Styles
import Element exposing (..)
import Utils.Spa as Spa

View File

@ -2,7 +2,7 @@ module Pages.SignIn exposing (Model, Msg, page)
import Spa.Page
import Components.Button
import Components.Styles as Styles
import Utils.Styles as Styles
import Element exposing (..)
import Element.Border as Border
import Element.Font as Font

View File

@ -3,7 +3,7 @@ module Pages.Top exposing (Model, Msg, page)
import Spa.Page
import Components.Hero
import Components.Section
import Components.Styles as Styles
import Utils.Styles as Styles
import Element exposing (..)
import Generated.Params as Params
import Html.Attributes as Attr

View File

@ -1,29 +1,17 @@
module Transitions exposing (transitions)
import Components.Styles as Styles
import Utils.Styles as Styles
import Element exposing (..)
import Generated.Docs.Pages
import Layout
import Layouts.Docs
import Layouts.Guide
import Spa.Path exposing (Path)
import Generated.Docs.Pages as Docs
import Spa.Transition as Transition exposing (Transition)
transitions :
{ layout : Transition (Element msg)
, page : Transition (Element msg)
, pages :
List
{ path : Path
, transition : Transition (Element msg)
}
}
transitions : Transition.Transitions (Element msg)
transitions =
{ layout = Transition.fadeUi 300
, page = Transition.fadeUi 300
, pages =
[ { path = Generated.Docs.Pages.path
[ { path = Docs.path
, transition = batmanNewspaper 600
}
]
@ -35,9 +23,9 @@ transitions =
batmanNewspaper : Int -> Transition (Element msg)
batmanNewspaper speed =
batmanNewspaper duration =
Transition.custom
{ speed = speed
{ duration = duration
, invisible =
\page ->
el
@ -47,7 +35,7 @@ batmanNewspaper speed =
, scale 0
, Styles.transition
{ property = "all"
, speed = speed
, duration = duration
}
]
page
@ -58,7 +46,7 @@ batmanNewspaper speed =
, width fill
, Styles.transition
{ property = "all"
, speed = speed
, duration = duration
}
]
page

View File

@ -10,11 +10,11 @@ module Utils.Spa exposing
, recipe
)
import Spa.Page
import Spa.Types
import Element exposing (Element)
import Generated.Routes as Routes exposing (Route)
import Global
import Spa.Page
import Spa.Types
type alias Page params model msg layoutModel layoutMsg appMsg =
@ -37,14 +37,6 @@ type alias Bundle msg appMsg =
Spa.Types.Bundle Route msg (Element msg) Global.Model Global.Msg appMsg (Element appMsg)
type alias Layout params model msg appMsg =
Spa.Types.Layout Route params model msg (Element msg) Global.Model Global.Msg appMsg (Element appMsg)
type alias Upgrade params model msg layoutModel layoutMsg appMsg =
Spa.Types.Upgrade Route params model msg (Element msg) layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg)
type alias LayoutContext msg =
Spa.Types.LayoutContext Route msg (Element msg) Global.Model Global.Msg
@ -53,6 +45,10 @@ type alias PageContext =
Spa.Types.PageContext Route Global.Model
type alias Layout params model msg appMsg =
Spa.Types.Layout Route params model msg (Element msg) Global.Model Global.Msg appMsg (Element appMsg)
layout :
Layout params model msg appMsg
-> Page params model msg layoutModel layoutMsg appMsg
@ -60,6 +56,10 @@ layout =
Spa.Page.layout Element.map
type alias Upgrade params model msg layoutModel layoutMsg appMsg =
Spa.Types.Upgrade Route params model msg (Element msg) layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg)
recipe :
Upgrade params model msg layoutModel layoutMsg appMsg
-> Recipe params model msg layoutModel layoutMsg appMsg

View File

@ -1,4 +1,4 @@
module Components.Styles exposing
module Utils.Styles exposing
( button
, colors
, fonts
@ -39,7 +39,7 @@ link =
, Font.color colors.coral
, transition
{ property = "opacity"
, speed = 150
, duration = 150
}
, mouseOver
[ alpha 0.6
@ -59,7 +59,7 @@ button =
, pointer
, transition
{ property = "all"
, speed = 150
, duration = 150
}
, mouseOver
[ Font.color colors.white
@ -88,14 +88,14 @@ h3 =
transition :
{ property : String
, speed : Int
, duration : Int
}
-> Attribute msg
transition { property, speed } =
transition { property, duration } =
Element.htmlAttribute
(Attr.style
"transition"
(property ++ " " ++ String.fromInt speed ++ "ms ease-in-out")
(property ++ " " ++ String.fromInt duration ++ "ms ease-in-out")
)

2893
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,22 @@
{
"name": "elm-spa",
"version": "1.0.0",
"description": "",
"description": "a package for building single-page applications!",
"main": "cli/src/index.js",
"bin": "./cli/src/index.js",
"scripts": {
"start": "npm link && npm run dev",
"build": "(cd cli && npm run build)",
"dev": "npm run build && npm run example",
"docs": "elm-doc-preview",
"example": "npm run examples:complex",
"examples:intro": "(cd examples/intro && npm install && npm run dev)",
"examples:complex": "(cd examples/complex && npm install && npm run dev)"
},
"dependencies": {},
"devDependencies": {},
"devDependencies": {
"elm": "0.19.1-3",
"elm-doc-preview": "3.0.4"
},
"keywords": []
}

View File

@ -1,6 +1,6 @@
module Internals.Transition exposing
( Transition
, speed, view
, duration, view
, optOut, none, fadeHtml, fadeUi
, Visibility
, visible, invisible
@ -10,7 +10,7 @@ module Internals.Transition exposing
{-|
@docs Transition
@docs speed, view, chooseFrom
@docs duration, view, chooseFrom
@docs optOut, none, fadeHtml, fadeUi
@docs Visibility
@ -46,7 +46,7 @@ type Transition ui_msg
type alias Options ui_msg =
{ speed : Int
{ duration : Int
, invisible : View ui_msg
, visible : View ui_msg
}
@ -57,8 +57,8 @@ type alias View ui_msg =
-> ui_msg
speed : Transition ui_msg -> Int
speed transition =
duration : Transition ui_msg -> Int
duration transition =
case transition of
OptOut ->
0
@ -67,7 +67,7 @@ speed transition =
0
Transition t ->
t.speed
t.duration
view :
@ -107,7 +107,7 @@ none =
fadeHtml : Int -> Transition (Html msg)
fadeHtml speed_ =
fadeHtml duration_ =
let
withOpacity : Int -> View (Html msg)
withOpacity opacity page =
@ -116,21 +116,21 @@ fadeHtml speed_ =
, Attr.style "transition" <|
String.concat
[ "opacity "
, String.fromInt speed_
, String.fromInt duration_
, "ms ease-in-out"
]
]
[ page ]
in
Transition <|
{ speed = speed_
{ duration = duration_
, invisible = withOpacity 0
, visible = withOpacity 1
}
fadeUi : Int -> Transition (Element msg)
fadeUi speed_ =
fadeUi duration_ =
let
withOpacity : Float -> View (Element msg)
withOpacity opacity page =
@ -142,21 +142,21 @@ fadeUi speed_ =
Attr.style "transition" <|
String.concat
[ "opacity "
, String.fromInt speed_
, String.fromInt duration_
, "ms ease-in-out"
]
]
page
in
Transition <|
{ speed = speed_
{ duration = duration_
, invisible = withOpacity 0
, visible = withOpacity 1
}
custom :
{ speed : Int
{ duration : Int
, invisible : View ui_msg
, visible : View ui_msg
}

View File

@ -1,7 +1,6 @@
module Spa exposing
( Program, create
, usingHtml
, queryParameters
)
{-|
@ -14,17 +13,21 @@ as the entrypoint to your app.
import Global
import Pages
import Routes
import Routes exposing (routes)
import Spa
import Transitions
import Utils.Spa
main : Utils.Spa.Program Pages.Model Pages.Msg
main =
Spa.create
{ ui = Spa.usingHtml
, routing =
{ routes = Routes.parsers
, toPath = Routes.toPath
, notFound = Routes.routes.notFound
, notFound = routes.notFound
}
, transitions = Transitions.transitions
, global =
{ init = Global.init
, update = Global.update
@ -38,7 +41,7 @@ as the entrypoint to your app.
# using elm-ui?
If you're a big fan of [mdgriffith/elm-ui](https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/) (or not-so-big-fan of CSS),
If you're a big fan of [mdgriffith/elm-ui](https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/) (or a "not-so-big-fan of CSS"),
this package supports using `Element msg` instead of `Html msg` for your pages and components.
Providing `Spa.create` with these `ui` options will do the trick!
@ -80,7 +83,7 @@ type alias Program flags globalModel globalMsg layoutModel layoutMsg =
Platform.Program flags (Model flags globalModel layoutModel) (Msg globalMsg layoutMsg)
{-| Pass this in when calling `Spa.create`
{-| If you're just using `elm/html`, you can pass this into `Spa.create`
main =
Spa.create
@ -104,10 +107,11 @@ usingHtml =
{-| Creates a new `Program` given some one-time configuration:
- `ui` - How do we convert the view to `Html msg`?
- `ui` - How do we convert our views into `Html msg`?
- `routing` - What are the app's routes?
- `global` - How do we manage shared state between pages?
- `page` - What pages do we have available?
- `transitions` - How should we transition between routes?
- `global` - How do we share state between pages?
- `page` - What page should we render?
-}
create :
@ -286,7 +290,7 @@ init config flags url key =
[ Cmd.map Page pageCmd
, Cmd.map Global pageGlobalCmd
, Cmd.map Global globalCmd
, Utils.delay (Transition.speed config.routing.transition) FadeInLayout
, Utils.delay (Transition.duration config.routing.transition) FadeInLayout
, cmd
]
)
@ -383,7 +387,7 @@ update config msg model =
ChangedUrl url ->
let
( path, speed ) =
( path, duration ) =
chooseFrom
{ transitions = config.routing.transitions
, from = model.url
@ -391,7 +395,7 @@ update config msg model =
}
|> Just
|> Maybe.withDefault (List.head config.routing.transitions)
|> Maybe.map (\item -> ( item.path, Transition.speed item.transition ))
|> Maybe.map (\item -> ( item.path, Transition.duration item.transition ))
|> Maybe.withDefault ( [], 0 )
in
( { model
@ -404,7 +408,7 @@ update config msg model =
}
, Cmd.batch
[ Utils.delay
speed
duration
(FadeInPage url)
]
)

View File

@ -8,26 +8,34 @@ module Spa.Page exposing
, keep
)
{-| Each page can be as simple or complex as you need:
1. [Static](#static) - a page without state
2. [Sandbox](#sandbox) - a page without side-effects
3. [Element](#element) - a page _with_ side-effects
4. [Component](#component) - a page that can change the global state
{-|
## what's that `always` for?
## Pick the simplest page for the job!
You may notice the examples below use `always`. This is to **opt-out** each
function from reading the global model.
1. [`static`](#static) - a page without state
If you need access to `Global.Model` in your `title`, `init`, `update`, `view`, or
`subscriptions` functions, just remove the always.
2. [`sandbox`](#sandbox) - a page without side-effects
**It is recommended to include this to keep your pages as simple as possible!**
3. [`element`](#element) - a page _with_ side-effects
4. [`component`](#component) - a page that can change the global state
### **heads up:** `always` incoming!
You may notice the examples below use the function `always`.
Page.static
{ title = always "Hello"
, view = always view
}
This is to **opt-out** each function from accessing data like [`PageContext`](./Spa-Types#PageContext)
If you decide you need access to the `Route`, query parameters, or `Global.Model`:
Remove the `always` from `title`, `init`, `update`, `view`, or
`subscriptions` functions.
# static
@ -50,13 +58,12 @@ If you need access to `Global.Model` in your `title`, `init`, `update`, `view`,
@docs component, send
# composing pages together
# manually composing pages?
The rest of this module contains types and functions that
can be generated with the [cli companion tool](https://github.com/ryannhg/elm-spa/tree/master/cli)
are automatically generated with the [CLI companion tool](https://github.com/ryannhg/elm-spa/tree/master/cli)!
If you're typing this stuff manually, you might need to know what
these are for!
If you'd rather type this stuff manually, these docs are for you!
## layout
@ -69,12 +76,23 @@ these are for!
@docs recipe
## what's a "bundle"?
## wait... what's a "bundle"?
We can "bundle" the `view` and `subscriptions` functions together,
because they both only need the current `model`.
We can "bundle" the `title`,`view`, and `subscriptions` functions together,
because they only need access to the current `model`.
So _instead_ of typing out these:
So _instead_ of typing out all this:
title bigModel =
case bigModel of
FooModel model ->
foo.title model
BarModel model ->
bar.title model
BazModel model ->
baz.title model
view bigModel =
case bigModel of
@ -98,7 +116,7 @@ So _instead_ of typing out these:
BazModel model ->
baz.subscriptions model
You only need **one** case expression: (woohoo, less boilerplate!)
You only create **one** case expression: (woohoo, less typing!)
bundle bigModel =
case bigModel of
@ -133,9 +151,9 @@ type alias Page route pageParams pageModel pageMsg ui_pageMsg layoutModel layout
{-| Implementing the `init`, `update` and `bundle` functions is much easier
when you turn a `Page` type into `Recipe`.
when you turn a `Page` type into a `Recipe`.
A `Recipe` contains a record waiting for page specific data.
A `Recipe` is just an Elm record waiting for its page specific data.
- `init`: just needs a `route`
@ -172,8 +190,8 @@ recipe =
Internals.Page.upgrade
{-| In the event that our `case` expression in `update` receives a `msg` that doesn't
match up with it's `model`, we use `keep` to leave the page as-is.
{-| If the `update` function receives a `msg` that doesn't
match up its `model`, we use `keep` to leave the page as-is.
update : Msg -> Model -> Spa.Update Model Msg
update bigMsg bigModel =
@ -427,8 +445,8 @@ element page =
, init = always init
, update = always update
, subscriptions = always subscriptions
-- no always, so `view` gets `Global.Model`
, view = view
, view = view -- no always used here, so view
-- has access to `PageContext`
}
title : String
@ -447,11 +465,14 @@ element page =
subscriptions model =
-- ...
view : Global.Model -> Model -> Html Msg
view global model =
view : Spa.PageContext -> Model -> Html Msg
view { global } model =
case global.user of
SignedIn _ -> viewSignOutForm
SignedOut -> viewSignInForm
SignedIn user ->
viewSignOutForm user model
SignedOut ->
viewSignInForm model
-}
component :
@ -492,7 +513,7 @@ component page =
)
{-| Useful for sending `Global.Msg` from a component.
{-| A utility for sending `Global.Msg` commands from your `Page.component`
init : Params.SignIn -> ( Model, Cmd Msg, Cmd Global.Msg )
init params =

View File

@ -1,21 +1,73 @@
module Spa.Path exposing
( Path
, dynamic
, static
, static, dynamic
)
{-|
## specify transitions for different routes!
If you're using the [CLI companion tool](https://github.com/ryannhg/elm-spa/tree/master/cli),
these are **automatically generated**.
If you're doing things by hand, this documentation might be helpful!
@docs Path
@docs static, dynamic
-}
import Internals.Path as Internals
{-| a `List` of path segments that you use with `Spa.Transition`
transitions : Spa.Transitions (Element msg)
transitions =
{ layout = Transition.none
, page = Transition.none
, pages =
[ -- applies fade to all pages under `/guide/*`
{ path = [ static "guide" ]
, transition = Transition.fadeUi 300
}
]
}
-}
type alias Path =
Internals.Path
{-| A static segment of a path.
[ static "docs" ]
-- /docs
[ static "docs", static "intro" ]
-- /docs/intro
-}
static : String -> Internals.Piece
static =
Internals.static
{-| A dynamic segment of a path.
[ static "docs", dynamic ]
-- /docs/welcome
-- /docs/hello
-- /docs/hooray
[ static "docs", dynamic, static "intro" ]
-- /docs/welcome/intro
-- /docs/hello/intro
-- /docs/hooray/intro
-}
dynamic : Internals.Piece
dynamic =
Internals.dynamic

View File

@ -1,20 +1,50 @@
module Spa.Transition exposing
( Transition
, none, fadeHtml, fadeUi, custom
, none, fadeHtml, fadeUi
, custom
)
{-|
## Create transitions from page to page!
A huge benefit to doing client-side rendering is the ability to
seamlessly navigate from one page to another!
This package is designed to make creating page transitions a breeze!
@docs Transition
@docs none, fadeHtml, fadeUi, custom
# use one of these transitions
@docs none, fadeHtml, fadeUi
# ot roll your own
@docs custom
-}
import Element exposing (Element)
import Html exposing (Html)
import Internals.Path exposing (Path)
import Internals.Transition
{-| Describes how to move from one page to another.
transition : Transition (Html msg)
transition =
Transition.none
anotherTransition : Transition (Element msg)
anotherTransition =
Transition.fadeUi 300
-}
type alias Transition ui_msg =
Internals.Transition.Transition ui_msg
@ -23,23 +53,110 @@ type alias Transition ui_msg =
-- TRANSITIONS
{-| Don't transition from one page to another
transitions : Transitions (Html msg)
transitions =
{ layout = Transition.none -- page loads instantly
, page = Transition.fadeHtml 300
, pages = []
}
-}
none : Transition ui_msg
none =
Internals.Transition.none
{-| Fade one page out and another one in. (For use with `elm/html`)
Animation duration is represented in **milliseconds**
transitions : Spa.Types.Transitions (Html msg)
transitions =
{ layout = Transition.none
, page = Transition.fadeHtml 300 -- 300 milliseconds
, pages = []
}
-}
fadeHtml : Int -> Transition (Html msg)
fadeHtml =
Internals.Transition.fadeHtml
{-| Fade one page out and another one in. (For use with `mdgriffith/elm-ui`)
Animation duration is represented in **milliseconds**
transitions : Spa.Types.Transitions (Element msg)
transitions =
{ layout = Transition.none
, page = Transition.fadeUi 300 -- 300 milliseconds
, pages = []
}
-}
fadeUi : Int -> Transition (Element msg)
fadeUi =
Internals.Transition.fadeUi
{-| Create your own custom transition!
Just provide three things:
- How long (in milliseconds) the transition lasts.
- What the page looks like when invisible.
- What the page looks like when **visible**.
```
batmanNewspaper : Int -> Transition (Element msg)
batmanNewspaper duration =
Transition.custom
{ duration = duration
, invisible =
\page ->
el
[ alpha 0
, width fill
, rotate (4 * pi)
, scale 0
, Styles.transition
{ property = "all"
, duration = duration
}
]
page
, visible =
\page ->
el
[ alpha 1
, width fill
, Styles.transition
{ property = "all"
, duration = duration
}
]
page
}
--
-- using it later on
--
transitions : Spa.Types.Transitions (Element msg)
transitions =
{ layout = batmanNewspaper 500 -- 🦇
, page = Transition.none
, pages = []
}
```
-}
custom :
{ speed : Int
{ duration : Int
, invisible : View ui_msg
, visible : View ui_msg
}

View File

@ -5,24 +5,25 @@ module Spa.Types exposing
, Update
, Bundle
, Layout, Upgrade
, Transitions
, LayoutContext, PageContext
)
{-|
## types so spooky, they got their own module! 👻
## types so spooky, they got their own module!
This module is all about exposing the types that `ryannhg/elm-app` uses
under the hood.
At a glance, there are a **lot of generic types**.
You might notice that there are a **lot of generic types**.
In practice, we can handle this with a single
In practice, we can avoid the messy types with a single
[`Utils/Spa.elm`](https://github.com/ryannhg/elm-spa/blob/master/example/src/Utils/Spa.elm) file that
makes your types easier to understand!
`elm-spa init` generates that file for you, but I've added examples below if you're
`elm-spa init` will generate that file for you, but I've added examples below if you're
doing things by hand.
@ -55,9 +56,22 @@ doing things by hand.
@docs Layout, Upgrade
# transitions
@docs Transitions
# context
@docs LayoutContext, PageContext
-}
import Dict exposing (Dict)
import Internals.Page as Page
import Internals.Path exposing (Path)
import Internals.Transition exposing (Transition)
{-|
@ -73,7 +87,7 @@ import Internals.Page as Page
import Element exposing (Element)
type alias Page params model msg layoutModel layoutMsg appMsg =
Spa.Types.Page params model msg (Element msg) layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg)
Spa.Types.Page Route params model msg (Element msg) layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg)
-- if using elm/html
@ -81,7 +95,7 @@ import Internals.Page as Page
import Html exposing (Html)
type alias Page params model msg layoutModel layoutMsg appMsg =
Spa.Types.Page params model msg (Html msg) layoutModel layoutMsg (Html layoutMsg) Global.Model Global.Msg appMsg (Html appMsg)
Spa.Types.Page Route params model msg (Html msg) layoutModel layoutMsg (Html layoutMsg) Global.Model Global.Msg appMsg (Html appMsg)
## using your alias
@ -112,7 +126,7 @@ type alias Page route params pageModel pageMsg ui_pageMsg layoutModel layoutMsg
import Element exposing (Element)
type alias Recipe params model msg layoutModel layoutMsg appMsg =
Spa.Types.Recipe params model msg layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg)
Spa.Types.Recipe Route params model msg layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg)
-- if using elm/html
@ -120,7 +134,7 @@ type alias Page route params pageModel pageMsg ui_pageMsg layoutModel layoutMsg
import Html exposing (Html)
type alias Recipe params model msg layoutModel layoutMsg appMsg =
Spa.Types.Recipe params model msg layoutModel layoutMsg (Html layoutMsg) Global.Model Global.Msg appMsg (Html appMsg)
Spa.Types.Recipe Route params model msg layoutModel layoutMsg (Html layoutMsg) Global.Model Global.Msg appMsg (Html appMsg)
## using your alias
@ -148,7 +162,7 @@ type alias Recipe route params pageModel pageMsg layoutModel layoutMsg ui_layout
**`src/Utils/Spa.elm`**
type alias Init model msg =
Spa.Types.Init model msg Global.Model Global.Msg
Spa.Types.Init Route model msg Global.Model Global.Msg
## using your alias
@ -175,7 +189,7 @@ type alias Init route layoutModel layoutMsg globalModel globalMsg =
**`src/Utils/Spa.elm`**
type alias Update model msg =
Spa.Types.Update model msg Global.Model Global.Msg
Spa.Types.Update Route model msg Global.Model Global.Msg
## using your alias
@ -207,7 +221,7 @@ type alias Update route layoutModel layoutMsg globalModel globalMsg =
import Element exposing (Element)
type alias Bundle msg appMsg =
Spa.Types.Bundle msg (Element msg) Global.Model Global.Msg appMsg (Element appMsg)
Spa.Types.Bundle Route msg (Element msg) Global.Model Global.Msg appMsg (Element appMsg)
-- if using elm/html
@ -215,7 +229,7 @@ type alias Update route layoutModel layoutMsg globalModel globalMsg =
import Html exposing (Html)
type alias Bundle msg appMsg =
Spa.Types.Bundle msg (Html msg) Global.Model Global.Msg appMsg (Html appMsg)
Spa.Types.Bundle Route msg (Html msg) Global.Model Global.Msg appMsg (Html appMsg)
## using your alias
@ -246,44 +260,135 @@ type alias Bundle route layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg
import Spa.Types
import Element exposing (Element)
type alias Bundle msg appMsg =
Spa.Types.Bundle msg (Element msg) Global.Model Global.Msg appMsg (Element appMsg)
type alias Layout params model msg appMsg =
Spa.Types.Layout Route params model msg (Element msg) Global.Model Global.Msg appMsg (Element appMsg)
-- if using elm/html
import Spa.Types
import Html exposing (Html)
type alias Bundle msg appMsg =
Spa.Types.Bundle msg (Html msg) Global.Model Global.Msg appMsg (Html appMsg)
type alias Layout params model msg appMsg =
Spa.Types.Layout Route params model msg (Html msg) Global.Model Global.Msg appMsg (Html appMsg)
## using your alias
**`.elm-spa/Generated/Pages.elm`**
**`src/Utils/Spa.elm`**
import Utils.Spa as Spa
bundle : Model -> Spa.Bundle Msg msg
bundle model_ =
case model_ of
-- ...
layout :
Layout params model msg appMsg
-> Page params model msg layoutModel layoutMsg appMsg
layout =
Spa.Page.layout Element.map
-}
type alias Layout route pageParams pageModel pageMsg ui_pageMsg globalModel globalMsg msg ui_msg =
Page.Layout route pageParams pageModel pageMsg ui_pageMsg globalModel globalMsg msg ui_msg
{-| TODO: PageContext docs
{-| Describes how to transition between layouts and pages.
transitions : Transitions (Html msg)
transitions =
{ layout = Transition.none -- page loads instantly
, page = Transition.fadeHtml 300
, pages = []
}
-}
type alias Transitions ui_msg =
{ layout : Transition ui_msg
, page : Transition ui_msg
, pages :
List
{ path : Path
, transition : Transition ui_msg
}
}
{-| This is what your `src/Pages/*.elm` files can access!
## creating your alias
**`src/Utils/Spa.elm`**
type alias PageContext =
Spa.Types.PageContext Route Global.Model
## using your alias
**`src/Pages/Top.elm`**
import Utils.Spa as Spa
page =
Page.static
{ title = always "Homepage"
, view = view -- leaving off always here!
}
view : PageContext -> Html Msg
view context =
case context.global.user of
SignedIn user ->
viewUser user
SignedOut ->
text "Who dis?"
-}
type alias PageContext route globalModel =
Page.PageContext route globalModel
{ global : globalModel
, route : route
, queryParameters : Dict String String
}
{-| TODO: LayoutContext docs
{-| This is what your `src/Layouts/*.elm` files can access!
## creating your alias
**`src/Utils/Spa.elm`**
type alias LayoutContext msg =
Spa.Types.LayoutContext Route msg (Element msg) Global.Model Global.Msg
## using your alias
**`src/Layout.elm`**
import Utils.Spa as Spa
view : Spa.LayoutContext msg -> Html msg
view { page, fromGlobalMsg, global } =
div [ class "app" ]
[ Html.map fromGlobalMsg (viewNavbar global)
, page
, viewFooter
]
viewNavbar : Global.Model -> Html Global.Msg
viewNavbar =
-- ...
viewFooter : Html msg
viewFooter =
-- ...
-}
type alias LayoutContext route msg ui_msg globalModel globalMsg =
Page.LayoutContext route msg ui_msg globalModel globalMsg
{ page : ui_msg
, route : route
, global : globalModel
, fromGlobalMsg : globalMsg -> msg
}
{-|
@ -298,28 +403,27 @@ type alias LayoutContext route msg ui_msg globalModel globalMsg =
import Spa.Types
import Element exposing (Element)
type alias Bundle msg appMsg =
Spa.Types.Bundle msg (Element msg) Global.Model Global.Msg appMsg (Element appMsg)
type alias Upgrade params model msg layoutModel layoutMsg appMsg =
Spa.Types.Upgrade Route params model msg (Element msg) layoutModel layoutMsg (Element layoutMsg) Global.Model Global.Msg appMsg (Element appMsg)
-- if using elm/html
import Spa.Types
import Html exposing (Html)
type alias Bundle msg appMsg =
Spa.Types.Bundle msg (Html msg) Global.Model Global.Msg appMsg (Html appMsg)
type alias Upgrade params model msg layoutModel layoutMsg appMsg =
Spa.Types.Upgrade Route params model msg (Html msg) layoutModel layoutMsg (Html layoutMsg) Global.Model Global.Msg appMsg (Html appMsg)
## using your alias
**`.elm-spa/Generated/Pages.elm`**
**`src/Utils/Spa.elm`**
import Utils.Spa as Spa
bundle : Model -> Spa.Bundle Msg msg
bundle model_ =
case model_ of
-- ...
recipe :
Upgrade params model msg layoutModel layoutMsg appMsg
-> Recipe params model msg layoutModel layoutMsg appMsg
recipe =
Spa.Page.recipe Element.map
-}
type alias Upgrade route pageParams pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg =