diff --git a/examples/Demo.elm b/examples/Demo.elm new file mode 100644 index 0000000..21cf352 --- /dev/null +++ b/examples/Demo.elm @@ -0,0 +1,182 @@ +import StartApp +import Html exposing (..) +import Html.Attributes exposing (href, class, style) +import Signal exposing (Signal) +import Effects exposing (..) +import Task +import Signal +import Task exposing (Task) +import Array exposing (Array) + +import Material.Layout as Layout exposing (defaultLayoutModel) +import Material + +import Demo.Buttons +import Demo.Grid +import Demo.Textfields + + +-- MODEL + + +type alias Model = + { layout : Layout.Model + , buttons : Demo.Buttons.Model + , textfields : Demo.Textfields.Model + } + + +layoutModel : Layout.Model +layoutModel = + { defaultLayoutModel + | state = Layout.initState (List.length tabs) + } + + +model : Model +model = + { layout = layoutModel + , buttons = Demo.Buttons.model + , textfields = Demo.Textfields.model + } + + +-- ACTION, UPDATE + + +type Action + = LayoutAction Layout.Action + | ButtonsAction Demo.Buttons.Action + | TextfieldAction Demo.Textfields.Action + + +update : Action -> Model -> (Model, Effects.Effects Action) +update action model = + case action of + LayoutAction a -> + let + (l, e) = Layout.update a model.layout + in + ({ model | layout = l }, Effects.map LayoutAction e) + + ButtonsAction a -> + let + (b, e) = Demo.Buttons.update a model.buttons + in + ({ model | buttons = b }, Effects.map ButtonsAction e) + + TextfieldAction a -> + ({ model | textfields = Demo.Textfields.update a model.textfields } + , Effects.none + ) + + +-- VIEW + + +type alias Addr = Signal.Address Action + + + +drawer : List Html +drawer = + [ Layout.title "Example drawer" + , Layout.navigation + [ Layout.link + [href "https://groups.google.com/forum/#!forum/elm-discuss"] + [text "Elm Discuss"] + , Layout.link + [href "http://elm-lang.org"] + [text "Elm"] + ] + ] + + +header : List Html +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"] + ] + ] + + +tabs : List (String, Addr -> Model -> List Html) +tabs = + [ ("Buttons", \addr model -> + [Demo.Buttons.view (Signal.forwardTo addr ButtonsAction) model.buttons]) + , ("Textfields", \addr model -> + [Demo.Textfields.view (Signal.forwardTo addr TextfieldAction) model.textfields]) + , ("Grid", \addr model -> Demo.Grid.view) + ] + + +tabViews : Array (Addr -> Model -> List Html) +tabViews = List.map snd tabs |> Array.fromList + + +tabTitles : List Html +tabTitles = List.map (fst >> text) tabs + + +view : Signal.Address Action -> Model -> Html +view addr model = + let top = + div + [ style + [ ("margin", "auto") + , ("width", "90%") + ] + ] + ((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 + { header = Just header + , drawer = Just drawer + , tabs = Just tabTitles + , main = [ top ] + } + |> Material.topWithColors Material.Teal Material.Red + + +init : (Model, Effects.Effects Action) +init = (model, Effects.none) + + +inputs : List (Signal.Signal Action) +inputs = + [ Layout.setupSizeChangeSignal LayoutAction + ] + + +app : StartApp.App Model +app = + StartApp.start + { init = init + , view = view + , update = update + , inputs = inputs + } + +main : Signal Html +main = + app.html + + +-- PORTS + + +port tasks : Signal (Task.Task Never ()) +port tasks = + app.tasks diff --git a/examples/Demo/Buttons.elm b/examples/Demo/Buttons.elm new file mode 100644 index 0000000..2beac6e --- /dev/null +++ b/examples/Demo/Buttons.elm @@ -0,0 +1,144 @@ +module Demo.Buttons where + +import Dict +import Html exposing (..) +import Html.Attributes exposing (..) +import Effects + +import Material.Button as Button exposing (..) +import Material.Grid as Grid +import Material.Icon as Icon + + +-- MODEL + + +type alias Index = (Int, Int) + + +tabulate' : Int -> List a -> List (Int, a) +tabulate' i ys = + case ys of + [] -> [] + y :: ys -> (i, y) :: tabulate' (i+1) ys + + +tabulate : List a -> List (Int, a) +tabulate = tabulate' 0 + + +type alias View = + Signal.Address Button.Action -> Button.Model -> Coloring -> List Html -> Html + +type alias View' = + Signal.Address Button.Action -> Button.Model -> Html + + +view' : View -> Coloring -> Html -> Signal.Address Button.Action -> Button.Model -> Html +view' view coloring elem addr model = + view addr model coloring [elem] + + +describe : String -> Bool -> Coloring -> String +describe kind ripple coloring = + let + c = + case coloring of + Plain -> "plain" + Colored -> "colored" + Primary -> "primary" + Accent -> "accent" + in + kind ++ ", " ++ c ++ if ripple then " w/ripple" else "" + + +row : (String, Html, View) -> Bool -> List (Int, (Bool, String, View')) +row (kind, elem, v) ripple = + [ Plain, Colored, Primary, Accent ] + |> List.map (\c -> (ripple, describe kind ripple c, view' v c elem)) + |> tabulate + + +buttons : List (List (Index, (Bool, String, View'))) +buttons = + [ ("flat", text "Flat Button", Button.flat) + , ("raised", text "Raised Button", Button.raised) + , ("FAB", Icon.i "add", Button.fab) + , ("mini-FAB", Icon.i "zoom_in", Button.minifab) + , ("icon", Icon.i "flight_land", Button.icon) + ] + |> List.concatMap (\a -> [row a False, row a True]) + |> tabulate + |> List.map (\(i, row) -> List.map (\(j, x) -> ((i,j), x)) row) + + +model : Model +model = + { clicked = "" + , buttons = + buttons + |> List.concatMap (List.map <| \(idx, (ripple, _, _)) -> (idx, Button.model ripple)) + |> Dict.fromList + } + + +-- ACTION, UPDATE + + +type Action = Action Index Button.Action + + +type alias Model = + { clicked : String + , buttons : Dict.Dict Index Button.Model + } + + +update : Action -> Model -> (Model, Effects.Effects Action) +update (Action idx action) model = + Dict.get idx model.buttons + |> Maybe.map (\m0 -> + let + (m1, e) = Button.update action m0 + in + ({ model | buttons = Dict.insert idx m1 model.buttons }, Effects.map (Action idx) e) + ) + |> Maybe.withDefault (model, Effects.none) + + +-- VIEW + + +view : Signal.Address Action -> Model -> Html +view addr model = + buttons |> List.concatMap (\row -> + row |> List.concatMap (\(idx, (ripple, description, view)) -> + let model' = + Dict.get idx model.buttons |> Maybe.withDefault (Button.model False) + in + [ Grid.cell + [ Grid.size Grid.All 3] + [ div + [ style + [ ("text-align", "center") + , ("margin-top", "1em") + , ("margin-bottom", "1em") + ] + ] + [ view + (Signal.forwardTo addr (Action idx)) + model' + , div + [ style + [ ("font-size", "9pt") + , ("margin-top", "1em") + ] + ] + [ text description + ] + ] + ] + ] + ) + ) + |> Grid.grid diff --git a/examples/Demo/Grid.elm b/examples/Demo/Grid.elm new file mode 100644 index 0000000..0ddf04f --- /dev/null +++ b/examples/Demo/Grid.elm @@ -0,0 +1,36 @@ +module Demo.Grid where + +import Material.Grid exposing (..) +import Html exposing (..) + + +view : List Html +view = + [ [1..12] + |> List.map (\i -> cell [size All 1] [text "1"]) + |> grid + , [1 .. 3] + |> List.map (\i -> cell [size All 4] [text <| "4"]) + |> grid + , [ cell [size All 6] [text "6"] + , cell [size All 4] [text "4"] + , cell [size All 2] [text "2"] + ] |> grid + , [ cell [size All 6, size Tablet 8] [text "6 (8 tablet)"] + , cell [size All 4, size Tablet 6] [text "4 (6 tablet)"] + , cell [size All 2, size Phone 4] [text "2 (4 phone)"] + ] |> grid + , Html.node "style" [] [text """ + .mdl-cell { + text-sizing: border-box; + background-color: #BDBDBD; + height: 200px; + padding-left: 8px; + padding-top: 4px; + color: white; + } + .mdl-grid:first-of-type .mdl-cell { + height: 50px; + } + """] + ] diff --git a/examples/Demo/Textfields.elm b/examples/Demo/Textfields.elm new file mode 100644 index 0000000..e5634b0 --- /dev/null +++ b/examples/Demo/Textfields.elm @@ -0,0 +1,52 @@ +module Demo.Textfields where + +import Array exposing (Array) +import Html exposing (Html) + +import Material.Textfield as Textfield +import Material.Grid as Grid exposing (..) + + +type alias Model = Array Textfield.Model + + +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 + | 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" + } + ] + |> 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 + + +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]) + |> grid