Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a function similar to ZStack in SwiftUI #342

Open
dullbananas opened this issue Apr 17, 2022 · 3 comments
Open

Add a function similar to ZStack in SwiftUI #342

dullbananas opened this issue Apr 17, 2022 · 3 comments
Labels
has-ellie This is a bug and has an ellie which demonstrates it.

Comments

@dullbananas
Copy link

It would be like row or column except it puts each element on top of the previous one

@NduatiK
Copy link

NduatiK commented Apr 25, 2022

Assuming you want a solution and don't care if its the library that does it.

You can pull this off using the inFront attribute. Ellie

zStack attrs children =
    case children of
        [] ->
            none
        bottomMost :: otherChildren ->
            el 
                (inFront (zStack attr otherChildren) :: attr)        
                bottomMost 

then

module Main exposing (..)

import Element exposing (Element, alignRight, centerY, el, fill, fillPortion, height, padding, px, rgb, rgb255, rgba, row, spacing, text, width)
import Element.Background as Background
import Element.Border as Border
import Element.Font as Font
import Element.Input as Input


type Msg
    = Noop Float


main =
    Element.layout [] content


content =
    zStack [width fill]
    [ text "Bottom"
    , el [Element.moveDown 10] ( text "Middle" )
    , el [Element.moveDown 20] (text "Top")
    ] 

zStack attrs children =
    case children of
        [] ->
            Element.none
        bottomMost :: otherChildren ->
            el 
                (Element.inFront (zStack attrs otherChildren) :: attrs)        
                bottomMost 

@github-actions github-actions bot added the has-ellie This is a bug and has an ellie which demonstrates it. label Apr 25, 2022
@coinop-logan
Copy link

coinop-logan commented Aug 2, 2024

@NduatiK's suggested approach is pretty good. But I want to add a bit of weight to the desire for more formal application of this principle. I should say I'm arguing solely from the perspective of ergonomics, and have no idea how complex this would be to actually implement...

For me, the simplicity and elegance of rows and columns, combined with the way Element.Lengths work, is where a lot of where elm-ui's pleasure comes from. It would be so nice if you could do this in the z direction. If this was implemented, each element would essentially be 3D by default, but this would be hidden until you started making zStacks. Using inFront successively lets you stack elements nicely, but you can't use Lengths in the z direction.

Now, is this really necessary to strive for? I can't say I've ever needed an Element to "fill" the whole z direction (or what that would mean exactly). And a "pixel" length doesn't make much sense - the analog would be a thin layer, I guess? So I can't say this looks like it would be simple to do.

BUT. If I could just as thoughtlessly extend elements in the z direction as I do in X and Y with rows and columns, that'd be so nice. As it is, every time I need to layer stuff in elm-ui, I stumble a bit and have to go to some old project, or search around a bit, to figure out how exactly to set it up.

I also wonder if formalizing this behavior in this way might clear up some of the other issues around inFront, in a sort of side effect..? Especially those around intuitions of borders, like #201?

Just my 2 cents!

@coinop-logan
Copy link

Another issue with the inFront workaround btw, is that every element inFront of some other Element is "outside" the scheme of sizes that makes elm-ui such a lovely thing to work with. For example, if a small Element has a much larger Element inFront of it, then the page layout will still treat the combined element as small, leading to things like (in my case) an Element that is long enough to give the page a scrollbar, without the main page Element extending that far, thus leading to the user scrolling down and seeing my background end before the end of the page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has-ellie This is a bug and has an ellie which demonstrates it.
Projects
None yet
Development

No branches or pull requests

3 participants