elm-mdl/examples/Demo.elm

341 lines
7.3 KiB
Elm
Raw Normal View History

2016-04-05 04:26:22 +00:00
module Main (..) where
2016-03-14 10:00:58 +00:00
import StartApp
import Html exposing (..)
2016-04-08 23:03:38 +00:00
import Html.Attributes exposing (href, class, style, key)
2016-03-14 10:00:58 +00:00
import Signal exposing (Signal)
import Effects exposing (..)
import Task
import Signal
import Task exposing (Task)
import Array exposing (Array)
2016-04-05 04:26:22 +00:00
import Hop
2016-04-08 22:20:27 +00:00
import Hop.Types
2016-04-05 04:26:22 +00:00
import Hop.Navigate exposing (navigateTo)
2016-04-08 22:20:27 +00:00
import Hop.Matchers exposing (match1)
2016-03-17 12:31:43 +00:00
import Material.Color as Color
2016-04-05 04:26:22 +00:00
import Material.Layout
2016-03-14 10:00:58 +00:00
import Material.Layout as Layout exposing (defaultLayoutModel)
import Material.Helpers exposing (lift, lift')
import Material.Style as Style
import Material.Scheme as Scheme
2016-03-14 10:00:58 +00:00
import Demo.Buttons
import Demo.Grid
import Demo.Textfields
2016-03-17 12:31:43 +00:00
import Demo.Snackbar
2016-03-17 21:30:49 +00:00
import Demo.Badges
2016-04-08 23:03:38 +00:00
import Demo.Elevation
2016-03-14 10:00:58 +00:00
2016-03-21 11:24:00 +00:00
--import Demo.Template
2016-03-14 10:00:58 +00:00
2016-04-08 22:20:27 +00:00
-- ROUTING
type Route
= Tab Int
| E404
type alias Routing =
( Route, Hop.Types.Location )
route0 : Routing
route0 =
( Tab 0, Hop.Types.newLocation )
router : Hop.Types.Router Route
router =
Hop.new
{ notFound = E404
, matchers =
( match1 (Tab 0) "/"
:: (tabs |> List.indexedMap (\idx (_, path, _) ->
match1 (Tab idx) ("/" ++ path))
)
)
}
2016-03-14 10:00:58 +00:00
-- MODEL
layoutModel : Layout.Model
layoutModel =
{ defaultLayoutModel
| state = Layout.initState (List.length tabs)
, mode = Layout.Waterfall True
, fixedHeader = False
}
2016-03-14 10:00:58 +00:00
type alias Model =
{ layout : Layout.Model
2016-04-08 22:20:27 +00:00
, routing : Routing
2016-03-14 10:00:58 +00:00
, buttons : Demo.Buttons.Model
, textfields : Demo.Textfields.Model
2016-03-17 12:31:43 +00:00
, snackbar : Demo.Snackbar.Model
2016-03-21 11:24:00 +00:00
--, template : Demo.Template.Model
2016-03-14 10:00:58 +00:00
}
model : Model
model =
{ layout = layoutModel
2016-04-08 22:20:27 +00:00
, routing = route0
2016-03-14 10:00:58 +00:00
, buttons = Demo.Buttons.model
, textfields = Demo.Textfields.model
2016-03-17 12:31:43 +00:00
, snackbar = Demo.Snackbar.model
2016-04-05 04:26:22 +00:00
--, template = Demo.Template.model
2016-03-14 10:00:58 +00:00
}
2016-04-05 04:26:22 +00:00
2016-03-14 10:00:58 +00:00
-- ACTION, UPDATE
type Action
2016-04-08 22:20:27 +00:00
-- Hop
= ApplyRoute ( Route, Hop.Types.Location )
| HopAction ()
-- Tabs
| LayoutAction Layout.Action
2016-03-14 10:00:58 +00:00
| ButtonsAction Demo.Buttons.Action
| TextfieldAction Demo.Textfields.Action
2016-03-17 12:31:43 +00:00
| SnackbarAction Demo.Snackbar.Action
2016-04-05 04:26:22 +00:00
--| TemplateAction Demo.Template.Action
2016-03-14 10:00:58 +00:00
2016-04-08 22:20:27 +00:00
nth : Int -> List a -> Maybe a
nth k xs =
List.drop k xs |> List.head
2016-03-14 10:00:58 +00:00
2016-04-05 04:26:22 +00:00
2016-04-08 22:20:27 +00:00
update : Action -> Model -> ( Model, Effects Action )
2016-03-14 10:00:58 +00:00
update action model =
2016-04-08 22:20:27 +00:00
case action of
2016-04-05 04:26:22 +00:00
LayoutAction a ->
let
( lifted, layoutFx ) =
lift .layout (\m x -> { m | layout = x }) LayoutAction Layout.update a model
routeFx =
2016-04-08 22:20:27 +00:00
case a of
Layout.SwitchTab k ->
nth k tabs
|> Maybe.map (\(_, path, _) -> Effects.map HopAction (navigateTo path))
|> Maybe.withDefault Effects.none
_ ->
Effects.none
2016-04-05 04:26:22 +00:00
in
2016-04-08 22:20:27 +00:00
( lifted, Effects.batch [ layoutFx, routeFx ] )
2016-04-05 04:26:22 +00:00
2016-04-08 22:20:27 +00:00
ApplyRoute route ->
( { model
| routing = route
, layout = setTab model.layout (fst route)
}
, Effects.none
)
2016-03-14 10:00:58 +00:00
2016-04-08 22:20:27 +00:00
HopAction _ ->
( model, Effects.none )
2016-03-14 10:00:58 +00:00
ButtonsAction a -> lift .buttons (\m x->{m|buttons =x}) ButtonsAction Demo.Buttons.update a model
2016-04-05 04:26:22 +00:00
2016-04-08 13:51:45 +00:00
TextfieldAction a -> lift .textfields (\m x->{m|textfields=x}) TextfieldAction Demo.Textfields.update a model
2016-04-08 22:20:27 +00:00
SnackbarAction a -> lift .snackbar (\m x->{m|snackbar =x}) SnackbarAction Demo.Snackbar.update a model
2016-04-05 04:26:22 +00:00
2016-03-21 11:24:00 +00:00
--TemplateAction a -> lift .template (\m x->{m|template =x}) TemplateAction Demo.Template.update a model
2016-03-14 10:00:58 +00:00
2016-04-08 22:20:27 +00:00
2016-03-14 10:00:58 +00:00
-- VIEW
2016-04-05 04:26:22 +00:00
type alias Addr =
Signal.Address Action
2016-03-14 10:00:58 +00:00
drawer : List Html
drawer =
[ Layout.title "Example drawer"
, Layout.navigation
[ Layout.link
2016-04-10 08:29:03 +00:00
[ href "https://github.com/debois/elm-mdl" ]
[ text "github" ]
2016-03-14 10:00:58 +00:00
, Layout.link
2016-04-10 08:29:03 +00:00
[ href "http://package.elm-lang.org/packages/debois/elm-mdl/latest/" ]
[ text "elm-package" ]
2016-03-14 10:00:58 +00:00
]
]
header : List Html
header =
[ Layout.row
[ Layout.title "elm-mdl"
, Layout.spacer
, Layout.navigation
[ Layout.link
[href "https://github.com/debois/elm-mdl"]
[span [] [text "github"] ]
, Layout.link
[href "http://package.elm-lang.org/packages/debois/elm-mdl/latest/"]
[text "elm-package"]
]
2016-03-14 10:00:58 +00:00
]
]
2016-04-08 22:20:27 +00:00
tabs : List (String, String, Addr -> Model -> Html)
2016-03-14 10:00:58 +00:00
tabs =
2016-04-08 23:03:38 +00:00
[ ("Buttons", "buttons", \addr model ->
Demo.Buttons.view (Signal.forwardTo addr ButtonsAction) model.buttons)
, ("Badges", "badges", \addr model -> Demo.Badges.view )
, ("Elevation", "elevation", \addr model -> Demo.Elevation.view )
, ("Grid", "grid", \addr model -> Demo.Grid.view)
, ("Snackbar", "snackbar", \addr model ->
Demo.Snackbar.view (Signal.forwardTo addr SnackbarAction) model.snackbar)
2016-04-08 22:20:27 +00:00
, ("Textfields", "textfields", \addr model ->
Demo.Textfields.view (Signal.forwardTo addr TextfieldAction) model.textfields)
2016-03-21 11:24:00 +00:00
{-
, ("Template", \addr model ->
[Demo.Template.view (Signal.forwardTo addr TemplateAction) model.template])
2016-03-21 11:24:00 +00:00
-}
2016-03-14 10:00:58 +00:00
]
2016-04-05 04:26:22 +00:00
2016-04-08 22:20:27 +00:00
e404 : Addr -> Model -> Html
e404 _ _ =
div
[
]
[ Style.styled Html.h1
2016-04-08 23:08:39 +00:00
[ Style.cs "mdl-typography--display-4"
, Color.background Color.primary
]
2016-04-08 22:20:27 +00:00
[]
[ text "404" ]
]
tabViews : Array (Addr -> Model -> Html)
2016-04-08 22:20:27 +00:00
tabViews = List.map (\(_,_,v) -> v) tabs |> Array.fromList
2016-03-14 10:00:58 +00:00
tabTitles : List Html
2016-04-05 04:26:22 +00:00
tabTitles =
2016-04-08 22:20:27 +00:00
List.map (\(x,_,_) -> text x) tabs
2016-04-05 04:26:22 +00:00
2016-03-14 10:00:58 +00:00
stylesheet : Html
2016-04-05 04:26:22 +00:00
stylesheet =
Style.stylesheet """
blockquote:before { content: none; }
blockquote:after { content: none; }
blockquote {
border-left-style: solid;
border-width: 1px;
padding-left: 1.3ex;
border-color: rgb(255,82,82);
2016-03-21 23:01:46 +00:00
font-style: normal;
/* TODO: Really need a way to specify "secondary color" in
inline css.
*/
}
2016-03-21 23:01:46 +00:00
p, blockquote {
max-width: 40em;
2016-03-21 23:01:46 +00:00
}
h1, h2 {
/* TODO. Need typography module with kerning. */
margin-left: -3px;
2016-03-21 23:01:46 +00:00
}
"""
2016-04-08 22:20:27 +00:00
setTab : Layout.Model -> Route -> Layout.Model
setTab layout route =
let
idx =
case route of
Tab k -> k
E404 -> -1
in
{ layout | selectedTab = idx }
2016-04-05 04:26:22 +00:00
2016-03-14 10:00:58 +00:00
view : Signal.Address Action -> Model -> Html
view addr model =
2016-04-05 04:26:22 +00:00
let
top =
div
[ style
[ ( "margin", "auto" )
2016-04-08 23:03:38 +00:00
, ( "padding-left", "8%" )
, ( "padding-right", "8%" )
2016-03-14 10:00:58 +00:00
]
2016-04-08 23:03:38 +00:00
, key <| toString (fst model.routing)
2016-04-05 04:26:22 +00:00
]
2016-04-08 22:20:27 +00:00
[ (Array.get model.layout.selectedTab tabViews
|> Maybe.withDefault e404)
addr
model
]
2016-03-14 10:00:58 +00:00
in
Layout.view (Signal.forwardTo addr LayoutAction) model.layout
{ header = header
, drawer = drawer
, tabs = tabTitles
, main = [ stylesheet, top ]
2016-03-14 10:00:58 +00:00
}
{- The following line is not needed when you manually set up
2016-03-15 16:47:47 +00:00
your html, as done with page.html. Removing it will then
2016-03-15 16:53:41 +00:00
fix the flicker you see on load.
-}
|> Scheme.topWithScheme Color.Teal Color.Red
2016-03-14 10:00:58 +00:00
2016-04-05 04:26:22 +00:00
init : ( Model, Effects.Effects Action )
init =
( model, Effects.none )
2016-03-14 10:00:58 +00:00
inputs : List (Signal.Signal Action)
inputs =
2016-03-30 19:19:06 +00:00
[ Layout.setupSignals LayoutAction
2016-04-08 22:20:27 +00:00
, Signal.map ApplyRoute router.signal
2016-03-14 10:00:58 +00:00
]
app : StartApp.App Model
app =
2016-04-05 04:26:22 +00:00
StartApp.start
{ init = init
, view = view
, update = update
, inputs = inputs
}
2016-03-14 10:00:58 +00:00
main : Signal Html
main =
2016-04-05 04:26:22 +00:00
app.html
2016-03-14 10:00:58 +00:00
-- PORTS
port tasks : Signal (Task.Task Never ())
port tasks =
2016-04-05 04:26:22 +00:00
app.tasks
port routeRunTask : Task () ()
port routeRunTask =
2016-04-08 22:20:27 +00:00
router.run