mirror of
https://github.com/correl/elm-mdl.git
synced 2025-01-12 11:08:14 +00:00
Components
This commit is contained in:
parent
1fdcc78ba7
commit
02ac83a9f7
10 changed files with 470 additions and 143 deletions
|
@ -44,7 +44,8 @@ reset model =
|
|||
{ model | count = 0 }
|
||||
|
||||
|
||||
update : Action -> Model -> (Model, Effects.Effects Action)
|
||||
|
||||
update : Action -> Model -> (Model, Effects Action)
|
||||
update action model =
|
||||
case Debug.log "" action of
|
||||
IncreaseButtonAction action' ->
|
||||
|
|
|
@ -66,7 +66,7 @@ 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
|
||||
TextfieldAction a -> lift .textfields (\m x->{m|textfields=x}) TextfieldAction 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
|
||||
|
||||
|
@ -115,7 +115,7 @@ tabs =
|
|||
[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)
|
||||
, ("Grid", \addr model -> [ Demo.Grid.view ])
|
||||
, ("Badges", \addr model -> Demo.Badges.view )
|
||||
{-
|
||||
, ("Template", \addr model ->
|
||||
|
|
|
@ -10,6 +10,7 @@ import Material.Grid as Grid
|
|||
import Material.Icon as Icon
|
||||
import Material.Style exposing (Style)
|
||||
|
||||
import Demo.Page as Page
|
||||
|
||||
|
||||
-- MODEL
|
||||
|
@ -132,9 +133,39 @@ view addr model =
|
|||
]
|
||||
)
|
||||
)
|
||||
|> (\contents ->
|
||||
div []
|
||||
[ Grid.grid [] contents
|
||||
]
|
||||
)
|
||||
|> Grid.grid []
|
||||
|> flip (::) []
|
||||
|> Page.body "Buttons" srcUrl intro references
|
||||
|
||||
intro : Html
|
||||
intro =
|
||||
Page.fromMDL "https://www.getmdl.io/components/#buttons-section" """
|
||||
> The Material Design Lite (MDL) button component is an enhanced version of the
|
||||
> standard HTML `<button>` element. A button consists of text and/or an image that
|
||||
> clearly communicates what action will occur when the user clicks or touches it.
|
||||
> The MDL button component provides various types of buttons, and allows you to
|
||||
> add both display and click effects.
|
||||
>
|
||||
> Buttons are a ubiquitous feature of most user interfaces, regardless of a
|
||||
> site's content or function. Their design and use is therefore an important
|
||||
> factor in the overall user experience. See the button component's Material
|
||||
> Design specifications page for details.
|
||||
>
|
||||
> The available button display types are flat (default), raised, fab, mini-fab,
|
||||
> and icon; any of these types may be plain (light gray) or colored, and may be
|
||||
> initially or programmatically disabled. The fab, mini-fab, and icon button
|
||||
> types typically use a small image as their caption rather than text.
|
||||
|
||||
"""
|
||||
|
||||
srcUrl : String
|
||||
srcUrl =
|
||||
"https://github.com/debois/elm-mdl/blob/master/examples/Demo/Buttons.elm"
|
||||
|
||||
references : List (String, String)
|
||||
references =
|
||||
[ Page.package "http://package.elm-lang.org/packages/debois/elm-mdl/latest/Material-Button"
|
||||
, Page.mds "https://www.google.com/design/spec/components/buttons.html"
|
||||
, Page.mdl "https://www.getmdl.io/components/#buttons-section"
|
||||
]
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
module Demo.Grid where
|
||||
|
||||
|
||||
import Html exposing (..)
|
||||
import Array
|
||||
|
||||
import Material.Grid exposing (..)
|
||||
import Material.Style exposing (Style, css)
|
||||
import Material.Color as Color
|
||||
|
||||
import Html exposing (..)
|
||||
import Markdown
|
||||
import Demo.Page as Page
|
||||
|
||||
-- Cell styling
|
||||
|
||||
|
@ -32,31 +36,36 @@ std = democell 200
|
|||
|
||||
-- Grid
|
||||
|
||||
view : List Html
|
||||
color : Int -> Style
|
||||
color k =
|
||||
Array.get (k % Array.length Color.palette) Color.palette
|
||||
|> Maybe.withDefault Color.Teal
|
||||
|> flip Color.color Color.S500
|
||||
|> Color.background
|
||||
|
||||
view : Html
|
||||
view =
|
||||
[ intro
|
||||
, [1..12]
|
||||
|> List.map (\i -> small [size All 1] [text "1"])
|
||||
[ [1..12]
|
||||
|> List.map (\i -> small [size All 1, color i] [text "1"])
|
||||
|> grid []
|
||||
, [1 .. 3]
|
||||
|> List.map (\i -> std [size All 4] [text <| "4"])
|
||||
|> List.map (\i -> std [size All 4, color i] [text <| "4"])
|
||||
|> grid []
|
||||
, [ std [size All 6] [text "6"]
|
||||
, std [size All 4] [text "4"]
|
||||
, std [size All 2] [text "2"]
|
||||
, [ std [size All 6, color 16] [text "6"]
|
||||
, std [size All 4, color 17] [text "4"]
|
||||
, std [size All 2, color 18] [text "2"]
|
||||
] |> grid []
|
||||
, [ std [size All 6, size Tablet 8] [text "6 (8 tablet)"]
|
||||
, std [size All 4, size Tablet 6] [text "4 (6 tablet)"]
|
||||
, std [size All 2, size Phone 4] [text "2 (4 phone)"]
|
||||
, [ std [size All 6, size Tablet 8, color 19] [text "6 (8 tablet)"]
|
||||
, std [size All 4, size Tablet 6, color 20] [text "4 (6 tablet)"]
|
||||
, std [size All 2, size Phone 4, color 21] [text "2 (4 phone)"]
|
||||
] |> grid []
|
||||
]
|
||||
|> Page.body "Grid" srcUrl intro references
|
||||
|
||||
|
||||
intro : Html
|
||||
intro = """
|
||||
From the
|
||||
[Material Design Lite documentation](http://www.getmdl.io/components/#layout-section/grid):
|
||||
|
||||
intro =
|
||||
Page.fromMDL "http://www.getmdl.io/components/#layout-section/grid" """
|
||||
> The Material Design Lite (MDL) grid component is a simplified method for laying
|
||||
> out content for multiple screen sizes. It reduces the usual coding burden
|
||||
> required to correctly display blocks of content in a variety of display
|
||||
|
@ -73,15 +82,17 @@ From the
|
|||
> of columns for the current screen size, it takes up the entirety of its
|
||||
> row.
|
||||
|
||||
#### See also
|
||||
Resize your browser-window to observe the effect on the Grid below.
|
||||
"""
|
||||
|
||||
- [Demo source code](https://github.com/debois/elm-mdl/blob/master/examples/Demo/Grid.elm)
|
||||
- [elm-mdl package documentation](http://package.elm-lang.org/packages/debois/elm-mdl/latest/Material-Grid)
|
||||
- [Material Design Specification](https://www.google.com/design/spec/layout/responsive-ui.html#responsive-ui-grid)
|
||||
- [Material Design Lite documentation](http://www.getmdl.io/components/#layout-section/grid)
|
||||
|
||||
#### Demo
|
||||
|
||||
""" |> Markdown.toHtml
|
||||
srcUrl : String
|
||||
srcUrl =
|
||||
"https://github.com/debois/elm-mdl/blob/master/examples/Demo/Grid.elm"
|
||||
|
||||
references : List (String, String)
|
||||
references =
|
||||
[ Page.package "http://package.elm-lang.org/packages/debois/elm-mdl/latest/Material-Grid"
|
||||
, Page.mds "https://www.google.com/design/spec/layout/responsive-ui.html#responsive-ui-grid"
|
||||
, Page.mdl "http://www.getmdl.io/components/#layout-section/grid"
|
||||
]
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ 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
|
||||
import Material.Elevation as Elevation
|
||||
|
||||
|
||||
-- REFERENCES
|
||||
|
@ -78,24 +79,28 @@ fromMDS =
|
|||
|
||||
title : String -> Html
|
||||
title t =
|
||||
Style.div
|
||||
Style.styled Html.h1
|
||||
[ Color.text Color.primary
|
||||
, cs "mdl-typography--display-4"
|
||||
--, cs "mdl-typography--display-4"
|
||||
-- TODO. Typography module
|
||||
]
|
||||
[]
|
||||
[ text t ]
|
||||
|
||||
|
||||
demoTitle : Html
|
||||
demoTitle =
|
||||
Style.div
|
||||
div [] []
|
||||
{-
|
||||
Style.div
|
||||
[ Color.text Color.primary
|
||||
, cs "mdl-typography--display-1"
|
||||
, css "text-align" "right"
|
||||
, css "padding" ".5em"
|
||||
, cs "mdl-typography--display2"
|
||||
-- TODO. Typography module
|
||||
]
|
||||
[ text "Demo" ]
|
||||
|
||||
|
||||
-}
|
||||
|
||||
-- VIEW SOURCE BUTTON
|
||||
|
||||
|
@ -110,6 +115,7 @@ fab url =
|
|||
[ css "position" "fixed"
|
||||
, css "right" "72px"
|
||||
, css "bottom" "72px"
|
||||
, css "z-index" "9999"
|
||||
, Button.colored
|
||||
--, attribute (href srcUrl)
|
||||
, attribute (Html.Attributes.attribute "onclick" ("alert('foo!');")) --("window.location.href = '" ++ srcUrl ++ "';") )
|
||||
|
@ -123,17 +129,20 @@ fab url =
|
|||
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
|
||||
)
|
||||
[ 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
|
||||
, Style.div
|
||||
[ Elevation.shadow 2 ]
|
||||
( demoTitle
|
||||
:: demo
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -4,10 +4,11 @@ import Effects exposing (Effects, none)
|
|||
import Html exposing (..)
|
||||
import Html.Attributes exposing (class, style, key)
|
||||
import Array exposing (Array)
|
||||
import Time exposing (Time, millisecond)
|
||||
|
||||
import Material.Helpers exposing (map1st, map2nd)
|
||||
import Material.Helpers exposing (map1st, map2nd, delay)
|
||||
import Material.Color as Color
|
||||
import Material.Style exposing (styled, cs)
|
||||
import Material.Style exposing (styled, cs, css)
|
||||
import Material.Snackbar as Snackbar
|
||||
import Material.Button as Button exposing (Action(..))
|
||||
import Material.Grid exposing (..)
|
||||
|
@ -24,9 +25,19 @@ type alias Mdl =
|
|||
Material.Model Action
|
||||
|
||||
|
||||
type Square'
|
||||
= Appearing
|
||||
| Idle
|
||||
| Disappearing
|
||||
|
||||
|
||||
type alias Square =
|
||||
(Int, Square')
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ count : Int
|
||||
, clicked : List Int
|
||||
, squares : List Square
|
||||
, mdl : Mdl
|
||||
}
|
||||
|
||||
|
@ -34,7 +45,7 @@ type alias Model =
|
|||
model : Model
|
||||
model =
|
||||
{ count = 0
|
||||
, clicked = []
|
||||
, squares = []
|
||||
, mdl = Material.model
|
||||
}
|
||||
|
||||
|
@ -43,9 +54,11 @@ model =
|
|||
|
||||
|
||||
type Action
|
||||
= Undo Int
|
||||
| AddSnackbar
|
||||
= AddSnackbar
|
||||
| AddToast
|
||||
| Appear Int
|
||||
| Disappear Int
|
||||
| Gone Int
|
||||
| MDL (Material.Action Action)
|
||||
|
||||
|
||||
|
@ -53,15 +66,31 @@ add : Model -> (Int -> Snackbar.Contents Action) -> (Model, Effects Action)
|
|||
add model f =
|
||||
let
|
||||
(mdl', fx) =
|
||||
Snackbar.add (f model.count) snackbarComponent model.mdl
|
||||
Snackbar.add (f model.count) snackbar model.mdl
|
||||
model' =
|
||||
{ model
|
||||
| mdl = mdl'
|
||||
, count = model.count + 1
|
||||
, clicked = model.count :: model.clicked
|
||||
, squares = (model.count, Appearing) :: model.squares
|
||||
}
|
||||
in
|
||||
(model', fx)
|
||||
( model'
|
||||
, Effects.batch
|
||||
[ Effects.tick (always (Appear model.count))
|
||||
, fx
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
mapSquare : Int -> (Square' -> Square') -> Model -> Model
|
||||
mapSquare k f model =
|
||||
{ model
|
||||
| squares =
|
||||
List.map
|
||||
( \((k', sq) as s) -> if k /= k' then s else (k', f sq) )
|
||||
model.squares
|
||||
}
|
||||
|
||||
|
||||
|
||||
update : Action -> Model -> (Model, Effects Action)
|
||||
|
@ -69,15 +98,25 @@ update action model =
|
|||
case action of
|
||||
AddSnackbar ->
|
||||
add model
|
||||
<| \k -> Snackbar.snackbar ("Snackbar message #" ++ toString k) "UNDO" (Undo k)
|
||||
<| \k -> Snackbar.snackbar ("Snackbar message #" ++ toString k) "UNDO" (Disappear k)
|
||||
|
||||
AddToast ->
|
||||
add model
|
||||
<| \k -> Snackbar.toast <| "Toast message #" ++ toString k
|
||||
|
||||
Undo k ->
|
||||
Appear k ->
|
||||
( model |> mapSquare k (always Idle)
|
||||
, none
|
||||
)
|
||||
|
||||
Disappear k ->
|
||||
( model |> mapSquare k (always Disappearing)
|
||||
, delay transitionLength (Gone k)
|
||||
)
|
||||
|
||||
Gone k ->
|
||||
({ model
|
||||
| clicked = List.filter ((/=) k) model.clicked
|
||||
| squares = List.filter (fst >> (/=) k) model.squares
|
||||
}
|
||||
, none)
|
||||
|
||||
|
@ -86,6 +125,7 @@ update action model =
|
|||
|> map1st (\m -> { model | mdl = m })
|
||||
|
||||
|
||||
|
||||
-- VIEW
|
||||
|
||||
|
||||
|
@ -103,67 +143,121 @@ addToastButton =
|
|||
[ Button.fwdClick AddToast ]
|
||||
|
||||
|
||||
snackbarComponent : Snackbar.Instance Mdl Action
|
||||
snackbarComponent =
|
||||
-- TODO: Bad name
|
||||
snackbar : Snackbar.Instance Mdl Action
|
||||
snackbar =
|
||||
Snackbar.instance MDL Snackbar.model
|
||||
|
||||
|
||||
clickView : Model -> Int -> Html
|
||||
clickView model k =
|
||||
boxHeight : String
|
||||
boxHeight = "48px"
|
||||
|
||||
|
||||
boxWidth : String
|
||||
boxWidth = "64px"
|
||||
|
||||
|
||||
transitionLength : Time
|
||||
transitionLength = 150 * millisecond
|
||||
|
||||
|
||||
transitions : (String, String)
|
||||
transitions =
|
||||
("transition"
|
||||
, "box-shadow 333ms ease-in-out 0s, "
|
||||
++ "width " ++ toString transitionLength ++ "ms, "
|
||||
++ "height " ++ toString transitionLength ++ "ms"
|
||||
)
|
||||
|
||||
|
||||
clickView : Model -> Square -> Html
|
||||
clickView model (k, square) =
|
||||
let
|
||||
color =
|
||||
Array.get ((k + 4) % Array.length Color.palette) Color.palette
|
||||
|> Maybe.withDefault Color.Teal
|
||||
|> flip Color.color Color.S500
|
||||
|
||||
sbmodel =
|
||||
snackbarComponent.get model.mdl
|
||||
selected' =
|
||||
Snackbar.activeAction (snackbar.get model.mdl) == Just (Disappear k)
|
||||
|
||||
selected =
|
||||
(k == sbmodel.seq - 1) &&
|
||||
(Snackbar.isActive sbmodel /= Nothing)
|
||||
(width, height, margin, selected) =
|
||||
case square of
|
||||
Idle ->
|
||||
(boxWidth, boxHeight, "16px 16px", selected')
|
||||
_ ->
|
||||
("0", "0", "16px 0", False)
|
||||
in
|
||||
styled div
|
||||
[ Color.background color
|
||||
, Color.text Color.primaryContrast
|
||||
-- TODO. Should have shadow styles someplace.
|
||||
, Elevation.shadow (if selected then 8 else 2)
|
||||
]
|
||||
[ style
|
||||
[ ("margin-right", "3ex")
|
||||
, ("margin-bottom", "3ex")
|
||||
, ("padding", "1.5ex")
|
||||
, ("width", "4ex")
|
||||
, ("border-radius", "2px")
|
||||
div
|
||||
[ style
|
||||
[ ("height", boxHeight)
|
||||
, ("width", width)
|
||||
, ("position", "relative")
|
||||
, ("display", "inline-block")
|
||||
, ("text-align", "center")
|
||||
, ("transition", "box-shadow 333ms ease-in-out 0s")
|
||||
, ("margin", margin)
|
||||
, ("transition",
|
||||
"width " ++ toString transitionLength ++ "ms ease-in-out 0s, "
|
||||
++ "margin " ++ toString transitionLength ++ "ms ease-in-out 0s"
|
||||
)
|
||||
, ("z-index", "0")
|
||||
]
|
||||
, key (toString k)
|
||||
, key <| toString k
|
||||
]
|
||||
[ text <| toString k ]
|
||||
[ styled div
|
||||
[ Color.background color
|
||||
, Color.text Color.primaryContrast
|
||||
, Elevation.shadow (if selected then 8 else 2)
|
||||
]
|
||||
[ style
|
||||
[ ("display", "inline-flex")
|
||||
, ("align-items", "center")
|
||||
, ("justify-content", "center")
|
||||
, ("height", height)
|
||||
, ("width", width)
|
||||
, ("border-radius", "2px")
|
||||
, transitions
|
||||
, ("overflow", "hidden")
|
||||
, ("box-sizing", "border-box")
|
||||
, ("flex", "0 0 auto")
|
||||
, ("position", "absolute")
|
||||
, ("bottom", "0")
|
||||
, ("left", "0")
|
||||
]
|
||||
]
|
||||
[ div [] [ text <| toString k ] ]
|
||||
]
|
||||
|
||||
|
||||
|
||||
view : Signal.Address Action -> Model -> Html
|
||||
view addr model =
|
||||
Page.body "Snackbar & Toast" srcUrl intro references
|
||||
[ grid []
|
||||
-- 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 ]
|
||||
[ addToastButton.view addr model.mdl [] [ text "Toast" ]
|
||||
[ grid [ css "margin-top" "32px" ]
|
||||
[ cell
|
||||
[ size All 2, size Phone 2, align Top ]
|
||||
[ addToastButton.view addr model.mdl
|
||||
[ Button.colored
|
||||
, css "margin" "16px"
|
||||
]
|
||||
[ text "Toast" ]
|
||||
]
|
||||
, cell
|
||||
[ size All 2, size Phone 2, align Top ]
|
||||
[ addSnackbarButton.view addr model.mdl [] [ text "Snackbar" ]
|
||||
[ addSnackbarButton.view addr model.mdl
|
||||
[ Button.colored
|
||||
, css "margin" "16px"
|
||||
]
|
||||
[ text "Snackbar" ]
|
||||
]
|
||||
, cell
|
||||
[ size Desktop 7, size Tablet 3, size Phone 12, align Top ]
|
||||
(model.clicked |> List.reverse |> List.map (clickView model))
|
||||
[ size Desktop 7, offset Desktop 1
|
||||
, size Tablet 3, offset Tablet 1
|
||||
, size Phone 4
|
||||
, align Top
|
||||
]
|
||||
(model.squares |> List.reverse |> List.map (clickView model))
|
||||
]
|
||||
, snackbarComponent.view addr model.mdl
|
||||
, snackbar.view addr model.mdl
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -1,52 +1,215 @@
|
|||
module Demo.Textfields where
|
||||
|
||||
import Array exposing (Array)
|
||||
import Html exposing (Html)
|
||||
import Effects exposing (Effects)
|
||||
import Regex
|
||||
|
||||
import Material.Textfield as Textfield
|
||||
import Material.Grid as Grid exposing (..)
|
||||
import Material.Helpers exposing (map1st)
|
||||
import Material
|
||||
|
||||
import Demo.Page as Page
|
||||
|
||||
|
||||
type alias Model = Array Textfield.Model
|
||||
-- MODEL
|
||||
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ mdl : Material.Model Action
|
||||
, rx : (String, Regex.Regex)
|
||||
}
|
||||
|
||||
|
||||
rx0 : String
|
||||
rx0 =
|
||||
"[0-9]*"
|
||||
|
||||
|
||||
setRegex : String -> (String, Regex.Regex)
|
||||
setRegex str =
|
||||
(str, Regex.regex str)
|
||||
|
||||
|
||||
model : Model
|
||||
model =
|
||||
let t0 = Textfield.model in
|
||||
[ t0
|
||||
, { t0 | label = Just { text = "Labelled", float = False } }
|
||||
, { t0 | label = Just { text = "Floating label", float = True }}
|
||||
, { t0
|
||||
model =
|
||||
{ mdl = Material.model
|
||||
, rx = setRegex rx0
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- ACTION, UPDATE
|
||||
|
||||
|
||||
|
||||
type Action
|
||||
= MDL (Material.Action Action)
|
||||
| Upd0 String
|
||||
| Upd4 String
|
||||
|
||||
|
||||
transferToDisabled : String -> Mdl -> Mdl
|
||||
transferToDisabled str =
|
||||
field3.map (\m ->
|
||||
{ m
|
||||
| value =
|
||||
if str == "" then
|
||||
""
|
||||
else
|
||||
"\"" ++ str ++ "\" (still disabled, though)"
|
||||
})
|
||||
|
||||
|
||||
match : String -> Regex.Regex -> Bool
|
||||
match str rx =
|
||||
Regex.find Regex.All rx str
|
||||
|> List.any (.match >> (==) str)
|
||||
|
||||
|
||||
checkRegex : String -> (String, Regex.Regex) -> Mdl -> Mdl
|
||||
checkRegex str (rx', rx) mdl =
|
||||
let
|
||||
value4 = field4.get mdl |> .value
|
||||
in
|
||||
mdl |> field4.map (\m -> { m | error =
|
||||
if match value4 rx then
|
||||
Nothing
|
||||
else
|
||||
"Doesn't match regex ' " ++ rx' ++ "'" |> Just
|
||||
})
|
||||
|
||||
|
||||
|
||||
update : Action -> Model -> (Model, Effects Action)
|
||||
update action model =
|
||||
case action of
|
||||
MDL action' ->
|
||||
Material.update MDL action' model.mdl
|
||||
|> map1st (\mdl' -> { model | mdl = mdl' })
|
||||
|
||||
Upd0 str ->
|
||||
( { model | mdl = transferToDisabled str model.mdl }
|
||||
, Effects.none
|
||||
)
|
||||
|
||||
Upd4 str ->
|
||||
( { model | mdl = checkRegex str model.rx model.mdl }
|
||||
, Effects.none
|
||||
)
|
||||
|
||||
|
||||
-- VIEW
|
||||
|
||||
|
||||
m0 : Textfield.Model
|
||||
m0 =
|
||||
Textfield.model
|
||||
|
||||
|
||||
type alias Mdl =
|
||||
Material.Model Action
|
||||
|
||||
|
||||
field0 : Textfield.Instance Mdl Action
|
||||
field0 =
|
||||
Textfield.instance 0 MDL m0
|
||||
[ Textfield.fwdInput Upd0
|
||||
]
|
||||
|
||||
|
||||
field1 : Textfield.Instance Mdl Action
|
||||
field1 =
|
||||
Textfield.instance 1 MDL
|
||||
{ m0 | label = Just { text = "Labelled", float = False } }
|
||||
[]
|
||||
|
||||
|
||||
field2 : Textfield.Instance Mdl Action
|
||||
field2 =
|
||||
Textfield.instance 2 MDL
|
||||
{ m0
|
||||
| label = Just { text = "Floating label", float = True }
|
||||
}
|
||||
[]
|
||||
|
||||
|
||||
field3 : Textfield.Instance Mdl Action
|
||||
field3 =
|
||||
Textfield.instance 3 MDL
|
||||
{ m0
|
||||
| label = Just { text = "Disabled", float = False }
|
||||
, isDisabled = True
|
||||
}
|
||||
, { t0
|
||||
| label = Just { text = "With error and value", float = False }
|
||||
, error = Just "The input is wrong!"
|
||||
, value = "Incorrect input"
|
||||
[]
|
||||
|
||||
|
||||
field4 : Textfield.Instance Mdl Action
|
||||
field4 =
|
||||
Textfield.instance 4 MDL
|
||||
{ m0
|
||||
| label = Just { text = "With error checking", float = False }
|
||||
}
|
||||
]
|
||||
|> Array.fromList
|
||||
|
||||
|
||||
type Action =
|
||||
Field Int Textfield.Action
|
||||
|
||||
|
||||
update : Action -> Model -> Model
|
||||
update (Field k action) fields =
|
||||
Array.get k fields
|
||||
|> Maybe.map (Textfield.update action)
|
||||
|> Maybe.map (\field' -> Array.set k field' fields)
|
||||
|> Maybe.withDefault fields
|
||||
[ Textfield.fwdInput Upd4 ]
|
||||
|
||||
|
||||
view : Signal.Address Action -> Model -> Html
|
||||
view addr model =
|
||||
model
|
||||
|> Array.indexedMap (\k field ->
|
||||
Textfield.view (Signal.forwardTo addr (Field k)) field
|
||||
)
|
||||
|> Array.toList
|
||||
|> List.map (\x -> cell [size All 3] [x])
|
||||
[ field0
|
||||
, field1
|
||||
, field2
|
||||
, field3
|
||||
, field4
|
||||
]
|
||||
|> List.map (\c ->
|
||||
cell
|
||||
[size All 4, offset Desktop 1]
|
||||
[c.view addr model.mdl]
|
||||
)
|
||||
|> List.intersperse (cell [size All 1] [])
|
||||
|> grid []
|
||||
|> flip (::) []
|
||||
|> Page.body "Textfields" srcUrl intro references
|
||||
|
||||
|
||||
intro : Html
|
||||
intro =
|
||||
Page.fromMDL "http://www.getmdl.io/components/#textfields-section" """
|
||||
> The Material Design Lite (MDL) text field component is an enhanced version of
|
||||
> the standard HTML `<input type="text">` and `<input type="textarea">` elements.
|
||||
> A text field consists of a horizontal line indicating where keyboard input
|
||||
> can occur and, typically, text that clearly communicates the intended
|
||||
> contents of the text field. The MDL text field component provides various
|
||||
> types of text fields, and allows you to add both display and click effects.
|
||||
>
|
||||
> Text fields are a common feature of most user interfaces, regardless of a
|
||||
> site's content or function. Their design and use is therefore an important
|
||||
> factor in the overall user experience. See the text field component's
|
||||
> [Material Design specifications page](https://www.google.com/design/spec/components/text-fields.html)
|
||||
> for details.
|
||||
>
|
||||
> The enhanced text field component has a more vivid visual look than a standard
|
||||
> text field, and may be initially or programmatically disabled. There are three
|
||||
> main types of text fields in the text field component, each with its own basic
|
||||
> coding requirements. The types are single-line, multi-line, and expandable.
|
||||
|
||||
This implementation provides only single-line.
|
||||
|
||||
"""
|
||||
|
||||
srcUrl : String
|
||||
srcUrl =
|
||||
"https://github.com/debois/elm-mdl/blob/master/examples/Demo/Textfields.elm"
|
||||
|
||||
|
||||
references : List (String, String)
|
||||
references =
|
||||
[ Page.package "http://package.elm-lang.org/packages/debois/elm-mdl/latest/Material-Textfield"
|
||||
, Page.mds "https://www.google.com/design/spec/components/text-fields.html"
|
||||
, Page.mdl "https://www.getmdl.io/components/#textfields-section"
|
||||
]
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@ module Material.Helpers where
|
|||
import Html
|
||||
import Html.Attributes
|
||||
import Effects exposing (Effects)
|
||||
import Time exposing (Time)
|
||||
import Task
|
||||
|
||||
filter : (a -> List b -> c) -> a -> List (Maybe b) -> c
|
||||
filter elem attr html =
|
||||
|
@ -89,3 +91,12 @@ lift get set fwd update action model =
|
|||
(submodel', e) = update action (get model)
|
||||
in
|
||||
(set model submodel', Effects.map fwd e)
|
||||
|
||||
|
||||
delay : Time -> a -> Effects a
|
||||
delay t x =
|
||||
Task.sleep t
|
||||
|> (flip Task.andThen) (always (Task.succeed x))
|
||||
|> Effects.task
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
module Material.Snackbar
|
||||
( Contents, Model, model, toast, snackbar, isActive
|
||||
( Contents, Model, model, toast, snackbar, isActive, activeAction
|
||||
, Action(Add, Action), update
|
||||
, view
|
||||
, Instance, instance, add
|
||||
|
@ -26,7 +26,7 @@ import Time exposing (Time)
|
|||
import Maybe exposing (andThen)
|
||||
|
||||
import Material.Component as Component exposing (Indexed)
|
||||
import Material.Helpers exposing (mapFx, addFx)
|
||||
import Material.Helpers exposing (mapFx, addFx, delay)
|
||||
|
||||
|
||||
-- MODEL
|
||||
|
@ -88,6 +88,7 @@ snackbar message actionMessage action =
|
|||
|
||||
|
||||
{-| TODO
|
||||
(Bad name)
|
||||
-}
|
||||
isActive : Model a -> Maybe (Contents a)
|
||||
isActive model =
|
||||
|
@ -99,6 +100,15 @@ isActive model =
|
|||
Nothing
|
||||
|
||||
|
||||
{-| TODO
|
||||
-}
|
||||
activeAction : Model a -> Maybe a
|
||||
activeAction model =
|
||||
isActive model
|
||||
|> flip Maybe.andThen .action
|
||||
|> Maybe.map snd
|
||||
|
||||
|
||||
contentsOf : Model a -> Maybe (Contents a)
|
||||
contentsOf model =
|
||||
case model.state of
|
||||
|
@ -121,13 +131,6 @@ type Transition
|
|||
| Click
|
||||
|
||||
|
||||
delay : Time -> a -> Effects a
|
||||
delay t x =
|
||||
Task.sleep t
|
||||
|> (flip Task.andThen) (\_ -> Task.succeed x)
|
||||
|> Effects.task
|
||||
|
||||
|
||||
move : Transition -> Model a -> (Model a, Effects Transition)
|
||||
move transition model =
|
||||
case (model.state, transition) of
|
||||
|
|
|
@ -138,6 +138,7 @@ view : Signal.Address Action -> Model -> Html
|
|||
view addr model =
|
||||
let hasFloat = model.label |> Maybe.map .float |> Maybe.withDefault False
|
||||
hasError = model.error |> Maybe.map (always True) |> Maybe.withDefault False
|
||||
labelText = model.label |> Maybe.map .text
|
||||
in
|
||||
filter div
|
||||
[ classList
|
||||
|
@ -162,10 +163,13 @@ view addr model =
|
|||
, onFocus addr Focus
|
||||
]
|
||||
[]
|
||||
, model.label |> Maybe.map (\l ->
|
||||
label [class "mdl-textfield__label"] [text l.text])
|
||||
, model.error |> Maybe.map (\e ->
|
||||
span [class "mdl-textfield__error"] [text e])
|
||||
, Just <| label
|
||||
[class "mdl-textfield__label"]
|
||||
(case labelText of
|
||||
Just str -> [ text str ]
|
||||
Nothing -> [])
|
||||
, model.error |> Maybe.map (\e ->
|
||||
span [class "mdl-textfield__error"] [text e])
|
||||
]
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue