Skip to content

Commit a10febd

Browse files
authored
feat: improve TSTable component with enhanced TypeScript support and data handling (#5)
1 parent ce31ca5 commit a10febd

File tree

4 files changed

+43
-23
lines changed

4 files changed

+43
-23
lines changed

examples/basic/src/App.vue

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<script setup lang="ts">
2-
import { TSTable } from 'tanstack-table-vue'
3-
import { createColumnHelper, FlexRender, getCoreRowModel, getSortedRowModel, type Column } from '@tanstack/vue-table'
2+
import { TSTable, type TableOptions } from 'tanstack-table-vue'
3+
import { createColumnHelper, FlexRender, getSortedRowModel, type Column } from '@tanstack/vue-table'
44
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './components/ui/table'
55
import { useQuery } from '@tanstack/vue-query'
6+
import { computed } from 'vue'
67
78
89
interface Person {
@@ -49,6 +50,13 @@ const { data, isLoading } = useQuery({
4950
},
5051
})
5152
53+
const persons = computed(() => {
54+
if (data.value) {
55+
return data.value
56+
}
57+
return []
58+
})
59+
5260
function getSortIcon(column: Column<Person>) {
5361
if (!column.getCanSort?.()) return null
5462
@@ -90,7 +98,7 @@ const columns = [
9098
columns: [
9199
columnHelper.group({
92100
id: 'moreInfo',
93-
header: 'More Info',
101+
header: 'More Info ',
94102
columns: [
95103
columnHelper.accessor('visits', {}),
96104
columnHelper.accessor('status', {}),
@@ -105,16 +113,15 @@ const columns = [
105113
})
106114
]
107115
108-
const tableOptions = {
116+
const tableOptions: TableOptions = {
109117
getSortedRowModel: getSortedRowModel(),
110-
getCoreRowModel: getCoreRowModel(),
111118
}
112119
</script>
113120

114121
<template>
115122
<div class="container mx-auto p-4">
116123
<h1 class="text-2xl font-bold mb-4">TSTable with Slots Example</h1>
117-
<TSTable :columns="columns" :data="defaultData" :tableOptions="tableOptions">
124+
<TSTable :columns="columns" :data="persons" :tableOptions="tableOptions">
118125

119126
<template #header-firstName="{ column }">
120127
<div class="flex items-center cursor-pointer" @click="column.toggleSorting()">

packages/core/src/components/TSTable.vue

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,57 @@
11
<script lang="ts">
2-
import type { ColumnDef, RowData, Table } from '@tanstack/vue-table'
2+
import type { ColumnDef, RowData, Table, TableOptionsWithReactiveData } from '@tanstack/vue-table'
33
import type { CellSlotProps, FooterSlotProps, HeaderSlotProps } from '../shared/types'
44
5+
export type TableOptions = Omit<TableOptionsWithReactiveData<any>, 'columns' | 'data' | 'getCoreRowModel'>
6+
57
export interface TSTableProps<TData extends RowData & object> {
68
columns: ColumnDef<TData, any>[]
79
data: TData[]
8-
tableOptions?: Record<string, any>
10+
tableOptions?: TableOptions
911
}
1012
</script>
1113

1214
<script setup lang="ts" generic="TData extends RowData & object">
13-
import { computed, useSlots } from 'vue'
14-
import { useVueTable, createColumnHelper, type ColumnDef as TStackColumnDef, getCoreRowModel } from '@tanstack/vue-table'
15+
import { computed, useSlots, watch } from 'vue'
16+
import { useVueTable, createColumnHelper, getCoreRowModel } from '@tanstack/vue-table'
1517
import { processColumns } from '../shared'
1618
1719
const props = defineProps<TSTableProps<TData>>()
1820
1921
const slots = useSlots()
2022
const columnHelper = createColumnHelper<TData>()
2123
24+
// Use memo pattern for expensive column processing
2225
const processedColumns = computed(() => {
23-
const initialTable = useVueTable<TData>({
24-
columns: props.columns as TStackColumnDef<TData, any>[],
25-
data: props.data,
26-
getCoreRowModel: getCoreRowModel(),
27-
...props.tableOptions
28-
})
29-
return processColumns(columnHelper, props.columns, slots, initialTable)
26+
return processColumns(columnHelper, props.columns, slots)
3027
})
3128
32-
const tableOptions = {
29+
// Create initial table options
30+
const initialTableOptions = {
3331
columns: processedColumns.value,
3432
data: props.data,
3533
getCoreRowModel: getCoreRowModel(),
3634
...props.tableOptions
3735
}
3836
39-
const table = useVueTable<TData>(tableOptions)
37+
// Initialize table with initial options
38+
const table = useVueTable<TData>(initialTableOptions)
39+
40+
// Watch for data changes and update table efficiently
41+
watch(() => props.data, (newData) => {
42+
table.setOptions((old) => ({
43+
...old,
44+
data: newData,
45+
}))
46+
}, { flush: 'sync' })
47+
48+
// Watch columns separately to avoid unnecessary recalculations
49+
watch(processedColumns, (newColumns) => {
50+
table.setOptions((old) => ({
51+
...old,
52+
columns: newColumns,
53+
}))
54+
}, { flush: 'sync' })
4055
4156
defineSlots<{
4257
default: (props: {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export { default as TSTable, type TSTableProps } from './TSTable.vue'
1+
export { default as TSTable, type TSTableProps, type TableOptions } from './TSTable.vue'

packages/core/src/shared/utils.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import type {
44
CellContext,
55
RowData,
66
ColumnDef as TStackColumnDef,
7-
Table,
87
ColumnDef,
98
} from '@tanstack/vue-table'
109
import type { Slots } from 'vue'
@@ -88,7 +87,6 @@ export const processColumns = <TData extends RowData & object>(
8887
columnHelper: ColumnHelper<TData>,
8988
columns: ColumnDef<TData, any>[],
9089
slots: Readonly<Slots>,
91-
table: Table<TData>,
9290
): TStackColumnDef<TData, any>[] => {
9391
return columns.map((col): TStackColumnDef<TData, any> => {
9492
// Handle group columns by checking if columns property exists
@@ -97,7 +95,7 @@ export const processColumns = <TData extends RowData & object>(
9795
id: col.id || String(Math.random()),
9896
header: (context: HeaderContext<TData, any>) => getHeader(col, slots, context),
9997
footer: col.footer ? (context: HeaderContext<TData, any>) => getFooter(col, slots, context) : undefined,
100-
columns: processColumns(columnHelper, col.columns as ColumnDef<TData, any>[], slots, table),
98+
columns: processColumns(columnHelper, col.columns as ColumnDef<TData, any>[], slots),
10199
meta: col.meta,
102100
})
103101
}

0 commit comments

Comments
 (0)