Skip to content

Commit

Permalink
fix: improve reactivity for data in Vue-adapter (#5694)
Browse files Browse the repository at this point in the history
  • Loading branch information
OlaAlsaker authored Aug 5, 2024
1 parent 2fea8c2 commit 7331506
Showing 1 changed file with 41 additions and 47 deletions.
88 changes: 41 additions & 47 deletions packages/vue-table/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
TableOptions,
createTable,
TableOptionsResolved,
RowData,
} from '@tanstack/table-core'
import { TableOptions, createTable, RowData } from '@tanstack/table-core'
import {
h,
watchEffect,
Expand All @@ -12,6 +7,7 @@ import {
isRef,
unref,
MaybeRef,
watch,
} from 'vue'
import { mergeProxy } from './merge-proxy'

Expand All @@ -24,13 +20,6 @@ type TableOptionsWithReactiveData<TData extends RowData> = Omit<
data: MaybeRef<TData[]>
}

type TableOptionsResolvedWithReactiveData<TData extends RowData> = Omit<
TableOptionsResolved<TData>,
'data'
> & {
data: MaybeRef<TData[]>
}

export const FlexRender = defineComponent({
props: ['render', 'props'],
setup: (props: { render: any; props: any }) => {
Expand All @@ -47,33 +36,48 @@ export const FlexRender = defineComponent({
},
})

export function useVueTable<TData extends RowData>(
function getOptionsWithReactiveData<TData extends RowData>(
options: TableOptionsWithReactiveData<TData>
) {
const resolvedOptions: TableOptionsResolvedWithReactiveData<TData> =
mergeProxy(
{
state: {}, // Dummy state
onStateChange: () => {}, // noop
renderFallbackValue: null,
mergeOptions(
defaultOptions: TableOptions<TData>,
options: TableOptions<TData>
) {
return mergeProxy(defaultOptions, options)
},
return mergeProxy(options, {
data: unref(options.data),
})
}

export function useVueTable<TData extends RowData>(
initialOptions: TableOptionsWithReactiveData<TData>
) {
const resolvedOptions = mergeProxy(
{
state: {}, // Dummy state
onStateChange: () => {}, // noop
renderFallbackValue: null,
mergeOptions(
defaultOptions: TableOptions<TData>,
options: TableOptions<TData>
) {
return mergeProxy(defaultOptions, options)
},
options
)
},
getOptionsWithReactiveData(initialOptions)
)

const table = createTable<TData>(resolvedOptions)

// Add support for reactivity
if (isRef(options.data)) {
resolvedOptions.data = unref(options.data)
// Add reactivity support
if (isRef(initialOptions.data)) {
watch(
initialOptions.data,
() => {
table.setState(prev => ({
...prev,
data: unref(initialOptions.data),
}))
},
{ immediate: true, deep: true }
)
}

const table = createTable<TData>(
resolvedOptions as TableOptionsResolved<TData>
)
// can't use `reactive` because update needs to be immutable
const state = ref(table.initialState)

Expand All @@ -83,11 +87,11 @@ export function useVueTable<TData extends RowData>(
get: (_, prop) => state.value[prop as keyof typeof state.value],
})

const newOptions = mergeProxy(prev, options, {
return mergeProxy(prev, getOptionsWithReactiveData(initialOptions), {
// merge the initialState and `options.state`
// create a new proxy on each `setOptions` call
// and get the value from state on each property access
state: mergeProxy(stateProxy, options.state ?? {}),
state: mergeProxy(stateProxy, initialOptions.state ?? {}),
// Similarly, we'll maintain both our internal state and any user-provided
// state.
onStateChange: (updater: any) => {
Expand All @@ -97,19 +101,9 @@ export function useVueTable<TData extends RowData>(
state.value = updater
}

options.onStateChange?.(updater)
initialOptions.onStateChange?.(updater)
},
})

// Add support for reactivity
if (isRef(options.data)) {
return {
...newOptions,
data: unref(options.data),
}
}

return newOptions
})
})

Expand Down

0 comments on commit 7331506

Please sign in to comment.