Missing files. (snackbar still broken).

This commit is contained in:
Søren Debois 2016-04-06 20:16:54 +02:00
parent aaf58fa37c
commit f994c82d50
15 changed files with 524 additions and 130 deletions

View file

@ -3,7 +3,7 @@ PAGES=../elm-mdl-gh-pages
comp:
elm-make examples/Component.elm --warn --output elm.js
elm.js:
demo:
elm-make examples/Demo.elm --warn --output elm.js
wip-pages :

View file

@ -15,7 +15,8 @@
"Material.Button",
"Material.Textfield",
"Material.Layout",
"Material.Grid"
"Material.Grid",
"Material.Component"
],
"dependencies": {
"debois/elm-dom": "1.0.0 <= v < 2.0.0",

View file

@ -14,7 +14,7 @@ import Material.Button as Button
type alias Model =
{ count : Int
, mdl : Material.Model
, mdl : Material.Model Action
-- Boilerplate: Model store for any and all MDL components you need.
}
@ -23,7 +23,7 @@ type alias Model =
model : Model
model =
{ count = 0
, mdl = Material.model
, mdl = Material.model
-- Always use this initial MDL component model store.
}
@ -66,6 +66,8 @@ update action model =
-- VIEW
type alias Mdl = Material.Model Action
{- We construct the instances of the Button component that we need, one
for the increase button, one for the reset button. First, the increase
button. The arguments are:
@ -79,7 +81,7 @@ button. The arguments are:
In this case, we hook up Click events of the button to the `Increase` action
defined above.
-}
increase : Button.Instance Material.Model Action
increase : Button.Instance Mdl Action
increase =
Button.instance 0 MDL
Button.flat (Button.model True)
@ -89,7 +91,7 @@ increase =
{- Next, the reset button. This one has id 1, does not ripple, and forwards its
click event to our Reset action.
-}
reset : Button.Instance Material.Model Action
reset : Button.Instance Mdl Action
reset =
Button.instance 1 MDL
Button.flat (Button.model False)

View file

@ -10,8 +10,9 @@ import Array exposing (Array)
import Material.Color as Color
import Material.Layout as Layout exposing (defaultLayoutModel)
import Material exposing (lift, lift')
import Material.Helpers exposing (lift, lift')
import Material.Style as Style
import Material.Scheme as Scheme
import Demo.Buttons
import Demo.Grid
@ -178,7 +179,7 @@ view addr model =
your html, as done with page.html. Removing it will then
fix the flicker you see on load.
-}
|> Material.topWithScheme Color.Teal Color.Red
|> Scheme.topWithScheme Color.Teal Color.Red
init : (Model, Effects.Effects Action)

View file

@ -11,8 +11,6 @@ import Material.Icon as Icon
import Material.Style exposing (Style)
import Material.Textfield as Textfield
import Material.Component as Component
import Material.Component.All as Setup
-- MODEL
@ -69,7 +67,6 @@ model =
buttons
|> List.concatMap (List.map <| \(idx, (ripple, _, _)) -> (idx, Button.model ripple))
|> Dict.fromList
, componentState = Setup.state
}
@ -78,15 +75,11 @@ model =
type Action
= Action Index Button.Action
| State (Setup.Action Action)
| Click
| Input String
type alias Model =
{ clicked : String
, buttons : Dict.Dict Index Button.Model
, componentState : Setup.State
}
@ -103,25 +96,6 @@ update action model =
)
|> Maybe.withDefault (model, Effects.none)
State action' ->
Component.update State update action' model
Click ->
( tf.map (\m -> { m | value = "You clicked!" }) model, Effects.none )
Input str ->
( tf.map (\m -> { m | value = "You wrote '" ++ str ++ "' in the other guy."}) model
, Effects.none
)
instance = Component.instance State
instance' = Component.instance' State
tf = instance <| Textfield.component Textfield.model 4
-- VIEW
@ -161,12 +135,7 @@ view addr model =
)
|> (\contents ->
div []
[ instance' (Button.component Button.flat (Button.model True) 1 |> onClick Click) addr model [] [ text "Click me (1)" ]
, instance' (Button.component Button.raised (Button.model False) 2) addr model [] [ text "Click me (2)" ]
, instance' (Textfield.component Textfield.model 3 |> Textfield.onInput Input) addr model
, tf.view addr model
, Grid.grid [] contents
[ Grid.grid [] contents
]
)
--i = instance' State (buttonWidget (Button.model True) 1) -- addr model.componentState [] [ text "Click me (1)" ]

101
examples/Demo/Elevation.elm Normal file
View file

@ -0,0 +1,101 @@
module Demo.Elevation where
import Effects exposing (Effects, none)
import Html exposing (..)
import Markdown
import Material.Template as Template
import Material exposing (lift, lift')
-- MODEL
type alias Model =
{ template : Template.Model
}
model : Model
model =
{ template = Template.model
}
-- ACTION, UPDATE
type Action
= TemplateAction Template.Action
update : Action -> Model -> (Model, Effects Action)
update action model =
case action of
TemplateAction action' -> lift .template (\m x -> {m|template=x}) TemplateAction Template.update action' model
-- VIEW
view : Signal.Address Action -> Model -> Html
view addr model =
div []
[ intro
, Template.view (Signal.forwardTo addr TemplateAction) model.template
]
intro : Html
intro = """
{-| From the [Material Design Lite documentation](https://github.com/google/material-design-lite/blob/master/src/shadow/README.md)
> The Material Design Lite (MDL) shadow is not a component in the same sense as
> an MDL card, menu, or textbox; it is a visual effect that can be assigned to a
> user interface element. The effect simulates a three-dimensional positioning of
> the element, as though it is slightly raised above the surface it rests upon
> a positive z-axis value, in user interface terms. The shadow starts at the
> edges of the element and gradually fades outward, providing a realistic 3-D
> effect.
>
> Shadows are a convenient and intuitive means of distinguishing an element from
> its surroundings. A shadow can draw the user's eye to an object and emphasize
> the object's importance, uniqueness, or immediacy.
>
> Shadows are a well-established feature in user interfaces, and provide users
> with a visual clue to an object's intended use or value. Their design and use
> is an important factor in the overall user experience.)
The [Material Design Specification](https://www.google.com/design/spec/what-is-material/elevation-shadows.html#elevation-shadows-elevation-android-)
pre-defines appropriate elevation for most UI elements; you need to manually
assign shadows only to your own elements.
You are encouraged to visit the
[Material Design specification](https://www.google.com/design/spec/what-is-material/elevation-shadows.html)
for details about appropriate use of shadows.
# TEMPLATE
From the
[Material Design Lite documentation](https://www.getmdl.io/components/index.html#TEMPLATE-section).
> ...
#### See also
- [Demo source code](https://github.com/debois/elm-mdl/blob/master/examples/Demo/TEMPLATE.elm)
- [elm-mdl package documentation](http://package.elm-lang.org/packages/debois/elm-mdl/latest/Material-TEMPLATE)
- [Material Design Specification](https://www.google.com/design/spec/components/TEMPLATE.html)
- [Material Design Lite documentation](https://www.getmdl.io/components/index.html#TEMPLATE)
#### Demo
""" |> Markdown.toHtml

140
examples/Demo/Page.elm Normal file
View file

@ -0,0 +1,140 @@
module Demo.Page
( demo, package, mds, mdl
, fromMDL, fromMDS
, body
)
where
import Html exposing (..)
import Html.Attributes exposing (href, class)
import Markdown
import Material.Grid exposing (..)
import Material.Style as Style exposing (styled, cs, css, attribute)
import Material.Button as Button
import Material.Color as Color
import Material.Icon as Icon
-- REFERENCES
demo : String -> (String, String)
demo url =
( "Demo source", url )
package : String -> (String, String)
package url =
( "Package documentation", url )
mds : String -> (String, String)
mds url =
( "Material Design Specification", url )
mdl : String -> (String, String)
mdl url =
( "Material Design Lite documentation", url )
references : List (String, String) -> List Html
references links =
[ text "References"
, ul []
( links |> List.map (\(str, url) ->
li [] [ a [ href url ] [ text str ] ]
)
)
]
-- DOCUMENTATION QUOTES
from : String -> String -> String -> Html
from title url body =
div []
[ text "From the "
, a [ href url ] [ text title ]
, text ":"
, Markdown.toHtml body
]
fromMDL : String -> String -> Html
fromMDL =
from "Material Design Lite documentation"
fromMDS : String -> String -> Html
fromMDS =
from "Material Design Specification"
-- TITLES
title : String -> Html
title t =
Style.div
[ Color.text Color.primary
, cs "mdl-typography--display-4"
-- TODO. Typography module
]
[ text t ]
demoTitle : Html
demoTitle =
Style.div
[ Color.text Color.primary
, cs "mdl-typography--display-1"
-- TODO. Typography module
]
[ text "Demo" ]
-- VIEW SOURCE BUTTON
addr : Signal.Address Button.Action
addr = (Signal.mailbox Button.Click).address
fab : String -> Html
fab url =
Button.fab addr (Button.model False)
[ css "position" "fixed"
, css "right" "72px"
, css "bottom" "72px"
, Button.colored
--, attribute (href srcUrl)
, attribute (Html.Attributes.attribute "onclick" ("alert('foo!');")) --("window.location.href = '" ++ srcUrl ++ "';") )
]
[ Icon.i "link" ]
-- BODY
body : String -> String -> Html -> List (String, String) -> List Html -> Html
body t srcUrl contents links demo =
div []
( title t
:: grid []
[ cell [ size All 6, size Phone 4 ] [ contents ]
, cell
[ size All 5, offset Desktop 1, size Phone 4, align Top ]
( references <| ("Demo source", srcUrl) :: links )
]
:: fab srcUrl
:: demoTitle
:: demo
)

View file

@ -5,13 +5,14 @@ import Html exposing (..)
import Html.Attributes exposing (class, style, key)
import Array exposing (Array)
import Material.Helpers exposing (map1st, map2nd)
import Material.Color as Color
import Material.Style exposing (styled, cs)
import Material.Snackbar as Snackbar
import Material.Button as Button exposing (Action(..))
import Material.Grid exposing (..)
import Material.Elevation as Elevation
import Material exposing (lift, lift')
import Material
import Demo.Page as Page
@ -19,12 +20,13 @@ import Demo.Page as Page
-- MODEL
type alias Mdl = Material.Model Action
type alias Model =
{ count : Int
, clicked : List Int
, snackbar : Snackbar.Model Action
, toastButton : Button.Model
, snackbarButton : Button.Model
, mdl : Mdl
}
@ -32,9 +34,7 @@ model : Model
model =
{ count = 0
, clicked = []
, snackbar = Snackbar.model
, toastButton = Button.model True
, snackbarButton = Button.model True
, mdl = Material.model
}
@ -43,10 +43,9 @@ model =
type Action
= Undo Int
-- Components
| SnackbarAction (Snackbar.Action Action)
| ToastButtonAction Button.Action
| SnackbarButtonAction Button.Action
| AddSnackbar
| AddToast
| MDL (Material.Action Action)
snackbar : Int -> Snackbar.Contents Action
@ -65,26 +64,26 @@ toast k =
add : (Int -> Snackbar.Contents Action) -> Model -> (Model, Effects Action)
add f model =
let
(snackbar', effects) =
Snackbar.update (Snackbar.Add (f model.count)) model.snackbar
in
({ model
| snackbar = snackbar'
, count = model.count + 1
, clicked = model.count :: model.clicked
}
, Effects.map SnackbarAction effects)
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)
update : Action -> Model -> (Model, Effects Action)
update action model =
case action of
SnackbarButtonAction Click ->
AddSnackbar ->
add snackbar model
ToastButtonAction Click ->
AddToast ->
add toast model
Undo k ->
@ -93,17 +92,33 @@ update action model =
}
, none)
SnackbarAction (Snackbar.Action action')
-> update action' model
SnackbarAction action' -> lift .snackbar (\m x -> {m|snackbar =x}) SnackbarAction Snackbar.update action' model
ToastButtonAction action' -> lift .toastButton (\m x -> {m|toastButton =x}) ToastButtonAction Button.update action' model
SnackbarButtonAction action' -> lift .snackbarButton (\m x -> {m|snackbarButton=x}) SnackbarButtonAction Button.update action' model
MDL action' ->
Material.update MDL action' model.mdl
|> map1st (\m -> { model | mdl = m })
-- VIEW
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 =
Snackbar.instance 2 MDL Snackbar.model []
clickView : Model -> Int -> Html
clickView model k =
let
@ -112,9 +127,12 @@ clickView model k =
|> Maybe.withDefault Color.Teal
|> flip Color.color Color.S500
sbmodel =
snackbarComponent.get model.mdl
selected =
(k == model.snackbar.seq - 1) &&
(Snackbar.isActive model.snackbar /= Nothing)
(k == sbmodel.seq - 1) &&
(Snackbar.isActive sbmodel /= Nothing)
in
styled div
[ Color.background color
@ -146,25 +164,17 @@ view addr model =
-- 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 ]
[ Button.raised
(Signal.forwardTo addr ToastButtonAction)
model.toastButton
[]
[ text "Toast" ]
[ addToast.view addr model.mdl [] [ text "Toast" ]
]
, cell
[ size All 2, size Phone 2, align Top ]
[ Button.raised
(Signal.forwardTo addr SnackbarButtonAction)
model.snackbarButton
[]
[ text "Snackbar" ]
[ addSnackbar.view addr model.mdl [] [ text "Snackbar" ]
]
, cell
[ size Desktop 7, size Tablet 3, size Phone 12, align Top ]
(model.clicked |> List.reverse |> List.map (clickView model))
]
, Snackbar.view (Signal.forwardTo addr SnackbarAction) model.snackbar
, snackbarComponent.view addr model.mdl
]

View file

@ -141,38 +141,41 @@ import Effects exposing (Effects)
import Material.Button as Button
import Material.Textfield as Textfield
import Material.Snackbar as Snackbar
import Material.Component as Component exposing (Indexed)
{-| Model encompassing all Material components.
-}
type alias Model =
type alias Model a =
{ button : Indexed Button.Model
, textfield : Indexed Textfield.Model
, snackbar : Indexed (Snackbar.Model a)
}
{-| Initial model.
-}
model : Model
model : Model a
model =
{ button = Dict.empty
, textfield = Dict.empty
, snackbar = Dict.empty
}
{-| Action encompassing actions of all Material components.
-}
type alias Action action =
Component.Action Model action
Component.Action (Model action) action
{-| Update function for the above Action.
-}
update :
(Action action -> action)
-> (Action action)
-> Model
-> (Model, Effects action)
-> Action action
-> Model action
-> (Model action, Effects action)
update =
Component.update

View file

@ -279,7 +279,8 @@ type alias Instance state obs =
(List Style -> List Html -> Html)
{-| Ydrk. -}
{-| Component instance.
-}
instance :
Int
-> (Component.Action (State state) obs -> obs)
@ -289,8 +290,8 @@ instance :
-> Instance (State state) obs
instance id lift view model0 observers =
Component.setup view update .button (\x y -> {y | button = x}) model0 id
|> Component.instance lift observers
Component.instance
view update .button (\x y -> {y | button = x}) id lift model0 observers
{-| Lift the button Click action to your own action. E.g.,

View file

@ -35,38 +35,27 @@ instead at `Material`.
@docs instance
# Instance consumption
@docs update
@docs update, Action
-}
import Effects exposing (Effects)
import Dict exposing (Dict)
import Material.Helpers exposing (map1, map2, map1st, map2nd)
import Material.Helpers exposing (map1, map2, map1st, map2nd, Update, Update')
-- TYPES
{- Variant of EA update function type, where effects may be
lifted to a different type.
-}
type alias Update' model action action' =
action -> model -> (model, Effects action')
{-| Standard EA update function type.
-}
type alias Update model action =
Update' model action action
{-| Standard EA view function type.
-}
type alias View model action a =
Signal.Address action -> model -> a
-- EMBEDDING MODELS
{-| Indexed families of things.
-}
@ -136,14 +125,13 @@ embedIndexed view update get set model0 id =
-- LIFTING ACTIONS
{-| We need a generic Action which encompasses x
{-| Generic MDL Action.
-}
type Action model obs =
A (model -> (model, Effects (Action model obs), Maybe obs))
-- FOR CONSUMERS
{-| Generic update function for Action.
@ -183,11 +171,12 @@ type alias Step model action obs =
and get/set/map for, well, getting, setting, and mapping the component
model.
-}
type alias Instance submodel model action a =
type alias Instance submodel model subaction action a =
{ view : View model action a
, get : model -> submodel
, set : submodel -> model -> model
, map : (submodel -> submodel) -> model -> model
, fwd : subaction -> action
}
@ -240,7 +229,7 @@ instance' :
(Action model action -> action) ->
List (Observer subaction action) ->
Embedding submodel model subaction a ->
Instance submodel model action a
Instance submodel model subaction action a
instance' lift observers embedding =
let
fwd =
@ -256,6 +245,7 @@ instance' lift observers embedding =
, get = get
, set = set
, map = \f model -> set (f (get model)) model
, fwd = fwd
}
@ -282,11 +272,8 @@ instance
-> (Action container observation -> observation)
-> model
-> List (Observer action observation)
-> Instance model container observation a
-> Instance model container action observation a
instance view update get set id lift model0 observers =
embedIndexed view update get set model0 id
|> instance' lift observers

View file

@ -53,3 +53,39 @@ map2nd : (b -> c) -> (a,b) -> (a,c)
map2nd f (x,y) = (x, f y)
{- Variant of EA update function type, where effects may be
lifted to a different type.
-}
type alias Update' model action action' =
action -> model -> (model, Effects action')
{-| Standard EA update function type.
-}
type alias Update model action =
Update' model action action
lift' :
(model -> submodel) -> -- get
(model -> submodel -> model) -> -- set
(subaction -> submodel -> submodel) ->
subaction -> -- action
model -> -- model
(model, Effects action)
lift' get set update action model =
(set model (update action (get model)), Effects.none)
lift :
(model -> submodel) -> -- get
(model -> submodel -> model) -> -- set
(subaction -> action) -> -- fwd
Update submodel subaction -> -- update
subaction -> -- action
model -> -- model
(model, Effects action)
lift get set fwd update action model =
let
(submodel', e) = update action (get model)
in
(set model submodel', Effects.map fwd e)

83
src/Material/Shadow.elm Normal file
View file

@ -0,0 +1,83 @@
module Material.Elevation
( shadow
, transition
) where
{-| From the [Material Design Lite documentation](https://github.com/google/material-design-lite/blob/master/src/shadow/README.md)
> The Material Design Lite (MDL) shadow is not a component in the same sense as
> an MDL card, menu, or textbox; it is a visual effect that can be assigned to a
> user interface element. The effect simulates a three-dimensional positioning of
> the element, as though it is slightly raised above the surface it rests upon
> a positive z-axis value, in user interface terms. The shadow starts at the
> edges of the element and gradually fades outward, providing a realistic 3-D
> effect.
>
> Shadows are a convenient and intuitive means of distinguishing an element from
> its surroundings. A shadow can draw the user's eye to an object and emphasize
> the object's importance, uniqueness, or immediacy.
>
> Shadows are a well-established feature in user interfaces, and provide users
> with a visual clue to an object's intended use or value. Their design and use
> is an important factor in the overall user experience.)
See also the
[Material Design specification](https://www.google.com/design/spec/what-is-material/elevation-shadows.html)
.
# Component
@docs shadow, transition
# View
@docs view
-}
import Effects exposing (Effects, none)
import Html exposing (..)
-- MODEL
{-| Component model.
-}
type alias Model =
{
}
{-| Default component model constructor.
-}
model : Model
model =
{
}
-- ACTION, UPDATE
{-| Component action.
-}
type Action
= MyAction
{-| Component update.
-}
update : Action -> Model -> (Model, Effects Action)
update action model =
(model, none)
-- VIEW
{-| Component view.
-}
view : Signal.Address Action -> Model -> Html
view addr model =
div [] [ h1 [] [ text "TEMPLATE" ] ]

View file

@ -2,6 +2,7 @@ module Material.Snackbar
( Contents, Model, model, toast, snackbar, isActive
, Action(Add, Action), update
, view
, Instance, instance, add
) where
{-| TODO
@ -24,6 +25,7 @@ import Task
import Time exposing (Time)
import Maybe exposing (andThen)
import Material.Component as Component exposing (Indexed)
import Material.Helpers exposing (mapFx, addFx)
@ -44,7 +46,7 @@ type alias Contents a =
-}
type alias Model a =
{ queue : List (Contents a)
, state : State a
, state : State' a
, seq : Int
}
@ -84,6 +86,7 @@ snackbar message actionMessage action =
, fade = 250
}
{-| TODO
-}
isActive : Model a -> Maybe (Contents a)
@ -107,7 +110,7 @@ contentsOf model =
-- SNACKBAR STATE MACHINE
type State a
type State' a
= Inert
| Active (Contents a)
| Fading (Contents a)
@ -270,3 +273,66 @@ view addr model =
)
buttonBody
]
-- COMPONENT
{-|
-}
type alias State s obs =
{ s | snackbar : Indexed (Model obs) }
{-|
-}
type alias Instance state obs =
Component.Instance (Model obs) state (Action obs) obs Html
{-|
-}
type alias Observer obs =
Component.Observer (Action obs) obs
{-| Component instance.
-}
instance :
Int
-> (Component.Action (State state obs) obs -> obs)
-> (Model obs)
-> List (Observer obs)
-> Instance (State state obs) obs
instance id lift model0 observers =
Component.instance
view update .snackbar (\x y -> {y | snackbar = x}) id lift model0 observers
{-|
TODO
-}
add :
Contents obs
-> Instance (State state obs) obs
-> (State state obs)
-> (State state obs, Effects obs)
add contents inst model =
let
(sb, fx) =
update (Add contents) (inst.get model)
in
(inst.set sb model, Effects.map inst.fwd fx)
{-| Lift the button Click action to your own action. E.g.,
-}
{-
fwdClick : obs -> (Observer obs)
fwdClick obs action =
case action of
Click -> Just obs
_ -> Nothing
-}

View file

@ -182,14 +182,10 @@ type alias State state =
{-|
-}
type alias Instance state obs =
Component.Instance
Model
state
obs
Html
Component.Instance Model state obs Html
{-| Component constructor.
{-| Component constructor. See module `Material`.
-}
instance :
Int
@ -198,13 +194,11 @@ instance :
-> List (Component.Observer Action obs)
-> Instance (State state) obs
instance id lift model0 observers =
instance =
let
update' action model = (update action model, Effects.none)
in
Component.setup view update' .textfield (\x y -> {y | textfield = x}) model0 id
|> Component.instance lift observers
Component.instance view update' .textfield (\x y -> {y | textfield = x})
{-| Lift the button Click action to your own action. E.g.,