Proposal for a Style Framework in Elm

Lucamug
3 min readMay 9, 2018

--

Demos | Code

I have been working on a possible API for a Style Framework in Elm built on top of style-elements.

I based it on these concepts

  • Familiarity
  • Simplicity
  • Robustness
  • Customizability

Familiarity

Developers used to popular frameworks such as Bootstrap, Bulma, Foundation, etc.

Let’s see how to write a button in

<button class=”btn btn-primary btn-lg”>Button</button>
<button class=”button is-primary is-large”>Button</button>
<button class=”button primary large”>Button</button>
<button class=”pure-button pure-button-primary button-large”>Button</button>

Everybody seems liking modifiers. Modifiers are extra classes to attach to an element to modify the aspect of that element.

So I thought to have this parallelism:

<button class=”btn btn-primary btn-lg”>Button</button>

in Elm would be equal to

button [ Primary Large ] ( Just DoSomething ) “Button”

Where Just DoSomething (or Nothing) is the message that Elm send out when the button is pressed.

Pretty simple!

There is also a default configuration:

button [] Nothing “Button”

I don’t think it can be any shorter than this.

The type signature is

button : List Modifier -> Maybe msg -> String -> Element msg

Under the hood this is using Element.Input.button element.

In case the message isNothing the button will be disabled.

Exceptions

  • What is we want to have something more complicated that just text for the button?
  • What if we want to apply the button style to links or other elements?
  • What if we want to add extra attributes?

We can use just the attribute parts of the button above. We generate the attributes using

buttonAttr : List Modifier -> List (Attribute msg)

So, this means that

button [] Nothing “Button”

Can be written as

Element.Input.button (buttonAttr []) 
{ onPress = Nothing
, label = text “Button”
}

Image button

This give us the freedom to replace the text with images for example

Element.Input.button (buttonAttr []) 
{ onPress = Nothing
, label = image []
{ src = "image.jpg"
, description = "Image"
}

}

Link button

Or to apply the button look-and-feel to a link, for example:

Element.link (buttonAttr [])
{ url = "http://example.com"
, label = text "Example"
}

Custom button

Or to add extra attributes

Input.button (Element.Border.width 10 :: buttonAttr []) <|
{ onPress = Nothing, label = text “Button” }

Custom constructors

We could create custom constructors for special cases too. For example

Element.link (buttonAttr [])
{ url = "http://example.com"
, label = text "Example"
}
-- equal tobuttonLink [] "http://example.com" "Example"

and

Element.Input.button (buttonAttr []) <|
{ onPress = Nothing
, label = image []
{ src = "image.jpg"
, description = "Button"
}
}
-- equal tobuttonImage [] Nothing "Button" "image.jpg"

But these seems very specific and probably no need to add them in a framework.

This is all for now. I will talk about Simplicity, Robustness and Customizability in following article.

In the meantime have a look at the demos, at the source code, use it and contribute to it if you like.

--

--

Responses (2)