Skip to content

Commit

Permalink
don't include table features by default anymore
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinVandy committed Sep 16, 2024
1 parent 3ce2287 commit 8b3631d
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 145 deletions.
23 changes: 15 additions & 8 deletions examples/react/row-selection/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,27 @@ import {
createFilteredRowModel,
createPaginatedRowModel,
flexRender,
tableFeatures,
useTable,
} from '@tanstack/react-table'
import { makeData } from './makeData'
import type { Person } from './makeData'
import type { Column, ColumnDef, Table } from '@tanstack/react-table'
import './index.css'

const _features = tableFeatures({
RowPagination,
RowSelection,
ColumnFiltering,
})

function App() {
const rerender = React.useReducer(() => ({}), {})[1]

const [rowSelection, setRowSelection] = React.useState({})
const [globalFilter, setGlobalFilter] = React.useState<string | undefined>('')

const columns = React.useMemo<Array<ColumnDef<any, Person>>>(
const columns = React.useMemo<Array<ColumnDef<typeof _features, Person>>>(
() => [
{
id: 'select',
Expand Down Expand Up @@ -100,11 +107,11 @@ function App() {
[],
)

const [data, setData] = React.useState(() => makeData(100000))
const refreshData = () => setData(() => makeData(100000))
const [data, setData] = React.useState(() => makeData(1_000))
const refreshData = () => setData(() => makeData(100_000)) // stress test

const table = useTable({
_features: { RowPagination, RowSelection, ColumnFiltering },
_features,
_rowModels: {
Core: createCoreRowModel(),
Filtered: createFilteredRowModel(),
Expand All @@ -115,7 +122,7 @@ function App() {
state: {
rowSelection,
},
enableRowSelection: true, //enable row selection for all rows
enableRowSelection: true, // enable row selection for all rows
// enableRowSelection: row => row.original.age > 18, // or enable row selection conditionally per row
onRowSelectionChange: setRowSelection,
debugTable: true,
Expand Down Expand Up @@ -162,7 +169,7 @@ function App() {
{table.getRowModel().rows.map((row) => {
return (
<tr key={row.id}>
{row.getVisibleCells().map((cell) => {
{row.getAllCells().map((cell) => {
return (
<td key={cell.id}>
{flexRender(
Expand Down Expand Up @@ -300,8 +307,8 @@ function Filter({
column,
table,
}: {
column: Column<any, any>
table: Table<any, any>
column: Column<typeof _features, Person>
table: Table<typeof _features, Person>
}) {
const firstValue = table
.getPreFilteredRowModel()
Expand Down
78 changes: 4 additions & 74 deletions packages/angular-table/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,76 +1,6 @@
import { type Signal, computed, signal } from '@angular/core'
import { constructTable } from '@tanstack/table-core'
import { lazyInit } from './lazy-signal-initializer'
import { proxifyTable } from './proxy'
import type {
RowData,
Table,
TableFeatures,
TableOptions,
TableState,
} from '@tanstack/table-core'

export * from '@tanstack/table-core'

export {
type FlexRenderContent,
FlexRenderComponent,
FlexRenderDirective,
injectFlexRenderContext,
} from './flex-render'

export function injectTable<
TFeatures extends TableFeatures,
TData extends RowData,
>(
options: () => TableOptions<TFeatures, TData>,
): Table<TFeatures, TData> & Signal<Table<TFeatures, TData>> {
return lazyInit(() => {
const resolvedOptions = {
state: {},
onStateChange: () => {},
renderFallbackValue: null,
...options(),
}

const table = constructTable(resolvedOptions)

// By default, manage table state here using the table's initial state
const state = signal<TableState<TFeatures>>(table.initialState as any) // TODO: fix type

// Compose table options using computed.
// This is to allow `tableSignal` to listen and set table option
const updatedOptions = computed<TableOptions<TFeatures, TData>>(() => {
// listen to table state changed
const tableState = state()
// listen to input options changed
const tableOptions = options()
return {
...table.options,
...resolvedOptions,
...tableOptions,
state: { ...tableState, ...tableOptions.state },
onStateChange: (updater) => {
const value =
updater instanceof Function ? updater(tableState) : updater
state.set(value)
resolvedOptions.onStateChange(updater)
},
}
})

// convert table instance to signal for proxify to listen to any table state and options changes
const tableSignal = computed(
() => {
table.setOptions(updatedOptions())
return table
},
{
equal: () => false,
},
)

// proxify Table instance to provide ability for consumer to listen to any table state changes
return proxifyTable(tableSignal)
})
}
export * from './flex-render'
export * from './proxy'
export * from './lazy-signal-initializer'
export * from './injectTable'
77 changes: 77 additions & 0 deletions packages/angular-table/src/injectTable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { type Signal, computed, signal } from '@angular/core'
import {
constructTable,
coreFeatures,
getInitialTableState,
} from '@tanstack/table-core'
import { lazyInit } from './lazy-signal-initializer'
import { proxifyTable } from './proxy'
import type {
RowData,
Table,
TableFeatures,
TableOptions,
TableState,
} from '@tanstack/table-core'

export function injectTable<
TFeatures extends TableFeatures,
TData extends RowData,
>(
options: () => TableOptions<TFeatures, TData>,
): Table<TFeatures, TData> & Signal<Table<TFeatures, TData>> {
return lazyInit(() => {
const resolvedOptions = {
...options(),
_features: {
...coreFeatures,
...options()._features,
},
}

const table = constructTable(resolvedOptions)

// By default, manage table state here using the table's initial state
const state = signal<TableState<TFeatures>>(
getInitialTableState(
resolvedOptions._features,
resolvedOptions.initialState,
),
)

// Compose table options using computed.
// This is to allow `tableSignal` to listen and set table option
const updatedOptions = computed<TableOptions<TFeatures, TData>>(() => {
// listen to table state changed
const tableState = state()
// listen to input options changed
const tableOptions = options()
return {
...table.options,
...resolvedOptions,
...tableOptions,
state: { ...tableState, ...tableOptions.state },
onStateChange: (updater) => {
const value =
updater instanceof Function ? updater(tableState) : updater
state.set(value)
resolvedOptions.onStateChange?.(updater)
},
}
})

// convert table instance to signal for proxify to listen to any table state and options changes
const tableSignal = computed(
() => {
table.setOptions(updatedOptions())
return table
},
{
equal: () => false,
},
)

// proxify Table instance to provide ability for consumer to listen to any table state changes
return proxifyTable(tableSignal)
})
}
4 changes: 2 additions & 2 deletions packages/angular-table/tests/createAngularTable.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { describe, expect, test } from 'vitest'
import { Component, input, isSignal, signal, untracked } from '@angular/core'
import { TestBed } from '@angular/core/testing'
import { createCoreRowModel, injectTable } from '../src/index'
import { createCoreRowModel, injectTable } from '../src/injectTable'
import { setSignalInputs } from './test-utils'
import type { ColumnDef, Table } from '../src/index'
import type { ColumnDef, Table } from '../src/injectTable'

describe('injectTable', () => {
test('should render with required signal inputs', () => {
Expand Down
17 changes: 11 additions & 6 deletions packages/react-table/src/useTable.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import * as React from 'react'

import { useState, useRef } from 'react'
import {
constructTable,
builtInFeatures,
getInitialTableState,
coreFeatures,
} from '@tanstack/table-core'
import type {
RowData,
Expand All @@ -13,10 +12,13 @@ import type {
TableState,
} from '@tanstack/table-core'

/**
* Creates a table instance and caches it in a ref so that it will only be constructed once.
*/
function useTableRef<TFeatures extends TableFeatures, TData extends RowData>(
options: TableOptions<TFeatures, TData>,
): Table<TFeatures, TData> {
const tableRef = React.useRef<Table<TFeatures, TData>>()
const tableRef = useRef<Table<TFeatures, TData>>()

if (!tableRef.current) {
tableRef.current = constructTable(options)
Expand All @@ -33,12 +35,15 @@ export function useTable<
TFeatures extends TableFeatures,
TData extends RowData,
>(tableOptions: TableOptions<TFeatures, TData>): Table<TFeatures, TData> {
const [state, setState] = React.useState<TableState<TFeatures>>(() =>
getInitialTableState(builtInFeatures, tableOptions.initialState),
const _features = { ...coreFeatures, ...tableOptions._features }

const [state, setState] = useState<TableState<TFeatures>>(() =>
getInitialTableState(_features, tableOptions.initialState),
)

const statefulOptions: TableOptions<TFeatures, TData> = {
...tableOptions,
_features,
state: { ...state, ...tableOptions.state },
onStateChange: (updater) => {
setState(updater)
Expand Down
7 changes: 7 additions & 0 deletions packages/table-core/src/core/coreFeatures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Rows } from './rows/Rows'
import { Cells } from './cells/Cells'
import { Columns } from './columns/Columns'
import { Headers } from './headers/Headers'
import { Tables } from './table/Tables'

export const coreFeatures = { Tables, Rows, Headers, Columns, Cells }
60 changes: 5 additions & 55 deletions packages/table-core/src/core/table/constructTable.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,11 @@
import { Headers } from '../headers/Headers'
import { Rows } from '../rows/Rows'
import { Cells } from '../cells/Cells'
import { Columns } from '../columns/Columns'
import { ColumnFaceting } from '../../features/column-faceting/ColumnFaceting'
import { ColumnFiltering } from '../../features/column-filtering/ColumnFiltering'
import { ColumnGrouping } from '../../features/column-grouping/ColumnGrouping'
import { ColumnOrdering } from '../../features/column-ordering/ColumnOrdering'
import { ColumnPinning } from '../../features/column-pinning/ColumnPinning'
import { ColumnResizing } from '../../features/column-resizing/ColumnResizing'
import { ColumnSizing } from '../../features/column-sizing/ColumnSizing'
import { ColumnVisibility } from '../../features/column-visibility/ColumnVisibility'
import { GlobalFaceting } from '../../features/global-faceting/GlobalFaceting'
import { GlobalFiltering } from '../../features/global-filtering/GlobalFiltering'
import { RowExpanding } from '../../features/row-expanding/RowExpanding'
import { RowPagination } from '../../features/row-pagination/RowPagination'
import { RowPinning } from '../../features/row-pinning/RowPinning'
import { RowSelection } from '../../features/row-selection/RowSelection'
import { RowSorting } from '../../features/row-sorting/RowSorting'
import { Tables } from './Tables'
import { isDev } from '../../utils'
import type { Table_CoreProperties } from './Tables.types'
import type { RowData } from '../../types/type-utils'
import type {
CoreTableFeatures,
TableFeature,
TableFeatures,
} from '../../types/TableFeatures'
import type { TableFeature, TableFeatures } from '../../types/TableFeatures'
import type { Table } from '../../types/Table'
import type { TableOptions } from '../../types/TableOptions'
import type { TableState } from '../../types/TableState'

export const coreFeatures = { Tables, Rows, Headers, Columns, Cells }

export const builtInFeatures = {
ColumnFaceting,
ColumnFiltering,
ColumnGrouping,
ColumnOrdering,
ColumnPinning,
ColumnResizing,
ColumnSizing,
ColumnVisibility,
GlobalFaceting,
GlobalFiltering,
RowExpanding,
RowPagination,
RowPinning,
RowSelection,
RowSorting,
}

export function getInitialTableState<TFeatures extends TableFeatures>(
features: TableFeatures,
initialState: Partial<TableState<TFeatures>> | undefined = {},
Expand All @@ -63,18 +20,11 @@ export function constructTable<
TFeatures extends TableFeatures,
TData extends RowData,
>(options: TableOptions<TFeatures, TData>): Table<TFeatures, TData> {
if (
process.env.NODE_ENV !== 'production' &&
(options.debugAll || options.debugTable)
) {
console.info('Creating Table Instance...')
if (isDev && (options.debugAll || options.debugTable)) {
console.info('Constructing Table Instance...')
}

const _features = {
...coreFeatures,
...builtInFeatures,
...options._features,
} as CoreTableFeatures & TFeatures
const { _features } = options

const featuresList: Array<TableFeature> = Object.values(_features)

Expand Down
Loading

0 comments on commit 8b3631d

Please sign in to comment.