https://github.com/jerbaroo/threepenny-gui-flexbox
Flexbox layouts for Threepenny-gui
https://github.com/jerbaroo/threepenny-gui-flexbox
css flexbox haskell layout threepenny-gui
Last synced: 6 months ago
JSON representation
Flexbox layouts for Threepenny-gui
- Host: GitHub
- URL: https://github.com/jerbaroo/threepenny-gui-flexbox
- Owner: jerbaroo
- License: bsd-3-clause
- Created: 2017-03-01T16:28:14.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2021-02-22T19:14:05.000Z (over 5 years ago)
- Last Synced: 2025-06-12T08:17:03.788Z (about 1 year ago)
- Topics: css, flexbox, haskell, layout, threepenny-gui
- Language: Haskell
- Homepage:
- Size: 39.1 KB
- Stars: 2
- Watchers: 1
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Threepenny-gui Flexbox
[](https://circleci.com/gh/barischj/threepenny-gui-flexbox) [](http://hackage.haskell.org/package/threepenny-gui-flexbox) [](http://stackage.org/nightly/package/threepenny-gui-flexbox) [](http://stackage.org/lts/package/threepenny-gui-flexbox)
Flexbox layouts for Threepenny-gui.
This library was written following the
wonderful
[A Complete Guide to Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox) and
using the equally wonderful [Clay](https://hackage.haskell.org/package/clay)
library as a CSS domain specific language.

# Usage
## Properties
Ultimately we just want to set Flexbox properties on elements, both parent and
child elements. In CSS these properties would look like `flex-grow: 1;`.
We collect Flexbox properties that apply to the parent element, things like
`flex-direction`, in a `ParentProps` data type. Flexbox properties that apply to
child elements, things like `flex-grow`, are collected in a `ChildProps` data
type.
If you want `ChildProps` with `flex-grow: 1;` you can just do:
``` Haskell
flexGrow 1
```
You can define multiple properties using `(<>)`:
``` Haskell
order 1 <> flexGrow 1 <> flexShrink 2
```
Some properties like `flexGrow` simply take an `Int` but others take a value
from the `Clay` library. Here's an example for `ParentProps`:
``` Haskell
display Clay.Display.inlineFlex <> flexWrap Clay.Flexbox.nowrap
```
If you just want `ParentProps` or `ChildProps` with default values:
``` Haskell
parentProps :: ParentProps
childProps :: ChildProps
```
## Setting Properties
Once you have your properties defined you'll want to apply them to elements. For
this you can use `setFlex` which can be used with Threepenny's reverse function
application operator `#`:
``` Haskell
UI.div # set UI.text "foo" # setFlex (flexGrow 1)
```
Note that `setFlex` will set any properties you don't specify explictly to the
default values from `parentProps` or `childProps`. If that is undesirable (for
instance, in case you have already used `setFlex` elsewhere to set several
properties and only want to change a few of them), you can instead use
`modifyFlex`, which leaves unspecified properties unchanged:
``` Haskell
myRow = UI.div # setFlex (
flexDirection Clay.Flexbox.row
<> flexWrap Clay.Flexbox.wrap
<> justifyContent Clay.Flexbox.spaceBetween
<> alignItems Clay.Common.baseline
)
-- Elsewhere:
myRow # modifyFlex (alignItems Clay.Common.center)
```
You can also convert `ParentProps` or `ChildProps` to a `[(String, String)]`
which
is
[how Threepenny expects CSS](http://hackage.haskell.org/package/threepenny-gui/docs/src/Graphics-UI-Threepenny-Core.html#style).
This can be done using `toStyle`:
``` Haskell
UI.div # set UI.style (toStyle $ order 1)
```
### 'flex'
We provide a utility function `flex` (and a few variants thereof) which takes
both parent and child elements and their respective `ParentProps` and
`ChildProps`, applies the properties through `setFlex` to the respective
elements and then returns the parent element with children attached.
Here is a full example, which produces the above image of three orange text
boxes in ratio 1:2:1. First done without `flex_p` and then with `flex_p`.
`flex_p` is a variant of `flex` which applies default Flexbox properties to the
parent element.
``` Haskell
-- |Example without 'flex_p'.
example :: Window -> UI ()
example w = void $
getBody w # setFlex parentProps #+ [
foo # setFlex (flexGrow 1)
, foo # setFlex (flexGrow 2)
, foo # setFlex (flexGrow 1)
]
-- |Example with 'flex_p'.
example' :: Window -> UI ()
example' w = void $
flex_p (getBody w) [
(foo, flexGrow 1)
, (foo, flexGrow 2)
, (foo, flexGrow 1)
]
-- | Simple coloured 'div'.
foo = UI.div # set UI.text "foo"
# set UI.style [("background-color", "#F89406"),
("margin", "8px")]
```