Skip to content

Commit

Permalink
lay ground work for better feature type inference
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinVandy committed Dec 15, 2024
1 parent d77172b commit c4191d7
Show file tree
Hide file tree
Showing 48 changed files with 625 additions and 678 deletions.
53 changes: 9 additions & 44 deletions examples/react/custom-features/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,8 @@ import type {
Column,
ColumnDef,
OnChangeFn,
RowData,
Table,
TableFeature,
TableFeatures,
TableState,
Updater,
} from '@tanstack/react-table'
import type { Person } from './makeData'
Expand All @@ -50,66 +47,34 @@ export interface Table_Density {
toggleDensity: (value?: DensityState) => void
}

// Use declaration merging to add our new feature APIs and state types to TanStack Table's existing types.
declare module '@tanstack/react-table' {
// declare our new feature as a plugin
interface Plugins {
densityPlugin: TableFeature
}
// merge our new feature's state with the existing table state
interface TableState_Plugins extends TableState_Density {}
// merge our new feature's options with the existing table options
interface TableOptions_Plugins extends TableOptions_Density {}
// merge our new feature's instance APIs with the existing table instance APIs
interface Table_Plugins extends Table_Density {}
// if you need to add cell instance APIs...
// interface Cell_Plugins extends Cell_Density {}
// if you need to add row instance APIs...
// interface Row_Plugins extends Row_Density {}
// if you need to add column instance APIs...
// interface Column_Plugins extends Column_Density {}
// if you need to add header instance APIs...
// interface Header_Plugins extends Header_Density {}

// Note: declaration merging on `ColumnDef` is not possible because it is a type, not an interface.
// But you can still use declaration merging on `ColumnDef.meta`
}

// end of TS setup!

// Here is all of the actual javascript code for our new feature
export const densityPlugin: TableFeature = {
export const densityPlugin: TableFeature<{
Table: Table_Density
TableOptions: TableOptions_Density
TableState: TableState_Density
}> = {
// define the new feature's initial state
getInitialState: <TFeatures extends TableFeatures>(
initialState: Partial<TableState<TFeatures>>,
): Partial<TableState<TFeatures>> => {
getInitialState: (initialState) => {
return {
density: 'md',
...initialState, // must come last
}
},

// define the new feature's default options
getDefaultTableOptions: <
TFeatures extends TableFeatures,
TData extends RowData,
>(
table: Table<TFeatures, TData>,
): TableOptions_Density => {
getDefaultTableOptions: (table) => {
return {
enableDensity: true,
onDensityChange: makeStateUpdater('density', table),
} as TableOptions_Density
}
},
// if you need to add a default column definition...
// getDefaultColumnDef: <TFeatures extends TableFeatures, TData extends RowData>(): Partial<ColumnDef<TFeatures, TData>> => {
// return { meta: {} } //use meta instead of directly adding to the columnDef to avoid typescript stuff that's hard to workaround
// },

// define the new feature's table instance methods
constructTableAPIs: <TFeatures extends TableFeatures, TData extends RowData>(
table: Table<TFeatures, TData>,
): void => {
constructTableAPIs: (table) => {
table.setDensity = (updater) => {
const safeUpdater: Updater<DensityState> = (old) => {
const newState = functionalUpdate(updater, old)
Expand Down
1 change: 0 additions & 1 deletion examples/svelte/basic-table-helper/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
const tableHelper = createTableHelper({
_features: { columnSizingFeature: {} },
_rowModels: {}, // client-side row models. `Core` row model is now included by default, but you can still override it here
debugTable: true,
// TData: {} as Person, // optionally, set the TData type for the table helper. Omit if this will be a table helper for multiple tables of all different data types
})
Expand Down
2 changes: 1 addition & 1 deletion examples/svelte/basic-table-helper/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// @ts-ignore
// @ts-ignore - Svelte mount types not properly recognized
import { mount } from 'svelte'
import App from './App.svelte'

Expand Down
2 changes: 1 addition & 1 deletion examples/svelte/column-ordering/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
columnVisibilityFeature,
})
const columns: ColumnDef<any, Person>[] = [
const columns: ColumnDef<typeof _features, Person>[] = [
{
header: 'Name',
footer: (props) => props.column.id,
Expand Down
3 changes: 1 addition & 2 deletions examples/svelte/filtering/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
return itemRank.passed
}
const columns: ColumnDef<any, Person>[] = [
const columns: ColumnDef<typeof _features, Person>[] = [
{
accessorFn: (row) => `${row.firstName} ${row.lastName}`,
id: 'fullName',
Expand Down Expand Up @@ -75,7 +75,6 @@
},
onGlobalFilterChange: setGlobalFilter,
globalFilterFn: fuzzyFilter,
enableMultiRowSelection: true,
})
$effect(() => {
Expand Down
2 changes: 2 additions & 0 deletions examples/svelte/sorting/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
createSortedRowModel,
createTable,
createTableState,
rowSortingFeature,
renderComponent,
sortFns,
tableFeatures,
} from '@tanstack/svelte-table'
import Header from './Header.svelte'
import './index.css'
Expand Down
2 changes: 1 addition & 1 deletion examples/svelte/sorting/src/Header.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import type { Header, rowSortingFeature } from '@tanstack/svelte-table'
import type { Header } from '@tanstack/svelte-table'
import type { Person } from './makeData'
import type { _features } from './tableHelper.svelte'
Expand Down
5 changes: 4 additions & 1 deletion examples/vue/basic/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
createCoreRowModel,
useTable,
createColumnHelper,
tableFeatures,
} from '@tanstack/vue-table'
import { ref } from 'vue'
Expand Down Expand Up @@ -43,7 +44,9 @@ const defaultData: Person[] = [
},
]
const columnHelper = createColumnHelper<any, Person>()
const _features = tableFeatures({})
const columnHelper = createColumnHelper<typeof _features, Person>()
const columns = [
columnHelper.group({
Expand Down
99 changes: 53 additions & 46 deletions examples/vue/column-ordering/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,59 +7,66 @@ import {
type Column,
createColumnHelper,
type ColumnVisibilityState,
columnOrderingFeature,
tableFeatures,
} from '@tanstack/vue-table'
import { makeData, type Person } from './makeData'
import { ref } from 'vue'
import { faker } from '@faker-js/faker'
const columnHelper = createColumnHelper<any, Person>()
const _features = tableFeatures({ columnOrderingFeature })
const columnHelper = createColumnHelper<typeof _features, Person>()
const data = ref(makeData(20))
const columns = ref([
columnHelper.group({
header: 'Name',
footer: (props) => props.column.id,
columns: [
columnHelper.accessor('firstName', {
cell: (info) => info.getValue(),
footer: (props) => props.column.id,
}),
columnHelper.accessor((row) => row.lastName, {
id: 'lastName',
cell: (info) => info.getValue(),
header: () => 'Last Name',
footer: (props) => props.column.id,
}),
],
}),
columnHelper.group({
header: 'Info',
footer: (props) => props.column.id,
columns: [
columnHelper.accessor('age', {
header: () => 'Age',
footer: (props) => props.column.id,
}),
columnHelper.group({
header: 'More Info',
columns: [
columnHelper.accessor('visits', {
header: () => 'Visits',
footer: (props) => props.column.id,
}),
columnHelper.accessor('status', {
header: 'Status',
footer: (props) => props.column.id,
}),
columnHelper.accessor('progress', {
header: 'Profile Progress',
footer: (props) => props.column.id,
}),
],
}),
],
}),
])
const columns = ref(
columnHelper.columns([
columnHelper.group({
header: 'Name',
footer: (props) => props.column.id,
columns: [
columnHelper.accessor('firstName', {
cell: (info) => info.getValue(),
footer: (props) => props.column.id,
}),
columnHelper.accessor((row) => row.lastName, {
id: 'lastName',
cell: (info) => info.getValue(),
header: () => 'Last Name',
footer: (props) => props.column.id,
}),
],
}),
columnHelper.group({
header: 'Info',
footer: (props) => props.column.id,
columns: [
columnHelper.accessor('age', {
header: () => 'Age',
footer: (props) => props.column.id,
}),
columnHelper.group({
header: 'More Info',
columns: [
columnHelper.accessor('visits', {
header: () => 'Visits',
footer: (props) => props.column.id,
}),
columnHelper.accessor('status', {
header: 'Status',
footer: (props) => props.column.id,
}),
columnHelper.accessor('progress', {
header: 'Profile Progress',
footer: (props) => props.column.id,
}),
],
}),
],
}),
]),
)
const columnVisibility = ref<ColumnVisibilityState>({})
const columnOrder = ref<ColumnOrderState>([])
Expand Down
12 changes: 10 additions & 2 deletions examples/vue/column-pinning/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import {
FlexRender,
createCoreRowModel,
useTable,
columnPinningFeature,
tableFeatures,
columnVisibilityFeature,
} from '@tanstack/vue-table'
import type {
Column,
Expand All @@ -16,7 +19,12 @@ import { faker } from '@faker-js/faker'
const data = ref(makeData(5000))
const columnHelper = createColumnHelper<any, Person>()
const _features = tableFeatures({
columnPinningFeature,
columnVisibilityFeature,
})
const columnHelper = createColumnHelper<typeof _features, Person>()
const columns = ref([
columnHelper.group({
Expand Down Expand Up @@ -116,7 +124,7 @@ const randomizeColumns = () => {
)
}
function toggleColumnVisibility(column: Column<any, any>) {
function toggleColumnVisibility(column: Column<typeof _features, Person>) {
columnVisibility.value = {
...columnVisibility.value,
[column.id]: !column.getIsVisible(),
Expand Down
13 changes: 12 additions & 1 deletion examples/vue/filters/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@
import {
ColumnFiltersState,
FlexRender,
columnFilteringFeature,
createColumnHelper,
createCoreRowModel,
createFacetedMinMaxValues,
createFacetedRowModel,
createFacetedUniqueValues,
createFilteredRowModel,
globalFilteringFeature,
tableFeatures,
useTable,
} from '@tanstack/vue-table'
import { ref } from 'vue'
import DebouncedInput from './DebouncedInput.vue'
import Filter from './Filter.vue'
type Person = {
firstName: string
lastName: string
Expand All @@ -21,6 +25,7 @@ type Person = {
status: string
progress: number
}
const defaultData: Person[] = [
{
firstName: 'tanner',
Expand All @@ -47,7 +52,13 @@ const defaultData: Person[] = [
progress: 10,
},
]
const columnHelper = createColumnHelper<any, Person>()
const _features = tableFeatures({
columnFilteringFeature,
globalFilteringFeature,
})
const columnHelper = createColumnHelper<typeof _features, Person>()
const columns = [
columnHelper.group({
header: 'Name',
Expand Down
15 changes: 14 additions & 1 deletion packages/angular-table/src/reactivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { toComputed } from './proxy'
import type { Signal } from '@angular/core'
import type { Table, TableFeature } from '@tanstack/table-core'

// TODO: remove this once we have a better way to define plugins
declare module '@tanstack/table-core' {
interface TableOptions_Plugins {
enableExperimentalReactivity?: boolean
Expand All @@ -14,7 +15,19 @@ declare module '@tanstack/table-core' {
}
}

export const reactivityFeature: TableFeature = {
interface TableOptions_Reactivity {
enableExperimentalReactivity?: boolean
}

interface Table_Reactivity {
_rootNotifier?: Signal<Table<any, any>>
_setRootNotifier?: (signal: Signal<Table<any, any>>) => void
}

export const reactivityFeature: TableFeature<{
TableOptions: TableOptions_Reactivity
Table: Table_Reactivity
}> = {
getDefaultTableOptions(table) {
return { enableExperimentalReactivity: false }
},
Expand Down
2 changes: 1 addition & 1 deletion packages/qwik-table/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,5 @@ export function useTable<
},
}))

return table.instance!
return table.instance! as Table<TFeatures, TData>
}
Loading

0 comments on commit c4191d7

Please sign in to comment.