JuliaPluto / PlutoUI.jl

https://featured.plutojl.org/basic/plutoui.jl
The Unlicense
299 stars 54 forks source link

combine order: bug? #259

Open aplavin opened 1 year ago

aplavin commented 1 year ago

combine returns values in the order of how widgets are displayed, while following the definition order would probably be more sensible:

@bind tmp PlutoUI.combine() do Child
    w1 = Child(Slider(0:10))
    w2 = Child(Scrubbable(5))
    @htl("$w1 $w2")
end

# tmp == (0, 5): slider is first, scrubbable is second
@bind tmp PlutoUI.combine() do Child
    w1 = Child(Slider(0:10))
    w2 = Child(Scrubbable(5))
    @htl("$w2 $w1")  # only changed order here
end

# tmp == (5, 0): scrubbable is first, slider is second
# I didn't expect that order changes
fonsp commented 1 year ago

dThanks for the feedback! The design is on purpose, but thanks for checking!

The problem with tracking when Child is called is that Child might not actually be called when your function runs, but only during the render of the object that it returns, e.g. in a Generator:

@htl("""
<ul>
$((
    @htl "<li>$(Child(CheckBox()))"
    for _ in 1:10
))
""")

Since this is an important feature of HypertextLiteral, i wanted to support it too. So with the current implementation, Child is tracked during a dummy render when you create a combine.

aplavin commented 1 year ago

Sure, it's an important usecase to support, but is the current child order itself "by design" or just as a result of the current way to handle children? For example, instead of the current "dummy render everything and record what order children display in", I can imagine an alternative approach:

This way, Child calls that happen during the function execution are recorded in their execution order, and those that only happen on render are recorder in their render order (that is equal to their execution order on render anyway).

The concrete usecase I encountered this difference and was suprised by it, is when I create a 2d array of inputs, and then display them in row-major or column-major order. Would never guess that the output will be different depending on how already created inputs are displayed!

fonsp commented 1 year ago

I would say that it's by design just to have a simple API. Otherwise, we would track both orders and union them (and track duplicates).

But in your case, it sounds like you should specify a name for each child, so that you get a named tuple. I added this option so that you don't have to depend on rendering order.

For your matrix case, also check out the CSS flex styling options to change between grid orders.