Feedback wanted: Proposal for responsive layouting helpers in Vaadin Flow

We would love to hear your thoughts on a proposed API for making it easier to implement responsive layout features in Flow applications without messing around with css @media or @container queries or windowResizeListeners. The RFC document below has commenting permissions for everybody, and you can also give your feedback in this thread.

We’ll keep it open for comments until Dec 15.

5 Likes

I think it is covered in the doc, but just to be sure:

If I want to generate completely different layouts for mobile and desktop (except for the outer layout) can I do it like this?:

@Route
public class MyView extends VerticalLayout {
    
    ActiveSignal<Boolean> smallSignal = this.useWidth()
      .whenLessThan(500, true)
      .orElse(false)
      .asSignal();

    public MyView() {

        ComponentEffect.effect(this, () -> {
            removeAll();
            var isSmall = smallSignal.value();
            if(isSmall) renderSmall();
            else renderBig();
        });

    }

    private void renderSmall() {...}
    private void renderBig() {...}

}

Yes. Something like that should work.

We might want to add a helper for doing that effect with less ceremony but that’s something that should work with any signal and not in any way be specific to signals related to the responsive functionality. I explored that topic as Selector in Design input: control flow with signals.

1 Like

Any plans to get this into V25?

It’s relatively high on our priority list but not yet confirmed for any specific release. So it’s likely to get into some Vaadin 25.x minor release.

1 Like

Coming here after watching the “Mastering Responsive Layouting in Vaadin” webinar yesterday
(For those who might have missed it : https://www.youtube.com/watch?v=yY2Y91O1Ms8 )
I found it very enlightening and has given me some new ideas to try out.
Thank you @rofa

Disclaimer: I have not yet read the RFC doc fully.

After the webinar I have a few points

The MasterDetailLayout:
IMO, good usability dictates, any editor should be displayed as a modal dialog.
I noticed there is a layout.setContainment(MasterDetailLayout.Containment.VIEWPORT); which, as per the document

The overlay covers the entire viewport (i.e. page)

This is not the same as a Dialog
Is it possible to provide a MasterDetailLayout.Containment.DIALOG , which would display the detail view as a dialog?

Also, as per default behaviour, the detail view pops up on every grid row selection change.
If I am not mistaken, in the demo, the selection passes the selected entity id to the detail view, which makes a DB call, before displaying the actual details.
This might not be the desired behaviour always. e.g. I might have selected some entity earlier and am using the keyboard to navigate the grid.
Obviously developers can optimise this, but maybe some kind of switch could be a better idea to trigger off the detail view?
In my projects I usually provide a separate column with icon buttons for edit and delete, which the user clicks to trigger the editor or confirm delete dialog.

The ResponsiveGrid
I suppose this is something all devs have struggled with: How to properly show a Grid on a mobile view?
The solution in the demo was to add another component column which was shown/hidden as required.

Perhaps auto magically switching between a Grid and a VirtualList could be a more elegant solution? Basically a composite component , which decides which child view to show based on available screen space.
-Both display data having multiple values
-Both can be populated via setItems
-Both accept renderers
-Both can be dynamically refreshed via the dataProvider

I had implemented this idea in my of my past projects (show/hide based on screen size) but it was sloppy and frankly speaking a dirty hack. I am sure experts can do it much better.

Obtaining client width
The demo made use of retrieveExtendedClientDetails to obtain the initial screen width when the app starts.
However this method is marked deprecated and recommended alternative is getExtendedClientDetails
Has this been reverted and the docs are yet to be updated, or did Rolf miss out on this?

LumoUtility
I was saddened to hear there will be no further changes to LumoUtility.
Come on Vaadin team, people like me turned to Vaadin because we struggle with css/js and a pure Java solution was just perfect.
Now you are telling us no more changes? Recently I had to use css just to change the font to italic
Please reconsider your decision

Tailwind + Aura
Same as above. Can we at least have predefined enums or constants, if not the whole AuraUtility?

On behalf of all developers, a message for the Vaadin Team :joy:

You were the chosen one! It was said that you would destroy the Sith, not join them! Bring balance to the Force, not leave it in darkness!

Thanks for the feedback!

good usability dictates, any editor should be displayed as a modal dialog

As a UX designer, I don’t fully agree: Modal dialogs are certainly one of the best ways to separate the editing UI from the rest, and ensure edits are either persisted or reverted, but they are certainly not the only pattern appropriate (or commonly used) for it. What would a DIALOG containment mode be like that would make it a better container for the editor?

Also, as per default behaviour, the detail view pops up on every grid row selection change.

This is not a default behavior, actually. I just used row selection as the trigger in the demo app. The MDL does nothing except display the detail contents when they are added to the layout, and you have full control over when and how that happens, so you could instead navigate to the detail view when a dedicated edit button is clicked.

Perhaps auto magically switching between a Grid and a VirtualList could be a more elegant solution?

That is another way of doing it, yes. It has a few drawbacks, however:

  1. Selection is not maintained, so you need to handle that yourself.
  2. VirtualList doesn’t currently have a concept of “selection”, so you need to also implement that somehow
  3. You need to populate two different components with the same data
  4. Switching between them has a significantly bigger performance impact than toggling column visibility.
    We have considered introducing a “list mode” in Grid to cover this use case, but have not proceeded with those plans yet.

The demo made use of retrieveExtendedClientDetails to obtain the initial screen width when the app starts. However this method is marked deprecated and recommended alternative is getExtendedClientDetails

The demo app is running on V24, in which that method is not yet deprecated. In V25 you should indeed use getExtendedClientDetails instead.

Tailwind + Aura Same as above. Can we at least have predefined enums or constants, if not the whole AuraUtility?

A Java API for Tailwind is planned, but we have not yet decided on the API design. Tailwind having thousands of utility classes, and support for dynamic or ad-hoc classes makes it a lot more challenging to design than the relatively small set of utilities in LumoUtility.

If you want to use a dialog for editing, then use the Dialog component. No need for Master-Detail Layout.