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

Column default width should be based on sampled content #1233

Closed
jouni opened this issue Feb 22, 2018 · 10 comments · Fixed by #1595
Closed

Column default width should be based on sampled content #1233

jouni opened this issue Feb 22, 2018 · 10 comments · Fixed by #1595
Assignees
Labels
enhancement New feature or request
Projects

Comments

@jouni
Copy link
Member

jouni commented Feb 22, 2018

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 – on 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.

@jouni jouni added the enhancement New feature or request label Feb 22, 2018
@karsten-eger
Copy link

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.

@robrez
Copy link

robrez commented Mar 2, 2018

Was looking to do something about this, too. Eg:

https://github.com/ag-grid/ag-grid/blob/master/src/ts/rendering/autoWidthCalculator.ts

@yveslange
Copy link

yveslange commented Sep 28, 2018

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

@robrez
Copy link

robrez commented Feb 8, 2019

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);
    }
  }

@jtomass jtomass added this to 🏃  Sprint in vaadin-core Mar 29, 2019
@Haprog Haprog moved this from 🏃  Sprint to 🏗  In Progress in vaadin-core Apr 1, 2019
@web-padawan web-padawan moved this from 🏗  In Progress to 🏃  Sprint in vaadin-core Apr 2, 2019
Haprog added a commit that referenced this issue Apr 11, 2019
Haprog added a commit that referenced this issue Apr 11, 2019
vaadin-core automation moved this from 🏃  Sprint to ✅ Done Apr 15, 2019
Haprog added a commit that referenced this issue Apr 15, 2019
New feature for automatically setting the width of a column based on the column contents. For more info see the new demo "Columns / Automatic Column Width" and the documentation of the `autoWidth` property of `vaadin-grid-column`.

Fixes #1233
@Haprog Haprog removed the in review label Apr 15, 2019
@Haprog
Copy link
Contributor

Haprog commented Apr 15, 2019

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.

@wolfey
Copy link

wolfey commented Jun 25, 2019

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

@enver-haase
Copy link

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

@web-padawan
Copy link
Member

@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

@web-padawan
Copy link
Member

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

@jouni
Copy link
Member Author

jouni commented Jun 28, 2019

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

HJK181 pushed a commit to CommerceExperts/vaadin-grid that referenced this issue Jul 12, 2019
New feature for automatically setting the width of a column based on the column contents. For more info see the new demo "Columns / Automatic Column Width" and the documentation of the `autoWidth` property of `vaadin-grid-column`.

Fixes vaadin#1233
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
No open projects
vaadin-core
  
✅ Done
Development

Successfully merging a pull request may close this issue.

9 participants