Orasund / elm-ui-widgets / Widget.Customize

Each and every widget can be customized by modifying the Style Type.

{- Make a button fill the full width -}
Widget.textButton
  ( Material.containedButton
    |> Customize.element [Element.width Element.fill]
  )
  { onPress = Just PressedButton
  , text = "Press Button"
  }

Element

A simple style type would be the following:

type alias MyStyle =
    { element : List (Attribute msg) }

myWidget : MyStyle -> Element msg
myWidget style =
    Element.el style.element <| Element.none

element : List b -> { a | element : List b } -> { a | element : List b }

elementButton : List b -> { a | elementButton : List b } -> { a | elementButton : List b }

mapElementButton : (b -> b) -> { a | elementButton : b } -> { a | elementButton : b }

elementColumn : List b -> { a | elementColumn : List b } -> { a | elementColumn : List b }

mapElementColumn : (b -> b) -> { a | elementColumn : b } -> { a | elementColumn : b }

elementRow : List b -> { a | elementRow : List b } -> { a | elementRow : List b }

mapElementRow : (b -> b) -> { a | elementRow : b } -> { a | elementRow : b }

elementTable : List b -> { a | elementTable : List b } -> { a | elementTable : List b }

mapElementTable : (b -> b) -> { a | elementTable : b } -> { a | elementTable : b }

elementPasswordInput : List b -> { a | elementPasswordInput : List b } -> { a | elementPasswordInput : List b }

mapElementPasswordInput : (b -> b) -> { a | elementPasswordInput : b } -> { a | elementPasswordInput : b }

elementTextInput : List b -> { a | elementTextInput : List b } -> { a | elementTextInput : List b }

mapElementTextInput : (b -> b) -> { a | elementTextInput : b } -> { a | elementTextInput : b }

Content

We can also style the content of an element.

type alias MyStyle =
    { element : List (Attribute msg)
    , content : List (Attribute msg)
    }

myWidget : MyStyle -> Element msg
myWidget style =
    Element.el style.element <|
        Element.el style.content <|
            Element.none

content : List b -> { a | content : List b } -> { a | content : List b }

contentText : List b -> { a | contentText : List b } -> { a | contentText : List b }

contentInFront : List b -> { a | contentInFront : List b } -> { a | contentInFront : List b }

mapContentInFront : (b -> b) -> { a | contentInFront : b } -> { a | contentInFront : b }

Conditional Styling

We can include styling that depends on some state.

type alias MyStyle =
    { element : List (Attribute msg)
    , ifDisabled : List (Attribute msg)
    , otherwise : List (Attribute msg)
    }

myWidget : MyStyle -> Bool -> Element msg
myWidget style isDisabled =
    Element.el
        (style.element
            ++ (if isDisabled then
                    style.ifDisabled

                else
                    style.otherwise
               )
        )
    <|
        Element.none

otherwise : List b -> { a | otherwise : List b } -> { a | otherwise : List b }

mapOtherwise : (b -> b) -> { a | otherwise : b } -> { a | otherwise : b }

ifActive : List b -> { a | ifActive : List b } -> { a | ifActive : List b }

mapIfActive : (b -> b) -> { a | ifActive : b } -> { a | ifActive : b }

ifDisabled : List b -> { a | ifDisabled : List b } -> { a | ifDisabled : List b }

mapIfDisabled : (b -> b) -> { a | ifDisabled : b } -> { a | ifDisabled : b }

ifFirst : List b -> { a | ifFirst : List b } -> { a | ifFirst : List b }

mapIfFirst : (b -> b) -> { a | ifFirst : b } -> { a | ifFirst : b }

ifLast : List b -> { a | ifLast : List b } -> { a | ifLast : List b }

mapIfLast : (b -> b) -> { a | ifLast : b } -> { a | ifLast : b }