mirror of
https://github.com/ryannhg/elm-spa.git
synced 2024-11-23 02:04:22 +03:00
its not perfect yet, but im super happy. thx hayley williams for getting me through this absolute mind-🤬
This commit is contained in:
parent
92be461f6d
commit
c77993f0d2
@ -231,16 +231,29 @@ type Item
|
||||
| DynamicFolder Filepath
|
||||
|
||||
|
||||
routeCaseTemplate : Item -> String
|
||||
routeCaseTemplate item =
|
||||
case item of
|
||||
StaticFile filepath ->
|
||||
staticRouteCase : String -> String
|
||||
staticRouteCase word =
|
||||
case word of
|
||||
"Top" ->
|
||||
"""
|
||||
Top _ ->
|
||||
"/"
|
||||
"""
|
||||
|
||||
last_ ->
|
||||
"""
|
||||
{{name}} _ ->
|
||||
"/{{slug}}"
|
||||
"""
|
||||
|> String.replace "{{name}}" (last filepath)
|
||||
|> String.replace "{{slug}}" (sluggify (last filepath))
|
||||
|> String.replace "{{name}}" last_
|
||||
|> String.replace "{{slug}}" (sluggify last_)
|
||||
|
||||
|
||||
routeCaseTemplate : Item -> String
|
||||
routeCaseTemplate item =
|
||||
case item of
|
||||
StaticFile filepath ->
|
||||
staticRouteCase (last filepath)
|
||||
|
||||
DynamicFile _ ->
|
||||
"""
|
||||
@ -321,6 +334,7 @@ module {{pagesModuleName}} exposing
|
||||
)
|
||||
|
||||
import App.Page
|
||||
import App.Pattern exposing (static, dynamic)
|
||||
import {{layoutModuleName}} as Layout
|
||||
import Utils.Spa as Spa
|
||||
import {{paramsModuleName}} as Params
|
||||
@ -339,7 +353,9 @@ import {{routeModuleName}} as Route exposing (Route)
|
||||
page : Spa.Page Route Model Msg layoutModel layoutMsg appMsg
|
||||
page =
|
||||
Spa.layout
|
||||
{ view = Layout.view
|
||||
{ pattern = {{pagesLayoutPattern}}
|
||||
, transition = Layout.transition
|
||||
, view = Layout.view
|
||||
, recipe =
|
||||
{ init = init
|
||||
, update = update
|
||||
@ -400,6 +416,7 @@ bundle bigModel =
|
||||
|> String.replace "{{pagesFolderPagesImports}}" (pagesFolderImports "Pages" details.folders)
|
||||
|> String.replace "{{pagesModelTypes}}" (pagesCustomTypes "Model" details)
|
||||
|> String.replace "{{pagesMsgTypes}}" (pagesCustomTypes "Msg" details)
|
||||
|> String.replace "{{pagesLayoutPattern}}" (pagesLayoutPattern details)
|
||||
|> String.replace "{{pagesRecipesTypeAliases}}" (pagesRecipesTypeAliases details)
|
||||
|> String.replace "{{pagesRecipesFunctions}}" (pagesRecipesFunctions details)
|
||||
|> String.replace "{{pagesInitFunction}}" (pagesInitFunction details)
|
||||
@ -451,6 +468,27 @@ pagesFolderImports suffix folders =
|
||||
|> asImports
|
||||
|
||||
|
||||
pagesLayoutPattern : Details -> String
|
||||
pagesLayoutPattern { moduleName } =
|
||||
String.split "." moduleName
|
||||
|> List.map
|
||||
(\piece ->
|
||||
case piece of
|
||||
"Dynamic" ->
|
||||
"dynamic"
|
||||
|
||||
_ ->
|
||||
"static \"" ++ sluggify piece ++ "\""
|
||||
)
|
||||
|> (\pieces ->
|
||||
if List.isEmpty pieces || pieces == [ "static \"\"" ] then
|
||||
"[]"
|
||||
|
||||
else
|
||||
"[ " ++ String.join ", " pieces ++ " ]"
|
||||
)
|
||||
|
||||
|
||||
pagesCustomTypes : String -> Details -> String
|
||||
pagesCustomTypes type_ { files, folders } =
|
||||
let
|
||||
|
@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env node
|
||||
const path = require('path')
|
||||
const cwd = process.cwd()
|
||||
const { File, Elm, bold } = require('./utils.js')
|
||||
|
@ -5,6 +5,7 @@ module Generated.Docs.Pages exposing
|
||||
)
|
||||
|
||||
import App.Page
|
||||
import App.Pattern exposing (static, dynamic)
|
||||
import Layouts.Docs as Layout
|
||||
import Utils.Spa as Spa
|
||||
import Generated.Docs.Params as Params
|
||||
@ -28,7 +29,9 @@ type Msg
|
||||
page : Spa.Page Route Model Msg layoutModel layoutMsg appMsg
|
||||
page =
|
||||
Spa.layout
|
||||
{ view = Layout.view
|
||||
{ pattern = [ static "docs" ]
|
||||
, transition = Layout.transition
|
||||
, view = Layout.view
|
||||
, recipe =
|
||||
{ init = init
|
||||
, update = update
|
||||
|
@ -5,6 +5,7 @@ module Generated.Guide.Dynamic.Dynamic.Pages exposing
|
||||
)
|
||||
|
||||
import App.Page
|
||||
import App.Pattern exposing (static, dynamic)
|
||||
import Layouts.Guide.Dynamic.Dynamic as Layout
|
||||
import Utils.Spa as Spa
|
||||
import Generated.Guide.Dynamic.Dynamic.Params as Params
|
||||
@ -25,7 +26,9 @@ type Msg
|
||||
page : Spa.Page Route Model Msg layoutModel layoutMsg appMsg
|
||||
page =
|
||||
Spa.layout
|
||||
{ view = Layout.view
|
||||
{ pattern = [ static "guide", dynamic, dynamic ]
|
||||
, transition = Layout.transition
|
||||
, view = Layout.view
|
||||
, recipe =
|
||||
{ init = init
|
||||
, update = update
|
||||
|
@ -14,4 +14,4 @@ toPath : Route -> String
|
||||
toPath route =
|
||||
case route of
|
||||
Top _ ->
|
||||
"/top"
|
||||
"/"
|
@ -5,6 +5,7 @@ module Generated.Guide.Dynamic.Faq.Pages exposing
|
||||
)
|
||||
|
||||
import App.Page
|
||||
import App.Pattern exposing (static, dynamic)
|
||||
import Layouts.Guide.Dynamic.Faq as Layout
|
||||
import Utils.Spa as Spa
|
||||
import Generated.Guide.Dynamic.Faq.Params as Params
|
||||
@ -25,7 +26,9 @@ type Msg
|
||||
page : Spa.Page Route Model Msg layoutModel layoutMsg appMsg
|
||||
page =
|
||||
Spa.layout
|
||||
{ view = Layout.view
|
||||
{ pattern = [ static "guide", dynamic, static "faq" ]
|
||||
, transition = Layout.transition
|
||||
, view = Layout.view
|
||||
, recipe =
|
||||
{ init = init
|
||||
, update = update
|
||||
|
@ -14,4 +14,4 @@ toPath : Route -> String
|
||||
toPath route =
|
||||
case route of
|
||||
Top _ ->
|
||||
"/top"
|
||||
"/"
|
@ -5,6 +5,7 @@ module Generated.Guide.Dynamic.Pages exposing
|
||||
)
|
||||
|
||||
import App.Page
|
||||
import App.Pattern exposing (static, dynamic)
|
||||
import Layouts.Guide.Dynamic as Layout
|
||||
import Utils.Spa as Spa
|
||||
import Generated.Guide.Dynamic.Params as Params
|
||||
@ -34,7 +35,9 @@ type Msg
|
||||
page : Spa.Page Route Model Msg layoutModel layoutMsg appMsg
|
||||
page =
|
||||
Spa.layout
|
||||
{ view = Layout.view
|
||||
{ pattern = [ static "guide", dynamic ]
|
||||
, transition = Layout.transition
|
||||
, view = Layout.view
|
||||
, recipe =
|
||||
{ init = init
|
||||
, update = update
|
||||
|
@ -5,6 +5,7 @@ module Generated.Guide.Pages exposing
|
||||
)
|
||||
|
||||
import App.Page
|
||||
import App.Pattern exposing (static, dynamic)
|
||||
import Layouts.Guide as Layout
|
||||
import Utils.Spa as Spa
|
||||
import Generated.Guide.Params as Params
|
||||
@ -33,7 +34,9 @@ type Msg
|
||||
page : Spa.Page Route Model Msg layoutModel layoutMsg appMsg
|
||||
page =
|
||||
Spa.layout
|
||||
{ view = Layout.view
|
||||
{ pattern = [ static "guide" ]
|
||||
, transition = Layout.transition
|
||||
, view = Layout.view
|
||||
, recipe =
|
||||
{ init = init
|
||||
, update = update
|
||||
|
@ -5,6 +5,7 @@ module Generated.Pages exposing
|
||||
)
|
||||
|
||||
import App.Page
|
||||
import App.Pattern exposing (static, dynamic)
|
||||
import Layout as Layout
|
||||
import Utils.Spa as Spa
|
||||
import Generated.Params as Params
|
||||
@ -43,7 +44,9 @@ type Msg
|
||||
page : Spa.Page Route Model Msg layoutModel layoutMsg appMsg
|
||||
page =
|
||||
Spa.layout
|
||||
{ view = Layout.view
|
||||
{ pattern = []
|
||||
, transition = Layout.transition
|
||||
, view = Layout.view
|
||||
, recipe =
|
||||
{ init = init
|
||||
, update = update
|
||||
|
@ -38,7 +38,7 @@ toPath route =
|
||||
|
||||
|
||||
Top _ ->
|
||||
"/top"
|
||||
"/"
|
||||
|
||||
|
||||
Docs_Folder subRoute ->
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Layout exposing (view)
|
||||
module Layout exposing (transition, view)
|
||||
|
||||
import App.Page
|
||||
import App.Transition as Transition exposing (Transition)
|
||||
import Components.Button
|
||||
import Components.Styles as Styles
|
||||
import Element exposing (..)
|
||||
@ -19,6 +20,11 @@ type alias Context msg =
|
||||
}
|
||||
|
||||
|
||||
transition : Transition (Element msg)
|
||||
transition =
|
||||
Transition.fadeUi 300
|
||||
|
||||
|
||||
view : Context msg -> Element msg
|
||||
view { page, global, toMsg } =
|
||||
column
|
||||
@ -93,14 +99,3 @@ viewButtonLink ( label, url ) =
|
||||
{ url = url
|
||||
, label = text label
|
||||
}
|
||||
|
||||
|
||||
transition :
|
||||
{ property : String, speed : Int }
|
||||
-> Element.Attribute msg
|
||||
transition { property, speed } =
|
||||
Element.htmlAttribute
|
||||
(Attr.style
|
||||
"transition"
|
||||
(property ++ " " ++ String.fromInt speed ++ "ms ease-in-out")
|
||||
)
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Layouts.Docs exposing (view)
|
||||
module Layouts.Docs exposing (transition, view)
|
||||
|
||||
import App.Transition as Transition exposing (Transition)
|
||||
import Element exposing (..)
|
||||
import Global
|
||||
|
||||
@ -11,6 +12,17 @@ type alias Context msg =
|
||||
}
|
||||
|
||||
|
||||
transition : Transition (Element msg)
|
||||
transition =
|
||||
Transition.fadeUi 200
|
||||
|
||||
|
||||
view : Context msg -> Element msg
|
||||
view { page } =
|
||||
page
|
||||
column [ width fill ]
|
||||
[ row [ spacing 16 ]
|
||||
[ link [] { label = text "apples", url = "/docs/apples" }
|
||||
, link [] { label = text "bananas", url = "/docs/bananas" }
|
||||
]
|
||||
, page
|
||||
]
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Layouts.Guide exposing (view)
|
||||
module Layouts.Guide exposing (transition, view)
|
||||
|
||||
import App.Transition as Transition exposing (Transition)
|
||||
import Components.Styles as Styles
|
||||
import Element exposing (..)
|
||||
import Global
|
||||
@ -12,6 +13,11 @@ type alias Context msg =
|
||||
}
|
||||
|
||||
|
||||
transition : Transition (Element msg)
|
||||
transition =
|
||||
Transition.fadeUi 3000
|
||||
|
||||
|
||||
view : Context msg -> Element msg
|
||||
view { page } =
|
||||
column
|
||||
|
@ -1,9 +1,15 @@
|
||||
module Layouts.Guide.Dynamic exposing (view)
|
||||
module Layouts.Guide.Dynamic exposing (transition, view)
|
||||
|
||||
import App.Transition as Transition exposing (Transition)
|
||||
import Element exposing (..)
|
||||
import Global
|
||||
|
||||
|
||||
transition : Transition (Element msg)
|
||||
transition =
|
||||
Transition.optOut
|
||||
|
||||
|
||||
type alias Context msg =
|
||||
{ page : Element msg
|
||||
, global : Global.Model
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Layouts.Guide.Dynamic.Dynamic exposing (view)
|
||||
module Layouts.Guide.Dynamic.Dynamic exposing (transition, view)
|
||||
|
||||
import App.Transition as Transition exposing (Transition)
|
||||
import Element exposing (..)
|
||||
import Global
|
||||
|
||||
@ -11,6 +12,11 @@ type alias Context msg =
|
||||
}
|
||||
|
||||
|
||||
transition : Transition (Element msg)
|
||||
transition =
|
||||
Transition.optOut
|
||||
|
||||
|
||||
view : Context msg -> Element msg
|
||||
view { page } =
|
||||
page
|
||||
|
@ -1,5 +1,6 @@
|
||||
module Layouts.Guide.Dynamic.Faq exposing (view)
|
||||
module Layouts.Guide.Dynamic.Faq exposing (transition, view)
|
||||
|
||||
import App.Transition as Transition exposing (Transition)
|
||||
import Element exposing (..)
|
||||
import Global
|
||||
|
||||
@ -11,6 +12,11 @@ type alias Context msg =
|
||||
}
|
||||
|
||||
|
||||
transition : Transition (Element msg)
|
||||
transition =
|
||||
Transition.optOut
|
||||
|
||||
|
||||
view : Context msg -> Element msg
|
||||
view { page } =
|
||||
page
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Main exposing (main)
|
||||
|
||||
import App
|
||||
import App.Pattern as Pattern
|
||||
import App.Transition as Transition
|
||||
import Element
|
||||
import Generated.Pages as Pages
|
||||
@ -17,6 +18,11 @@ main =
|
||||
}
|
||||
, routing =
|
||||
{ transition = Transition.fadeUi 300
|
||||
, patterns =
|
||||
[ ( [], Transition.fadeUi 300 )
|
||||
, ( [ Pattern.static "guide" ], Transition.fadeUi 3000 )
|
||||
, ( [ Pattern.static "docs" ], Transition.fadeUi 200 )
|
||||
]
|
||||
, routes = Routes.parsers
|
||||
, toPath = Routes.toPath
|
||||
, notFound = Routes.routes.notFound
|
||||
|
101
src/App.elm
101
src/App.elm
@ -61,6 +61,7 @@ import Browser
|
||||
import Browser.Navigation as Nav
|
||||
import Html exposing (Html)
|
||||
import Internals.Page as Page
|
||||
import Internals.Pattern as Pattern exposing (Pattern)
|
||||
import Internals.Transition as Transition exposing (Transition)
|
||||
import Internals.Utils as Utils
|
||||
import Url exposing (Url)
|
||||
@ -117,6 +118,7 @@ create :
|
||||
, routes : List (Parser (route -> route) route)
|
||||
, toPath : route -> String
|
||||
, notFound : route
|
||||
, patterns : List ( Pattern, Transition ui_msg )
|
||||
}
|
||||
, global :
|
||||
{ init :
|
||||
@ -163,6 +165,7 @@ create config =
|
||||
{ fromUrl = fromUrl config.routing
|
||||
, toPath = config.routing.toPath
|
||||
, routes = config.routing.routes
|
||||
, patterns = config.routing.patterns
|
||||
}
|
||||
, init = page.init
|
||||
, update =
|
||||
@ -175,6 +178,7 @@ create config =
|
||||
{ bundle = page.bundle
|
||||
, map = config.ui.map
|
||||
, global = config.global.subscriptions
|
||||
, transition = config.routing.transition
|
||||
}
|
||||
, view =
|
||||
view
|
||||
@ -212,6 +216,7 @@ type alias Model flags globalModel model =
|
||||
, key : Nav.Key
|
||||
, global : globalModel
|
||||
, page : model
|
||||
, transitioningPattern : Pattern
|
||||
, visibilities :
|
||||
{ layout : Transition.Visibility
|
||||
, page : Transition.Visibility
|
||||
@ -256,6 +261,7 @@ init config flags url key =
|
||||
, key = key
|
||||
, global = globalModel
|
||||
, page = pageModel
|
||||
, transitioningPattern = []
|
||||
, visibilities =
|
||||
{ layout = Transition.invisible
|
||||
, page = Transition.visible
|
||||
@ -282,6 +288,7 @@ type Msg globalMsg msg
|
||||
| Global globalMsg
|
||||
| Page msg
|
||||
| FadeInLayout
|
||||
| FadeInPage Url
|
||||
|
||||
|
||||
update :
|
||||
@ -289,6 +296,7 @@ update :
|
||||
{ fromUrl : Url -> route
|
||||
, toPath : route -> String
|
||||
, routes : Routes route a
|
||||
, patterns : List ( Pattern, Transition ui_msg )
|
||||
}
|
||||
, init : route -> Page.Init layoutModel layoutMsg globalModel globalMsg
|
||||
, update :
|
||||
@ -318,6 +326,22 @@ update config msg model =
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
FadeInPage url ->
|
||||
url
|
||||
|> config.routing.fromUrl
|
||||
|> (\route -> config.init route { global = model.global })
|
||||
|> (\( pageModel, pageCmd, globalCmd ) ->
|
||||
( { model
|
||||
| visibilities = { layout = Transition.visible, page = Transition.visible }
|
||||
, page = pageModel
|
||||
}
|
||||
, Cmd.batch
|
||||
[ Cmd.map Page pageCmd
|
||||
, Cmd.map Global globalCmd
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
ClickedLink (Browser.Internal url) ->
|
||||
if url == model.url then
|
||||
( model, Cmd.none )
|
||||
@ -333,20 +357,32 @@ update config msg model =
|
||||
)
|
||||
|
||||
ChangedUrl url ->
|
||||
url
|
||||
|> config.routing.fromUrl
|
||||
|> (\route -> config.init route { global = model.global })
|
||||
|> (\( pageModel, pageCmd, globalCmd ) ->
|
||||
( { model
|
||||
| url = url
|
||||
, page = pageModel
|
||||
}
|
||||
, Cmd.batch
|
||||
[ Cmd.map Page pageCmd
|
||||
, Cmd.map Global globalCmd
|
||||
]
|
||||
)
|
||||
)
|
||||
let
|
||||
( pattern, speed ) =
|
||||
chooseFrom
|
||||
{ patternTransitions = config.routing.patterns
|
||||
, from = model.url
|
||||
, to = url
|
||||
}
|
||||
|> Just
|
||||
|> Maybe.withDefault (List.head config.routing.patterns)
|
||||
|> Maybe.map (Tuple.mapSecond Transition.speed)
|
||||
|> Maybe.withDefault ( [], 0 )
|
||||
in
|
||||
( { model
|
||||
| url = url
|
||||
, visibilities =
|
||||
{ layout = Transition.visible
|
||||
, page = Transition.invisible
|
||||
}
|
||||
, transitioningPattern = pattern
|
||||
}
|
||||
, Cmd.batch
|
||||
[ Utils.delay
|
||||
speed
|
||||
(FadeInPage url)
|
||||
]
|
||||
)
|
||||
|
||||
Global globalMsg ->
|
||||
config.update.global
|
||||
@ -391,6 +427,7 @@ subscriptions :
|
||||
layoutModel
|
||||
-> Page.Bundle layoutMsg ui_layoutMsg globalModel globalMsg (Msg globalMsg layoutMsg) ui_msg
|
||||
, global : globalModel -> Sub globalMsg
|
||||
, transition : Transition ui_msg
|
||||
}
|
||||
-> Model flags globalModel layoutModel
|
||||
-> Sub (Msg globalMsg layoutMsg)
|
||||
@ -402,6 +439,8 @@ subscriptions config model =
|
||||
, fromPageMsg = Page
|
||||
, global = model.global
|
||||
, map = config.map
|
||||
, transitioningPattern = model.transitioningPattern
|
||||
, visibility = model.visibilities.page
|
||||
}
|
||||
).subscriptions
|
||||
, Sub.map Global (config.global model.global)
|
||||
@ -431,6 +470,8 @@ view config model =
|
||||
, fromPageMsg = Page
|
||||
, global = model.global
|
||||
, map = config.map
|
||||
, transitioningPattern = model.transitioningPattern
|
||||
, visibility = model.visibilities.page
|
||||
}
|
||||
in
|
||||
{ title = bundle.title
|
||||
@ -442,3 +483,35 @@ view config model =
|
||||
{ layout = identity, page = bundle.view }
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- Transition magic
|
||||
|
||||
|
||||
chooseFrom :
|
||||
{ patternTransitions : List ( Pattern, Transition ui_msg )
|
||||
, from : Url
|
||||
, to : Url
|
||||
}
|
||||
-> Maybe ( Pattern, Transition ui_msg )
|
||||
chooseFrom options =
|
||||
let
|
||||
( fromPath, toPath ) =
|
||||
( options.from, options.to )
|
||||
|> Tuple.mapBoth urlPath urlPath
|
||||
in
|
||||
options.patternTransitions
|
||||
|> List.reverse
|
||||
|> List.filter
|
||||
(\( pattern, transition ) ->
|
||||
Pattern.matches fromPath pattern
|
||||
&& Pattern.matches toPath pattern
|
||||
&& (transition /= Transition.optOut)
|
||||
)
|
||||
|> List.head
|
||||
|
||||
|
||||
urlPath : Url -> List String
|
||||
urlPath url =
|
||||
url.path |> String.dropLeft 1 |> String.split "/"
|
||||
|
@ -119,6 +119,8 @@ You only need **one** case expression: (woohoo, less boilerplate!)
|
||||
-}
|
||||
|
||||
import Internals.Page exposing (..)
|
||||
import Internals.Pattern as Pattern exposing (Pattern)
|
||||
import Internals.Transition as Transition exposing (Transition)
|
||||
import Internals.Utils as Utils
|
||||
|
||||
|
||||
@ -505,6 +507,21 @@ layout map options =
|
||||
, bundle =
|
||||
\model context ->
|
||||
let
|
||||
viewLayout page =
|
||||
options.view
|
||||
{ page = page
|
||||
, global = context.global
|
||||
, toMsg = context.fromGlobalMsg
|
||||
}
|
||||
|
||||
myLayoutsVisibility : Transition.Visibility
|
||||
myLayoutsVisibility =
|
||||
if context.transitioningPattern == options.pattern then
|
||||
context.visibility
|
||||
|
||||
else
|
||||
Transition.visible
|
||||
|
||||
bundle : { title : String, view : ui_msg, subscriptions : Sub msg }
|
||||
bundle =
|
||||
options.recipe.bundle
|
||||
@ -513,14 +530,17 @@ layout map options =
|
||||
, fromPageMsg = toMsg >> context.fromPageMsg
|
||||
, global = context.global
|
||||
, map = map
|
||||
, transitioningPattern = context.transitioningPattern
|
||||
, visibility = context.visibility
|
||||
}
|
||||
in
|
||||
{ title = bundle.title
|
||||
, view =
|
||||
options.view
|
||||
{ page = bundle.view
|
||||
, global = context.global
|
||||
, toMsg = context.fromGlobalMsg
|
||||
Transition.view
|
||||
options.transition
|
||||
myLayoutsVisibility
|
||||
{ layout = viewLayout
|
||||
, page = bundle.view
|
||||
}
|
||||
, subscriptions = bundle.subscriptions
|
||||
}
|
||||
|
21
src/App/Pattern.elm
Normal file
21
src/App/Pattern.elm
Normal file
@ -0,0 +1,21 @@
|
||||
module App.Pattern exposing
|
||||
( Pattern
|
||||
, dynamic
|
||||
, static
|
||||
)
|
||||
|
||||
import Internals.Pattern as Internals
|
||||
|
||||
|
||||
type alias Pattern =
|
||||
Internals.Pattern
|
||||
|
||||
|
||||
static : String -> Internals.Piece
|
||||
static =
|
||||
Internals.static
|
||||
|
||||
|
||||
dynamic : Internals.Piece
|
||||
dynamic =
|
||||
Internals.dynamic
|
@ -1,12 +1,12 @@
|
||||
module App.Transition exposing
|
||||
( Transition
|
||||
, optOut, none, fadeHtml, fadeUi
|
||||
, optOut, none, fadeHtml, fadeUi, custom
|
||||
)
|
||||
|
||||
{-|
|
||||
|
||||
@docs Transition
|
||||
@docs optOut, none, fadeHtml, fadeUi
|
||||
@docs optOut, none, fadeHtml, fadeUi, custom
|
||||
|
||||
-}
|
||||
|
||||
@ -41,3 +41,20 @@ fadeHtml =
|
||||
fadeUi : Int -> Transition (Element msg)
|
||||
fadeUi =
|
||||
Internals.Transition.fadeUi
|
||||
|
||||
|
||||
custom :
|
||||
{ speed : Int
|
||||
, invisible : View ui_msg
|
||||
, visible : View ui_msg
|
||||
}
|
||||
-> Transition ui_msg
|
||||
custom =
|
||||
Internals.Transition.custom
|
||||
|
||||
|
||||
type alias View ui_msg =
|
||||
{ layout : ui_msg -> ui_msg
|
||||
, page : ui_msg
|
||||
}
|
||||
-> ui_msg
|
||||
|
@ -9,6 +9,9 @@ module Internals.Page exposing
|
||||
, upgrade
|
||||
)
|
||||
|
||||
import Internals.Pattern exposing (Pattern)
|
||||
import Internals.Transition as Transition exposing (Transition)
|
||||
|
||||
|
||||
type Page pageParams pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg
|
||||
= Page (Page_ pageParams pageModel pageMsg ui_pageMsg layoutModel layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg)
|
||||
@ -67,6 +70,8 @@ type alias Bundle layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg =
|
||||
, fromGlobalMsg : globalMsg -> msg
|
||||
, fromPageMsg : layoutMsg -> msg
|
||||
, map : (layoutMsg -> msg) -> ui_layoutMsg -> ui_msg
|
||||
, visibility : Transition.Visibility
|
||||
, transitioningPattern : Pattern
|
||||
}
|
||||
->
|
||||
{ title : String
|
||||
@ -76,7 +81,9 @@ type alias Bundle layoutMsg ui_layoutMsg globalModel globalMsg msg ui_msg =
|
||||
|
||||
|
||||
type alias Layout pageParams pageModel pageMsg ui_pageMsg globalModel globalMsg msg ui_msg =
|
||||
{ view :
|
||||
{ pattern : Pattern
|
||||
, transition : Transition ui_msg
|
||||
, view :
|
||||
{ page : ui_msg
|
||||
, global : globalModel
|
||||
, toMsg : globalMsg -> msg
|
||||
|
48
src/Internals/Pattern.elm
Normal file
48
src/Internals/Pattern.elm
Normal file
@ -0,0 +1,48 @@
|
||||
module Internals.Pattern exposing
|
||||
( Pattern
|
||||
, Piece
|
||||
, dynamic
|
||||
, matches
|
||||
, static
|
||||
)
|
||||
|
||||
|
||||
type alias Pattern =
|
||||
List Piece
|
||||
|
||||
|
||||
type Piece
|
||||
= Static String
|
||||
| Dynamic
|
||||
|
||||
|
||||
static : String -> Piece
|
||||
static =
|
||||
Static
|
||||
|
||||
|
||||
dynamic : Piece
|
||||
dynamic =
|
||||
Dynamic
|
||||
|
||||
|
||||
matches : List String -> List Piece -> Bool
|
||||
matches strings pieces =
|
||||
List.length pieces
|
||||
<= List.length strings
|
||||
&& (List.map2
|
||||
comparePiece
|
||||
strings
|
||||
pieces
|
||||
|> List.all ((==) True)
|
||||
)
|
||||
|
||||
|
||||
comparePiece : String -> Piece -> Bool
|
||||
comparePiece str piece =
|
||||
case piece of
|
||||
Static xyz ->
|
||||
str == xyz
|
||||
|
||||
Dynamic ->
|
||||
True
|
@ -1,7 +1,7 @@
|
||||
module Internals.Transition exposing
|
||||
( Transition
|
||||
, speed, view
|
||||
, optOut, none, fadeHtml, fadeUi
|
||||
, optOut, none, fadeHtml, fadeUi, custom
|
||||
, Visibility
|
||||
, visible, invisible
|
||||
)
|
||||
@ -9,7 +9,7 @@ module Internals.Transition exposing
|
||||
{-|
|
||||
|
||||
@docs Transition
|
||||
@docs speed, view
|
||||
@docs speed, view, chooseFrom
|
||||
@docs optOut, none, fadeHtml, fadeUi
|
||||
|
||||
@docs Visibility
|
||||
@ -20,6 +20,7 @@ module Internals.Transition exposing
|
||||
import Element exposing (Element)
|
||||
import Html exposing (Html)
|
||||
import Html.Attributes as Attr
|
||||
import Url exposing (Url)
|
||||
|
||||
|
||||
type Visibility
|
||||
@ -40,10 +41,10 @@ invisible =
|
||||
type Transition ui_msg
|
||||
= OptOut
|
||||
| None
|
||||
| Transition (Transition_ ui_msg)
|
||||
| Transition (Options ui_msg)
|
||||
|
||||
|
||||
type alias Transition_ ui_msg =
|
||||
type alias Options ui_msg =
|
||||
{ speed : Int
|
||||
, invisible : View ui_msg
|
||||
, visible : View ui_msg
|
||||
@ -160,3 +161,11 @@ fadeUi speed_ =
|
||||
, invisible = withOpacity 0
|
||||
, visible = withOpacity 1
|
||||
}
|
||||
|
||||
custom :
|
||||
{ speed : Int
|
||||
, invisible : View ui_msg
|
||||
, visible : View ui_msg
|
||||
} -> Transition ui_msg
|
||||
custom =
|
||||
Transition
|
Loading…
Reference in New Issue
Block a user