TanStack Table V9 Roadmap #5270
-
TanStack Table V9 RoadmapThis was a draft discussion for v9. See #5595 for the updated proposals and plan.
|
Beta Was this translation helpful? Give feedback.
Replies: 9 comments 8 replies
-
that sounds amazing. Making it easier to introduce/build plugins and better row selection features stand out for me. I will consider some suggestions in in next few days! |
Beta Was this translation helpful? Give feedback.
-
API Alignment With TanStack FormWhile some of the TanStack projects, like Query or Store use only "hooks" - others, like Router and Form need "components" or, rather, templating to handle what we need. Looking at Form and Router's APIs - we have something of a builder pattern emerging with components accepting functions as the means of headless distribution. It would be nice to have this consistent across all TanStack projects, as I think components enable us to have an easier time educating users, controlling lifecycle methods or other FW specific APIs inside of the components, and more. Because of this, I'm wondering if instead of the proposed: //TanStack Table V9 (original proposal)
import {
useReactTableCore, //core instead of useReactTable
flexRender,
getTableHeaderGroups,
getHeaderContext,
getTableRowModel,
getRowVisibleCells,
getCellContext,
getCanColumnSort,
getToggleSortingHandler,
getIsColumnSorted,
} from '@tanstack/react-table';
const table = useReactTableCore({
columns,
data,
// etc...
});
return (
<table>
<thead>
{getTableHeaderGroups({ table }).map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th key={header.id}>
{header.isPlaceholder ? null : (
<div
{...{
className: getCanColumnSort({
column: header.column,
table,
})
? 'cursor-pointer select-none'
: '',
onClick: getToggleSortingHandler({
column: header.column,
table,
}),
}}
>
{flexRender(
header.column.columnDef.header,
getHeaderContext({ header, table }),
)}
{{
asc: ' 🔼',
desc: ' 🔽',
}[
getIsColumnSorted({
column: header.column,
table,
}) as string
] ?? null}
</div>
)}
</th>
))}
</tr>
))}
</thead>
<tbody>
{getTableRowModel({ table }).rows.map((row) => (
<tr key={row.id}>
{getRowVisibleCells(row).map((cell) => (
<td key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
getCellContext({ cell, table }),
)}
</td>
))}
</tr>
))}
</tbody>
</table>
); We have something like this: //TanStack Table V9 (new proposal)
import {
createTable, //core instead of useReactTable
flexRender,
getTableHeaderGroups,
getHeaderContext,
getTableRowModel,
getRowVisibleCells,
getCellContext,
getCanColumnSort,
getToggleSortingHandler,
getIsColumnSorted,
} from '@tanstack/react-table';
const tableFactory = createTable({
methods: {
// If any of these methods are not provided, but are utilized under-the-hood,
// we will warn the user that they need to provide an implementation.
// Otherwise these methods will NOOP: `() => null`
getTableHeaderGroups,
getHeaderContext,
getTableRowModel,
getRowVisibleCells,
getCellContext,
getCanColumnSort,
getToggleSortingHandler,
getIsColumnSorted,
}
})
const App = () => {
const table = tableFactory.useTable({
columns,
data,
// etc...
});
return (
<table>
<thead>
<table.HeaderGroups>
{(headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th key={header.id}>
{header.isPlaceholder ? null : (
<div
{...{
className: table.getCanColumnSort(header.column)
? 'cursor-pointer select-none'
: '',
onClick: table.getToggleSortingHandler(header.column),
}}
>
{flexRender(
header.column.columnDef.header,
table.getHeaderContext(header),
)}
{{
asc: ' 🔼',
desc: ' 🔽',
}[
table.getIsColumnSorted(header.column) as string
] ?? null}
</div>
)}
</th>
))}
</tr>
)}
</table.HeaderGroups>
</thead>
<tbody>
<table.RowModel>
{({ rows }) => (
<>
{rows.map((row) => (
<tr key={row.id}>
{getRowVisibleCells(row).map((cell) => (
<td key={cell.id}>
{flexRender(
cell.column.columnDef.cell,
getCellContext({ cell, table }),
)}
</td>
))}
</tr>))}
</>
)}
</table.RowModel>
</tbody>
</table>
);
} What do you think? |
Beta Was this translation helpful? Give feedback.
-
Hey hey, long time user here. I came across this discussion while doing a input in my local web group about this library, as it's one of my favorite libraries. Keep up the good work. Hope my input is appreciated. I just want to share my POV what makes the library great for me. 1. Statically Defined and Importable API Functions and Core HooksI'm not so sold on the proposal to split every single method out. One thing I like is the discoverability via intellisense. Moving all functions makes it way harder to use without visiting the documentation. Searching through imports instead of just an instance sounds like a worse consumer experience to me. I really love the documentation was well. But I like to use my IDE to search for a set of methods or options that sound like what I want to do and consult the documentation for the specific behavior. That said, I really like the idea to move things out, declutter and make user plugins easier again. What do you think about the an api along the lines of this proposal: import {
paginated,
sorted,
filtered,
} from '@tanstack/table-core'
import {
withPagination,
withSorting,
withFilters,
useReactTableCore,
} from "@tanstack/react-table";
import {
customized,
withCustomization
} from "./my-custom-plugin"
const useTable = useReactTableCore([
withFilters,
withPagination,
withSorting,
withCustomization
])
const App = () => {
const table = useTable({
data,
columns,
// ...otherOptions
})
// do things with a specific row model
paginated(table).getPreRowModel()
return () => <>
{table.getRowModel().rows.map(row => {/** ... **/})}
<button onClick={() => paginated(table).setPageIndex(0)}>Go to first page</button>
<button onClick={() => customized(table).shuffleRows()}>Shuffle</button>
</>
} Considering other levels // delegated decorator looks neater
filtered(column)
filtered(row)
// dedicated decorator
filteredColumn(column)
filteredRow(row) In this proposal, extensions would be split. The table feature basically handles it's slice of state, it's data transformation, caching etc. The decorator accesses a feature to provide a convenient, rich api. Maybe some methods could be sliced into separate decorators or actual methods only, but at least It could make sense to introduce a feature registry on the table that decorators could use to access the feature, so maybe a full plugin would be a triplet of withFeature, getFeature(table) and featured(table) I remember a pain about plugin order issues in react-table v6 that lead to the introduction of internal features, removing them from user control. One common example was filters after pagination. Maybe, standard features could access another feature in development mode and throw or warn if this constellations are detected. 5. Multiple Filters Per ColumnSince the filter value can be anything, multi filters are already supported, aren't they? I've implemented them a couple of times. How would the changed API look like? I think this would be a really cool addition, but maybe this could also just be an example in the documentation. Is there anything I'm missing? I don't see complex filter ui scenarios that are not possible at the moment. Which is another reason, why I love❤ this project 6. Make Column FilterFns StatefulActually, similar to above, my personal preferred solution for this issue in the current version is an object as filter value that reference the filter function and value. I totally second your point that convenient api for this would be awesome. If the shift of proposal 1 is made to extract functions from the core instance - no matter whether it's through my decorator proposal, independent or extended functions - this could be also interesting to promote community extensions, because the usage wouldn't feel so different from the built-in functionality. That said, more built-in features are always nice |
Beta Was this translation helpful? Give feedback.
-
IMO, priority should be given to better and more complete documentation for faster onboarding of new users. And when I say new users I mean users that are relatively new to JS/TS and can't figure out things simply by reading the APIs and the source code. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
5. Multiple Filters Per ColumnI think this screenshot from airtable is an excellent example of a filtering UI which should be possible in v9. The data model required will be more complex, but this kind of flexibility is pretty powerful. |
Beta Was this translation helpful? Give feedback.
-
Are there any plans to fix reactivity problems? #4876 (comment) |
Beta Was this translation helpful? Give feedback.
-
Hello everyone, I really like the work you all have put into such an amazing product. A few ideas for future development considerations:
|
Beta Was this translation helpful? Give feedback.
-
Closing this draft discussion in favor of: #5595 |
Beta Was this translation helpful? Give feedback.
Closing this draft discussion in favor of: #5595