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

Is there a way to autosize column width to content? #525

Open
boxfoot opened this issue Apr 10, 2020 · 5 comments
Open

Is there a way to autosize column width to content? #525

boxfoot opened this issue Apr 10, 2020 · 5 comments

Comments

@boxfoot
Copy link
Contributor

boxfoot commented Apr 10, 2020

I'm looking for a way to size a column to fit the longest possible content rendered in that cell. So for example, if all rows would render content of 100px for this column, the column would be 100px wide -- but if one row renders 200px of content, the column would be 200px wide.

Is there a way to do that?

@wcjordan
Copy link
Member

wcjordan commented Apr 13, 2020

Unfortunately we don't provide anything out of the box. You could conceivably implement this yourself and plug in to FDT though. You could approach it 2 ways depending on an accuracy / performance trade-off.

Approach 1:
Render all cells to the DOM offscreen outside of FDT. Find the max the width of all cells and pass that value to FDT. This would be the more accurate but slower approach since it requires rendering all cells in a column (and fetching all data).

Approach 2:
Wrap your cell component in a HOC which measures the cell width after rendering. This width value could then be passed to some state store / cache which can be used to calculate the max width and use that to size the column. This would be faster since it uses FDT to only render cells in the viewport, but would be inaccurate since scrolling might alter the max width if a wider cell scrolls into view.

This approach would be similar to React Virtualized's CellMeasurer.

@Tanner-MS
Copy link
Contributor

I was debating about 2 different approaches where the consumer calculates this:

Approach 1 (calculate ahead of time and keep up to date):
Add a maxContentWidth prop to the Cell and when the resizer is double clicked the FDT calls onColumnResizeEnd with that prop value for that column.

Approach 2 (calculate on demand):
Add a getColumnSnappedWidth callback attribute to the FDT that we call when the resizer is double clicked with the columnKey, firstRowIndex, endRowIndex and then the consumer can calculate it for that column for all the data or for just the data that is present on the screen. Then FDT calls onColumnResizeEnd with that value it got back.

Thoughts?

@pradeepnschrodinger
Copy link
Collaborator

@Tanner-MS , thanks for you suggestions. A couple questions:

Approach 1 (calculate ahead of time and keep up to date):
Add a maxContentWidth prop to the Cell and when the resizer is double clicked the FDT calls onColumnResizeEnd with that prop value for that column.

Is the maxContentWidth just a prop passed by the user?
If so, since the max width is already available to the user, the user can simply pass in an onDoubleClick prop to the cell renderer.
The user can then make the handler resize the column based on the already computed maxContentWidth.

One advantage of customizing the onDoubleClick handler like this would be that FDT doesn't have to know about max content widths, nor would we fix the implementation of the double click handler.

Approach 2 (calculate on demand):
Add a getColumnSnappedWidth callback attribute to the FDT that we call when the resizer is double clicked with the columnKey, firstRowIndex, endRowIndex and then the consumer can calculate it for that column for all the data or for just the data that is present on the screen. Then FDT calls onColumnResizeEnd with that value it got back.

Same reasoning as above. We can have the user pass in a double click handler which uses the consumer to calculate the max content width on the fly.

@Tanner-MS
Copy link
Contributor

Tanner-MS commented Aug 5, 2021

@pradeepnschrodinger

Is the maxContentWidth just a prop passed by the user?
If so, since the max width is already available to the user, the user can simply pass in an onDoubleClick prop to the cell renderer.
The user can then make the handler resize the column based on the already computed maxContentWidth.

maxContent width would be different than maxWidth. Max content is the widest width your value content would reach, max width is the largest the cell can go. Assuming this is the largest you can resize to as well. Also for this functionality you only want the double click on the resizer, not anywhere else in the header cell. While the user could parse this out based on the target of the event.

Same reasoning as above. We can have the user pass in a double click handler which uses the consumer to calculate the max content width on the fly.

Guess same reason as having this built in makes it simpler on the consumer. They wouldnt have to query the target of the double click.

@pradeepnschrodinger
Copy link
Collaborator

maxContent width would be different than maxWidth. Max content is the widest width your value content would reach, max width is the largest the cell can go.

Apologies for the confusion; I meant to use maxContentWidth instead of maxWidth.
Since, maxContentWidth is already precomputed by the user, they can just have the onDoubleClick handler make use of it, without having FDT know about maxContentWidth.

Also for this functionality you only want the double click on the resizer, not anywhere else in the header cell. While the user could parse this out based on the target of the event.

Good points

Guess same reason as having this built in makes it simpler on the consumer. They wouldnt have to query the target of the double click.

Definitely. Passing a generic double click handler that targets just the resizer sounds like a better idea, maybe something like onColumnResizerDoubleClick?
The user can keep track of the current row indices through handlers like onScrollEnd, so all the information to calculate maxContentWidth on the fly will be available to the user.


Also as a side note: In the v2.0-beta branch, we've moved out the resizing functionality from the main table component to a separate plugin based cell component.
Here, props like minWidth and onColumnResizeEnd, belong to the cell component.
So adding another prop like onColumnResizerDoubleClick will be relatively simpler than in master.

Also, since these plugins are decoupled out of the table component, we could even have a new plugin that contains business logic to compute the actual max content width.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants