Nice way to wrap content around other content

114 views
Skip to first unread message

Joseph Collard

unread,
Oct 8, 2013, 9:34:26 AM10/8/13
to elm-d...@googlegroups.com
I was curious if anyone knew of a nice way to wrap content? 


This is done using a: flow left [menu, padding, content]

It would be nice if the text would start to go all the way to the left once it gets to the bottom of the menu. I have achieved this in the past using CSS by giving a div the property {float: left} or {float: right}. Does anyone know a nice way to do this with Elm?

It would be nice if there were something like: flow left [float-left menu, padding, content]

Thanks in advance!

Evan Czaplicki

unread,
Oct 8, 2013, 3:05:18 PM10/8/13
to elm-d...@googlegroups.com
There is not a way to do this at the moment. I tend to get the size of thing roughly right and do the layout manually, which is not ideal. I can think of two nice ways to do this:
  1. Have a special container function that also takes a bunch of text. Not really sure what the API would look like from there.
  2. Have a way to link a bunch of Elements to say show as much as they can, and then pass the rest along to the next box.
I think things like Adobe products are probably the best place to look for nice ways to do this, rather than the HTML way.

Does anyone have other ideas or want to flesh out the two above?


--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Jeff Smits

unread,
Oct 9, 2013, 3:48:12 AM10/9/13
to elm-discuss
I tried to come up with some different models for this but I can't think of anything except the flow model from CSS and fitting text into arbitrary closed forms.
I don't like your first solution very much. Solution 2 has potential though, because you can also do columns with that mechanism.

Evan Czaplicki

unread,
Oct 9, 2013, 7:43:10 PM10/9/13
to elm-d...@googlegroups.com
Yeah, I would really love to make columns easy :) I tend to like using them to get additional screen density, and it'd be a cool way to visually distinguish Elm applications. I know there is some adobe product that does this!

Maybe something like:

textBoxes : Int -> Text -> [Element]

Where the first argument is how many boxes you want and the second is the full text you'd like to display. So to make a two column display, you'd say:

columns = textBoxes 2 myWords
main = flow right <| map (size (300,700)) columns

Joseph's case would be more like this:

[top, body] = textBoxes 2 myWords

main = flow down
         [ size (100,400) navigation `beside` size (500,400) top
         , width 600 body ]

I suspect this is not purely functional though :/ If the first element is used twice with different sizes, it's unclear how things should flow in the second element.

Evan Czaplicki

unread,
Oct 9, 2013, 7:53:41 PM10/9/13
to elm-d...@googlegroups.com, Antony Courtney
Oh, how about this?! A possible use of Automatons! In this model you can ask for as many Elements as you want, each with specific dimensions.

chunk : Text -> Automaton (Int,Int) Element

columns = chunk myWords

main = let (chunk', left ) = step (300,700) chunk
           (_     , right) = step (300,700) chunk'
       in  flow right [ left, right ]

This API also has weaknesses though, like how do you ask for "the rest"? I should see if session types are appropriate to improve this... Short of that, maybe something like this would work:

data Chunk = Block (Int,Int) | Rest
chunk : Text -> Automaton Chunk Element

Evan Czaplicki

unread,
Oct 9, 2013, 8:04:02 PM10/9/13
to elm-d...@googlegroups.com, Jeff Smits, Alex Neslusan, gideon....@gmail.com
+Jeff, Alex, Gideon

Please remove people I just added in the next reply. I just remembered talking to these guys about Automaton recently and wanted to draw their attention to this thread :)

Alex Neslusan

unread,
Oct 9, 2013, 10:23:48 PM10/9/13
to elm-d...@googlegroups.com, Antony Courtney
Would the idea of this be for each step to take as much text as it can, leaving the rest of the text for successive steps?

Alex Neslusan

unread,
Oct 10, 2013, 4:37:51 AM10/10/13
to elm-d...@googlegroups.com, Antony Courtney
What about something like this? I don't really know how to do it with Text instead of String. http://share-elm.com/sprout/525666ebe4b0d6a98b153186

fit str rest (w, h) =
    let words = split " " str
        len = length words
        e = width w <| plainText str
    in  if (heightOf e > h)
            then fit (join " " (take (len - 1) words)) (last words ++ " " ++ rest) (w, h)
            else (e, rest)

Alex Neslusan

unread,
Oct 10, 2013, 5:08:34 AM10/10/13
to elm-d...@googlegroups.com, Antony Courtney
I adapted the idea from my previous reply into an Automaton with roughly the same interface as Evan's idea, using hiddenState:
http://share-elm.com/sprout/52566e38e4b0d6a98b1531b8

Gideon Smeding

unread,
Oct 10, 2013, 7:03:03 AM10/10/13
to elm-d...@googlegroups.com, Antony Courtney
It's definitely an interesting proposal, although the direct calls to step aren't very elegant the approach with automata has some promise.

Sorry I can't contribute more. At the moment I have very little time unfortunately and, worse, no regular access to internet because I've just moved.

cheers!
-gideon

Alex Neslusan

unread,
Oct 10, 2013, 8:51:43 AM10/10/13
to elm-d...@googlegroups.com, Antony Courtney
You could use this basic idea to do wrapping text around arbitrary elements like the original post of this thread was asking for:
http://share-elm.com/sprout/5256a22ae4b0d6a98b1531fb

It's a pretty hacky proof of concept, but once we get markdown interpolation I could see a refined version of this working decently well.

Oh and by the way, you have to select the master/HEAD version to get the share-elm links to work.

Evan Czaplicki

unread,
Oct 10, 2013, 1:16:03 PM10/10/13
to elm-d...@googlegroups.com, Antony Courtney
That's awesome Alex :D I sort of agree that using step directly is not the prettiest. That leads to two things: (1) maybe the Automaton library should have a "run" function for lists and (2) we can do a higher level API on top of this.

You can do safe blocks as follows:

data Blocks = Block (Int,Int) Blocks | Rest
chunk : Blocks -> Text -> [Element]

This ensures that every sequence of blocks is sure to get all the text. You can even do some syntax tricks to make this nicer:

(>>) = Block
blocks = (100,200) >> (300,200) >> Rest
main = flow right (chunk blocks myText)

That's all a bit weird though because the Blocks ADT is basically a list where cons is Block and nil is Rest. So the API could just be

chunk : [(Int,Int)] -> Text -> [Element]

chunk [] myText == [<all the text>]
chunk [(100,100)] myText == [<small block>, <everything else>]

I'm not sure if it is necessary to have the automaton library be public facing. Can you think of use cases that are not covered by the idea presented here? Maybe you want to do some complex layout that depends on what has happened so far?

I think the big thing is to figure out how to make Text expressive enough to make this nice. Like some way to unify markdown blocks and Text or something. Let's start a thread about this when someone has the first insight :)
Reply all
Reply to author
Forward
0 new messages