Home > Software engineering >  elm-ui center elements in wrapped row
elm-ui center elements in wrapped row

Time:01-16

I'm using Elm with mdgriffiths/elm-ui, and I've really been enjoying it. Right now, I'm trying to create a centered, wrapped row of elements:

enter image description here

I can get it to this point:

enter image description here

using this code:

button : String -> String -> Element Msg
button label url =
    link
        [ height (px 150)
        , width (px 150)
        , Border.width 1
        , Background.color (rgb255 255 255 255)
        ]
        { url = url
        , label =
            Element.paragraph
                [ Font.center ]
                [ textEl [] label ]
        }


row : Element Msg
row =
    Element.wrappedRow
        [ Element.spacing 25
        , Element.centerX
        , Element.centerY
        , width (fill |> Element.maximum 600)
        , Font.center
        ]
        [ button "A" "/a"
        , button "B" "/b"
        , button "C" "/c"
        , button "D" "/d"
        ]

But when I try adding Element.centerX to my buttons like this

link
    [ Element.centerX
    , ...
    ]

I get this instead:

enter image description here

I've also tried Font.center without success, and I don't know what else I can try.

I'm not sure if I'm missing something I should be using, or if the whole thing needs re-arranging, or if I just need to use the built-in CSS stuff.

Update:

Link to an Ellie with the issues I'm seeing.

https://ellie-app.com/7NpM6SPfhLHa1

CodePudding user response:

This Github issue is useful for this problem. I'm afraid you will have to use some CSS (unless I'm missing something). I've found this before with elm-ui; every now and then it can't quite do what you want and you need a bit of CSS.

This works for me (taken from the post by AlienKevin in the link above). You need to set "marginLeft" and "marginRight" to "auto".

module Main exposing (main)

import Element as E
import Element.Border
import Html.Attributes


box : String -> E.Element msg
box label =
    E.paragraph
        [ E.width <| E.px 200
        , Element.Border.width 1
        , E.htmlAttribute (Html.Attributes.style "marginLeft" "auto")
        , E.htmlAttribute (Html.Attributes.style "marginRight" "auto")
        ]
        [ E.text label ]


row : E.Element msg
row =
    E.wrappedRow []
        [ box "A"
        , box "B"
        , box "C"
        ]


main =
    E.layout [] row

(See here for an Ellie.)

CodePudding user response:

You can also do the following:

  1. Define the following elm-ui classes. I usually setup a UI.elm module for this
centerWrap : Attribute msg
centerWrap =
    Html.Attributes.class "centerWrap"
        |> htmlAttribute


dontCenterWrap : Attribute msg
dontCenterWrap =
    Html.Attributes.class "dontCenterWrap"
        |> htmlAttribute
  1. Add the following to your css. Basically says center elements if has centerWrap class but not dontCenterWrap class.
:not(.dontCenterWrap).centerWrap>div.wrp {
    justify-content: center !important;
}
  1. Apply the attribute
    wrappedRow [ width fill, UI.centerWrap, spaceEvenly ] [...]
  1. Assuming you created a custom element that centerWraps and wanted to disable that you could use UI.dontCenterWrap
centerWrappedRow attr children =
    wrappedRow (UI.centerWrap :: attr) children

-- somewhere else
...
    centerWrappedRow [UI.dontCenterWrap] [..]
...
  • Related