elm-mdl/examples/Demo/Snackbar.elm

207 lines
4.9 KiB
Elm
Raw Normal View History

2016-03-17 19:56:04 +00:00
module Demo.Snackbar where
import Effects exposing (Effects, none)
import Html exposing (..)
import Html.Attributes exposing (class, style, key)
import Array exposing (Array)
import Material.Helpers exposing (map1st, map2nd)
2016-03-19 22:47:21 +00:00
import Material.Color as Color
import Material.Style exposing (styled, cs)
2016-03-17 19:56:04 +00:00
import Material.Snackbar as Snackbar
import Material.Button as Button exposing (Action(..))
import Material.Grid exposing (..)
2016-03-30 07:19:18 +00:00
import Material.Elevation as Elevation
import Material
2016-03-17 19:56:04 +00:00
2016-03-30 07:19:18 +00:00
import Demo.Page as Page
2016-03-17 19:56:04 +00:00
-- MODEL
type alias Mdl = Material.Model Action
2016-03-17 19:56:04 +00:00
type alias Model =
{ count : Int
, clicked : List Int
, mdl : Mdl
2016-03-17 19:56:04 +00:00
}
model : Model
model =
{ count = 0
, clicked = []
, mdl = Material.model
2016-03-17 19:56:04 +00:00
}
-- ACTION, UPDATE
type Action
= Undo Int
| AddSnackbar
| AddToast
| MDL (Material.Action Action)
2016-03-17 19:56:04 +00:00
snackbar : Int -> Snackbar.Contents Action
snackbar k =
Snackbar.snackbar
("Snackbar message #" ++ toString k)
"UNDO"
(Undo k)
toast : Int -> Snackbar.Contents Action
toast k =
Snackbar.toast
<| "Toast message #" ++ toString k
add : (Int -> Snackbar.Contents Action) -> Model -> (Model, Effects Action)
add f model =
let
(mdl', fx) =
Snackbar.add (f model.count) snackbarComponent model.mdl
model' =
{ model
| mdl = mdl'
, count = model.count + 1
, clicked = model.count :: model.clicked
}
in
(model', fx)
2016-03-17 19:56:04 +00:00
update : Action -> Model -> (Model, Effects Action)
update action model =
case action of
AddSnackbar ->
2016-03-17 19:56:04 +00:00
add snackbar model
AddToast ->
2016-03-17 19:56:04 +00:00
add toast model
Undo k ->
({ model
| clicked = List.filter ((/=) k) model.clicked
}
, none)
MDL action' ->
Material.update MDL action' model.mdl
|> map1st (\m -> { model | mdl = m })
2016-03-17 19:56:04 +00:00
-- VIEW
2016-03-17 19:56:04 +00:00
addSnackbar : Button.Instance Mdl Action
addSnackbar =
Button.instance 0 MDL
Button.raised (Button.model True)
[ Button.fwdClick AddSnackbar ]
addToast : Button.Instance Mdl Action
addToast =
Button.instance 1 MDL
Button.raised (Button.model True)
[ Button.fwdClick AddToast ]
snackbarComponent : Snackbar.Instance Mdl Action
snackbarComponent =
2016-04-06 19:49:02 +00:00
Snackbar.instance 2 MDL Snackbar.model
2016-03-17 19:56:04 +00:00
2016-03-19 22:47:21 +00:00
clickView : Model -> Int -> Html
clickView model k =
2016-03-17 19:56:04 +00:00
let
color =
2016-03-19 22:47:21 +00:00
Array.get ((k + 4) % Array.length Color.palette) Color.palette
|> Maybe.withDefault Color.Teal
|> flip Color.color Color.S500
sbmodel =
snackbarComponent.get model.mdl
2016-03-19 22:47:21 +00:00
selected =
(k == sbmodel.seq - 1) &&
(Snackbar.isActive sbmodel /= Nothing)
2016-03-17 19:56:04 +00:00
in
2016-03-19 22:47:21 +00:00
styled div
[ Color.background color
, Color.text Color.primaryContrast
-- TODO. Should have shadow styles someplace.
2016-03-30 07:19:18 +00:00
, Elevation.shadow (if selected then 8 else 2)
2016-03-19 22:47:21 +00:00
]
[ style
2016-03-17 19:56:04 +00:00
[ ("margin-right", "3ex")
, ("margin-bottom", "3ex")
, ("padding", "1.5ex")
, ("width", "4ex")
, ("border-radius", "2px")
, ("display", "inline-block")
, ("text-align", "center")
2016-03-19 22:47:21 +00:00
, ("transition", "box-shadow 333ms ease-in-out 0s")
2016-03-17 19:56:04 +00:00
]
, key (toString k)
]
[ text <| toString k ]
2016-03-19 22:47:21 +00:00
2016-03-17 19:56:04 +00:00
view : Signal.Address Action -> Model -> Html
view addr model =
2016-03-31 19:58:30 +00:00
Page.body "Snackbar & Toast" srcUrl intro references
2016-03-30 07:19:18 +00:00
[ grid []
2016-03-17 19:56:04 +00:00
-- TODO. Buttons should be centered. Desperately need to be able
-- to add css/classes to top-level element of components (div
-- in grid, button in button, div in textfield etc.)
[ cell [ size All 2, size Phone 2, align Top ]
[ addToast.view addr model.mdl [] [ text "Toast" ]
2016-03-17 19:56:04 +00:00
]
2016-03-31 19:58:30 +00:00
, cell
[ size All 2, size Phone 2, align Top ]
[ addSnackbar.view addr model.mdl [] [ text "Snackbar" ]
2016-03-17 19:56:04 +00:00
]
, cell
[ size Desktop 7, size Tablet 3, size Phone 12, align Top ]
2016-03-19 22:47:21 +00:00
(model.clicked |> List.reverse |> List.map (clickView model))
2016-03-17 19:56:04 +00:00
]
, snackbarComponent.view addr model.mdl
2016-03-17 19:56:04 +00:00
]
intro : Html
2016-03-30 07:19:18 +00:00
intro =
Page.fromMDL "https://www.getmdl.io/components/index.html#snackbar-section" """
2016-03-17 19:56:04 +00:00
> The Material Design Lite (MDL) __snackbar__ component is a container used to
> notify a user of an operation's status. It displays at the bottom of the
> screen. A snackbar may contain an action button to execute a command for the
> user. Actions should undo the committed action or retry it if it failed for
> example. Actions should not be to close the snackbar. By not providing an
> action, the snackbar becomes a __toast__ component.
2016-03-30 07:19:18 +00:00
"""
2016-03-17 19:56:04 +00:00
2016-03-31 19:58:30 +00:00
2016-03-30 07:19:18 +00:00
srcUrl : String
srcUrl =
"https://github.com/debois/elm-mdl/blob/master/examples/Demo/Snackbar.elm"
2016-03-17 19:56:04 +00:00
2016-03-31 19:58:30 +00:00
2016-03-30 07:19:18 +00:00
references : List (String, String)
references =
2016-03-31 19:58:30 +00:00
[ Page.package "http://package.elm-lang.org/packages/debois/elm-mdl/latest/Material-Snackbar"
2016-03-30 07:19:18 +00:00
, Page.mds "https://www.google.com/design/spec/components/snackbars-toasts.html"
, Page.mdl "https://www.getmdl.io/components/index.html#snackbar-section"
]
2016-03-17 19:56:04 +00:00