Vaadin-grid: Column default width should be based on sampled content

Created on 22 Feb 2018  路  10Comments  路  Source: vaadin/vaadin-grid

The current default width for all columns is a hardcoded 100px. A better default would be to leave the width undefined and use the content as the measured width, which could be overridden with an explicit width set by the developer or by the end user (column resizing).

The first set/page of data should be used for the measurement, and use the largest width of each column.

I suppose this is even fairly simple to implement 鈥撀爋n the first render, the columns are rendered without a width or flex-grow, so they get their natural width. Then measure all the cells in each row (if no explicit width is set for the column) and pick the largest number and set that as the explicit width of the column and restore flex-grow to the previous value.

enhancement

Most helpful comment

This has now been implemented in master as a new opt-in feature (autoWidth property and auto-width attribute on vaadin-grid-column). However it's likely that we will make this the default behaviour for columns in the next major version.

All 10 comments

When we want to achieve auto-sizing we set the flex-grow attribute right now. Works the same way then.

Having auto-sizing as the default would be nice indeed.

Any news on that feature ?

I have created, what I personally called a "widthMap" that holds all the biggest width for every column.

My solution is pretty slow since it goes over each cells and rows.

Is it possible to get, somehow, the current displayed page (data/items) ? I could compute it manually but I'm stuck when it comes to sorting and filtering.

Without using a data-provider

Best regards,
YL

We added a behavior where double clicking a resize handle samples widths and resizes that column. It relies the boundingRects of content already rendered in the cells. And thus, only samples "connected" content. This seems to work okay.

To achieve sizing for the whole grid, only in rare cases, we can loop through all columns and use this same routine. This is done just after the a grid render - and debounced. This is less okay - there is definitely an obvious fouc-like "jump" when the grid repaints; Although, I think that goes undetected by most users

All of this is admittedly less than ideal but we have been able to "get by" with it. Our implementation is something like this:

  _onDoubleClickGrid(e) {
    //  modelForEvent uses grid.getEventContext
    //  and checks if e.composedPath contains a "resize-handle"
    let model = this._modelForEvent(e);
    if (model && model.resizeHandle) {
      this._sampleAndResizeColumn(model.col);
    }
  }

  _sampleAndResizeColumn(col) {
    let sampledWidth = this._sampleColumnWidth(col);
    if (sampledWidth) {
      let query = `vaadin-grid-column[data-index="${col}"]`;
      let colDom = this.shadowRoot.querySelector(query);
      if (colDom) {
        colDom.width = sampledWidth + "px";
      }
    }
  }

  _sampleColumnWidth(col) {
    let grid = this.$.grid;
    let cells = grid.querySelectorAll("vaadin-grid-cell-content");
    if (cells && cells.length) {
      let max = 0;
      let currentWidth = 0;
      let offsetX = 0;
      for (let i = 0; i < cells.length; i++) {
        let cell = cells[i];
        if (cell.slot && cell.firstElementChild) {
          let cellContent = cell.firstElementChild;
          if (cellContent.data && cellContent.data.col === col) {
            let rect = cellContent.getBoundingClientRect();
            let w = rect.width;
            max = Math.max(max, w);
            if (!currentWidth) {
              let colRect = cell.getBoundingClientRect();
              currentWidth = cell.width;
              offsetX = Math.abs(colRect.x - rect.x);
              //attempt to adjust for extra padding from css
            }
          }
        }
      }
      return max + (offsetX * 2);
    }
  }

This has now been implemented in master as a new opt-in feature (autoWidth property and auto-width attribute on vaadin-grid-column). However it's likely that we will make this the default behaviour for columns in the next major version.

Any chance you could backport this to Vaadin 8 or offer a workaround?

I don't see this as Flow API in 13.0.9 - am I correct it is not there yet?

@wolfey Vaadin 8 has a completely different implementation for the components, so backporting would be non-trivial. Check the open issues at https://github.com/vaadin/framework

@enver-haase the API implemented in scope of this issue is only available at Vaadin 14.

@wolfey, Vaadin 7/8 Grid has had this feature for a long time already.

Was this page helpful?
0 / 5 - 0 ratings