rl-king / elm-masonry / Masonry

Distribute elements over columns, ordered from left to right while taking element height into account so all columns are about the same length.

Create


type Masonry a

empty : Maybe String -> Masonry a

A Masonry a containing no items.

If you're rendering multiple Masonry a on the same page provide an id to not get the elements mixed up when getting their height.

Masonry.empty Nothing

init : Maybe String -> List a -> ( Masonry a, Platform.Cmd.Cmd Msg )

Create a Masonry a from List a and get each element height.

If you're rendering multiple Masonry a on the same page provide an id to not get the elements mixed up when getting their height.

Masonry.init (Just "search-results") results

append : List a -> Masonry a -> ( Masonry a, Platform.Cmd.Cmd Msg )

Append List a to an existing Masonry a and get each element height.

View


type alias Config a msg =
{ toView : Id -> a -> Html msg
, columns : Basics.Int 
}

Configure how you want your Masonry a to render. Each element gets rendered by toView and columns is the amount of columns.

Each element is wrapped in a div and rendered with the class "elm-masonry-item-height-unknown". Once the height is known the class is updated to "elm-masonry-item-height-known". Because we need the elements to render in order to measure their height you might see some reordering happening live in the browser. Set opacity: 0; of elements with an unknown height class if this is bothersome.

view : Config a msg -> Masonry a -> Html msg

Render Masonry a and distribute elements over columns taking the height of each element into account.

viewList : Config a msg -> List a -> Html msg

Render a List a without all the fancy height calculations.

If you know all elements will be about the same height you don't really need to get each element height and calculate in what order the elements should be displayed.

This function will just distribute all elements over each column ordered from left to right regardless of their height.

Update


type Msg

A message type for the Masonry a to update.

update : Msg -> Masonry a -> Masonry a

Update Masonry a.

Height

Sometimes the element height changes after page initialisation, like when it contains an image for example.

Update the height of an element with getHeight.

type Msg
    = ImageLoaded Masonry.Id

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        ImageLoaded id ->
            ( model
            , Cmd.map MasonryMsg (Masonry.getHeight id)
            )

viewItem : Masonry.Id -> () -> Html msg
viewItem id _ =
    img [ on "load" (Decode.succeed (ImageLoaded id)) ] []


type Id

A unique element Id.

getHeight : Id -> Platform.Cmd.Cmd Msg

Get the height of the element with given Id.