API suggestion request (for a new Vaadin Grid feature)

We are planning a responsive feature for Grid that switches it to a kind of “list style” mode when the width is less than some specified size.
This will work by

  • Automatically revealing one (or more) special columns when the Grid is smaller than X;
  • At the same time hiding all the “normal” columns;
  • For the special columns, you will specify a renderer (e.g. ComponentRenderer or LitRenderer) that determines how that/those special column(s) will render (e.g. what data is included and how it’s laid out)

How would you design the API for this feature?

  • How do you specify which columns are the “special” ones?
  • How do you specify the breakpoint (the width at which the visibility switch happens)?
  • How do you enable this feature on the Grid?

(Flow, Lit and React API suggestions are all welcome)

Screen Recording 2025-01-22 at 18.25.42

3 Likes
  • How do you specify which columns are the “special” ones?

Flow: grid.addResponsiveColumn(Breakpoint.PHONE).setPropertiesLikeNormal();

  • How do you specify the breakpoint (the width at which the visibility switch happens)?

As Java Developer I would expect Vaadin to identify common breakpoints and provide those options in a typesafe manner for us Developer (enum with css variables on the client side for customizing if needed) This comes with a follow up question: can I define columns for different view points? (Phone / tablet comes to mind where you have one vs 3-5 columns)

Personally I would also like to have a grid.addResponsiveChangedListener which would allow me to alter other parts of the application based on the current resolution / breakpoint. The event should contain the old as well as the new breakpoint and if feasible also the real resolution.

  • How do you enable this feature on the Grid?

It does not have to be enabled - if I add a responsive column, I would expect the grid to know. If there is no responsive column(s), nothing changes.

3 Likes

Sure, whatever the API is like it could take both enums or width-strings.

What I meant to ask was really “Is the API for specifying the breakpoint the same as the API for specifying which columns are special?”

In your suggestion, it is. In other designs, it might not be, e.g. if we would only support one breakpoint, but multiple “special” columns, would it make more sense to specify the breakpoint on the Grid itself rather than separately on each column?

We could make this feature support an arbitrary number of breakpoints, allowing you to define which columns are visible for each, but note that we are then probably talking about two slightly different features:

  1. The feature proposed above: A column that is only visible below a certain width that is specifically intended for when a multi-column Grid doesn’t really work well, UX-wise. Here, the column displayed on mobile is not visible on desktop.

  2. The feature I think you’re asking about: A Grid that shows a particular subset of normal columns for various different breakpoints, e.g. to avoid horizontal scrolling. Here, the columns displayed for a tablet are also visible on desktop.

Of course for maximum flexibility you could define a whole set of breakpoints or some kind of min/max rules for each column, but that would seem rather overkill as well as complicated to use.

As for a responsiveChangedListener, isn’t that already covered by https://vaadin.com/docs/latest/flow/advanced/browser-access#browser-window-resize-events? Would there be any benefit in Grid having its own?

if we would only support one breakpoint, but multiple “special” columns, would it make more sense to specify the breakpoint on the Grid itself rather than separately on each column?

If you would only support one breakpoint the natural position of the API would be on the Grid level rather than on each column to ensure people don’t falsely add different breakpoints by accident in multiple columns or hope that multiple breakpoints are supported.

but note that we are then probably talking about two slightly different features

Yes and no :) I understand where this misunderstanding comes from… but I’m on your side and was really looking into option 1 - where each breakpoint would define their own set of columns. Desktop (all / Default) / Tablet (Special Columns) / Mobile (Special Columns)

As for a responsiveChangedListener, isn’t that already covered by https://vaadin.com/docs/latest/flow/advanced/browser-access#browser-window-resize-events? Would there be any benefit in Grid having its own?

I could ask the same: why do we need special columns If Developers could subscribe to the event mentioned above and re-creating the grid based on the current resolution? You are building the feature for improved Developer Experience (technically it’s already doable today) - that’s why my wish came: a component with special API for responsibility should IMHO also have a listener for it to ease API discoverability

1 Like

I’ve some issue with this approach https://vaadin.com/docs/latest/flow/advanced/browser-access#browser-window-resize-events has some issues. I use this to decide whether it is mobile/tablet/desktop based on that I show different views. For mobile screen, when there is a grid, I show only one column and when the user clicks on a row, I show a another view which is nothing but a Sidebar from vaadin plus. When the user moves from portrait to landscape, that is getting treated as a window resize it gets reset to the grid view and he loses the Sidebar. So browser resize is something not working for all cases

@knoobie, assuming the mutually-exclusively-displayed columns, with support for multiple breakpoints and multiple columns per breakpoint, how would you design the API to give developers a chance to understand what it does?

Also, would it then be possible to assign the same column to multiple breakpoint-groups, if I want it to be visible both in “tablet” and “mobile” sizes?

@psrinivasababu your issue can be solved by keeping track of the sidebar’s state instead of just handling it in the resize listener.

To answer @knoobie, indeed, this is doable today with 20+ lines of code, as shown here, and this feature is planned to reduce that to 1–3 lines, as well as significantly better performance as the switching would happen on the clientside. But let me turn the question around: what would you do with a grid-specific responsive-listener?

I think my flow API from above would still work.

It’s not possible with my approach - the code for the column has to be duplicated or the suggested API allows multiple Breakpoints instead of only a single one per column.

Based on the information I could for example change the footer of the grid to display less information, change the whole grid from no-select to single select and change the in-lined buttons that were in a hidden column to be shown below the grid and react based on the selection. (e.g. edit / delete and such operations)

One alternative approach would be that there are no special “responsive columns” or similar but instead that every column can be configured to be visible when the grid width is within a specific range. Columns are by default visible for widths between 0 and Integer.MAX_VALUE. There are predefined range object constants for e.g. mobile, tablet and desktop but the developer can also create their own objects with arbitrary limits.

The benefit of this design is that the API surface is minimal with only one new configuration property on regular columns and that it’s very flexible since you can define arbitrary combinations for all columns. The drawback compared to a having a dedicated column type for responsive columns is that you need to apply some configuration also to all your 100 “default” columns and not only to the single mobile column.

I like that, but I dismissed the idea in my head beforehand because it would result in a lot of configuration / changed for people that wanna use the new feature with their already configured Grids. All previously added column would be required to be changed from min=0 to min=399 and a new column has to be added with max=398

From my point of view:

As a developer I would expect (or hope) that the api surface exposed to make a grid responsive, resembles the one that would make a formlayout responsive, or a Tabsheet, or a map, menu or whatever other component. Something that feels like a first class citizen in the component api instead of a bolted-on afterthought thing with different mechanics and api vocabulary per component.

(I have not read every reply to this post as it was going too far for me, so apologies if this was implied already and I’m talking nonsense :-P )

1 Like

That can be addressed with one addition while still preserving the overall flexibility. There could be one additional method on the grid to override the default width limits that is used for columns that don’t have anything explicitly defined.

Thanks for all the feedback, guys!

We’ll analyze this and figure out how to proceed in the next couple of weeks.

P.S. I agree that consistency between responsiveness features in different components is desirable, but there’s also the factor that different components need to be responsive in different ways, which tends to require different APIs.

We’re also looking into simplifying FormLayout’s API so that you wouldn’t have to specify each breakpoint manually (unless you really really want to).

3 Likes

Just my two pennies; i have added a detail to the row on mobile screens so the row is not so high. The row collapse once i click on the row and then i see the other data from the hidden columns. In this case the whole grid has a good height on mobile screens

That’s actually a clever approach, @OnDemand – providing the content that would normally be shown in multiple columns in the row details, so that the single column cell doesn’t have to be so tall, while still making all that content available to mobile users.

Perhaps we can also add the ability to minimize/deploy this content for desktop devices?