Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"preview": "vite preview"
},
"dependencies": {
"@tanstack/vue-query": "^5.74.0",
"@tanstack/vue-table": "^8.21.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
Expand Down
44 changes: 33 additions & 11 deletions examples/basic/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { TSTable } from 'tanstack-table-vue'
import { createColumnHelper, FlexRender, getCoreRowModel, getSortedRowModel, type Column } from '@tanstack/vue-table'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from './components/ui/table'
import { useQuery } from '@tanstack/vue-query'


interface Person {
Expand Down Expand Up @@ -40,6 +41,14 @@ const defaultData: Person[] = [
},
]

const { data, isLoading } = useQuery({
queryKey: ['people'],
queryFn: async () => {
await new Promise(resolve => setTimeout(resolve, 2000))
return defaultData
},
})

function getSortIcon(column: Column<Person>) {
if (!column.getCanSort?.()) return null

Expand All @@ -66,20 +75,19 @@ function getStatusClass(status: string) {

const columnHelper = createColumnHelper<Person>()

// Create columns with type assertion
const columns = [
columnHelper.group({
id: 'name',
header: 'Name',
columns: [
columnHelper.accessor('firstName', {}),
columnHelper.accessor('lastName', {}),
],
columnHelper.display({
id: 'avatar',
header: 'Avatar',
}),
columnHelper.accessor('firstName', {}),
columnHelper.accessor('lastName', {}),
columnHelper.accessor('age', {}),
columnHelper.group({
id: 'info',
header: 'Info',
columns: [
columnHelper.accessor('age', {}),
columnHelper.group({
id: 'moreInfo',
header: 'More Info',
Expand All @@ -91,6 +99,10 @@ const columns = [
}),
],
}),
columnHelper.display({
id: 'actions',
header: 'Actions',
})
]

const tableOptions = {
Expand Down Expand Up @@ -136,11 +148,21 @@ const tableOptions = {
</TableRow>
</TableHeader>
<TableBody>
<TableRow v-for="row in table.getRowModel().rows" :key="row.id">
<TableCell v-for="cell in row.getVisibleCells()" :key="cell.id">
<FlexRender :render="cell.column.columnDef.cell" :props="cell.getContext()" />
<TableRow v-if="isLoading" v-for="i in 5" :key="`skeleton-${i}`">
<TableCell v-for="j in table.getAllLeafColumns().length" :key="`cell-${i}-${j}`" class="py-3">
<div class="h-5 w-full bg-muted rounded animate-pulse"></div>
</TableCell>
</TableRow>
<template v-else-if="table.getRowModel().rows?.length">
<TableRow v-for="row in table.getRowModel().rows" :key="row.id">
<TableCell v-for="cell in row.getVisibleCells()" :key="cell.id">
<FlexRender :render="cell.column.columnDef.cell" :props="cell.getContext()" />
</TableCell>
</TableRow>
</template>
<TableRow v-else>
<TableCell colspan="100%" class="h-24 text-center">No results.</TableCell>
</TableRow>
</TableBody>
</Table>
</template>
Expand Down
4 changes: 3 additions & 1 deletion examples/basic/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { VueQueryPlugin } from '@tanstack/vue-query'

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'

createApp(App).mount('#app')
createApp(App).use(VueQueryPlugin).mount('#app')
4 changes: 2 additions & 2 deletions packages/core/src/components/TSTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { ColumnDef, RowData, Table } from '@tanstack/vue-table'
import type { CellSlotProps, FooterSlotProps, HeaderSlotProps } from '../shared/types'

export interface TSTableProps<TData extends RowData & object> {
columns: ColumnDef<TData>[]
columns: ColumnDef<TData, any>[]
data: TData[]
tableOptions?: Record<string, any>
}
Expand All @@ -21,7 +21,7 @@ const columnHelper = createColumnHelper<TData>()

const processedColumns = computed(() => {
const initialTable = useVueTable<TData>({
columns: props.columns as unknown as TStackColumnDef<TData>[],
columns: props.columns as TStackColumnDef<TData, any>[],
data: props.data,
getCoreRowModel: getCoreRowModel(),
...props.tableOptions
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/shared/types.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import type { CellContext, Column, HeaderContext, Row, RowData } from '@tanstack/vue-table'

export interface HeaderSlotProps<TData extends RowData> {
column: Column<TData>
context: HeaderContext<TData, unknown>
column: Column<TData, any>
context: HeaderContext<TData, any>
}

export interface CellSlotProps<TData extends RowData> {
row: Row<TData>
context: CellContext<TData, unknown>
context: CellContext<TData, any>
value: any
}

export interface FooterSlotProps<TData extends RowData> {
column: Column<TData>
context: HeaderContext<TData, unknown>
column: Column<TData, any>
context: HeaderContext<TData, any>
}
42 changes: 21 additions & 21 deletions packages/core/src/shared/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import type { Slots } from 'vue'
import capitalize from 'lodash.capitalize'

const getHeader = <TData extends RowData & object>(
col: ColumnDef<TData>,
col: ColumnDef<TData, any>,
slots: Readonly<Slots>,
context: HeaderContext<TData, unknown>,
context: HeaderContext<TData, any>,
) => {
const columnId = (col as any).accessorKey || col.id || ''
const slotName = `header-${columnId}`
Expand All @@ -36,9 +36,9 @@ const getHeader = <TData extends RowData & object>(
}

const getFooter = <TData extends RowData & object>(
col: ColumnDef<TData>,
col: ColumnDef<TData, any>,
slots: Readonly<Slots>,
context: HeaderContext<TData, unknown>,
context: HeaderContext<TData, any>,
) => {
const columnId = (col as any).accessorKey || col.id || ''
const slotName = `footer-${columnId}`
Expand All @@ -60,9 +60,9 @@ const getFooter = <TData extends RowData & object>(
}

const getCell = <TData extends RowData & object>(
col: ColumnDef<TData>,
col: ColumnDef<TData, any>,
slots: Readonly<Slots>,
context: CellContext<TData, unknown>,
context: CellContext<TData, any>,
) => {
const columnId = (col as any).accessorKey || col.id || ''
const slotName = `cell-${columnId}`
Expand All @@ -86,18 +86,18 @@ const getCell = <TData extends RowData & object>(

export const processColumns = <TData extends RowData & object>(
columnHelper: ColumnHelper<TData>,
columns: ColumnDef<TData>[],
columns: ColumnDef<TData, any>[],
slots: Readonly<Slots>,
table: Table<TData>,
): TStackColumnDef<TData>[] => {
return columns.map((col): TStackColumnDef<TData> => {
): TStackColumnDef<TData, any>[] => {
return columns.map((col): TStackColumnDef<TData, any> => {
// Handle group columns by checking if columns property exists
if ('columns' in col && Array.isArray(col.columns)) {
return columnHelper.group({
id: col.id || String(Math.random()),
header: (context: HeaderContext<TData, unknown>) => getHeader(col, slots, context),
footer: col.footer ? (context: HeaderContext<TData, unknown>) => getFooter(col, slots, context) : undefined,
columns: processColumns(columnHelper, col.columns, slots, table),
header: (context: HeaderContext<TData, any>) => getHeader(col, slots, context),
footer: col.footer ? (context: HeaderContext<TData, any>) => getFooter(col, slots, context) : undefined,
columns: processColumns(columnHelper, col.columns as ColumnDef<TData, any>[], slots, table),
meta: col.meta,
})
}
Expand All @@ -107,29 +107,29 @@ export const processColumns = <TData extends RowData & object>(
if (accessorCol.accessorKey) {
return columnHelper.accessor(accessorCol.accessorKey, {
id: accessorCol.id || accessorCol.accessorKey,
header: (context: HeaderContext<TData, unknown>) => getHeader(col, slots, context),
footer: col.footer ? (context: HeaderContext<TData, unknown>) => getFooter(col, slots, context) : undefined,
cell: (context: CellContext<TData, unknown>) => getCell(col, slots, context),
header: (context: HeaderContext<TData, any>) => getHeader(col, slots, context),
footer: col.footer ? (context: HeaderContext<TData, any>) => getFooter(col, slots, context) : undefined,
cell: (context: CellContext<TData, any>) => getCell(col, slots, context),
meta: col.meta,
})
}

if (accessorCol.accessorFn) {
return columnHelper.accessor(accessorCol.accessorFn, {
id: accessorCol.id || String(Math.random()),
header: (context: HeaderContext<TData, unknown>) => getHeader(col, slots, context),
footer: col.footer ? (context: HeaderContext<TData, unknown>) => getFooter(col, slots, context) : undefined,
cell: (context: CellContext<TData, unknown>) => getCell(col, slots, context),
header: (context: HeaderContext<TData, any>) => getHeader(col, slots, context),
footer: col.footer ? (context: HeaderContext<TData, any>) => getFooter(col, slots, context) : undefined,
cell: (context: CellContext<TData, any>) => getCell(col, slots, context),
meta: col.meta,
})
}

// Default case - treat as display column
return columnHelper.display({
id: col.id || String(Math.random()),
header: (context: HeaderContext<TData, unknown>) => getHeader(col, slots, context),
footer: col.footer ? (context: HeaderContext<TData, unknown>) => getFooter(col, slots, context) : undefined,
cell: (context: CellContext<TData, unknown>) => getCell(col, slots, context),
header: (context: HeaderContext<TData, any>) => getHeader(col, slots, context),
footer: col.footer ? (context: HeaderContext<TData, any>) => getFooter(col, slots, context) : undefined,
cell: (context: CellContext<TData, any>) => getCell(col, slots, context),
meta: col.meta,
})
})
Expand Down
58 changes: 58 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.