begin transitions work

This commit is contained in:
Ryan Haskell-Glatz 2019-11-18 18:28:47 -06:00
parent 4ed173c2fc
commit 92be461f6d
10 changed files with 281 additions and 29 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
.DS_Store .DS_Store
./dist ./dist
elm-stuff/0.19.1 elm-stuff
!elm-stuff/.elm-spa
./node_modules ./node_modules

View File

@ -2,8 +2,9 @@
> for building single page apps > for building single page apps
## run the example! ## local development
``` ```
npm run example npm run dev
``` ```

6
elm-analyse.json Normal file
View File

@ -0,0 +1,6 @@
{
"checks" : {
"SingleFieldRecord": false,
"ImportAll": false
}
}

View File

@ -1,20 +1,21 @@
{ {
"type": "package", "type": "package",
"name": "ryannhg/elm-app", "name": "ryannhg/elm-app",
"summary": "a way to build single page apps with Elm", "summary": "a way to build single page apps with Elm",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"version": "1.0.0", "version": "1.0.0",
"exposed-modules": [ "exposed-modules": [
"App", "App",
"App.Page", "App.Page",
"App.Types" "App.Types"
], ],
"elm-version": "0.19.0 <= v < 0.20.0", "elm-version": "0.19.0 <= v < 0.20.0",
"dependencies": { "dependencies": {
"elm/browser": "1.0.0 <= v < 2.0.0", "elm/browser": "1.0.0 <= v < 2.0.0",
"elm/core": "1.0.0 <= v < 2.0.0", "elm/core": "1.0.0 <= v < 2.0.0",
"elm/html": "1.0.0 <= v < 2.0.0", "elm/html": "1.0.0 <= v < 2.0.0",
"elm/url": "1.0.0 <= v < 2.0.0" "elm/url": "1.0.0 <= v < 2.0.0",
}, "mdgriffith/elm-ui": "1.1.5 <= v < 2.0.0"
"test-dependencies": {} },
"test-dependencies": {}
} }

View File

@ -3,7 +3,7 @@
"source-directories": [ "source-directories": [
"src", "src",
"../../src", "../../src",
"elm-stuff/.generated" "elm-stuff/.elm-spa"
], ],
"elm-version": "0.19.1", "elm-version": "0.19.1",
"dependencies": { "dependencies": {

View File

@ -1,6 +1,7 @@
module Main exposing (main) module Main exposing (main)
import App import App
import App.Transition as Transition
import Element import Element
import Generated.Pages as Pages import Generated.Pages as Pages
import Generated.Routes as Routes import Generated.Routes as Routes
@ -15,7 +16,8 @@ main =
, map = Element.map , map = Element.map
} }
, routing = , routing =
{ routes = Routes.parsers { transition = Transition.fadeUi 300
, routes = Routes.parsers
, toPath = Routes.toPath , toPath = Routes.toPath
, notFound = Routes.routes.notFound , notFound = Routes.routes.notFound
} }

View File

@ -11,8 +11,6 @@ module App exposing
`App.create` replaces [Browser.application](https://package.elm-lang.org/packages/elm/browser/latest/Browser#application) `App.create` replaces [Browser.application](https://package.elm-lang.org/packages/elm/browser/latest/Browser#application)
as the entrypoint to your app. as the entrypoint to your app.
module Main exposing (main)
import App import App
import Global import Global
import Pages import Pages
@ -63,6 +61,7 @@ import Browser
import Browser.Navigation as Nav import Browser.Navigation as Nav
import Html exposing (Html) import Html exposing (Html)
import Internals.Page as Page import Internals.Page as Page
import Internals.Transition as Transition exposing (Transition)
import Internals.Utils as Utils import Internals.Utils as Utils
import Url exposing (Url) import Url exposing (Url)
import Url.Parser as Parser exposing (Parser) import Url.Parser as Parser exposing (Parser)
@ -114,7 +113,8 @@ create :
, map : (layoutMsg -> Msg globalMsg layoutMsg) -> ui_layoutMsg -> ui_msg , map : (layoutMsg -> Msg globalMsg layoutMsg) -> ui_layoutMsg -> ui_msg
} }
, routing : , routing :
{ routes : List (Parser (route -> route) route) { transition : Transition ui_msg
, routes : List (Parser (route -> route) route)
, toPath : route -> String , toPath : route -> String
, notFound : route , notFound : route
} }
@ -154,6 +154,7 @@ create config =
, routing = , routing =
{ fromUrl = fromUrl config.routing { fromUrl = fromUrl config.routing
, toPath = config.routing.toPath , toPath = config.routing.toPath
, transition = config.routing.transition
} }
} }
, update = , update =
@ -180,6 +181,7 @@ create config =
{ toHtml = config.ui.toHtml { toHtml = config.ui.toHtml
, bundle = page.bundle , bundle = page.bundle
, map = config.ui.map , map = config.ui.map
, transition = config.routing.transition
} }
, onUrlChange = ChangedUrl , onUrlChange = ChangedUrl
, onUrlRequest = ClickedLink , onUrlRequest = ClickedLink
@ -210,6 +212,10 @@ type alias Model flags globalModel model =
, key : Nav.Key , key : Nav.Key
, global : globalModel , global : globalModel
, page : model , page : model
, visibilities :
{ layout : Transition.Visibility
, page : Transition.Visibility
}
} }
@ -217,6 +223,7 @@ init :
{ routing : { routing :
{ fromUrl : Url -> route { fromUrl : Url -> route
, toPath : route -> String , toPath : route -> String
, transition : Transition ui_msg
} }
, init : , init :
{ global : { global :
@ -249,11 +256,16 @@ init config flags url key =
, key = key , key = key
, global = globalModel , global = globalModel
, page = pageModel , page = pageModel
, visibilities =
{ layout = Transition.invisible
, page = Transition.visible
}
} }
, Cmd.batch , Cmd.batch
[ Cmd.map Page pageCmd [ Cmd.map Page pageCmd
, Cmd.map Global pageGlobalCmd , Cmd.map Global pageGlobalCmd
, Cmd.map Global globalCmd , Cmd.map Global globalCmd
, Utils.delay (Transition.speed config.routing.transition) FadeInLayout
, cmd , cmd
] ]
) )
@ -269,6 +281,7 @@ type Msg globalMsg msg
| ClickedLink Browser.UrlRequest | ClickedLink Browser.UrlRequest
| Global globalMsg | Global globalMsg
| Page msg | Page msg
| FadeInLayout
update : update :
@ -295,6 +308,16 @@ update :
-> ( Model flags globalModel layoutModel, Cmd (Msg globalMsg layoutMsg) ) -> ( Model flags globalModel layoutModel, Cmd (Msg globalMsg layoutMsg) )
update config msg model = update config msg model =
case msg of case msg of
FadeInLayout ->
( { model
| visibilities =
{ layout = Transition.visible
, page = model.visibilities.page
}
}
, Cmd.none
)
ClickedLink (Browser.Internal url) -> ClickedLink (Browser.Internal url) ->
if url == model.url then if url == model.url then
( model, Cmd.none ) ( model, Cmd.none )
@ -395,6 +418,7 @@ view :
, bundle : , bundle :
layoutModel layoutModel
-> Page.Bundle layoutMsg ui_layoutMsg globalModel globalMsg (Msg globalMsg layoutMsg) ui_msg -> Page.Bundle layoutMsg ui_layoutMsg globalModel globalMsg (Msg globalMsg layoutMsg) ui_msg
, transition : Transition ui_msg
} }
-> Model flags globalModel layoutModel -> Model flags globalModel layoutModel
-> Browser.Document (Msg globalMsg layoutMsg) -> Browser.Document (Msg globalMsg layoutMsg)
@ -411,6 +435,10 @@ view config model =
in in
{ title = bundle.title { title = bundle.title
, body = , body =
[ config.toHtml bundle.view [ config.toHtml <|
Transition.view
config.transition
model.visibilities.layout
{ layout = identity, page = bundle.view }
] ]
} }

43
src/App/Transition.elm Normal file
View File

@ -0,0 +1,43 @@
module App.Transition exposing
( Transition
, optOut, none, fadeHtml, fadeUi
)
{-|
@docs Transition
@docs optOut, none, fadeHtml, fadeUi
-}
import Element exposing (Element)
import Html exposing (Html)
import Internals.Transition
type alias Transition ui_msg =
Internals.Transition.Transition ui_msg
-- TRANSITIONS
optOut : Transition ui_msg
optOut =
Internals.Transition.optOut
none : Transition ui_msg
none =
Internals.Transition.none
fadeHtml : Int -> Transition (Html msg)
fadeHtml =
Internals.Transition.fadeHtml
fadeUi : Int -> Transition (Element msg)
fadeUi =
Internals.Transition.fadeUi

View File

@ -0,0 +1,162 @@
module Internals.Transition exposing
( Transition
, speed, view
, optOut, none, fadeHtml, fadeUi
, Visibility
, visible, invisible
)
{-|
@docs Transition
@docs speed, view
@docs optOut, none, fadeHtml, fadeUi
@docs Visibility
@docs visible, invisible
-}
import Element exposing (Element)
import Html exposing (Html)
import Html.Attributes as Attr
type Visibility
= Invisible
| Visible
visible : Visibility
visible =
Visible
invisible : Visibility
invisible =
Invisible
type Transition ui_msg
= OptOut
| None
| Transition (Transition_ ui_msg)
type alias Transition_ ui_msg =
{ speed : Int
, invisible : View ui_msg
, visible : View ui_msg
}
type alias View ui_msg =
{ layout : ui_msg -> ui_msg
, page : ui_msg
}
-> ui_msg
speed : Transition ui_msg -> Int
speed transition =
case transition of
OptOut ->
0
None ->
0
Transition t ->
t.speed
view :
Transition ui_msg
-> Visibility
->
{ layout : ui_msg -> ui_msg
, page : ui_msg
}
-> ui_msg
view transition visibility ({ layout, page } as record) =
case transition of
OptOut ->
layout page
None ->
layout page
Transition t ->
case visibility of
Visible ->
t.visible record
Invisible ->
t.invisible record
-- TRANSITIONS
optOut : Transition ui_msg
optOut =
OptOut
none : Transition ui_msg
none =
None
fadeHtml : Int -> Transition (Html msg)
fadeHtml speed_ =
let
withOpacity : Int -> View (Html msg)
withOpacity opacity { layout, page } =
layout
(Html.div
[ Attr.style "opacity" (String.fromInt opacity)
, Attr.style "transition" <|
String.concat
[ "opacity "
, String.fromInt speed_
, "ms ease-in-out"
]
]
[ page ]
)
in
Transition <|
{ speed = speed_
, invisible = withOpacity 0
, visible = withOpacity 1
}
fadeUi : Int -> Transition (Element msg)
fadeUi speed_ =
let
withOpacity : Float -> View (Element msg)
withOpacity opacity { layout, page } =
layout
(Element.el
[ Element.width Element.fill
, Element.height Element.fill
, Element.alpha opacity
, Element.htmlAttribute <|
Attr.style "transition" <|
String.concat
[ "opacity "
, String.fromInt speed_
, "ms ease-in-out"
]
]
page
)
in
Transition <|
{ speed = speed_
, invisible = withOpacity 0
, visible = withOpacity 1
}

View File

@ -1,2 +1,10 @@
# ryannhg/elm-app # ryannhg/elm-app
> the elm package that makes building `elm-spa` super easy! > the elm package that makes building `elm-spa` super easy!
## local development
```
npm run dev
```