module Material ( Model, model , Action, update ) where {-| Material Design component library for Elm based on Google's [Material Design Lite](https://www.getmdl.io/). Click [here](https://debois.github.io/elm-mdl/) for a live demo. # Component model The component model of the library is simply the Elm Architecture, e.g., each component has Model, Action, view, and update. A minimal example using this library in plain Elm Architecture can be found [here](https://github.com/debois/elm-mdl/blob/master/examples/Component-EA.elm). Nesting large amounts of components in the Elm Architecture is somewhat unwieldy because of the large amount of boilerplate one has to write. This library includes "component support", for getting rid of most of that boilerplate. A minimal example using component support is [here](http://github.com/debois/elm-mdl/blob/master/examples/Component.elm). It is important to note that component support lives __within__ the Elm architecture; it is not an alternative architecture. # Getting started The easiest way to get started is to start with one of the minimal examples above. We recommend going with the library's component support rather than working directly in plain Elm Architecture. # This module This module contains only convenience functions for working with nested components in the Elm architecture. A minimal example using this library with component support can be found [here](http://github.com/debois/elm-mdl/blob/master/examples/Component.elm). We encourage you to use the library in this fashion. All examples in this subsection is from the [above minimal example](http://github.com/debois/elm-mdl/blob/master/examples/Component.elm) Here is how you use component support in general. First, boilerplate. 1. Include `Material`: `import Material` 2. Add a model container Material components to your model: type alias Model = { ... , mdl : Material.Model } model : Model = { ... , mdl = Material.model } 3. Add an action for Material components. type Action = ... | MDL (Material.Action Action) 4. Handle that action in your update function as follows: update action model = case action of ... MDL action' -> let (mdl', fx) = Material.update MDL action' model.mdl in ( { model | mdl = mdl' } , fx ) Next, make the component instances you need. Do this in the View section of your source file. Let's say you need a textfield for name entry, and you'd like to be notifed whenever the field changes value through your own NameChanged action: import Material.Textfield as Textfield ... type Action = ... | NameChanged String ... update action model = case action of ... NameChanged name -> -- Do whatever you need to do. ... nameInput : Textfield.Instance Material.Model Action nameInput = Textfield.instance 2 MDL Textfield.model [ Textfield.fwdInput NameChanged ] view addr model = ... nameInput.view addr model.mdl The win relative to using plain Elm Architecture is that adding a component neither requires you to update your model, your Actions, nor your update function. (As in the above example, you will frequently have to update the latter two anyway, but now it's not boilerplate, its "business logic".) ## Optimising for size Using this module will force all elm-mdl components to be built and included in your application. If this is unacceptable, you can custom-build a version of this module that uses only the components you need. To do so, you need to re-implement the present module, modifying the values `model` and `Model`. The module source can be found [here](https://github.com/debois/elm-mdl/blob/master/src/Material.elm). You do not need to re-build the entire elm-mdl library; simply copy the source of this module, give it a new name, modify as itMatendicated above, then use your modified module rather than this one. @docs Model, model, Action, update -} import Dict 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 a = { button : Indexed Button.Model , textfield : Indexed Textfield.Model , snackbar : Indexed (Snackbar.Model a) } {-| Initial 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) action {-| Update function for the above Action. -} update : (Action action -> action) -> Action action -> Model action -> (Model action, Effects action) update = Component.update