# Elm-Ui-Widgets - A collection of Widgets for Elm-Ui

**URL:** <https://discourse.elm-lang.org/t/elm-ui-widgets-a-collection-of-widgets-for-elm-ui/5343>\
**Category:** Show and Tell\
**Created:** [March 21, 2020, 7:31pm UTC](https://discourse.elm-lang.org/t/elm-ui-widgets-a-collection-of-widgets-for-elm-ui/5343 "2020-03-21T19:31:28Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lucas\_Payr](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/lucas_payr/32/4993_2.png) [@Lucas\_Payr](https://discourse.elm-lang.org/u/Lucas_Payr)\
**Post date:** [March 21, 2020, 7:31pm UTC](https://discourse.elm-lang.org/t/elm-ui-widgets-a-collection-of-widgets-for-elm-ui/5343/1 "2020-03-21T19:31:28Z")

</div>

After about a month of tinkering, I proudly present: [Orasund/elm-ui-widgets](https://package.elm-lang.org/packages/Orasund/elm-ui-widgets/latest/)

Essentially a collection of reusable views (and some components) written in Elm-Ui.

Examples of all widgets can be found [here](https://orasund.github.io/elm-ui-widgets/). For styling, I used my own [Orasund/elm-ui-framework](https://package.elm-lang.org/packages/Orasund/elm-ui-framework/latest/).

## Why create such a package?

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

- There are (nearly) no widgets for Elm-Ui, and that’s a problem because while going from `Element` to `Html` is easy, the opposite is not always possible (as a lot of styling in Elm-Ui would not be adapted to the `Html` element.)
- There is no collection of widgets, all in one place. A lot of components get reimplemented over and over again. It’s hard to keep track of what package is currently the best.

This package tries to solve both of these problems.

## Why does this package also include components?

I wrote a component whenever the wiring of a similar reusable view results in more effort than the boilerplate of the component.

## Where will it go from here?

I really would like to write a native material-design implementation in Elm. But after doing this package as a first step, (Which I already wrote while having the [material.io](http://material.io) docs as reference) I am not quite sure how I can avoid a lot of boilerplating. It seems like a [Master View Type](https://www.freecodecamp.org/news/scaling-elm-views-with-master-view-types/) would be the solution, but I’m not quite sure how I can ensure the customizability when my entire page can be described as a single type. (I don’t want to know how many parameters such a type would need).

---

<div class="post-metadata">

**Author:** ![DullBananas](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/dullbananas/32/3709_2.png) [@DullBananas](https://discourse.elm-lang.org/u/DullBananas)\
**Post date:** [March 22, 2020, 4:51am UTC](https://discourse.elm-lang.org/t/elm-ui-widgets-a-collection-of-widgets-for-elm-ui/5343/2 "2020-03-22T04:51:07Z")

</div>

I might try this when I continue working on the user interface for [my project](https://github.com/dullbananas/editsc).

---

<div class="post-metadata">

**Author:** ![aforemny](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/aforemny/32/2557_2.png) [@aforemny](https://discourse.elm-lang.org/u/aforemny)\
**Post date:** [March 24, 2020, 7:57pm UTC](https://discourse.elm-lang.org/t/elm-ui-widgets-a-collection-of-widgets-for-elm-ui/5343/3 "2020-03-24T19:57:16Z")

</div>

Hi Lucas,

thank you for sharing this! I am happy to see a library that offers a collection of widgets and one that targets elm-ui in one package.

I am especially curious about avoiding boilerplate in a package like this, and I am wondering if I can share an experience of mine with you regarding that. I am not immediately seeing a relation to the master view type pattern, so I might be misunderstanding you. I will share it anyways:

In elm-mdc, also a native(-ish) material design implementation in Elm, albeit with different goals from what you describe, we introduced a “widget store” that is basically the sum of `Dict String widget`s for any `widget` type. The individual widgets would then index into that store by `String` identifiers. I have found that to be a good technique to minimize the boilerplate per widget that one might otherwise need.

In case that is something that interests you, and my explanation is a bit sparse (most likely), please let me know and I can elaborate!

---

<div class="post-metadata">

**Author:** ![Lucas\_Payr](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/lucas_payr/32/4993_2.png) [@Lucas\_Payr](https://discourse.elm-lang.org/u/Lucas_Payr)\
**Post date:** [March 24, 2020, 8:40pm UTC](https://discourse.elm-lang.org/t/elm-ui-widgets-a-collection-of-widgets-for-elm-ui/5343/4 "2020-03-24T20:40:12Z")

</div>

The idea behind a Master View type (I hate that name, but can’t think of a better one),  
would be to have a type that represents your entire page. You wouldn’t have any boilerplate any more, because the package would do everything for you. But the problem here is that it hard to customize.

Here is how my current implementation of such a Type would look like:

```auto
type Widget msg
    = TextButtonWidget (TextButton msg)
    | IconButtonWidget (IconButton msg)
    | ToggleButtonWidget (ToggleButton msg)
    | FAButtonWidget (FAButton msg)
    | SpeedDialWidget (FAButton msg)
    | CardWidget (Card msg)

type TextButton msg
    = TextButton
        { emphasis : ButtonEmphasis
        , label : String
        , enabled : Bool
        , onClick : msg
        , icon : Maybe (Svg Never)
        }

type ButtonEmphasis
    = Low
    | Default
    | High

type IconButton msg
    = IconButton
        { enabled : Bool
        , onClick : msg
        , icon : Svg Never
        }

type ToggleButton msg
    = ToggleButton
        { options :
            List
                ( String
                , { enabled : Bool
                  , onClick : String -> msg
                  , icon : Svg Never
                  }
                )
        , selected : Maybe String
        }

{- ... -}

```

and then I would write a function like

```auto
{ init : model
, widgets : model -> Widget msg
, update : msg -> model -> model
}
-> Program () model msg

```

that takes care of the boilerplate for me.

I could even use extendable records to ensure that widgets with less required wiring could be applied to a `Widget msg -> Html msg` function. (Check out [Richard Feldman’s talk about Elm-css](https://www.youtube.com/watch?v=n5faeSW71ko), if your curious why I’m talking about extendable records)

The problem here is that if I want to make anything customizable, I need to put those options either in a `Config` type or in the `Widget` type. So I’m still not sure if this is actually a usefull idea.

* * *

I also thought about your approach: Having a widget store that sort of mimics the mutable behaviour of components. Then the user would set up the store once and “register” new widgets to it. The problem here is that I feel like it might be a bad idea to trust the programmer that they ensure each id is actually unique.

* * *

So in conclusion, yeah maybe I need help, maybe not. I don’t know. I’ve not yet decided if I actually want to work on this. But I’m guessing that if I want to go the full mile and return a complete `progamm`, then internally I will properly use a widget store like you described.

---

<div class="post-metadata">

**Author:** ![aforemny](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/aforemny/32/2557_2.png) [@aforemny](https://discourse.elm-lang.org/u/aforemny)\
**Post date:** [March 25, 2020, 7:25am UTC](https://discourse.elm-lang.org/t/elm-ui-widgets-a-collection-of-widgets-for-elm-ui/5343/5 "2020-03-25T07:25:20Z")

</div>

Hi Lucas,

thank you very much for elaborating! I do understand what you’ve meant better now.

I would be very curious how that would turn out! So if you do attempt that approach, be sure to post its outcome again here!

Regarding the “widget store”, I want to make two clarifications that were not identifiable from my original description. You are right in saying that a “widget store” requires wiring (say, `init, subscriptions, update`) and that then widgets are free with respect to boilerplate. I have not found naming widgets an issue for two reasons:

- establishing a hierarchical naming schema eliminates a big class of potential collisions, ie. “save button on page a” and “save button on page b”
- you may have as many "widget store"s as you like and identifiers have only to be unique within that store, ie. one widget store per page

Keep us posted as you progress! 🙂

---

<div class="post-metadata">

**Author:** ![ceddlyburge](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/ceddlyburge/32/2316_2.png) [@ceddlyburge](https://discourse.elm-lang.org/u/ceddlyburge)\
**Post date:** [March 26, 2020, 10:40am UTC](https://discourse.elm-lang.org/t/elm-ui-widgets-a-collection-of-widgets-for-elm-ui/5343/6 "2020-03-26T10:40:49Z")

</div>

This is a great idea! I use elm-ui,and am rubbish at ui design, so I have been looking for something simple to do the hard work …

---

<div class="post-metadata">

**Author:** ![ceddlyburge](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/ceddlyburge/32/2316_2.png) [@ceddlyburge](https://discourse.elm-lang.org/u/ceddlyburge)\
**Post date:** [March 30, 2020, 4:59pm UTC](https://discourse.elm-lang.org/t/elm-ui-widgets-a-collection-of-widgets-for-elm-ui/5343/7 "2020-03-30T16:59:20Z")

</div>

Hi There. I have had a think about the boilerplate, and taken a look at the repo, and the elm-mdc repo.

I think it would be difficult / impossible / a bad idea to create a customisable master view type to cover every use case.

It seems that reducing the boiler plate, and making it as easy to integrate as possible is probably the way forward.

Following on from that, you could provide some master view types for specific use cases.

This seems to be similar ish to the way that bootstrap and other things work. Usually if you want a totally custom thing tailored to your use case, than you can do everything yourself,and its not too difficult. However, if you have a simple use case, and just want to get something up and running quickly, then you can start from an opinionated template (a bit like [the bootstrap examples](https://getbootstrap.com/docs/4.4/examples/)).

Cheers, Cedd

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [April 9, 2020, 4:59pm UTC](https://discourse.elm-lang.org/t/elm-ui-widgets-a-collection-of-widgets-for-elm-ui/5343/8 "2020-04-09T16:59:27Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
