mirror of
https://github.com/correl/elm-mdl.git
synced 2025-03-12 17:00:06 -09:00
add routing to Demo example
This commit is contained in:
parent
edf172bd61
commit
72384a5e33
2 changed files with 308 additions and 78 deletions
|
@ -1,3 +1,5 @@
|
|||
module Main (..) where
|
||||
|
||||
import StartApp
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (href, class, style)
|
||||
|
@ -7,48 +9,56 @@ import Task
|
|||
import Signal
|
||||
import Task exposing (Task)
|
||||
import Array exposing (Array)
|
||||
|
||||
import Routing
|
||||
import Hop
|
||||
import Hop.Navigate exposing (navigateTo)
|
||||
import Material.Color as Color
|
||||
import Material.Layout
|
||||
import Material.Layout as Layout exposing (defaultLayoutModel)
|
||||
import Material exposing (lift, lift')
|
||||
import Material.Style as Style
|
||||
|
||||
import Demo.Buttons
|
||||
import Demo.Grid
|
||||
import Demo.Textfields
|
||||
import Demo.Snackbar
|
||||
import Demo.Badges
|
||||
--import Demo.Template
|
||||
|
||||
|
||||
--import Demo.Template
|
||||
-- MODEL
|
||||
|
||||
|
||||
layoutModel : Layout.Model
|
||||
layoutModel =
|
||||
{ defaultLayoutModel
|
||||
| state = Layout.initState (List.length tabs)
|
||||
| state = Layout.initState (List.length tabs)
|
||||
}
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ layout : Layout.Model
|
||||
, routing : Routing.Model
|
||||
, buttons : Demo.Buttons.Model
|
||||
, textfields : Demo.Textfields.Model
|
||||
, snackbar : Demo.Snackbar.Model
|
||||
--, template : Demo.Template.Model
|
||||
, snackbar :
|
||||
Demo.Snackbar.Model
|
||||
--, template : Demo.Template.Model
|
||||
}
|
||||
|
||||
|
||||
model : Model
|
||||
model =
|
||||
{ layout = layoutModel
|
||||
, routing = Routing.initialModel
|
||||
, buttons = Demo.Buttons.model
|
||||
, textfields = Demo.Textfields.model
|
||||
, snackbar = Demo.Snackbar.model
|
||||
--, template = Demo.Template.model
|
||||
, snackbar =
|
||||
Demo.Snackbar.model
|
||||
--, template = Demo.Template.model
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- ACTION, UPDATE
|
||||
|
||||
|
||||
|
@ -57,37 +67,106 @@ type Action
|
|||
| ButtonsAction Demo.Buttons.Action
|
||||
| TextfieldAction Demo.Textfields.Action
|
||||
| SnackbarAction Demo.Snackbar.Action
|
||||
--| TemplateAction Demo.Template.Action
|
||||
| RoutingAction Routing.Action
|
||||
| HopAction ()
|
||||
|
||||
|
||||
update : Action -> Model -> (Model, Effects.Effects Action)
|
||||
|
||||
--| TemplateAction Demo.Template.Action
|
||||
|
||||
|
||||
changeTab : Layout.Action -> Effects Action
|
||||
changeTab action =
|
||||
let
|
||||
navTo path =
|
||||
Effects.map HopAction (navigateTo path)
|
||||
in
|
||||
case action of
|
||||
Layout.SwitchTab n ->
|
||||
case n of
|
||||
0 ->
|
||||
navTo "/snackbar"
|
||||
|
||||
1 ->
|
||||
navTo "/textfields"
|
||||
|
||||
2 ->
|
||||
navTo "/buttons"
|
||||
|
||||
3 ->
|
||||
navTo "/grid"
|
||||
|
||||
4 ->
|
||||
navTo "/badges"
|
||||
|
||||
_ ->
|
||||
navTo "/404"
|
||||
|
||||
_ ->
|
||||
Effects.none
|
||||
|
||||
|
||||
update : Action -> Model -> ( Model, Effects.Effects Action )
|
||||
update action model =
|
||||
case Debug.log "Action: " action of
|
||||
LayoutAction a -> lift .layout (\m x->{m|layout =x}) LayoutAction Layout.update a model
|
||||
ButtonsAction a -> lift .buttons (\m x->{m|buttons =x}) ButtonsAction Demo.Buttons.update a model
|
||||
TextfieldAction a -> lift' .textfields (\m x->{m|textfields=x}) Demo.Textfields.update a model
|
||||
SnackbarAction a -> lift .snackbar (\m x->{m|snackbar =x}) SnackbarAction Demo.Snackbar.update a model
|
||||
--TemplateAction a -> lift .template (\m x->{m|template =x}) TemplateAction Demo.Template.update a model
|
||||
LayoutAction a ->
|
||||
let
|
||||
( lifted, layoutFx ) =
|
||||
lift .layout (\m x -> { m | layout = x }) LayoutAction Layout.update a model
|
||||
|
||||
routeFx =
|
||||
changeTab a
|
||||
|
||||
fx =
|
||||
Effects.batch [ layoutFx, routeFx ]
|
||||
in
|
||||
( lifted, fx )
|
||||
|
||||
ButtonsAction a ->
|
||||
lift .buttons (\m x -> { m | buttons = x }) ButtonsAction Demo.Buttons.update a model
|
||||
|
||||
TextfieldAction a ->
|
||||
lift' .textfields (\m x -> { m | textfields = x }) Demo.Textfields.update a model
|
||||
|
||||
SnackbarAction a ->
|
||||
lift .snackbar (\m x -> { m | snackbar = x }) SnackbarAction Demo.Snackbar.update a model
|
||||
|
||||
RoutingAction a ->
|
||||
let
|
||||
( routing', fx ) =
|
||||
Routing.update a model.routing
|
||||
|
||||
model' =
|
||||
{ model | routing = routing' }
|
||||
in
|
||||
( model'
|
||||
, Effects.map RoutingAction fx
|
||||
)
|
||||
|
||||
HopAction _ ->
|
||||
( model, Effects.none )
|
||||
|
||||
|
||||
|
||||
--TemplateAction a -> lift .template (\m x->{m|template =x}) TemplateAction Demo.Template.update a model
|
||||
-- VIEW
|
||||
|
||||
|
||||
type alias Addr = Signal.Address Action
|
||||
|
||||
type alias Addr =
|
||||
Signal.Address Action
|
||||
|
||||
|
||||
drawer : List Html
|
||||
drawer =
|
||||
[ Layout.title "Example drawer"
|
||||
, Layout.navigation
|
||||
[ Layout.link
|
||||
[href "https://github.com/debois/elm-mdl"]
|
||||
[text "github"]
|
||||
, Layout.link
|
||||
[href "http://package.elm-lang.org/packages/debois/elm-mdl/latest/"]
|
||||
[text "elm-package"]
|
||||
]
|
||||
[ Layout.link
|
||||
[ href "https://github.com/debois/elm-mdl" ]
|
||||
[ text "github" ]
|
||||
, Layout.link
|
||||
[ href "http://package.elm-lang.org/packages/debois/elm-mdl/latest/" ]
|
||||
[ text "elm-package" ]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
|
@ -96,41 +175,52 @@ header =
|
|||
[ Layout.title "elm-mdl"
|
||||
, Layout.spacer
|
||||
, Layout.navigation
|
||||
[ Layout.link
|
||||
[ href "https://www.getmdl.io/components/index.html" ]
|
||||
[ text "MDL" ]
|
||||
, Layout.link
|
||||
[ href "https://www.google.com/design/spec/material-design/introduction.html"]
|
||||
[ text "Material Design"]
|
||||
]
|
||||
[ Layout.link
|
||||
[ href "https://www.getmdl.io/components/index.html" ]
|
||||
[ text "MDL" ]
|
||||
, Layout.link
|
||||
[ href "https://www.google.com/design/spec/material-design/introduction.html" ]
|
||||
[ text "Material Design" ]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
tabs : List (String, Addr -> Model -> List Html)
|
||||
tabs : List ( String, Addr -> Model -> List Html )
|
||||
tabs =
|
||||
[ ("Snackbar", \addr model ->
|
||||
[Demo.Snackbar.view (Signal.forwardTo addr SnackbarAction) model.snackbar])
|
||||
, ("Textfields", \addr model ->
|
||||
[Demo.Textfields.view (Signal.forwardTo addr TextfieldAction) model.textfields])
|
||||
, ("Buttons", \addr model ->
|
||||
[Demo.Buttons.view (Signal.forwardTo addr ButtonsAction) model.buttons])
|
||||
, ("Grid", \addr model -> Demo.Grid.view)
|
||||
, ("Badges", \addr model -> Demo.Badges.view )
|
||||
{-
|
||||
, ("Template", \addr model ->
|
||||
[Demo.Template.view (Signal.forwardTo addr TemplateAction) model.template])
|
||||
-}
|
||||
[ ( "Snackbar"
|
||||
, \addr model ->
|
||||
[ Demo.Snackbar.view (Signal.forwardTo addr SnackbarAction) model.snackbar ]
|
||||
)
|
||||
, ( "Textfields"
|
||||
, \addr model ->
|
||||
[ Demo.Textfields.view (Signal.forwardTo addr TextfieldAction) model.textfields ]
|
||||
)
|
||||
, ( "Buttons"
|
||||
, \addr model ->
|
||||
[ Demo.Buttons.view (Signal.forwardTo addr ButtonsAction) model.buttons ]
|
||||
)
|
||||
, ( "Grid", \addr model -> Demo.Grid.view )
|
||||
, ( "Badges", \addr model -> Demo.Badges.view )
|
||||
{-
|
||||
, ("Template", \addr model ->
|
||||
[Demo.Template.view (Signal.forwardTo addr TemplateAction) model.template])
|
||||
-}
|
||||
]
|
||||
|
||||
|
||||
tabViews : Array (Addr -> Model -> List Html)
|
||||
tabViews = List.map snd tabs |> Array.fromList
|
||||
tabViews =
|
||||
List.map snd tabs |> Array.fromList
|
||||
|
||||
|
||||
tabTitles : List Html
|
||||
tabTitles = List.map (fst >> text) tabs
|
||||
tabTitles =
|
||||
List.map (fst >> text) tabs
|
||||
|
||||
|
||||
stylesheet : Html
|
||||
stylesheet = Style.stylesheet """
|
||||
stylesheet =
|
||||
Style.stylesheet """
|
||||
blockquote:before { content: none; }
|
||||
blockquote:after { content: none; }
|
||||
blockquote {
|
||||
|
@ -143,66 +233,111 @@ stylesheet = Style.stylesheet """
|
|||
inline css.
|
||||
*/
|
||||
}
|
||||
p, blockquote {
|
||||
p, blockquote {
|
||||
max-width: 33em;
|
||||
font-size: 13px;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
|
||||
view : Signal.Address Action -> Model -> Html
|
||||
view addr model =
|
||||
let top =
|
||||
div
|
||||
[ style
|
||||
[ ("margin", "auto")
|
||||
, ("padding-left", "5%")
|
||||
, ("padding-right", "5%")
|
||||
]
|
||||
]
|
||||
((Array.get model.layout.selectedTab tabViews
|
||||
|> Maybe.withDefault (\addr model ->
|
||||
[div [] [text "This can't happen."]]
|
||||
)
|
||||
) addr model)
|
||||
routingView addr model
|
||||
|
||||
|
||||
routingView : Signal.Address Action -> Model -> Html
|
||||
routingView addr model =
|
||||
case (Debug.log "Route " model.routing.route) of
|
||||
Routing.Home ->
|
||||
let
|
||||
model' =
|
||||
{ model | layout = setTab model.layout 0 }
|
||||
in
|
||||
appView addr model'
|
||||
|
||||
Routing.TabRoute tabNumber ->
|
||||
let
|
||||
model' =
|
||||
{ model | layout = setTab model.layout tabNumber }
|
||||
in
|
||||
appView addr model'
|
||||
|
||||
Routing.NotFoundRoute ->
|
||||
div [] [ h2 [] [ text "Not found" ] ]
|
||||
|
||||
|
||||
setTab layout tabNumber =
|
||||
{ layout | selectedTab = tabNumber }
|
||||
|
||||
|
||||
appView : Signal.Address Action -> Model -> Html
|
||||
appView addr model =
|
||||
let
|
||||
top =
|
||||
div
|
||||
[ style
|
||||
[ ( "margin", "auto" )
|
||||
, ( "padding-left", "5%" )
|
||||
, ( "padding-right", "5%" )
|
||||
]
|
||||
]
|
||||
((Array.get model.layout.selectedTab tabViews
|
||||
|> Maybe.withDefault
|
||||
(\addr model ->
|
||||
[ div [] [ text "This can't happen." ] ]
|
||||
)
|
||||
)
|
||||
addr
|
||||
model
|
||||
)
|
||||
in
|
||||
Layout.view (Signal.forwardTo addr LayoutAction) model.layout
|
||||
Layout.view
|
||||
(Signal.forwardTo addr LayoutAction)
|
||||
model.layout
|
||||
{ header = Just header
|
||||
, drawer = Just drawer
|
||||
, tabs = Just tabTitles
|
||||
, main = [ stylesheet, top ]
|
||||
}
|
||||
{- The following line is not needed when you manually set up
|
||||
your html, as done with page.html. Removing it will then
|
||||
fix the flicker you see on load.
|
||||
-}
|
||||
|> Material.topWithScheme Color.Teal Color.Red
|
||||
{- The following line is not needed when you manually set up
|
||||
your html, as done with page.html. Removing it will then
|
||||
fix the flicker you see on load.
|
||||
-}
|
||||
|>
|
||||
Material.topWithScheme Color.Teal Color.Red
|
||||
|
||||
|
||||
init : (Model, Effects.Effects Action)
|
||||
init = (model, Effects.none)
|
||||
routerSignal : Signal Action
|
||||
routerSignal =
|
||||
Signal.map RoutingAction Routing.signal
|
||||
|
||||
|
||||
init : ( Model, Effects.Effects Action )
|
||||
init =
|
||||
( model, Effects.none )
|
||||
|
||||
|
||||
inputs : List (Signal.Signal Action)
|
||||
inputs =
|
||||
[ Layout.setupSizeChangeSignal LayoutAction
|
||||
, routerSignal
|
||||
]
|
||||
|
||||
|
||||
app : StartApp.App Model
|
||||
app =
|
||||
StartApp.start
|
||||
{ init = init
|
||||
, view = view
|
||||
, update = update
|
||||
, inputs = inputs
|
||||
}
|
||||
StartApp.start
|
||||
{ init = init
|
||||
, view = view
|
||||
, update = update
|
||||
, inputs = inputs
|
||||
}
|
||||
|
||||
|
||||
main : Signal Html
|
||||
main =
|
||||
app.html
|
||||
app.html
|
||||
|
||||
|
||||
|
||||
-- PORTS
|
||||
|
@ -210,4 +345,9 @@ main =
|
|||
|
||||
port tasks : Signal (Task.Task Never ())
|
||||
port tasks =
|
||||
app.tasks
|
||||
app.tasks
|
||||
|
||||
|
||||
port routeRunTask : Task () ()
|
||||
port routeRunTask =
|
||||
Routing.run
|
||||
|
|
90
examples/Routing.elm
Normal file
90
examples/Routing.elm
Normal file
|
@ -0,0 +1,90 @@
|
|||
module Routing (..) where
|
||||
|
||||
import Task exposing (Task)
|
||||
import Effects exposing (Effects, Never)
|
||||
import Hop
|
||||
import Hop.Types exposing (Location, PathMatcher, Router, newLocation)
|
||||
import Hop.Navigate exposing (navigateTo)
|
||||
import Hop.Matchers exposing (match1, match2, match3, str)
|
||||
|
||||
|
||||
type Route
|
||||
= Home
|
||||
| TabRoute Int
|
||||
| NotFoundRoute
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ location : Location
|
||||
, route : Route
|
||||
}
|
||||
|
||||
|
||||
initialModel : Model
|
||||
initialModel =
|
||||
{ location = newLocation
|
||||
, route = Home
|
||||
}
|
||||
|
||||
|
||||
type Action
|
||||
= HopAction ()
|
||||
| ApplyRoute ( Route, Location )
|
||||
| NavigateTo String
|
||||
|
||||
|
||||
update : Action -> Model -> ( Model, Effects Action )
|
||||
update action model =
|
||||
case action of
|
||||
NavigateTo path ->
|
||||
( model, Effects.map HopAction (navigateTo path) )
|
||||
|
||||
ApplyRoute ( route, location ) ->
|
||||
( { model
|
||||
| route = route
|
||||
, location = location
|
||||
}
|
||||
, Effects.none
|
||||
)
|
||||
|
||||
HopAction () ->
|
||||
( model, Effects.none )
|
||||
|
||||
|
||||
indexMatcher : PathMatcher Route
|
||||
indexMatcher =
|
||||
match1 Home "/"
|
||||
|
||||
|
||||
tabMatcher : String -> Int -> PathMatcher Route
|
||||
tabMatcher tabName tabNumber =
|
||||
match1 (TabRoute tabNumber) ("/" ++ tabName)
|
||||
|
||||
|
||||
matchers : List (PathMatcher Route)
|
||||
matchers =
|
||||
[ indexMatcher
|
||||
, (tabMatcher "snackbar" 0)
|
||||
, (tabMatcher "textfields" 1)
|
||||
, (tabMatcher "buttons" 2)
|
||||
, (tabMatcher "grid" 3)
|
||||
, (tabMatcher "badges" 4)
|
||||
]
|
||||
|
||||
|
||||
router : Router Route
|
||||
router =
|
||||
Hop.new
|
||||
{ matchers = matchers
|
||||
, notFound = NotFoundRoute
|
||||
}
|
||||
|
||||
|
||||
run : Task () ()
|
||||
run =
|
||||
router.run
|
||||
|
||||
|
||||
signal : Signal Action
|
||||
signal =
|
||||
Signal.map ApplyRoute router.signal
|
Loading…
Add table
Reference in a new issue