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.