Orasund / elm-ui-widgets

Collection of reusable views for elm-ui.
https://orasund.github.io/elm-ui-widgets/
BSD 3-Clause "New" or "Revised" License
85 stars 11 forks source link

Elm-Ui-Widgets

This package contains independent widgets (no components) written for Elm-Ui. These widgets have no dependencies to other parts of this package. So you can just use as much as you need.

Feel free to start an issue on the repository if you have any questions.

Example using the Material Design style

Table of Contents

Example

Each widget comes with a Widget Type and a Style Type.

As example, consider the button widget.

Style Type

button: ButtonStyle msg
    ->
        { text : String
        , icon : Icon
        , onPress : Maybe msg
        }
    -> Element msg

In comparison to Elm-Ui's button, we see that List (Attribute msg) has changed into a Style Type. If we look into the Style type, we see that it mirrors the implementation.

  type alias ButtonStyle msg =
      { elementButton : List (Attribute msg)
      , ifDisabled : List (Attribute msg)
      , ifActive : List (Attribute msg)
      , otherwise : List (Attribute msg)
      , content : 
            { elementRow : List (Attribute msg)
            , content :
                { text : { contentText : List (Attribute msg) }
                , icon : IconStyle
                }
            }
        }
      }

So the resulting Elm-Ui code looks like this:

 button style { onPress, text, icon } =
    Input.button
        (style.elementButton
            ++ (if onPress == Nothing then
                    style.ifDisabled

                else
                    style.otherwise
                )
        )
        { onPress = onPress
        , label =
            Element.row style.content.elementRow
                [ icon
                    (if onPress == Nothing then
                        style.content.content.icon.ifDisabled

                        else
                        style.content.content.icon.otherwise
                    )
                , Element.text text |> Element.el style.content.content.text.contentText
                ]
        }

Styles

For actually displaying the button we have a few different implementations:

containedButton : Palette -> ButtonStyle msg
containedButton =
    Button.containedButton

outlinedButton : Palette -> ButtonStyle msg
outlinedButton =
    Button.outlinedButton

textButton : Palette -> ButtonStyle msg
textButton =
    Button.textButton

Widget Type

We also have a Widget Type for the button:

type alias Button msg =
    { text : String
    , icon : Icon
    , onPress : Maybe msg
    }

We can use it to build more complex widgets, for example a select button:

type alias Select msg =
    { selected : Maybe Int
    , options :
        List
            { text : String
            , icon : Icon
            }
    , onSelect : Int -> Maybe msg
    }

select :
    Select msg
    -> List ( Bool, Button msg )

selectButton :
    ButtonStyle msg
    -> ( Bool, Button msg )
    -> Element msg

Checkout the examples in Widget for more details.

Reusable Views vs. Components

In Elm we like to use reusable views instead of components. At first this packages had a few components, but they where more complicated in comparison. They got slowly turned into reusable views one by one. Most have been reduced even further into view functions: Reusable views without a model. All function in Widget are view functions.

Alternatives

For comparison, here are some alternative packages for creating UIs:

Motivation

After looking at the current packages that implement various reusable views (and components) I noticed two things:

This package tries to solve both of these problems.

Changelog