TanStack / table

🤖 Headless UI for building powerful tables & datagrids for TS/JS - React-Table, Vue-Table, Solid-Table, Svelte-Table
https://tanstack.com/table
MIT License
25.24k stars 3.08k forks source link

[v7] Table 100% width #1639

Closed ivanov-v closed 5 years ago

ivanov-v commented 5 years ago

I use useBlockLayout and I don’t understand how to make the table stretch 100% of the width of the parent. In theory, the width of the columns should be adjusted as it was at V6

tannerlinsley commented 5 years ago

Out of the box, no, it does not behave like v6, since it is not using a flexbox model. useBlockLayout uses inline-block divs with precise widths. You can stretch the table container itself to take up the full width, but in a block or absolute layout, your columns will not grow automatically. The only way I know of to reliably do that is using the default html-table-element layout.

ivanov-v commented 5 years ago

Out of the box, no, it does not behave like v6, since it is not using a flexbox model. useBlockLayout uses inline-block divs with precise widths. You can stretch the table container itself to take up the full width, but in a block or absolute layout, your columns will not grow automatically. The only way I know of to reliably do that is using the default html-table-element layout.

but then I can not set the width of the columns?

tannerlinsley commented 5 years ago

Yes you can. width can be set on columns, and also, if you are using resizable columns, minWidth and maxWidth are also used

ivanov-v commented 5 years ago

Yes you can. width can be set on columns, and also, if you are using resizable columns, minWidth and maxWidth are also used

Good. I’ll think about how to do it better. It’s not clear from the documentation how inline-block divs affects performance. Please explain)

useBlocklayout is a plugin hook that adds support for headers and cells to be rendered as inline-block divs (or other non-table elements) with explicit width. Similar to the useAbsoluteLayout hook, this becomes useful if and when you need to virtualize rows and cells for performance.

ivanov-v commented 5 years ago

Yes you can. width can be set on columns, and also, if you are using resizable columns, minWidth and maxWidth are also used

How can i set width without useBlockLayout?

{
    accessor: 'q',
    Header: 'Header',
    width: 300,
},

does not work. Or I didn’t understand you)

tannerlinsley commented 5 years ago

Please refer to this example: https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/block-layout

coreybruyere commented 5 years ago

@tannerlinsley is there a way to get a full width table (100%) and have cells stretch out to fill out the 100% table? When using regular table elements as well?

tannerlinsley commented 5 years ago

When you say stretch, that could mean many things. Do you want each cell to grow equally? Do you want them to grow with their original size ratio? Do you want the 1st, 4th and last column to grow equally to fill the empty space?

You can see how that can be interpreted in so many ways. A lot of those ways were handled by the flex layout, since flexbox can do most of that natively, but flexbox calculations get really messed up when you move to column groups, column spans, etc. The alignment can get really off.

If you really really want an HTML-element table layout that will go 100%, then you could try this example. It even supports collapsible cells!

https://codesandbox.io/s/github/tannerlinsley/react-table/tree/master/examples/full-width-table

coreybruyere commented 5 years ago

Thanks @tannerlinsley. I was looking for the default table behavior and styles you'd get with a 100% width table: https://codepen.io/coreybruyere/pen/oNNVzPa

That example works great but now my first column cell which has an expander and an empty th header is also expanding. That entire column should have a max width of 32px:

Screen Shot 2019-11-20 at 10 21 33 AM

The columns array

    const MOCK_COLUMNS = React.useMemo(
        () => [
            {
                // Expander cell
                Header: () => null, // No header
                Cell: ({ row }) => {
                    // Look for comment property before rendering expander
                    return row.original.comment ? (
                        <ThemeConsumer>
                            {(theme) => (
                                <span {...row.getExpandedToggleProps()}>
                                    {row.isExpanded ? (
                                        <Icon.Decrease color={theme.colors.base[5]} />
                                    ) : (
                                        <Icon.Expand color={theme.colors.base[5]} />
                                    )}
                                </span>
                            )}
                        </ThemeConsumer>
                    ) : null;
                },
                id: 'expander',
                width: 32 // Arbitrary value to make room for icon - Not working
            },
            {
                Header: 'Test',
                accessor: 'test',
                minWidth: 300
            },
            {
                Header: 'Results',
                accessor: 'results',
                minWidth: 300
            },
            {
                Header: 'Range',
                accessor: 'range',
                minWidth: 300
            }
        ],
        []
    );

The table header with custom, styled components mapping through header groups:

                        <TableHeader>
                            {headerGroups.map((headerGroup) => (
                                <TableRow {...headerGroup.getHeaderGroupProps()}>
                                    {headerGroup.headers.map((column) => (
                                        <TableCell {...column.getHeaderProps()}>{column.render('Header')}</TableCell>
                                    ))}
                                </TableRow>
                            ))}
                        </TableHeader>
tannerlinsley commented 5 years ago

As shown in that example, you can use a column.collapse flag to apply a style that will collapse specific columns to their smallest needed width.

OlegBrony commented 4 years ago

so it's impossible to make table with 100% and fixing some cells? for example I can't make table with 100%, 30vw for first cell, 30 vw for second and rest for others? in example you just removed useBlockLayout, but only with this you can set custom width to columns.

tannerlinsley commented 4 years ago

Technically that is feasible, it's all just a matter of setting it up in your renderer and accepting any tradeoffs that may come with it. For instance, instead of setting up the collapse option like I did above, you could just use width and set each column as best you can.

If you are looking for true column flex though (similar to v6), you'll have to venture down a custom path of using useBlockLayout and flex styles. I don't suggest people do that, since there were a few problems with flex layout that could never be solved, namely cross-browser nested column header alignment and scrollbar offsets from scrollable table bodies.

rasgo-cc commented 4 years ago

Im also looking for the same behavior as @OlegBrony.

namely cross-browser

@tannerlinsley just wanted to add that in case react-table is used in an electon app (as is my case), that wouln't be a problem. Will look how that can be accomplished with useBlockLayout. Any additional pointers on how that can be accomplished would be very welcome.

Jucesr commented 4 years ago

Just now I decided to upgrade from V6 to V7. I got everything right but the resize functionality. In V6 when resizing It does not affect other columns but in V7 it does.

React V6: https://giphy.com/gifs/Jpp6HWUT1GR2IJMCSv/fullscreen React V7; https://giphy.com/gifs/dCR44Nywbz7wDNjwVi/fullscreen

My Code: https://codesandbox.io/s/cool-fermi-6jtgo?file=/src/Table.js

What am I missing?

alexmittsel commented 4 years ago

@Jucesr Hi! Did you solve the problem?

ZiedHf commented 4 years ago

Is there anyway to have a table with 100% of the parent width + the resizing feature ? I posted this question on Stackoverflow here.